簡體   English   中英

可調整大小和可旋轉的矩形D3?

[英]Resizable and Rotatable Rectangle D3?

我正在嘗試創建一個矩形,我可以使用位於矩形頂部的處理程序(小圓圈)調整大小並旋轉它。 與大多數允許我們調整大小和旋轉形狀的繪圖工具類似。

我在矩形的頂部添加了三個圓圈。 一個圓圈用於調整矩形的寬度(右側的圓圈)。 另一個矩形用於調整條形的高度(頂部的圓圈)。 調整矩形的大小非常有效。

 margin = {top: 40, right: 20, bottom: 30, left: 70},
      width = 600 - margin.left - margin.right,
      height = 400 - margin.top - margin.bottom;

    var svg  = d3.select('#canvas').attr("width",width).attr("height",height);

    gContainer =  svg.append('g')
                     .attr("class", "gContainer")
                     .attr("transform", function(d,i){
                          return "translate("+300+","+200+")"
                     })

    gBars = gContainer.append('g').attr("class", "gBar");


    gBars.append("rect")
         .attr("class", "Bar")
         .attr("fill","black")
         .attr("width", 40)
         .attr("height", function(d) { return height - 200})
         .style("opacity", 0.5);


    var handlerRadius = 3.5;
    handlerPointsPosition=[];


    elementWidth = Number(d3.select(".Bar").attr("width"));
    elementHeight = Number(d3.select(".Bar").attr("height"));

    x0 = 0 + (elementWidth/2) ;
    y0 = 0 ;

    x1 = 0 + (elementWidth);
    y1 = 0 +(elementHeight/2) ;

    x2= 0 + (elementWidth/2) ;
    y2= -20;

    handlerPointsPosition = [[x0,y0],[x1,y1],[x2,y2]];


    var rectangleHandlers = d3.behavior.drag()
              .origin(function(d) { return d; })
              .on("dragstart", dragstarted)
              .on("drag", dragged)




    gHandlerPoints= gContainer.selectAll("g.HandlerPoint")
       .data(handlerPointsPosition)
       .enter().append('g')
       .attr("class", "gHandlerPoint")
       .attr("id", function(d,i){return "gHandlerPoint_id_"+i;})
       .attr("transform", function(d,i){
         //console.log(d);
            return "translate("+d[0]+","+d[1]+")"
       })
       .call(rectangleHandlers);

    gHandlerPoints.append("circle")
              .attr("class", "handlerPoint")
              .style("fill", "white")
              .style("stroke", "blue")
              .attr("stroke","")
              .attr("r",function(d,i){return (i == 2 ? 4: 3.5);})
              .attr("id", function(d,i){return "HandlerPointId_"+i;})

    gContainer.append("line")
              .attr("class","handlerLine")
              .attr("x1", (elementWidth/2) )
              .attr("y1", 0- handlerRadius)
              .attr("x2", (elementWidth/2) )
              .attr("y2", -20 + handlerRadius)
              .attr("stroke-width", 1)
              .attr("stroke", "blue");


    function updateHandlerPosition(id, dX, dY)
    {
      d3.select(id).attr("transform", function(d,i){
             return "translate(" + [ dX, dY] + ")"
      })
    }

    function dragstarted(d,i) {
       dragIconX = d3.transform(d3.select(this).attr("transform")).translate[0];
       dragIconY = d3.transform(d3.select(this).attr("transform")).translate[1];

       barStartWidth = d3.select(".Bar").attr("width");
    }

    function dragged(d,i) {
      barHeight = d3.select(".Bar").attr("height");
      if(i == 0) // circle on the top edge of the bar
      {
        dragIconY = dragIconY + d3.mouse(this)[1];
        updateHandlerPosition("#gHandlerPoint_id_"+i, dragIconX, dragIconY );
        updateHandlerPosition("#gHandlerPoint_id_1", (barStartWidth), (barHeight/2) );

        var x = d3.transform(d3.select(".gContainer").attr("transform")).translate[0];
        var y = d3.transform(d3.select(".gContainer").attr("transform")).translate[1];

        d3.select(".gContainer").attr("transform", function(d,i){
               y = y + dragIconY;
               return "translate(" + [ x , y] + ")"
        })

        console.log(height, barHeight, barHeight - Number(dragIconY));
        d3.select(".Bar").attr("height", barHeight - Number(dragIconY));
      }
      else if (i==1) // circle on the right side of the bar
      {
        oldMouseX = dragIconX;
        dragIconX = d3.mouse(this)[0]+dragIconX;
        barWidth = dragIconX;
        updateHandlerPosition("#gHandlerPoint_id_"+i, dragIconX, dragIconY );
        updateHandlerPosition("#gHandlerPoint_id_0", (barWidth/2), 0 );
        updateHandlerPosition("#gHandlerPoint_id_2", (barWidth/2), -20);
        d3.select(".handlerLine").attr("x1",(barWidth/2)).attr("x2", (barWidth/2));
        d3.select(".Bar").attr("width", Math.abs(dragIconX));
      }
      else if(i==3) //circle on very top
      {

           // code for rotation should come here.

      }
    }

鏈接到jsFiddle: http//jsfiddle.net/Q5Jag/2103/

我把第三個圓圈用於旋轉(圓圈在最頂部)。 但是,我不知道如何修復旋轉。 當我在最頂部拖動圓圈時,我希望矩形旋轉。 我還希望能夠在旋轉時相應地調整圓的大小。

任何想法?

您可以計算相對於矩形中心的旋轉。 v1視為從旋轉的矩形中心到旋轉手柄的矢量,將v2視為從旋轉的矩形中心到旋轉手柄的矢量。 請閱讀此處以了解其背后的數學知識。

// old vector
v1 = {};
v1.x = oldMouseX-gCenterX;
v1.y = oldMouseY-gCenterY;

// new vector
v2 = {};
v2.x = dragHandleX-gCenterX;
v2.y = dragHandleY-gCenterY;

angle = Math.atan2(v2.y,v2.x) - Math.atan2(v1.y,v1.x);

哪里

  • gCenterXgCenterY是矩形中心的坐標
  • oldMouseXoldMouseY是旋轉前鼠標指針的坐標
  • dragHandleXdragHandleY是旋轉后鼠標指針的坐標

這是完整的代碼: http//jsfiddle.net/Q5Jag/2109/ (但如果你混合旋轉和調整大小它會失敗)

暫無
暫無

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

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