gpt4 book ai didi

javascript - 具有三个 handle 的贝塞尔曲线错放控制点

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:36:16 26 4
gpt4 key购买 nike

我借助 Raphael 库的示例成功绘制了四种不同的曲线。现在,我想创建一条包含多个 handle 的曲线。如何在此示例中添加更多句柄。

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

我编辑了代码并再次尝试放置多个 handle 以在中间显示主 handle ,但遇到了一些问题,我不知道我是否理解它背后的概念。我想创建一个带有 handle 的图形,如下图所示,并且能够操纵 handle ;

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>

我想我错过了控制点和值,没有安排好

最佳答案

看看这个fiddle - 我想我有它做你正在寻找的东西。 (编辑: 修复了这个 fiddle ,因此您不必在 curve() 构造函数中指定反射控制点)

我认为关键在于曲线中间点的第二个控制点只是第一个控制点的反射(reflect)(根据 SVG documentation ),因此您必须“伪造”该控制。 (您的代码确实存在一些问题,您的 update() 函数试图更新不存在的数组值,例如 path[1][6] = Y; ... path[1] 只有三个元素)

如果您希望两个控制点独立运行(这样曲线通过该点就不一定是平滑的),我认为您必须从路径中删除“S”,并更改一些代码(此处是 one like that )

如果您希望允许两个控制点从该点移动不同的距离,但要保持通过该点的曲线平滑,我认为您必须手动完成。您可以从第二个示例开始,但您必须以编程方式将移动控制点的 Angular 反射(reflect)到相反的控制点,同时允许从相反的控制点到曲线上的点的距离保持固定。

关于javascript - 具有三个 handle 的贝塞尔曲线错放控制点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8378887/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com