簡體   English   中英

具有三個手柄的貝塞爾曲線錯位了控制點

[英]Bezier curve with three handles misplaces the control points

我設法用拉斐爾圖書館的例子繪制了四條不同的曲線。 現在,我想創建一個包含多個手柄的曲線。 如何在此示例中添加更多句柄。

<!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/

我編輯了代碼並再次嘗試放置多個句柄以顯示中間的主句柄但有一些問題,我不知道我是否理解它背后的概念。 我想用下圖創建一個帶手柄的圖形,並能夠操縱手柄;

在此輸入圖像描述

三個句柄的代碼是;

<!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>

我想我已經錯過了,沒有正確安排控制點和值

看看這個小提琴 - 我想我已經做到了你正在尋找的東西。 編輯:修復這個小提琴,這樣你就不必在curve()構造函數中指定反射的控制點)

我認為關鍵是曲線中間點的第二個控制點只是第一個控制點的反映(根據SVG文檔 ),所以你必須對那些控制的'假'進行排序。 (你的代碼確實有一些問題,你的update()函數試圖更新不存在的數組值,比如path[1][6] = Y; ... path[1]只有三個元素)

如果你希望兩個控制點獨立運行(這樣曲線在這一點上不一定是平滑的),我認為你必須從你的路徑中刪除“S”,並改變一些代碼(這里是一個像那個

如果您希望允許兩個控制點從該點移動不同的距離,但保持曲線平滑點,我認為您必須手動執行此操作。 您可以從第二個示例開始,但是您必須以編程方式將移動控制點的角度反映到相對的控制點,同時允許從相對控制點到曲線上的點的距離保持固定。

暫無
暫無

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

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