Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 30.11.2018, 17:31
Новичок на форуме
Отправить личное сообщение для Vad0k Посмотреть профиль Найти все сообщения от Vad0k
 
Регистрация: 30.11.2018
Сообщений: 8

Визуализация связей между блоками с использованием SVG и JS
Доброго времени форумчане.
Сижу сейчас на работе и тут мне прилетело задание сделать визуальный конфигуратор ... застрял на реализации связей между компонентами:
Реализовываю с использованием SVG + JS (ES6)... Перенос элементов реализовал, но линии прям не поддаются пока что сделать. Подумал перейти на библиотеку, чтобы упростить работу (связывания элементов).
Посоветуйте, по возможности алгоритм или библиотеку для манипулирования SVG (построение связей).


// Перетаскивание элементов
(function () {
    let $document = $(document);

    const $svg = $('#main .canvas-svg');
    // PC
    $document.on('mousedown', $svg, startDrag);
    $document.on('mousemove', $svg, drag);
    $document.on('mouseup', $svg, endDrag);
    $document.on('mouseleave', $svg, endDrag);

    // MOBILE
    $document.on('touchstart', $svg, startDrag);
    $document.on('touchmove', $svg, drag);
    $document.on('touchend', $svg, endDrag);
    $document.on('touchleave', $svg, endDrag);
    $document.on('touchcancel', $svg, endDrag);


    let selectedElement = false,
        offsetElement,
        transformElement;

    let selectLineChanel = false;
    let arrayLineChanel = [];

    function startDrag(e) {

        if (e.target.classList.contains('input-chanel')) { // при наведении на точку канала
            let lineChanel = document.createElementNS('http://www.w3.org/2000/svg', 'line');
            lineChanel.setAttributeNS(null, 'x1', e.target.getAttributeNS(null,'cx'));
            lineChanel.setAttributeNS(null, 'y1', e.target.getAttributeNS(null,'cy'));
            lineChanel.setAttributeNS(null, 'stroke-width', 5);
            lineChanel.setAttributeNS(null,'stroke', '#000');
            e.target.parentNode.insertBefore(lineChanel, e.target);
            arrayLineChanel.push(lineChanel); // добавляем линию в массив
            selectLineChanel = true;

            console.log('startDrawLine');
        } else if (e.target.classList.contains('draggable')) { // при наведении на элемент
            selectedElement = e.target;
            initialiseDragging(e);
            console.log('startDragElement')
        } else if (e.target.parentNode.classList.contains('draggable-group')) {
            selectedElement = e.target.parentNode;
            initialiseDragging(e);
            console.log('startDragElement');
        }
    }
    function drag(e) {
        if(selectLineChanel){
            e.preventDefault();
            let coord = getMousePosition(e);
            arrayLineChanel[arrayLineChanel.length-1].setAttributeNS(null, 'x2',coord.x - offsetElement.x);
            arrayLineChanel[arrayLineChanel.length-1].setAttributeNS(null, 'y2',coord.y - offsetElement.y);
            console.log('drawLine:',coord.x, offsetElement.x);
        } else if (selectedElement) {
            e.preventDefault();
            let coord = getMousePosition(e);
            transformElement.setTranslate(coord.x - offsetElement.x, coord.y - offsetElement.y);
            console.log('drag');
        }
    }
    function endDrag(e) {
        if(selectLineChanel && !e.target.classList.contains('output-chanel')){
            arrayLineChanel[arrayLineChanel.length-1].remove();
            selectLineChanel = false;
            console.log('endDrawLine');
        }

        if(selectedElement){
            selectedElement = false;
            console.log('endDragElement');
        }

    }

    function getMousePosition(e) {
        let CTM = activeSVG.getScreenCTM(); // Возвращает DOMMatrix, представляющую матрицу, которая преобразует систему координат текущего элемента в систему координат окна просмотра SVG для фрагмента документа SVG.
        if (e.touches) { e = e.touches[0]; } // iPhone
        return {
            x: (e.clientX - CTM.e) / CTM.a,
            y: (e.clientY - CTM.f) / CTM.d
        }
    }

    function initialiseDragging(e) {
        offsetElement = getMousePosition(e);
        // Make sure the first transformElement on the element is a translate transformElement
        let transforms = selectedElement.transform.baseVal;
        if (transforms.length === 0 || transforms.getItem(0).type !== SVGTransform.SVG_TRANSFORM_TRANSLATE) {
            // Create an transformElement that translates by (0, 0)
            let translate = activeSVG.createSVGTransform();
            translate.setTranslate(0, 0);
            selectedElement.transform.baseVal.insertItemBefore(translate, 0);
        }
        // Get initial translation
        transformElement = transforms.getItem(0);
        offsetElement.x -= transformElement.matrix.e;
        offsetElement.y -= transformElement.matrix.f;
    }

})();

Последний раз редактировалось Vad0k, 30.11.2018 в 17:35.
Ответить с цитированием
  #2 (permalink)  
Старый 30.11.2018, 19:28
Аватар для j0hnik
Профессор
Отправить личное сообщение для j0hnik Посмотреть профиль Найти все сообщения от j0hnik
 
Регистрация: 01.12.2016
Сообщений: 3,650

https://www.youtube.com/watch?v=4P1-JwZF0Vo&t=3942s
Ответить с цитированием
  #3 (permalink)  
Старый 30.11.2018, 21:29
Аватар для SuperZen
Профессор
Отправить личное сообщение для SuperZen Посмотреть профиль Найти все сообщения от SuperZen
 
Регистрация: 08.11.2017
Сообщений: 642

С обтеканием линий вокруг объектов я юзал https://github.com/bgrins/javascript-astar, можно создавать уменьшенную копию существующих объектов, например 1 к 10, чтобы быстродействие было хорошим... а потом чтобы они были квадратными ))... линии...
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с работой JS в SVG Chebishev Events/DOM/Window 2 15.04.2014 18:29
Обмен сообщениями между js загруженной страницы и расширением для браузера prihod Events/DOM/Window 6 11.12.2011 21:51
Связь SVG и JS Questioner Общие вопросы Javascript 5 23.08.2011 16:51
Корзина на JS с использованием COOKIE vah-smile Элементы интерфейса 3 05.03.2011 16:37
Галерея с использованием JS. keks20 jQuery 2 19.01.2011 18:22