Переместите динамически созданный SVG с помощью мыши - PullRequest
0 голосов
/ 12 января 2019

Я довольно новичок в HTML и JS, но я пытаюсь изучить некоторые основы. Сейчас я экспериментирую с графикой.
Я пытаюсь создать два элемента SVG динамически с помощью JS, а затем перемещать их по отдельности с помощью мыши.
Я могу создавать их и регистрировать на них события мыши по отдельности, но не могу заставить их двигаться. Чтобы попытаться переместиться туда, в моей функции dragging () я назначаю svg style.top и style.left значению указателя. Я могу подтвердить в консоли JS, что событие отправлено с SGV и что верхний и левый стили меняются в теге элемента, но позиция на экране не меняется.
Я последовал другому примеру, где svg был перемещен с помощью мыши, назначающей стиль top, и оставлен со значениями мыши, поэтому я не уверен, почему это не работает.
Спасибо

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
    <title>SVG Test</title>    
</head>
<body>

<h1>Testing <abbr>SVG</abbr></h1>
<div id="svg54583"></div>
<script>     

        // create the svg element
       var svg1 = document.createElementNS("http://www.w3.org/2000/svg", "svg");

        // set width and height
        svg1.setAttribute("width", "100");
        svg1.setAttribute("height", "100");
        svg1.setAttribute("id", "firstsvg");
        svg1.onmousedown = startdrag;

        // create a circle
        var cir1 = document.createElementNS("http://www.w3.org/2000/svg", "circle");
        cir1.setAttribute("cx", "80");
        cir1.setAttribute("cy", "80");
        cir1.setAttribute("r", "30");
        cir1.setAttribute("fill", "red");

        // attach it to the container
        svg1.appendChild(cir1);

        // attach container to document
        //document.getElementById("svg54583").appendChild(svg1);
        document.body.appendChild(svg1);

        var svg1 = document.createElementNS("http://www.w3.org/2000/svg", "svg");

        // set width and height
        svg1.setAttribute("width", "100");
        svg1.setAttribute("height", "100");
        svg1.setAttribute("id", "secondsvg");
        svg1.onmousedown = startdrag;

        // create a circle
        var cir1 = document.createElementNS("http://www.w3.org/2000/svg", "circle");
        cir1.setAttribute("cx", "80");
        cir1.setAttribute("cy", "80");
        cir1.setAttribute("r", "30");
        cir1.setAttribute("fill", "red");

        // attach it to the container
        svg1.appendChild(cir1);

        // attach container to document
        //document.getElementById("svg54583").appendChild(svg1);
        document.body.appendChild(svg1);

        function startdrag(e)
        { 

            var elmnt = e.target;
            elmnt.onmousemove = dragging;   

        }

        function dragging(e)
        {
            var elmnt = e.target;
            elmnt.style.top = e.clientY ;
            elmnt.style.left = e.clientX ;
            console.log(elmnt);
        }    

</script>

1 Ответ

0 голосов
/ 12 января 2019

Несколько замечаний: Ваш код правильный, но он очень многословный, поэтому мне нужно было его уменьшить. В коде вы найдете функцию для создания элемента SVG из объекта. Я использую эту функцию для создания элементов SVG и кругов.

Также я помещаю элементы SVG в массив. Проще работать с похожими элементами, если они есть в массиве.

Основная идея:

  1. Элементы svg имеют position:absolute. Положение svg может быть установлено с помощью свойств top и left в css

  2. При перетаскивании мышью значение true. Если drag - true, вы можете перетащить элемент svg. Новая позиция svg (это свойства top и left) устанавливаются в css в зависимости от положения мыши и расстояния delta между мышью и верхним левым углом элемента SVG.

  3. При перетаскивании мышью вверх - false. Элемент svg больше нельзя перетаскивать.

Пожалуйста, прочитайте код и комментарии и дайте мне знать, если вы не понимаете.

const SVG_NS = "http://www.w3.org/2000/svg";
let svg1 = {
  width: 100,
  height: 100
};

let circle1 = {
  cx: 80,
  cy: 80,
  r: 30,
  fill: "red"
};

let drag = null;// a flag to know if you can drag or not
let _array = [];// the array of scg elements
let delta = {};// distance between the mouse and the top left coener of the SVG element
let m = {};// mouse position

function createSVGElement(o, elmtName, parent) {
  var elmt = document.createElementNS(SVG_NS, elmtName);
  for (var name in o) {
    if (o.hasOwnProperty(name)) {
      elmt.setAttributeNS(null, name, o[name]);
    }
  }
  parent.appendChild(elmt);
  return elmt;
}

let firstsvg = createSVGElement(svg1, "svg", svg54583);
let firstCircle = createSVGElement(circle1, "circle", firstsvg);

let secondsvg = createSVGElement(svg1, "svg", svg54583);
let secondCircle = createSVGElement(circle1, "circle", secondsvg);

_array.push(firstsvg);
_array.push(secondsvg);



_array.forEach((svg, i) => {
  svg.addEventListener("mousedown", evt => {
    // you can drag
    drag = i + 1; // i + 1 because 0 is false. I need it to be true
    let pos = svg.getBoundingClientRect();
    // distance between the mouse and the top left coener of the SVG
    delta.x = evt.clientX - pos.x;
    delta.y = evt.clientY - pos.y;
  });
});

svg54583.addEventListener("mousemove", evt => {
  if (drag) {
    m = oMousePos(svg54583, evt); //console.log("m",m);
    _array[drag - 1].style.left = m.x - delta.x + "px";
    _array[drag - 1].style.top = m.y - delta.y + "px";
  }
});

svg54583.addEventListener("mouseup", evt => {
  drag = null;
});

function oMousePos(elmt, evt) {
  var ClientRect = elmt.getBoundingClientRect();
  return {
    //objeto
    x: Math.round(evt.clientX - ClientRect.left),
    y: Math.round(evt.clientY - ClientRect.top)
  };
}
*{margin:0;padding:0;}
svg{border:1px solid; position:absolute;background:white;}

svg:nth-of-type(2){left:200px;}

#svg54583{width:100vw; height:100vh; background:lightGrey; border:1px solid;}
<div id="svg54583"></div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...