Swa*_*ain 2 html svg bezier vector-graphics reactjs
我一直在尝试在 svg 中制作这个形状。问题是,我想用蓝色手柄来操纵它。我已经制作了一个简单的箭头,并且能够使用二次贝塞尔曲线改变其形状。但我不知道如何做这种形状。有什么方法可以将线条转换成这种弯曲的形式吗?
您可以使用getPointAtLength和getTotalLengthAPI 沿着任何任意 SVG 几何体“骑行”,并生成正弦波。
这是一个纯 TypeScript 的示例(在这里找到一个带有一些额外功能的交互式 React CodeSandbox)。
function computeWave(
path: SVGPathElement,
freq: number,
maxAmp: number,
phase: number,
res: number
) {
// Get the points of the geometry with the given resolution
const length = path.getTotalLength();
const points = [];
if (res < 0.1) res = 0.1; // prevent infinite loop
for (let i = 0; i <= length + res; i += res) {
const { x, y } = path.getPointAtLength(i);
points.push([x, y]);
}
// For each of those points, generate a new point...
const sinePoints = [];
for (let i = 0; i < points.length - 1; i++) {
// Numerical computation of the angle between this and the next point
const [x0, y0] = points[i];
const [x1, y1] = points[i + 1];
const ang = Math.atan2(y1 - y0, x1 - x0);
// Turn that 90 degrees for the normal angle (pointing "left" as far
// as the geometry is considered):
const normalAngle = ang - Math.PI / 2;
// Compute the sine-wave phase at this point.
const pointPhase = ((i / (points.length - 1)) * freq - phase) * Math.PI * 2;
// Compute the sine-wave amplitude at this point.
const amp = Math.sin(pointPhase) * maxAmp;
// Apply that to the current point.
const x = x0 + Math.cos(normalAngle) * amp;
const y = y0 + Math.sin(normalAngle) * amp;
sinePoints.push([x, y]);
}
// Terminate the sine points where the shape ends.
sinePoints.push(points[points.length - 1]);
// Compute SVG polyline string.
return sinePoints
.map(([x, y], i) => `${i === 0 ? "M" : "L"}${x},${y}`)
.join(" ");
}
Run Code Online (Sandbox Code Playgroud)
它在橙色线之后生成蓝色线(描述为M100,100 C150,100,150,250,200,200):

当然,您可以对此进行调整,例如在末端“捏住”波,以避免任意相位的任何突然结束等。
| 归档时间: |
|
| 查看次数: |
422 次 |
| 最近记录: |