gpt4 book ai didi

javascript - 创建一个不中断上一次调用的循环动画

转载 作者:搜寻专家 更新时间:2023-10-31 21:49:01 24 4
gpt4 key购买 nike

我正在尝试创建垂直行圆圈的循环动画。每一行都从浏览器底部开始到顶部,以 0 到 2 秒之间的随机间隔出现。问题在于,当动画在时间上靠得太近时,新动画会中断前一个动画,因此有时一排圆圈不会一直延伸到浏览器的顶部。我怎样才能防止这种情况发生,而不是让多行同时设置动画?

这是 fiddle

    var timer;

var newLine1 = function(){
clearInterval(timer);
var posX = Math.random() * canvas.width;
posY = canvas.height;

timer = setInterval(function() {
posY -= 20;

c.fillStyle = "rgba(23, 23, 23, 0.05)";
c.fillRect(0, 0, canvas.width, canvas.height);

c.fillStyle = "white";
c.beginPath();
c.arc(posX, posY, 10, 0, twoPi, false);
c.fill();

}, 30);
setTimeout(newLine1, Math.random() * 2000);
};
newLine1();

最佳答案

这是使用垂直渐变圆圈的上升图像和首选动画循环 (requestAnimationFrame) 的一种方法。

注释代码和演示:

// canvas related variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

// cache PI*2 because it's used often
var PI2=Math.PI*2;

// variables related to the stream of circles
var radius=10;
var alpha=1.00;
var alphaFade=0.05;

// create an in-memory canvas containing
// a stream of vertical circles
// with alpha=1.00 at top and alpha=0.00 at bottom
// This canvas is drawImage'd on the on-screen canvas
// to simulate animating circles
var streamHeight=(1/alphaFade)*radius*2;
var columnCanvas=document.createElement('canvas');
var columnCtx=columnCanvas.getContext('2d');
columnCanvas.width=radius*2;
columnCanvas.height=streamHeight;
for(var y=radius;y<ch+radius*2;y+=radius*2){
columnCtx.fillStyle='rgba(255,255,255,'+alpha+')';
columnCtx.beginPath();
columnCtx.arc(radius,y,radius,0,PI2);
columnCtx.closePath();
columnCtx.fill();
alpha-=alphaFade;
}

// just testing, remove this
document.body.appendChild(columnCanvas);


// create an array of stream objects
// each stream-object is a column of circles
// at random X and with Y
// animating from bottom to top of canvas
var streams=[];

// add a new stream
function addStream(){

// reuse any existing stream that's already
// scrolled off the top of the canvas
var reuseStream=-1;
for(var i=0;i<streams.length;i++){
if(streams[i].y<-streamHeight){
reuseStream=i;
break;
}
}

// create a new stream object with random X
// and Y is off-the bottom of the canvas
var newStream={
x: Math.random()*(cw-radius),
y: ch+radius+1
}


if(reuseStream<0){
// add a new stream to the array if no stream was available
streams.push(newStream);
}else{
// otherwise reuse the stream object at streams[reuseStream]
streams[reuseStream]=newStream;
}


}

// move all streams upward if the
// elapsed time is greater than nextMoveTime
var nextMoveTime=0;

// move all streams every 16ms X 3 = 48ms
var moveInterval=16*3;

// add a new stream if the
// elapsed time is greater than nextAddStreamTime
var nextAddStreamTime=0;

// set the background color of the canvas to black
ctx.fillStyle='black';

// start the animation frame
requestAnimationFrame(animate);

// the animation frame
function animate(currentTime){

// request a new animate loop
requestAnimationFrame(animate);

// add a new stream if the
// current elapsed time is > nextAddStreamTime
if(currentTime>nextAddStreamTime){
nextAddStreamTime+=Math.random()*1000;
addStream();
}

// move all streams upward if the
// current elapsed time is > nextMoveTime
if(currentTime>nextMoveTime){
nextMoveTime+=moveInterval;
ctx.fillRect(0,0,cw,ch);
for(var i=0;i<streams.length;i++){
var s=streams[i];
if(s.y<-streamHeight){continue;}
ctx.drawImage(columnCanvas,s.x,s.y);
s.y-=radius*2;
}
}

}
body{ background-color: ivory; padding:10px; }
canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=400></canvas>

关于javascript - 创建一个不中断上一次调用的循环动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27208681/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com