2016-11-26 2 views
3

Ich versuche ein Rechteck zu erstellen, in dem ich die Größe ändern und es mithilfe von Handlern (kleine Kreise) oben auf dem Rechteck drehen kann. Ähnlich wie bei den meisten Zeichenwerkzeugen, mit denen wir die Formen skalieren und drehen können.Veränderbares und drehbares Rechteck D3?

Ich habe drei Kreise oben auf meinem Rechteck hinzugefügt. Ein Kreis dient zum Ändern der Breite des Rechtecks ​​(Kreis auf der rechten Seite). Ein weiteres Rechteck dient zum Ändern der Höhe des Balkens (Kreis oben). Die Größe des Rechtecks ​​zu ändern funktioniert perfekt.

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. 

     } 
    } 

Link zu jsFiddle: http://jsfiddle.net/Q5Jag/2103/

Ich legte den dritten Kreis für eine Drehung (der Kreis auf der ganz oben). Ich habe jedoch keine Ahnung, wie ich die Rotation fixiere. Ich möchte das Rechteck drehen, wenn ich den Kreis ganz oben ziehe. Ich möchte auch in der Lage sein, den Kreis entsprechend zu verändern, wenn er gedreht wird.

Irgendeine Idee?

Antwort

1

Sie können die Drehung in Bezug auf die Mitte Ihres Rechtecks ​​berechnen. Betrachten v1 als Vektor von der Mitte des Rechtecks ​​zur Drehgriff vor der Drehung undv2 als einen Vektor von der Mitte des Rechtecks ​​zur Dreh nach Drehung behandeln. Lesen Sie here, um die Mathematik dahinter zu kennen.

// 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); 

wo

  • gCenterX und gCenterY sind Koordinaten der Mitte des Rechtecks ​​
  • oldMouseX und oldMouseY Koordinaten des Mauszeigers sind vor der Drehung
  • dragHandleX und dragHandleY Koordinaten des Mauszeigers sind nach Drehung

Hier ist der vollständige Code: http://jsfiddle.net/Q5Jag/2109/ (Aber es schlägt fehl, wenn Sie Rotation und Größenänderung mischen)

Verwandte Themen