我们如何根据某一事件的进展来绘制一个封闭的抛物型bezier曲线?
更多背景:
PS:还有其他问题,这些问题显示了如何构建一个圆形进度条,但是我看到的是一个抛物线进度条。
发布于 2022-06-25 13:47:41
您可以用一些SVG和画布的混合填充画布中的任何SVG曲线来计算一些事情:
const path = document.querySelector( '#computing-path' );
const canvas = document.querySelector( 'canvas' );
const progress = document.querySelector( '#progress' );
const bezierPoints = [
[50, 50],
[0, 30],
[20, 180],
[180, 150]
];
const ctx = canvas.getContext( '2d' );
/* We need to set the SVG path to compute its length */
path.setAttribute( 'd', `M${bezierPoints[0].join()} C ${bezierPoints[1].join()} ${bezierPoints[2].join()} ${bezierPoints[3].join()}` );
const pathLength = path.getTotalLength();
/* `p` will be a normalised value between 0 and 1 */
function draw( p = 0 ){
ctx.clearRect( 0, 0, canvas.width, canvas.height );
if( p <= 0 ) return;
ctx.save();
ctx.lineWidth = 10;
ctx.strokeStyle = 'white';
/** This is the crucial bit - the second value is very large because we want the empty space of the dash to stretch to at least the end. */
ctx.setLineDash([ p * pathLength, pathLength * 10 ]);
ctx.beginPath();
ctx.moveTo( ...bezierPoints[0] );
ctx.bezierCurveTo(
...bezierPoints[1],
...bezierPoints[2],
...bezierPoints[3]
);
ctx.stroke();
ctx.restore();
}
draw( progress.value );
progress.addEventListener( 'input', event => draw( progress.value ));html, body { height: 100%; }
body { background: gray; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 20px; }
canvas { border: 1px solid white; }<svg xmlns="http://www.w3.org/2000/svg" style="visibility:hidden;position:fixed;top:0;left:0;transform:translate(-100%,-100%)"><path id="computing-path" /></svg>
<canvas width="200" height="200"></canvas>
<input id="progress" type="range" min="0" max="1" value=".5" step=".01" />
https://stackoverflow.com/questions/68824272
复制相似问题