2011-12-04 49 views
4

我設法繪製四個不同的曲線與拉斐爾庫的例子。現在,我想創建一個帶有多個句柄的單曲線。在這個例子中,我如何添加更多的句柄。三把手貝塞爾曲線錯位控制點

<!DOCTYPE html> 
<html> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
     <title>Bezier curve</title> 
      <style> 
     #holder { 
      height: 100%; 
      left: 100%; 
      margin: -100% 0 0 -100%; 
      position: absolute; 
      top: 100%; 
      width: 100%; 
     } 
     </style> 
     <script src='jquery.js'></script> 
     <script src="raphael.js"></script> 
     <script> 
      $('document').ready(function() { 
       var r = Raphael("holder", window.innerWidth, window.innerHeight) 

       function curve(x, y, ax, ay, bx, by, zx, zy, color) { 
        var path = [["M", x, y], ["C", ax, ay, bx, by, zx, zy]], 
         path2 = [["M", x, y], ["L", ax, ay], ["M", bx, by], ["L", zx, zy]], 
         curve = r.path(path).attr({stroke: color || Raphael.getColor(), "stroke-width": 4, "stroke-linecap": "round"}), 
         controls = r.set(
          r.path(path2).attr({stroke: "#ccc", "stroke-dasharray": ". ","stroke-width":2}), 
          r.circle(x, y, 5).attr({fill: "#9F2200", stroke: "none"}), 
          r.circle(ax, ay, 5).attr({fill: "#9F2200", stroke: "none"}), 
          r.circle(bx, by, 5).attr({fill: "#9F2200", stroke: "none"}), 
          r.circle(zx, zy, 5).attr({fill: "#9F2200", stroke: "none"}) 
         ); 
        controls[1].update = function (x, y) { 
         var X = this.attr("cx") + x, 
          Y = this.attr("cy") + y; 
         this.attr({cx: X, cy: Y}); 
         path[0][1] = X; 
         path[0][2] = Y; 
         path2[0][2] = X; 
         path2[0][2] = Y; 
         controls[2].update(x, y); 
        }; 
        controls[2].update = function (x, y) { 
         var X = this.attr("cx") + x, 
          Y = this.attr("cy") + y; 
         this.attr({cx: X, cy: Y}); 
         path[1][3] = X; 
         path[1][2] = Y; 
         path2[1][4] = X; 
         path2[1][2] = Y; 
         curve.attr({path: path}); 
         controls[0].attr({path: path2}); 
        }; 
        controls[3].update = function (x, y) { 
         var X = this.attr("cx") + x, 
          Y = this.attr("cy") + y; 
         this.attr({cx: X, cy: Y}); 
         path[1][3] = X; 
         path[1][4] = Y; 
         path2[2][5] = X; 
         path2[2][2] = Y; 
         curve.attr({path: path}); 
         controls[0].attr({path: path2}); 
        }; 
        controls[4].update = function (x, y) { 
         var X = this.attr("cx") + x, 
          Y = this.attr("cy") + y; 
         this.attr({cx: X, cy: Y}); 
         path[1][5] = X; 
         path[1][6] = Y; 
         path2[3][6] = X; 
         path2[3][2] = Y; 
         controls[3].update(x, y); 
        }; 
        controls.drag(move, up); 
       } 
       function move(dx, dy) { 
        this.update(dx - (this.dx || 0), dy - (this.dy || 0)); 
        console.log(this.dx,this.dy); 
        this.dx = dx; 
        this.dy = dy; 
       } 
       function up() { 
        this.dx = this.dy = 0; 
       } 
       curve(70, 100, 110, 100, 130, 200, 170, 200, "hsb(0, 0, 0)"); 
       curve(800, 200, 800, 100, 600, 100, 600, 200, "hsb(0, 0, 0)"); // xp1,yp1, , , , , xp2,yp2 where (xp1,xp2) & (xp2,yp2) are two end points 

        curve(500, 200,500, 300, 300, 300, 300, 200, "hsb(0, 0, 0)"); // xp1,yp1, , , , , xp2,yp2 where (xp1,xp2) & (xp2,yp2) are two end points 

        curve(920, 100,880, 100, 1020, 200, 980, 200, "hsb(0, 0, 0)"); 

      }); 
     </script> 
    </head> 
    <body> 
     <div id="holder"></div> 
    </body> 
</html> 

</body> 

的鏈接,演示是http://jsfiddle.net/insane36/fddGJ/1/

我編輯的代碼,並再次試圖把多個手柄,以顯示在中間的主手柄,但有一些問題,我不知道如果我瞭解它背後的概念。我想創建一個如下圖所示的手柄圖形,並且能夠操縱手柄;

enter image description here

三個手柄的代碼;

<!DOCTYPE html> 
<html> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
     <title>Bezier curve</title> 
      <style> 
     #holder { 
      height: 100%; 
      left: 100%; 
      margin: -100% 0 0 -100%; 
      position: absolute; 
      top: 100%; 
      width: 100%; 
     } 
     </style> 
     <script src="raphael.js"></script> 
     <script> 
      window.onload=function() { 
       var r = Raphael("holder", window.innerWidth, window.innerHeight) 

       function curve(x1, y1, cx1, cy1, cx2, cy2, x2, y2,cx3,cy3,cx4,cy4, color) { //zx --x1 
        var path = [["M", x1, y1], ["C", cx1, cy1, cx2, cy2, x2, y2,"S",cx3,cy3,cx4,cy4]], 
         path2 = [["M", x1, y1], ["L", cx1, cy1], ["M", cx2, cy2], ["L", x2, y2],["M", cx3,cy3],['L',cx4,cy4]], 
         curve = r.path(path).attr({stroke: color || Raphael.getColor(), "stroke-width": 4, "stroke-linecap": "round"}), 
         controls = r.set(
          r.path(path2).attr({stroke: "#ccc", "stroke-dasharray": ". ","stroke-width":2}), 
          r.circle(x1, y1, 5).attr({fill: "#9F2200", stroke: "none"}), 
          r.circle(cx1, cy1, 5).attr({fill: "#9F2200", stroke: "none"}), 
          r.circle(cx2, cy2, 5).attr({fill: "#9F2200", stroke: "none"}), 
          r.circle(x2, y2, 5).attr({fill: "#9F2200", stroke: "none"}), 
          r.circle(cx3, cy3, 5).attr({fill: "#9F2200", stroke: "none"}), 
           r.circle(cx4, cy4, 5).attr({fill: "#9F2200", stroke: "none"}) 

         ); 
        controls[1].update = function (x, y) { 
         var X = this.attr("cx") + x, 
          Y = this.attr("cy") + y; 
         this.attr({cx: X, cy: Y}); 
         path[0][9] = X; 
         path[0][2] = Y; 
         path2[0][10] = X; 
         path2[0][2] = Y; 
         controls[2].update(x, y); 
        }; 
        controls[2].update = function (x, y) { 
         var X = this.attr("cx") + x, 
          Y = this.attr("cy") + y; 
         this.attr({cx: X, cy: Y}); 
         path[1][11] = X; 
         path[1][2] = Y; 
         path2[1][12] = X; 
         path2[1][2] = Y; 
         curve.attr({path: path}); 
         controls[0].attr({path: path2}); 
        }; 
        controls[3].update = function (x, y) { 
         var X = this.attr("cx") + x, 
          Y = this.attr("cy") + y; 
         this.attr({cx: X, cy: Y}); 
         path[1][3] = X; 
         path[1][4] = Y; 
         path2[2][13] = X; 
         path2[2][2] = Y; 
         curve.attr({path: path}); 
         controls[0].attr({path: path2}); 
        }; 
        controls[4].update = function (x, y) { 
         var X = this.attr("cx") + x, 
          Y = this.attr("cy") + y; 
         this.attr({cx: X, cy: Y}); 
         path[1][5] = X; 
         path[1][6] = Y; 
         path2[3][14] = X; 
         path2[3][2] = Y; 
         controls[3].update(x, y); 
        }; 
        controls[5].update = function (x, y) { 
         var X = this.attr("cx") + x, 
          Y = this.attr("cy") + y; 
         this.attr({cx: X, cy: Y}); 
         path[1][8] = X; 
         path[1][9] = Y; 
         path2[4][15] = X; 
         path2[4][2] = Y; 
         controls[4].update(x, y); 
        }; 
         controls[6].update = function (x, y) { 
         var X = this.attr("cx") + x, 
          Y = this.attr("cy") + y; 
         this.attr({cx: X, cy: Y}); 
         path[1][10] = X; 
         path[1][11] = Y; 
         path2[5][16] = X; 
         path2[5][2] = Y; 
         controls[5].update(x, y); 
        }; 

        controls.drag(move, up); 
       } 
       function move(dx, dy) { 
        this.update(dx - (this.dx || 0), dy - (this.dy || 0)); 
        console.log(this.dx,this.dy); 
        this.dx = dx; 
        this.dy = dy; 
       } 
       function up() { 
        this.dx = this.dy = 0; 
       } 
       curve(10, 80, 40, 10, 65,10,150,150,95, 80, 180,180, "hsb(0, 0, 0)"); 

      }; 
     </script> 
    </head> 
    <body> 
     <div id="holder"></div> 
    </body> 
</html> 

</body> 
</html> 

我想我已經錯過了,並沒有安排適當的控制點和值

+1

我做了類似於你想要做的事情:http://type.method.ac,但是我不能通過查看它來告訴你代碼有什麼問題。我沒有在我的路徑中使用「S」節點,但可能是我自己的無知。 – Duopixel

+0

您是否使用貝塞爾曲線進行此操作?我沒有看到曲線。 – Sandeep

+1

這些字母在一個單獨的文件http://shape.method.ac/js/letters.js – Duopixel

回答

1

看看這個fiddle - 我想我有它做你在找什麼。 (編輯:固定這個小提琴,這樣你就不必指定在curve()構造的反射控制點)

我覺得最關鍵的是曲線上的中間點的第二個控制點僅僅是一個反射第一個控制點(按照SVG documentation),所以你必須對這種控制進行「假」。 (你的代碼確實有一些問題,在您的update()函數試圖更新不存在的數組的值,比如path[1][6] = Y;...path[1]只有三個元素)如果你想在兩個控制點

(我們認爲你必須從你的路徑中刪除「S」,並且改變一些代碼(這裏是one like that

如果你想要兩個控制點允許從點移動不同的距離,但保持曲線平滑點,我認爲你必須手動完成。您可以從第二個示例開始,但是您必須以編程方式將移動控制點的角度反映到相反的控制點,同時允許從相反控制點到曲線上的點的距離保持固定。

+0

謝謝,它看起來不錯,但我有一個問題。哪些是中間控制點的變量。 – Sandeep

+0

第一個控制點是cx2,cy2,第二個控制點是cx2b,cy2b。在第一種情況下,在構造函數中計算cx2b,cy2b(即通過反映第一個控制點)。在第二種情況下,cx2b和cy2b被傳入構造函數。 –

+0

如果我想要動態創建這樣的路徑,無論用戶點擊了什麼,我想生成一條小曲線,當點擊另一個點時,它將與已經繪製的曲線相關聯並創建句柄和新曲線。 – Sandeep