Создание разметки Pushpin по SVG
Пример IoT от моего коллеги Philippe очень впечетляет. Одной из особенностей является разметка pushpin, которая представляет собой датчик в модели. Разметка построена SVG. 2 года назад, Philippe также создал блог о работе с разметкой SVG в Forge Viewer. Хотя рабочий процесс немного сложнее для некоторых клиентов, поскольку он включает в себя комплексные функции, результатом которых является отличная демонстрация.
Итак, я попытался изолировать основной раздел, чтобы сделать небольшой пример: когда пользователь нажимает на местоположение объекта, будет создана разметка pushpin. Хотя Forge Viewer 6.0 предоставляет расширение Pushpin, я думаю, что основная логика SVG также будет полезна в некоторых сценариях.
Некоторые трюки для обмена:
- SVG содержится в svg элементе, а svg обернут div DOM.
- Графика SVG просчитывается библиотекой JavaScript svg-snap, благодаря которой мы можем динамически манипулировать графикой. В моем примере, радиус круга является фиксированным.
- Поскольку SVG отображается в пространстве экрана в 2D-координации, когда камера Forge Viewer изменяется, нам необходимо обновить местоположение SVG соответственно в случае события CAMERA_CHANGE_EVENT. Forge Viewer предоставляет метод worldToClient, который может преобразовать позицию 3D-модели в координаты2D-экрана.
- В CAMERA_CHANGE_EVENT, исходная позиция 3D-модели будет недоступна. В моем примере я прикрепляю 3D-данные к SVG DOM с помощью словаря DOM.data.
- Чтобы получить выбранную позицию объекта, образец использует viewer.impl.hitTest, который может обеспечить точку пересечения и dbid объекта.
- //предположим, что _viewer3D доступен
- var _viewer3D;
- function init(){
- //делегировать событие щелчка мыши
- $(_viewer3D.container).bind("click", onMouseClick);
- // делегировать событие CAMERA_CHANGE_EVENT
- _viewer3D.addEventListener(Autodesk.Viewing.CAMERA_CHANGE_EVENT, function(rt){
- // находим все разметки pushpin
- var $eles = $("div[id^='mymk']");
- var DOMeles = $eles.get();
- for(var index in DOMeles){
- // получить каждый элемент DOM
- var DOMEle = DOMeles[index];
- var divEle = $('#' + DOMEle.id);
- // выходим из трехмерной системы координат
- var val = divEle.data('3DData');
- var pushpinModelPt = JSON.parse(val);
- // получаем обновленную точку экрана
- var screenpoint = _viewer3D.worldToClient(new THREE.Vector3(
- pushpinModelPt.x,
- pushpinModelPt.y,
- pushpinModelPt.z,));
- // обновляем позицию SVG.
- divEle.css({
- 'left': screenpoint.x - pushpinModelPt.rad*2,
- 'top': screenpoint.y - pushpinModelPt.rad
- });
- }
- });
- }
- function onMouseClick (event) {
- var screenPoint = {
- x: event.clientX,
- y: event.clientY
- };
- // получаем выбранную трехмерную позицию объекта
- var hitTest = _viewer3D.impl.hitTest(screenPoint.x,screenPoint.y,true);
- if(hitTest)
- {
- drawPushpin({x:hitTest1.intersectPoint.x,
- y:hitTest1.intersectPoint.y,
- z:hitTest1.intersectPoint.z});
- }
- }
- // генерируем случайный идентификатор для каждой разметки pushpin
- function makeid() {
- var text = "";
- var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
- for( var i=0; i < 5; i++ )
- text += possible.charAt(Math.floor(Math.random() * possible.length));
- return text;
- }
- function drawPushpin(pushpinModelPt){
- // конвертирование 3D-позиции в координаты 2D-экрана
- var screenpoint = _viewer3D.worldToClient(
- new THREE.Vector3(pushpinModelPt.x,
- pushpinModelPt.y,
- pushpinModelPt.z,));
- // создаем контейнер div
- var randomId = makeid();
- var htmlMarker = '<div id="mymk' + randomId + '"></div>';
- var parent = _viewer3D.container
- $(parent).append(htmlMarker);
- $('#mymk'+randomId ).css({
- 'pointer-events': 'none',
- 'width': '20px',
- 'height': '20px',
- 'position': 'absolute',
- 'overflow': 'visible'
- });
- // создаем элемент svg и нарисуем круг
- $('#mymk'+randomId).append('<svg id="mysvg'+randomId+ '"></svg>')
- var snap = Snap($('#mysvg'+randomId)[0]);
- var rad = 12;
- var circle = snap.paper.circle(14, 14, rad);
- circle.attr({
- fill: "#FF8888",
- fillOpacity: 0.6,
- stroke: "#FF0000",
- strokeWidth: 3
- });
- // установить положение SVG
- // настраиваем, чтобы центр окружности представлял собой положение точки щелчка
- var $container = $('#mymk'+randomId);
- $container.css({
- 'left': screenpoint.x - rad*2,
- 'top': screenpoint.y - rad
- });
- // сохраняем данные 3D-точки в DOM
- var div = $('#mymk'+randomId);
- // добавление информации о радиусе с помощью трехмерных данных
- pushpinModelPt.radius = rad;
- var storeData = JSON.stringify(pushpinModelPt);
- div.data('3DData', storeData);
- }
- init();
Источник: https://forge.autodesk.com/blog/create-pushpin-markup-svg
Обсуждение: http://adn-cis.org/forum/index.php?topic=
Опубликовано 09.08.2018Отредактировано 09.08.2018 в 17:29:28