话不多说,直接上代码
实现效果,左边元素拖动致右边,左边元素扔保留。效果图
<html>
<head>
<meta charset="utf-8">
<title>Drag</title>
<style>
.legendDiv{position: absolute;}
</style>
</head>
<body>
<div style="width:800px;height:500px;margin-left: 200px;">
<svg class="legendDiv" style="min-width:300px;height:500px;border:1px solid #eee;background:rgba(250, 247, 247, 1);"></svg>
<svg class="dragDiv" style="width:800px;height:500px;border:1px solid #eee;background:rgba(212, 203, 203,1);"></svg>
</div>
<!-- <script src="./d3.min.js" charset="utf-8"></script> -->
<script src="https://d3js.org/d3.v5.js"></script>
<script>
var width = 500;
var width1 = 300;
var height = 500;
//拖拽目的区域
var circles = [ { cx: 350, cy:200, r:30 ,fill:'red'},
{ cx: 550, cy:200, r:30 , fill:'blue'},];
var svg = d3.select(".dragDiv")
var gggg=svg.append("g")
.attr("width",width)
.attr("height",height);
var drag = d3.drag()
.on("drag", dragmove);
drowNode();
function drowNode(params) {
gggg.selectAll("circle")
.data(circles)
.enter()
.append("circle")
.attr("cx",function(d){ return d.cx; })
.attr("cy",function(d){ return d.cy; })
.attr("r",function(d){ return d.r; })
.attr("fill",function(d){ return d.fill; })
.call(drag);
}
function dragmove(d) {
d3.select(this)
.attr("cx", d.cx = d3.event.x )
.attr("cy", d.cy = d3.event.y );
}
//拖拽目的区域,增加缩放
var inner = svg.select('g')
var zoom = d3.zoom().on('zoom', function () { // 放大
inner.attr('transform', d3.event.transform)
})
svg.call(zoom)
//拖拽模板区域
//变量circles1是为了解决拖拽元素后,原位置扔保留元素
var circles1 = [ { cx: 50, cy:200, r:30 ,fill:'red'},
{ cx: 50, cy:200, r:30 ,fill:'red'},
{ cx: 150, cy:200, r:30 , fill:'blue'},
{ cx: 150, cy:200, r:30 , fill:'blue'},];
var svg1 = d3.select(".legendDiv")
var circlePosition = {}
var circleExist = false
var gggg1=svg1.append("g")
.attr("width",width)
.attr("height",height);
var drag1 = d3.drag()
.on("start",g1CreatCircle)
.on("end",g1RemoveCircle)
.on("drag", dragmove1);
gggg1.selectAll("circle")
.data(circles1)
.enter()
.append("circle")
.attr("cx",function(d){ return d.cx; })
.attr("cy",function(d){ return d.cy; })
.attr("r",function(d){ return d.r; })
.attr("fill",function(d){ return d.fill; })
.call(drag1);
//记录被拖拽元素原有位置,不能直接使用引用,因为拖拽后当前元素的位置会发生变化,circlePosition也会发生变化
function g1CreatCircle(d) {
circlePosition = JSON.parse(JSON.stringify(d))
}
//拖拽结束后,模板区域被拖拽元素返回原有位置
function g1RemoveCircle(d) {
d3.select(this)
.attr("cx", d.cx = circlePosition.cx )
.attr("cy", d.cy = circlePosition.cy )
circleExist = false
}
function dragmove1(d) {
var _this = d3.select(this)
d3.select(this)
.attr("cx", d.cx = d3.event.x )
.attr("cy", d.cy = d3.event.y )
.call(function () {
//判断拖拽目的区域是否需要添加被拖拽的元素
if(d.cx >= 300){
//由于目的区域支持缩放,此处插入元素存在位置bug,未想到解决方法,请自行解决
var lastCircle = {cx:d.cx,cy:d.cy,r:d.r,fill:d.fill}
if (circleExist ===false) {
circleExist = true
circles.push(lastCircle)
drowNode()
}else{
// console.log(lastCircle)
circles[circles.length-1] = lastCircle
gggg.selectAll("circle")
.remove()
drowNode()
}
}else{
if (circleExist ===true) {
gggg.selectAll("circle")
.remove()
circles.pop()
drowNode()
circleExist =false
}
}
});
}
</script>
</body>
</html>