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

Я понимаю, что можно использовать арифметику и парсить аттрибут transform="translate(x y)" рекурсивно к родителю, но есть некоторые сложности, что не всегда я перемещаю элементы через translate, а иногда на некоторых узлах используя атрибуты x, y или cx, cy, а может вообще быть path... .
let outputChanel = e.target; // наведенный элемент
let cx = +outputChanel.getAttributeNS(null, 'cx'); // получить [B]локальную[/B] координату относительно группы <g>, но т.к <g> может быть рекурсивное множество вложенных и относительно смещенных между собой.
let cy = +outputChanel.getAttributeNS(null, 'cy');
let cc = getAbsoluteCoords(outputChanel, cx, cy); // вот хотелось реализовать данную функцию, которая будет брать матрицу и смотреть её параметр смещения по осям (matrix.e и matrix.f), НО относительно родительского <SVG>

selectLineChanel.setAttributeNS(null, 'x2', cc.x);
selectLineChanel.setAttributeNS(null, 'y2', cc.y);

selectLineChanel = false;
console.log('endDrawLine (ok)', cc.cx, cc.cy, e.target);


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

    const $svg = $('#main .canvas-svg'); // 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;


    function startDrag(e) {

        if (e.target.classList.contains('output-chanel')) { // при наведении на точку канала
            selectLineChanel = document.createElementNS('http://www.w3.org/2000/svg', 'line');
            //initialiseDragging(e, selectLineChanel);
            let outputChanel = e.target;
            let coord = getMousePosition(e);

            selectLineChanel.setAttributeNS(null, 'x1', coord.x);
            selectLineChanel.setAttributeNS(null, 'y1', coord.y);
            selectLineChanel.setAttributeNS(null, 'stroke-width', 5);
            selectLineChanel.setAttributeNS(null,'stroke', '#000');
            selectLineChanel.setAttributeNS(null,'stroke-linecap', 'round');

            let groupChanelLine = activeSVG.querySelector('.chanel-lines');
            groupChanelLine.appendChild(selectLineChanel);

            console.log('startDrawLine');
        } else if (e.target.classList.contains('draggable')) { // при наведении на элемент
            selectedElement = e.target;
            initialiseDragging(e, selectedElement);
            console.log('startDragElement')
        } else if (e.target.parentNode.classList.contains('draggable-group')) {
            selectedElement = e.target.parentNode;
            initialiseDragging(e, selectedElement);
            console.log('startDragElement');
        }
    }
    function drag(e) {
        e.preventDefault();
        if(selectLineChanel){
            let coord = getMousePosition(e);
            selectLineChanel.setAttributeNS(null, 'x2', coord.x);
            selectLineChanel.setAttributeNS(null, 'y2', coord.y);
            //console.log('drawLine: x =',coord.x, 'offsetElementX =', offsetElement.x, 'y =', coord.y, 'offsetElementY =', offsetElement.y);
        } else if (selectedElement) {
            let coord = getMousePosition(e);
            transformElement.setTranslate(coord.x - offsetElement.x, coord.y - offsetElement.y);
            console.log('drag');
        }
    }
    function endDrag(e) {
        if (selectLineChanel) {
            console.log(e.target);
            if (e.target.classList.contains('input-chanel')) {
                let outputChanel = e.target;
                let cx = +outputChanel.getAttributeNS(null, 'cx');
                let cy = +outputChanel.getAttributeNS(null, 'cy');
                let cc = getAbsoluteCoords(outputChanel, cx, cy);

                selectLineChanel.setAttributeNS(null, 'x2', cc.x);
                selectLineChanel.setAttributeNS(null, 'y2', cc.y);

                selectLineChanel = false;
                console.log('endDrawLine (ok)', cc.cx, cc.cy, e.target);
            } else {
                selectLineChanel.remove();
                selectLineChanel = false;
                console.log('endDrawLine (cancel)');
            }
        }
        if(selectedElement){
            selectedElement = false;
            console.log('endDragElement');
        }
    }


    function convertCoords(element, x, y) {
        let offset = activeSVG.getBoundingClientRect();
        let matrix = element.getScreenCTM();

        return {
            x: (matrix.a * x) + (matrix.c * y) + matrix.e - offset.left,
            y: (matrix.b * x) + (matrix.d * y) + matrix.f - offset.top
        };
    }

    function getAbsoluteCoords(element, x, y) {
        let offset = activeSVG.getBoundingClientRect();
        let matrix = element.getScreenCTM();

        return {
            x: (x + matrix.e),
            y: (y + matrix.f)
        };
    }



    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, element) {
        offsetElement = getMousePosition(e);
        
        let transforms = element.transform.baseVal;
        if (transforms.length === 0 || transforms.getItem(0).type !== SVGTransform.SVG_TRANSFORM_TRANSLATE) {
           
            let translate = activeSVG.createSVGTransform();
            translate.setTranslate(0, 0);
            element.transform.baseVal.insertItemBefore(translate, 0);
        }
      
        transformElement = transforms.getItem(0);
        offsetElement.x -= transformElement.matrix.e;
        offsetElement.y -= transformElement.matrix.f;
    }

})();

Последний раз редактировалось Vad0k, 05.12.2018 в 15:30.
Ответить с цитированием