2011-12-04 2 views
4

Raphael 라이브러리의 예제를 사용하여 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/

하지만 몇 가지 문제를 가지고 있는데 잘 모릅니다 경우 I 그것의 뒤에 개념을 이해했다. 아래 그림과 같이 손잡이가있는 그림을 만들고 손잡이를 조작 할 수 있기를 원했습니다.

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에서 봐 배치하지 않은 생각 - 나는 당신이 찾고있는 일을 생각. 나는 키가 곡선의 중간 지점의 제 2 제어 지점이 바로 반영이라고 생각

: (편집 그래서 당신은 curve() 생성자에서 반사 제어 지점을 지정할 필요가 없습니다이 바이올린을 고정) 첫 번째 제어점 (SVG documentation) 중 하나이므로 해당 제어를 '가짜'로 정렬해야합니다. 당신이 두 개의 제어 지점을 원하는 경우

(코드는path[1]는 세 가지 요소를 가지고 ... path[1][6] = Y;처럼 업데이트() 함수가 존재하지 않는 배열 값을 업데이트하려고 한 몇 가지 문제를 가지고 있었다) 독립적으로 행동하십시오 (곡선이 반드시 그 점을 통과하여 부드럽게 움직이지 않도록), 경로에서 "S"를 제거하고 코드 일부를 변경해야한다고 생각합니다 (여기에 one like that)

포인트와 다른 거리를 이동할 수있는 두 개의 컨트롤 포인트가 있지만 점을 통과하는 커브를 부드럽게 유지하려면 손으로해야한다고 생각합니다. 두 번째 예제부터 시작할 수 있지만 움직이는 제어점의 각도를 반대쪽 제어점에 프로그램 적으로 반영하고 반대쪽 제어점에서 곡선의 점까지의 거리를 고정 된 상태로 유지해야합니다.

+0

고마워요, 좋아 보이지만 질문이 있습니다. 중간에있는 조절 점에 대한 변수는 다음과 같습니다. – Sandeep

+0

첫 번째 제어점은 cx2, cy2이고 두 번째 제어점은 cx2b, cy2b입니다. 첫 번째 경우에 생성자에서 cx2b, cy2b가 계산됩니다 (즉, 첫 번째 제어점을 반영하여). 두 번째 경우에는 cx2b 및 cy2b가 생성자에 전달됩니다. –

+0

이러한 경로를 동적으로 만들고 싶다면 사용자가 클릭 할 때마다 작은 커브를 생성하고 다른 포인트를 클릭하면 이미 그려진 커브와 연관되어 핸들 및 새 커브를 만들 수 있습니다. – Sandeep

관련 문제