pit*_*rio 3 html javascript canvas
几天前我来到stackoverflow询问如何在画布上缓慢绘制箭头。没有人能够给我正确的答案......所以我希望这对某人有所帮助。
基本上,我想在地图上动画从一个国家到另一个国家的入侵过程。要做到这一点,我应该使用画布并绘制一个从 A 国移动到 B 国的箭头,但不是一个固定的箭头......一个逐渐增长的箭头。
下面的代码绘制了一个箭头,但不是渐进式的。因此,我需要像具有 5 秒过渡的 CSS 动画一样绘制这条曲线。
function drawCurve (ctx, x0, y0, x1, y1, x2, y2){
ctx.beginPath();
ctx.moveTo( x0, y0 );
ctx.quadraticCurveTo( x1, y1, x2, y2 );
ctx.stroke();
ctx.closePath();
}
var docCanvas = document.getElementById('canvas');
var ctx = docCanvas.getContext('2d');
drawCurve(ctx, 0, 100, 150, -50, 300, 100);Run Code Online (Sandbox Code Playgroud)
<canvas id="canvas" width="480" height="320"></canvas>Run Code Online (Sandbox Code Playgroud)
经过一番挖掘,我找到了这个解决方案,它提供了我想要的一切。
基本上drawBezierSplit()允许您绘制二次贝塞尔曲线的一部分。
所有功劳都归功于帕特里克·加尔布雷思。
/**
* Animates bezier-curve
*
* @param ctx The canvas context to draw to
* @param x0 The x-coord of the start point
* @param y0 The y-coord of the start point
* @param x1 The x-coord of the control point
* @param y1 The y-coord of the control point
* @param x2 The x-coord of the end point
* @param y2 The y-coord of the end point
* @param duration The duration in milliseconds
*/
function animatePathDrawing(ctx, x0, y0, x1, y1, x2, y2, duration) {
var start = null;
var step = function animatePathDrawingStep(timestamp) {
if (start === null)
start = timestamp;
var delta = timestamp - start,
progress = Math.min(delta / duration, 1);
// Clear canvas
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
// Draw curve
drawBezierSplit(ctx, x0, y0, x1, y1, x2, y2, 0, progress);
if (progress < 1) {
window.requestAnimationFrame(step);
}
};
window.requestAnimationFrame(step);
}
/**
* Draws a splitted bezier-curve
*
* @param ctx The canvas context to draw to
* @param x0 The x-coord of the start point
* @param y0 The y-coord of the start point
* @param x1 The x-coord of the control point
* @param y1 The y-coord of the control point
* @param x2 The x-coord of the end point
* @param y2 The y-coord of the end point
* @param t0 The start ratio of the splitted bezier from 0.0 to 1.0
* @param t1 The start ratio of the splitted bezier from 0.0 to 1.0
*/
function drawBezierSplit(ctx, x0, y0, x1, y1, x2, y2, t0, t1) {
ctx.beginPath();
if( 0.0 == t0 && t1 == 1.0 ) {
ctx.moveTo( x0, y0 );
ctx.quadraticCurveTo( x1, y1, x2, y2 );
} else if( t0 != t1 ) {
var t00 = t0 * t0,
t01 = 1.0 - t0,
t02 = t01 * t01,
t03 = 2.0 * t0 * t01;
var nx0 = t02 * x0 + t03 * x1 + t00 * x2,
ny0 = t02 * y0 + t03 * y1 + t00 * y2;
t00 = t1 * t1;
t01 = 1.0 - t1;
t02 = t01 * t01;
t03 = 2.0 * t1 * t01;
var nx2 = t02 * x0 + t03 * x1 + t00 * x2,
ny2 = t02 * y0 + t03 * y1 + t00 * y2;
var nx1 = lerp ( lerp ( x0 , x1 , t0 ) , lerp ( x1 , x2 , t0 ) , t1 ),
ny1 = lerp ( lerp ( y0 , y1 , t0 ) , lerp ( y1 , y2 , t0 ) , t1 );
ctx.moveTo( nx0, ny0 );
ctx.quadraticCurveTo( nx1, ny1, nx2, ny2 );
}
ctx.stroke();
ctx.closePath();
}
/**
* Linearly interpolates between two numbers
*/
function lerp(v0, v1, t) {
return ( 1.0 - t ) * v0 + t * v1;
}
var docCanvas = document.getElementById('canvas');
var ctx = docCanvas.getContext('2d');
animatePathDrawing(ctx, 0, 100, 150, -50, 300, 100, 5000);Run Code Online (Sandbox Code Playgroud)
<canvas id="canvas" width="480" height="320"></canvas>Run Code Online (Sandbox Code Playgroud)
编辑:
如果你需要一个 polyfill,你可以使用以下代码:
(function() {
var lastTime = 0;
var vendors = ['webkit', 'moz'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame =
window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame)
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}());
Run Code Online (Sandbox Code Playgroud)
链接: http : //www.pjgalbraith.com/drawing-animated-curves-javascript/
| 归档时间: |
|
| 查看次数: |
1838 次 |
| 最近记录: |