如何在svg图像中实现可拖动功能?

时间:2017-05-15 19:53:49

标签: jquery jquery-ui svg jquery-ui-draggable

在这段代码中,我使用Jquery-draggable来设置标记。正如您在https://jsbin.com/yekukar/edit?html,css,js

所看到的那样,它很有效

但我希望在点击该行时(“在代码中为角度”),事件“onmousemove”停止在该位置标记角度值。我尝试了“onclick”事件,但不是它不允许测量在点击点上顺利进行。

拜托,我需要任何人建议。很多!!!

SNIPPET HTML - CODIGO COMPLETO EM https://jsbin.com/yekukar/edit?html,css,js

    <svg class="ang" width="100%" height="500">

                <path d="M 1000 300 L 800 300" class="deg45" transform="rotate(0 300 300)">
            </path>
                <text text-anchor="left" x="850" y="300" style="font-size: 15pt;"  transform="rotate(0 300 300)">0 degrees</text>

            <circle cx="900" cy="300" id="center" r="2" />
            <circle cx="900" cy="300" id="dynamic" r="2" fill="none" />
                <path id="deg" d="M 300 300 L 400 300" stroke="#000" stroke-width="1px" />
                <text text-anchor="left" x="0" y="100" id="txt" style="font-size: 20pt;" transform="rotate(45 100 100)"></text>

摘录JS

                var center = document.querySelector("#center"),
            dynamic = document.querySelector("#dynamic"),
            path = document.querySelector("#deg"),
            svg = document.querySelector("svg"),
            txt = document.querySelector("#txt"),
            svgNS = svg.namespaceURI,
            degree = String.fromCharCode(176),
            arrows = String.fromCharCode(845);

            function Point(x, y) {
            return {
            "X": x,
            "Y": y
            };
            }

            // Credits goes to Stackoverflow: http://stackoverflow.com/a/14413632
            function getAngleFromPoint(point, centerPoint) {
            var dy = (point.Y - centerPoint.Y),
            dx = (point.X - centerPoint.X);
            var theta = Math.atan2(dy, dx);
            var angle = (((theta * 180) / Math.PI)) % 360;
            angle = (angle < 0) ? 360 + angle : angle;
            return angle;
            }
            // Credits goes to http://snipplr.com/view/47207/
            function getDistance(point1, point2) {
            var xs = 0;
            var ys = 0;

            xs = point2.X - point1.X;
            xs = xs * xs;

            ys = point2.Y - point1.Y;
            ys = ys * ys;

            return Math.sqrt(xs + ys);
            }

            function fitSVG() {
            var width = window.innerWidth,
            height = window.innerHeight;
            svg.setAttribute("width", width);
            svg.setAttribute("height", height);
            }

            svg.onmousemove = function (e) {
            var centerPoint = new Point(center.getAttribute("cx"), center.getAttribute("cy"));
            var point = new Point(e.clientX, e.clientY);
            var angle = Math.round(100 * getAngleFromPoint(point, centerPoint)) / 100;
            var distance = Math.round(getDistance(point, centerPoint));
            var d = "M " + centerPoint.X + " " + centerPoint.Y + " L " + point.X + " " + point.Y;
            path.setAttribute("d", d);
            txt.setAttribute("x", point.X);
            txt.setAttribute("y", point.Y);
            txt.textContent = distance + arrows + " (" + angle + degree + ")";
            txt.setAttribute("transform", "rotate(" + angle + " " + point.X + " " + point.Y + ")");

            dynamic.setAttribute("r", distance);
            fitSVG();
            }

            //JQUERY DRAGGABLE

            grid_size = 10;

            $(" .ang")
            .draggable({
            grid: [grid_size, grid_size]
            })

            .on("mouseover", function () {
            $(this).addClass("move-cursor")
            })

            .on("mousedown", function () {
            $(this)
            .removeClass("move-cursor")
            .addClass("grab-cursor")
            .addClass("opac");

            $(" .text ").hide();

            })

            .on("mouseup", function () {
            $(this)
            .removeClass("grab-cursor")
            .removeClass("opac")
            .addClass("move-cursor");
            });

1 个答案:

答案 0 :(得分:2)

目前尚不清楚你想要完成什么,但我怀疑它是这样的:

  1. 当用户移动鼠标时,计算角度
  2. 当用户点击鼠标时,停止计算角度
  3. 允许用户拖动svg,而不是在发生这种情况时计算角度
  4. 希望这会有所帮助:

    代码:https://jsfiddle.net/Twisty/8fy76yrt/24/

    显示:https://jsfiddle.net/Twisty/8fy76yrt/24/show/

    <强>的JavaScript

    $(function() {
      var center = $("#center"),
        dynamic = $("#dynamic"),
        path = $("#deg"),
        svg = $("svg"),
        txt = $("#txt"),
        svgNS = svg[0].namespaceURI,
        degree = String.fromCharCode(176),
        arrows = String.fromCharCode(845),
        follow = true;
    
      function Point(x, y) {
        return {
          "X": x,
          "Y": y
        };
      }
    
      // Credits goes to Stackoverflow: http://stackoverflow.com/a/14413632
      function getAngleFromPoint(point, centerPoint) {
        var dy = (point.Y - centerPoint.Y),
          dx = (point.X - centerPoint.X);
        var theta = Math.atan2(dy, dx);
        var angle = (((theta * 180) / Math.PI)) % 360;
        angle = (angle < 0) ? 360 + angle : angle;
        return angle;
      }
      // Credits goes to http://snipplr.com/view/47207/
      function getDistance(point1, point2) {
        var xs = 0;
        var ys = 0;
    
        xs = point2.X - point1.X;
        xs = xs * xs;
    
        ys = point2.Y - point1.Y;
        ys = ys * ys;
    
        return Math.sqrt(xs + ys);
      }
    
      function fitSVG() {
        var width = window.innerWidth,
          height = window.innerHeight;
        svg.width(width);
        svg.height(height);
      }
    
      function updateSVG(e) {
        if (follow) {
          var centerPoint = new Point(center[0].getAttribute("cx"), center[0].getAttribute("cy"));
          var point = new Point(e.clientX, e.clientY);
          var angle = Math.round(100 * getAngleFromPoint(point, centerPoint)) / 100;
          var distance = Math.round(getDistance(point, centerPoint));
          var d = "M " + centerPoint.X + " " + centerPoint.Y + " L " + point.X + " " + point.Y;
          path.attr("d", d);
          txt.attr("x", point.X);
          txt.attr("y", point.Y);
          txt.html(distance + arrows + " (" + angle + degree + ")");
          txt.attr("transform", "rotate(" + angle + " " + point.X + " " + point.Y + ")");
          dynamic.attr("r", distance);
        }
        fitSVG();
      }
    
      grid_size = 10;
    
      svg
        .mousemove(updateSVG)
        .click(function() {
          follow = !follow;
          return true;
        })
        .draggable({
          classes: {
            "ui-draggable-dragging": "opac"
          },
          cursor: "grab",
          grid: [grid_size, grid_size],
          start: function(e, ui) {
            $(this).find(".text").hide();
            follow = false;
          },
          stop: function() {
            follow = true;
          }
        });
    });
    

    有很多变化。我更喜欢保留尽可能多的jQuery,如果可能的话不要混合代码。所以我将所有jQuery对象分配给变量。要使用正确的SVG属性,可以根据需要调用第一个元素索引[0]。您将在updateSVG()中看到这一点。我还根据需要切换到.attr()

    follow是一个有用的变量,用于跟踪我们是否应该按照鼠标移动。 click上的svg事件将切换此值。我们也会在start中将其关闭,然后再在stop中关闭。