【问题标题】:Dynamically flexible path between two points in SVGSVG中两点之间的动态灵活路径
【发布时间】:2016-07-27 09:40:17
【问题描述】:

您好,有人可以帮我像这里一样弯曲路径吗

here u can see it in action(这几乎是我需要的,但它在画布上)

问题
我怎么计算呢?
哪个公式描述了这个 以及如何正确描述路径的参数“d”

这是我的代码(也许需要一些改进?)

var app = angular.module('app', []);


app.controller("ctrl", function ($scope) {
  var lineGraph = d3.select("#container").append("svg:svg").attr("width", '100%').attr("height", '100%'); 
  $scope.linesArr = [];
  $scope.blocksArr = [{
    id: 0,
    x: 0,
    y: 0,
    lineToID: [2]
  },{
    id: 1,
    x: 0,
    y: 0,
    lineToID: [0,2]
  },{
    id: 2,
    x: 0,
    y: 0,
    lineToID: []
  }];

  $scope.createLines = function(){
    for(var i = 0; i < $scope.blocksArr.length; i++){
      if($scope.blocksArr[i].lineToID.length){
        for(var j = 0; j < $scope.blocksArr[i].lineToID.length; j++){
          $scope.linesArr[$scope.blocksArr[i].id + ":"+j] = (lineGraph.append("svg:line"));
        }
      }
    }
  };
  $scope.createLines();

  $scope.checkPoints = function(){

    for(var i = 0; i < $scope.blocksArr.length; i++){
      $scope.blocksArr[i].x = parseInt(document.querySelector('#b' + i).style.left) + (document.querySelector('#b' + i).offsetWidth / 2);
      $scope.blocksArr[i].y = parseInt(document.querySelector('#b' + i).style.top) + (document.querySelector('#b' + i).offsetHeight / 2);

      if($scope.blocksArr[i].lineToID.length){
        for(var j = 0; j < $scope.blocksArr[i].lineToID.length; j++){
          $scope.linesArr[$scope.blocksArr[i].id+":"+j]
            .attr("x1", $scope.blocksArr[$scope.blocksArr[i].id].x)
            .attr("y1", $scope.blocksArr[$scope.blocksArr[i].id].y)
            .attr("x2", $scope.blocksArr[$scope.blocksArr[i].lineToID[j]].x)
            .attr("y2", $scope.blocksArr[$scope.blocksArr[i].lineToID[j]].y)
            .style("stroke", "rgb(6,120,155)");
          //console.log();
        }
      }
    }
  };


  $scope.dragOptions = {
    start: function(e) {
      //console.log("STARTING");
    },
    drag: function(e) {
      $scope.checkPoints();

      //console.log("DRAGGING");
    },
    stop: function(e) {
      //console.log("STOPPING");
    },
    container: 'container'
  }


});












app.directive('ngDraggable', function($document) {
  return {
    restrict: 'A',
    scope: {
      dragOptions: '=ngDraggable'
    },
    link: function(scope, elem, attr) {
      var startX, startY, x = 0, y = 0,
          start, stop, drag, container;

      var width  = elem[0].offsetWidth,
          height = elem[0].offsetHeight;

      // Obtain drag options
      if (scope.dragOptions) {
        start  = scope.dragOptions.start;
        drag   = scope.dragOptions.drag;
        stop   = scope.dragOptions.stop;
        var id = scope.dragOptions.container;
        if (id) {
          container = document.getElementById(id).getBoundingClientRect();
        }
      }

      // Bind mousedown event
      elem.on('mousedown', function(e) {
        e.preventDefault();
        startX = e.clientX - elem[0].offsetLeft;
        startY = e.clientY - elem[0].offsetTop;
        $document.on('mousemove', mousemove);
        $document.on('mouseup', mouseup);
        if (start) start(e);
      });

      // Handle drag event
      function mousemove(e) {
        y = e.clientY - startY;
        x = e.clientX - startX;
        setPosition();
        if (drag) drag(e);
      }

      // Unbind drag events
      function mouseup(e) {
        $document.unbind('mousemove', mousemove);
        $document.unbind('mouseup', mouseup);
        if (stop) stop(e);
      }

      // Move element, within container if provided
      function setPosition() {
        if (container) {
          if (x < container.left) {
            x = container.left;
          } else if (x > container.right - width) {
            x = container.right - width;
          }
          if (y < container.top) {
            y = container.top;
          } else if (y > container.bottom - height) {
            y = container.bottom - height;
          }
        }

        elem.css({
          top: y + 'px',
          left:  x + 'px'
        });
      }
    }
  }
})
html,body, #container{
  height: 100%;
  margin: 0;
}
.box{
  position: absolute;
  width: 100px;
  height: 30px;
  line-height: 30px;
  border: 1px solid #c07f7f;
  text-align: center;
  background: #f3f4ff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<div ng-controller="ctrl" ng-app="app" id="container">
  <div class="box" id="b{{$index}}" ng-repeat="i in blocksArr" ng-draggable='dragOptions' ng-style="{top: blocksArr[$index].y, left: blocksArr[$index].x}">{{$index}}</div>
</div>

【问题讨论】:

  • 欢迎堆栈溢出!请编辑您的问题以将您的代码放入问题中(不仅在另一个站点)。那么,请澄清你的问题。你有什么问题?你能制作出你想要的静态 SVG 吗?你不知道如何让 SVG 看起来像你想要的吗?你要做什么,出了什么问题?
  • 嗨。 tnx。现在好点了吗?
  • 你已经包含了你的代码(干得好),但你仍然没有描述你的问题,你想要什么(具体地)以及你的问题是什么。
  • @Phrogz 现在很酷?
  • 那么,当你说“弯曲”一条路径时,你的意思是你想让直的红线变成一条曲线吗?或者你想简单地拖动点来移动带有直线的直角三角形的角?

标签: javascript svg


【解决方案1】:

我猜,我想你想要的是:

  • 在屏幕上显示两个点。
  • 计算一个与这些点接触的轴对齐直角三角形。
  • 为三角形的边缘绘制一个三角形填充和彩色线条。
  • 允许用户使用鼠标单击这些点并将其拖动到新位置。
  • 根据这些点动态更新直角三角形。

目前尚不清楚您在上面的哪个部分遇到了问题(可能是“全部”除外)。一般来说,计算机编程就是确定你想做什么,把它分解成简单的步骤(就像我上面所做的那样),然后一次一个地处理这些步骤。

  1. 你能计算屏幕上的两个“随机”点吗? (提示:Math.random() 可能是合适的,否则你可以选择两个固定的起始位置。)
  2. 你能在屏幕上画两个点吗? (提示:您可以使用 SVG &lt;circle&gt; 并调整 cxcy 属性。)
  3. 你能计算出第三个点应该在哪里吗? (提示:一种方法是使用一个点的“x”值和另一个点的“y”值。)
  4. 你能在这些点之间画一个实心三角形吗? (提示:一种简单的方法是使用 SVG &lt;polygon&gt; 并调整 points 属性。)
  5. 你能为边缘画三条线吗? (提示:使用&lt;line&gt;&lt;polyline&gt; 元素在文档中比&lt;polygon&gt; 更晚,以便它们在顶部绘制......但&lt;circle&gt; 元素在文档中甚至更低,以便圆圈绘制最重要的。)
  6. 你能做到当用户点击并拖动圆圈时,它们会停留在鼠标下方吗? (提示:请参阅this answer 和我的示例,或访问 Google 了解如何使 SVG 元素可拖动。)
  7. 在拖动处理程序期间,您可以重新计算三角形、点和线并全部更新吗? (提示:您可以使用setAttribute() 来更新SVG 元素的属性,例如setAttribute(myPoly,'points',arrayOfPoints.join()),也可以使用SVG DOM bindings——例如myPoly.getItem(0).x = 43。)

您的问题目前过于宽泛和模糊。编辑此问题以使其特定于您的确切愿望和不适合您的确切代码,或者创建一个具有类似目标的新问题。您的代码 sn-p 对您那里的所有代码基本上没有任何用处。

【讨论】:

    猜你喜欢
    • 2020-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多