【问题标题】:Clip path is moving with group of elements when using d3.drag使用 d3.drag 时,剪辑路径与元素组一起移动
【发布时间】:2019-09-13 13:41:35
【问题描述】:

我正在尝试在剪切路径上拖动一组形状。第一次,它工作正常,但一旦我开始拖动,剪辑就根本不起作用。

这是我的工作代码;

var svg = d3.select("svg");

// draw a circle
    svg.append("clipPath")       // define a clip path
    	.attr("id", "clip") // give the clipPath an ID
      .append("circle")            // shape it as an ellipse
    	.attr("cx", 100)            // position the x-centre
    	.attr("cy", 80)            // position the y-centre
    	.attr("r", 80)            // set the x radius
			.attr("fill", "red")


		var g = svg.append("g")
				.datum({x:0, y:0})
				.attr("transform", function(d) { return 'translate(' + d.x + ' '+ d.y + ')'; })
				.attr("clip-path","url(#clip)")
				.call(d3.drag()
            .on("start", function(d){
							d3.select(this).raise().classed("active", true);
						})
            .on("drag", function(d){
							d3.select(this).attr("transform","translate(" + (d3.event.x) + "," + (d3.event.y) + ")" );
						})
            .on("end", function(d){
							d3.select(this).classed("active", false);
						}));


    g.append("rect")
    	.attr("x",100)
    	.attr("y",80)
    	.attr("height",100)
    	.attr("width",200)

			g.append("line")
				.attr("x1", 100)
				.attr("y1", 80)
				.attr("x2", 200)
				.attr("y2", 80)
				.style("stroke", "purple")
				.style("stroke-width", 12)
.svgClass{
border:2px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>
        <svg width="500" height="300" class="svgClass"></svg>

您可以在拖动时看到,第一次剪裁的形状一直在移动。没有进一步的剪辑。

为方便起见,我再次重绘了外圈。检查此代码;

var svg = d3.select("svg");

    // draw a circle
        svg.append("clipPath")       // define a clip path
        	.attr("id", "clip") // give the clipPath an ID
          .append("circle")            // shape it as an ellipse
        	.attr("cx", 100)            // position the x-centre
        	.attr("cy", 80)            // position the y-centre
        	.attr("r", 80)            // set the x radius
    			.attr("fill", "red")
          
          // redraw circle to make it easy
          
          svg.append("circle")            // shape it as an ellipse
        	.attr("cx", 100)            // position the x-centre
        	.attr("cy", 80)            // position the y-centre
        	.attr("r", 80)            // set the x radius
    			.attr("fill", "red")


    		var g = svg.append("g")
    				.datum({x:0, y:0})
    				.attr("transform", function(d) { return 'translate(' + d.x + ' '+ d.y + ')'; })
    				.attr("clip-path","url(#clip)")
    				.call(d3.drag()
                .on("start", function(d){
    							d3.select(this).raise().classed("active", true);
    						})
                .on("drag", function(d){
    							d3.select(this).attr("transform","translate(" + (d3.event.x) + "," + (d3.event.y) + ")" );
    						})
                .on("end", function(d){
    							d3.select(this).classed("active", false);
    						}));


        g.append("rect")
        	.attr("x",100)
        	.attr("y",80)
        	.attr("height",100)
        	.attr("width",200)

    			g.append("line")
    				.attr("x1", 100)
    				.attr("y1", 80)
    				.attr("x2", 200)
    				.attr("y2", 80)
    				.style("stroke", "purple")
    				.style("stroke-width", 12)
.svgClass{
border:2px solid red;
}
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>
        <svg width="500" height="300" class="svgClass"></svg>

在这里您可以看到剪辑根本不起作用。我想将这个拖动限制在圆圈内,如果超出剪辑边界,它应该相应地剪辑它。

谁能帮我解决这个要求?或者让我知道我在哪里 做错了。

【问题讨论】:

    标签: javascript html css d3.js


    【解决方案1】:

    拖动回调正在转换已应用剪辑路径的同一 g 元素。这意味着 g 元素的剪辑路径也在被转换,这就是为什么当你拖动你的形状时,剪辑的形状会四处移动。

    下面的 sn-p 使用灰色矩形来显示剪辑路径定义,并使用粉红色矩形来显示转换后的g 元素的区域。圆圈保留了原始剪辑形状,因为 g 元素的剪辑路径正在与元素的其余部分一起平移。

    <svg width="300" height="300">
      <clipPath id="cut">
        <rect width="100" height="100" x="100" y="50"></rect>
      </clipPath>
        
      <rect x="100" y="50" width="100" height="100" fill="#eee"></rect>
        
      <g clip-path="url(#cut)" transform="translate(50, 50)">
        <rect x="100" y="50" width="100" height="100" fill="pink"></rect>
        <circle       
          class="consumption"
          cx="100" 
          cy="100" 
          r="50">
        </circle>
      </g>
    </svg>

    在下面的 sn-p 中,剪辑路径应用于外部 g 元素(未翻译并且与原始剪辑路径定义具有相同的坐标),而转换应用于内部g 元素。

    <svg width="300" height="300">
      <clipPath id="cut">
        <rect width="100" height="100" x="100" y="50"></rect>
      </clipPath>
        
      <rect x="100" y="50" width="100" height="100" fill="#eee"></rect>
        
      <g clip-path="url(#cut)">
        <rect x="100" y="50" width="100" height="100" fill="pink"></rect>
          
        <g transform="translate(100, 50)">
          <circle       
            class="consumption"
            cx="100" 
            cy="100" 
            r="50">
          </circle>
        </g>
      </g>
    </svg>

    因此,如示例中所示,您应该将剪辑路径应用于外部 g 元素,同时转换内部 g 元素。

    【讨论】:

    • 其实我想并排拖动和剪辑..就像我在圆圈上拖动它一样,它应该根据剪辑区域进行剪辑..
    • 嗨。对不起。我不确定你是什么意思。我的理解是,您希望剪切区域保持在同一位置,并且当您拖动对象时,它会以不同的方式出现,因为它会被原始剪切路径剪切。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-02
    • 1970-01-01
    • 1970-01-01
    • 2020-01-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多