用鼠标移动动态创建的SVG [英] Move dynamically created SVG with mouse

查看:154
本文介绍了用鼠标移动动态创建的SVG的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对HTML和JS还是很陌生,但是我正在尝试学习一些基础知识.现在,我正在尝试图形.
我正在尝试使用JS动态创建两个svg元素,然后用鼠标分别移动它们.
我能够创建它们,并分别在其上注册鼠标事件,但是无法使它们移动.为了尝试移动位置,在我的dragging()函数中,将svg style.top和style.left分配给指针的值.我可以在JS控制台中确认事件是从SGV发送的,并且element标记中的顶部和左侧样式正在更改,但是屏幕上的位置没有更改.
我跟随另一个示例,该示例使用鼠标将svg移动到顶部,并使用鼠标值向左分配样式,因此我不确定为什么这不起作用.
谢谢

I'm pretty new to HTML and JS, but I'm trying to learn some of the basics. Now I'm experimenting with graphics.
I'm trying to create two svg elements dynamically with JS and then move them individually with the mouse.
I'm able to create them, and register the mouse events on them individually, but can't get them to move. To try to move there positions, in my dragging() function I assign the svg style.top and style.left to the value of the pointer. I can confirm in the JS console that the event is sent from the SGV and that the top and left styles are changing in the element tag, but the position on screen is not changing.
I followed another example where the svg was moved with the mouse assigning style top and left with the mouse values, so I'm not sure why this isn't working.
Thanks

<?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>

推荐答案

一些观察结果:您的代码是正确的,但是它非常冗长,因此我需要减少它.在代码中,您将找到一个从对象创建SVG元素的函数.我正在使用此功能来创建svg元素和圆圈.

A few observations: your code is correct, however it's extremely verbose so I needed to reduce it. In the code you'll find a function to create an SVG element from an object. I'm using this function to create the svg elements and the circles.

我也将SVG元素放置在一个数组中.当您将相似的元素放入数组中时,使用wotk会更容易.

Also I'm putting the SVG elements in an array. It's easier to wotk with similar elements when you have them in an array.

主要思想是:

  1. svg元素的位置为 position:absolute .可以使用css

在鼠标向下拖动时为true.如果drag为true,则可以拖动svg元素.svg的新位置(它的 top left 属性)在css中设置为鼠标位置和鼠标之间的距离 delta 的函数.鼠标和SVG元素的左上角.

On mouse down drag is true. If drag is true you can drag the svg element. The new position of the svg (it's top and left properties) are set in css in function of the mouse position and the distance delta between the mouse and the top left corner of the SVG element.

在鼠标上拖动时为false.svg元素不能再拖动.

On mouse up drag is false. The svg element can't be dragged any longer.

请阅读代码和注释,如果您听不懂,请告诉我.

Please read the code and the comments and let me know if you don't understand.

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>

这篇关于用鼠标移动动态创建的SVG的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆