我有一组控制点,代表一个高阶贝塞尔曲线 如何使用单个SVG路径绘制此曲线?
UPD:
例如,我有一组点:(x1,y1)(x2,y2)(x3,y3)(x4,y4)(x5,y5)。
如何在术语中使用SVG路径C
,S
,Q
或T
?
UPD 2:解决方案
我问这个问题是用TweenMax描绘一个动画对象路径
后来我收到GreenSock forum的答复
这是CodePen example。
答案 0 :(得分:10)
简短回答:你不能。
SVG只有内置二次(二阶)和三次曲线(三阶),而你显示的曲线是四阶(四阶)。 SVG没有通用的“N term Bezier”绘图指令,所以你必须在这里做出妥协。
一些选项:
toDataURL
函数从结果中构建图像,然后在SVG中将该图像加载为图像。这将完美地运行,但如果您使用创建的SVG路径样式,使画布生成相同的样式可能是一个挑战。底线:如果你需要显示更高阶的贝塞尔曲线,SVG不是一个合适的技术(我建议你只使用画布做动画,或者更好,像d3.js或{ {3}}。可能是后者)。
如果您最终自己动手,那么采样功能非常简单。曲线是参数化的,由值t
控制,从0到1(包括),并且可以写为嵌套线性插值:
getCurvePoint(t, points) {
if (points.length === 1) return points[0];
var newpoints = [];
for(var i=0,j=1; j<points.length; i++,j++) {
newpoints[i] = lerp2d(t, points[i], points[j]);
}
return getCurvePoint(t,newpoints);
}
lerp
函数是标准线性插值函数:
lerp(ratio, start, end) {
return ratio*start + (1-ratio)*end;
}
lerp2d(ratio, start, end) {
return {
x: lerp(ratio, start.x, end.x),
y: lerp(ratio, start.y, end.y)
};
}
一个简单的jsbin示例:paper.js使用点
var points = [
{x:50, y:100},
{x:50, y:250},
{x:210, y:250},
{x:250, y:50},
{x:380, y:150}
];
给我们:
http://jsbin.com/pesutibefu/edit?html,js,output
虽然如果你需要动画漂亮的路径,可拖动的控制点等,Paper.js草图会更容易使用。
答案 1 :(得分:1)
SVG不支持Quadratic和Cubic以外的Bezier曲线。因此,在命令(C,S,Q或T)方面没有任何表示。
贝塞尔曲线可以用两种方式定义:使用“C”命令表示立方体或使用“Q”命令表示二次曲线。那些命令有固定长度的参数 4为二次方,6为立方,因此示例SVG字符串将显示为“Q 150,-300 300,0”您可以看到类似“Q 150,-300 300的SVG字符串,0 50,150 100,200“,但这只是一条接一条的两条四条曲线,”Q“的参数数量始终是4的倍数,”C“的参数数量总是6的倍数。
list中的每个命令:
M = moveto
L = lineto
H =水平线到
V =垂直线到
C =曲线到
S =平滑曲线
Q =二次Bézier曲线
T =平滑的二次Bézier曲线到
A =椭圆弧
Z =近距离
在JavaScript或实际上在任何其他标准API(.NET绘图,核心图形,Android Canvas)中都有表示,但在所有这些API中除了Cubic或Quad之外没有任何其他方法。另外根据我的经验,我从未见过具有绘制更高阶贝塞尔曲线的特征的绘图应用程序。因此,您最好的选择是将高阶曲线简化为Q或C.