2017-10-08 71 views
0

我工作的拖放使用d3js下降SVG。有兩個問題,我認爲它們是相互關聯的。D3js拖放一個對象並檢測它被丟棄的位置。

  1. 當圓圈被丟棄時,它必須檢測到它被放到矩形中。我看過的一些例子使用鼠標的x和y座標,但我不完全理解它。

  2. 的另一個問題是,圓圈顯示矩形後面。有沒有辦法把它帶到前面時,圓圈中移動不改變,其中圓,矩形創建即順序(先矩形創建圈子)。

var width = window.innerWidth, 
 
    height = window.innerHeight; 
 

 
var drag = d3.behavior.drag() 
 
    .on("dragstart", dragstarted) 
 
    .on("drag", dragged) 
 
    .on("dragend", dragended); 
 

 
//create circle and space evenly 
 
var svg = d3.select("body") 
 
    .append("svg") 
 
    .attr("width", width) 
 
    .attr("height", height); 
 

 
var circle = d3.select("svg") 
 
    .append("circle") 
 
    .attr("cx", 50) 
 
    .attr("cy", 30) 
 
    .attr("r", 15) 
 
    .attr("transform", "translate(0,0)") 
 
    .style("stroke", "black") 
 
    .call(drag); 
 

 

 
function dragstarted(d) { 
 
    d3.event.sourceEvent.stopPropagation(); 
 
} 
 

 
function dragged(d) { 
 
    d3.select(this).attr("transform", "translate(" + [d3.event.x, d3.event.y] + ")"); 
 
} 
 

 
function dragended(d) { 
 
    d3.event.sourceEvent.stopPropagation(); 
 

 
    // here would be some way to detect if the circle is dropped inside the rect. 
 
    
 
} 
 

 
var ellipse = svg.append("rect") 
 
     .attr("x", 150) 
 
     .attr("y", 50) 
 
     .attr("width", 50) 
 
     .attr("height", 140) 
 
     .attr("fill", "green");
<script src="https://d3js.org/d3.v3.min.js"></script>

任何幫助表示讚賞。

回答

0

更新仍然包括邊界客戶矩形,而是通過任何數量的存在矩形的迭代。 New Fiddle here.

這裏是我的問題的解決方案。我用一個偉大的小「moveToBack」輔助函數seen here移動RECT到後面不改變它出現的順序。

爲了獲得圓形和矩形的位置,我大量使用了香草js getBoundingClientRect()方法。你可以在this JS Fiddle中看到所有這些。

var width = window.innerWidth, 
    height = window.innerHeight; 

var drag = d3.behavior.drag() 
    .on("dragstart", dragstarted) 
    .on("drag", dragged) 
    .on("dragend", dragended); 

//create circle and space evenly 
var svg = d3.select("body") 
    .append("svg") 
    .attr("width", width) 
    .attr("height", height); 

var circle = d3.select("svg") 
    .append("circle") 
    .attr("r", 15) 
    .attr("transform", "translate(50,30)") 
    .style("stroke", "black") 
    .attr("id", "circle") 
    .call(drag); 


d3.selection.prototype.moveToBack = function() { 
    return this.each(function() { 
    var firstChild = this.parentNode.firstChild; 
    if (firstChild) { 
     this.parentNode.insertBefore(this, firstChild); 
    } 
    }); 
}; 

var rect = svg.append("rect") 
     .attr("x", 150) 
     .attr("y", 50) 
     .attr("width", 50) 
     .attr("height", 140) 
     .attr("fill", "green") 
     .attr("id", "rect") 
     .moveToBack(); 

var rect2 = svg.append("rect") 
     .attr("x", 350) 
     .attr("y", 50) 
     .attr("width", 50) 
     .attr("height", 140) 
     .attr("fill", "green") 
     .attr("id", "rect") 
     .moveToBack(); 

function dragstarted(d) { 
    d3.event.sourceEvent.stopPropagation(); 
} 

function dragged(d) { 
    d3.select(this).attr("transform", "translate(" + d3.event.x + "," + d3.event.y + ")"); 
} 

function dragended(d) { 
    // Define boundary 
    var rects = document.querySelectorAll("rect"); 
    for (var i = 0; i < rects.length; i++) { 
    var rectDimensions = rects[i].getBoundingClientRect(); 
    var xmin = rectDimensions.x; 
    var ymin = rectDimensions.y; 
    var xmax = rectDimensions.x + rectDimensions.width; 
    var ymax = rectDimensions.y + rectDimensions.height; 
    // Get circle position 
    var circlePos = document.getElementById("circle").getBoundingClientRect(); 
    var x1 = circlePos.x; 
    var y1 = circlePos.y; 
    var x2 = circlePos.x + circlePos.width; 
    var y2 = circlePos.y + circlePos.height; 
    if(x2 >= xmin && x1 <= xmax && y2 >= ymin && y1 <= ymax) { 
     rects[i].setAttribute("fill", "red"); 
    } else { 
     rects[i].setAttribute("fill", "green"); 
    } 
    } 
    d3.event.sourceEvent.stopPropagation(); 
} 
+0

謝謝你的迴應。我一直在尋找一種不涉及邊界框的解決方案,因爲我只有一個矩形,並且這些項目被放入矩形中。 [鏈接](http://bl.ocks.org/jmuyskens/8993967)。像這樣的東西,當這些框被拖動時,它會根據是否有頂部元素變成紅色。 – ben

+0

@ben我更新了我的代碼和[JS小提琴](https://jsfiddle.net/heybignick/a0447ah2/7/)遍歷任意數量的矩形。 – Nick