title: Resizable and Rotatable Rectangle D3?
body: <p>I am trying to create a rectangle where I can resize and rotate it using handlers (small circles) located on the top of the rectangle. Similar to the most of the drawing tools that allow us to resize and rotate the shapes. </p>
  
  <p>I added three circles on the top of my rectangle. One circle is for resizing the width of the rectangle (circle on the right side). Another rectangle is for resizing the height of the bar (circle on the top). Resizing the rectangle works perfectly.</p>
  
  <pre><code> 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.
  
        }
      }
  </code></pre>
  
  <p>Link to jsFiddle: <a href="http://jsfiddle.net/Q5Jag/2103/" rel="nofollow noreferrer">http://jsfiddle.net/Q5Jag/2103/</a></p>
  
  <p>I put the third circle for rotation (the circle on the very top). However, I have no idea how to fix the rotation. I want the rectangle to rotate when I drag the circle on the very top. I also want to be able to resize the circle accordingly when it is rotated. </p>
  
  <p>Any idea?</p>