feat: 实现飞白笔触效果,settling阶段根据速度方向绘制墨迹拖尾

This commit is contained in:
张翔
2026-05-03 19:43:34 +08:00
parent 9b1939dd02
commit 14f16ed794
+42
View File
@@ -189,6 +189,8 @@ function updateParticle(p: Particle, maxTrail: number): void {
}
}
p.prevVx = p.vx;
p.prevVy = p.vy;
p.x += p.vx;
p.y += p.vy;
p.vx *= 0.98;
@@ -377,6 +379,43 @@ function drawInkLayers(
}
}
function drawFeibai(
ctx: CanvasRenderingContext2D,
p: Particle,
rgb: string,
): void {
const speed = Math.sqrt(p.prevVx * p.prevVx + p.prevVy * p.prevVy);
if (speed < 0.1) {
return;
}
const dirX = -p.prevVx / speed;
const dirY = -p.prevVy / speed;
const length = p.radius * (3 + Math.random() * 2);
const endX = p.x + dirX * length;
const endY = p.y + dirY * length;
const perpX = -dirY;
const perpY = dirX;
const curvature = (Math.random() - 0.5) * length * 0.15;
const cpX = (p.x + endX) / 2 + perpX * curvature;
const cpY = (p.y + endY) / 2 + perpY * curvature;
const grad = ctx.createLinearGradient(p.x, p.y, endX, endY);
grad.addColorStop(0, `rgba(${rgb}, ${p.opacity * 0.25})`);
grad.addColorStop(1, 'transparent');
ctx.save();
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(p.x, p.y);
ctx.quadraticCurveTo(cpX, cpY, endX, endY);
ctx.strokeStyle = grad;
ctx.lineWidth = Math.max(0.3, p.radius * 0.6);
ctx.stroke();
ctx.restore();
}
function drawParticle(
ctx: CanvasRenderingContext2D,
p: Particle,
@@ -400,6 +439,9 @@ function drawParticle(
drawInkLayers(ctx, p, config);
} else if (p.phase === 'settling') {
drawInkLayers(ctx, p, config);
if (config.showFeibai) {
drawFeibai(ctx, p, rgb);
}
} else if (p.phase === 'fading') {
const grad1 = ctx.createRadialGradient(p.x, p.y, 0, p.x, p.y, r * 1.5);
grad1.addColorStop(0, `rgba(${rgb}, ${p.opacity * 0.6})`);