簡體   English   中英

沿d3中的路徑拖動

[英]Drag along path in d3

使用d3和React我畫了一條路。 在此路徑上,我有多個只能沿該路徑拖動的圓。 但是,當該路徑上有一個圓圈時,我當前的實現(僅適用於這種情況)有效。

(在dragStart上,無論位置如何,它都將移動到路徑上的長度0,並且每當我拖動第二個圓時,它就會從上一個圓的位置開始)。

我的問題是:如何沿着d3中的路徑拖動多個圓(或我們)? 有沒有一種方法可以根據當前圓的cx和cy獲取路徑上的currentLength位置?

 var currentLength = 0; class MyComponent extends Component { constructor(props) { super(props) currentLength = 0; } componentDidMount() { var drag = d3.behavior.drag() .on('drag', this.move); var g = d3.select(this._base); var circle = g.selectAll('circle').data(this.props.data); var onEnter = circle.enter(); onEnter.append('circle') .attr({ r: 10, cx: (d) => dx, cy: (d) => dy }) .style('fill', 'blue') .call(drag); } move(d) { currentLength += d3.event.dx + d3.event.dy if (currentLength < 0) { currentLength = 0 } var pointAtCurrentLength = d3.select('#path').node().getPointAtLength(currentLength) this.cx.baseVal.value = pointAtCurrentLength.x; this.cy.baseVal.value = pointAtCurrentLength.y; } render() { return <g ref={(c)=>this._base=c}></g> } } 

與此類似,只有可拖動的圈子和多個圈子: http : //bl.ocks.org/mbostock/1705868

這是此示例的快速修改,使圓可拖動:

 <!DOCTYPE html> <meta charset="utf-8"> <style> path { fill: none; stroke: #000; stroke-width: 1.5px; } line { fill: none; stroke: red; stroke-width: 1.5px; } circle { fill: red; } </style> <body> <script src="//d3js.org/d3.v3.min.js"></script> <script> var points = [[600,276],[586,393],[378,388],[589,148],[346,227],[365,108]]; var width = 960, height = 500; var line = d3.svg.line() .interpolate("cardinal"); var drag = d3.behavior.drag() .on("drag", dragged); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); var path = svg.append("path") .datum(points) .attr("d", line); var line = svg.append("line"); var circle = svg.append("circle") .attr("transform", "translate(" + points[0] + ")") .attr("r", 7) .call(drag); svg.append("circle") .attr("transform", "translate(" + points[5] + ")") .attr("r", 7) .call(drag); function dragged(d) { var m = d3.mouse(svg.node()), p = closestPoint(path.node(), m); d3.select(this) .attr("transform", "translate(" + p[0] + "," + p[1] + ")") } function closestPoint(pathNode, point) { var pathLength = pathNode.getTotalLength(), precision = 8, best, bestLength, bestDistance = Infinity; // linear scan for coarse approximation for (var scan, scanLength = 0, scanDistance; scanLength <= pathLength; scanLength += precision) { if ((scanDistance = distance2(scan = pathNode.getPointAtLength(scanLength))) < bestDistance) { best = scan, bestLength = scanLength, bestDistance = scanDistance; } } // binary search for precise estimate precision /= 2; while (precision > 0.5) { var before, after, beforeLength, afterLength, beforeDistance, afterDistance; if ((beforeLength = bestLength - precision) >= 0 && (beforeDistance = distance2(before = pathNode.getPointAtLength(beforeLength))) < bestDistance) { best = before, bestLength = beforeLength, bestDistance = beforeDistance; } else if ((afterLength = bestLength + precision) <= pathLength && (afterDistance = distance2(after = pathNode.getPointAtLength(afterLength))) < bestDistance) { best = after, bestLength = afterLength, bestDistance = afterDistance; } else { precision /= 2; } } best = [best.x, best.y]; best.distance = Math.sqrt(bestDistance); return best; function distance2(p) { var dx = px - point[0], dy = py - point[1]; return dx * dx + dy * dy; } } </script> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM