d3实现元素穿梭,拖拽,缩放

话不多说,直接上代码

实现效果,左边元素拖动致右边,左边元素扔保留。效果图

fa779d32f50c38c05be66fc3abfed85c.png


<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>  

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值