我想用javascript创建一个雪花动画。帧速率为200ms,看起来还不错,但不是100%流畅。以下示例使用20ms即可,或完全低效且浪费CPU?
window.setInterval(snow.draw, 20);
snow = {
count: 60,
delay: 20,
flutter: 0.2,
wind: 1.0,
w1: 1,
minSpeed: 0.3,
maxSpeed: 4,
cv: null,
flakes: [],
toggle: function() {
if(window.snowtimer)
snow.stop();
else
snow.start();
},
resize: function() {
snow.cv.width = innerWidth;
snow.cv.height = innerHeight;
snow.gt = snow.ct.createLinearGradient(0,0,0,snow.cv.height);
snow.gt.addColorStop(0.0, '#6666ff');
snow.gt.addColorStop(1.0, '#ffffff');
snow.ct.fillStyle = snow.gt;
},
start: function() {
snow.cv = document.createElement('canvas');
snow.cv.width = snow.cv.height = 10; // set initial size
snow.cv.id = 'backgroundSnowCanvas';
document.body.appendChild(snow.cv);
snow.createFlake();
snow.ct = snow.cv.getContext('2d'),
snow.cv.style.position = 'absolute';
snow.cv.style.top = 0;
snow.cv.style.left = 0;
snow.cv.style.zIndex = -1;
snow.resize();
var c = snow.count;
snow.flakes = [];
do {
snow.flakes.push(new snow.flake());
} while(--c);
snow.ct.fillRect(0,0,snow.cv.width,snow.cv.height);
window.snowtimer = window.setInterval(snow.draw, snow.delay);
window.addEventListener('resize',snow.resize);
},
stop: function() {
window.clearInterval(window.snowtimer);
var c = document.getElementById('backgroundSnowCanvas');
c.parentNode.removeChild(c);
window.snowtimer=snow=null;
},
draw: function() {
var ct = snow.ct, f = snow.flakes, c = snow.count;
ct.fillRect(0,0,snow.cv.width,snow.cv.height);
do {
if(f[--c].draw(ct) && ++fdone) { };
} while(c);
snow.wind += Math.cos(snow.w1++ / 180.0);
},
flake: function() {
this.draw = function(ct) {
ct.drawImage(snow.flakeImage,this.x + snow.wind,this.y,this.sz,this.sz);
this.animate();
};
this.animate = function() {
this.y += this.speed;
this.x += this.flutter * Math.cos(snow.flutter * snow.flutter * this.y);
if(this.y > innerHeight)
this.init(1);
};
this.init = function(f) {
this.speed = snow.minSpeed + (Math.random() * (snow.maxSpeed - snow.minSpeed));
this.sz = ~~(Math.random() * 40) + 20;
this.flutter = ~~(Math.random() * snow.flutter * (60-this.sz));
this.x = (Math.random() * (innerWidth + this.sz)) - this.sz;
this.y = f ? -this.sz : Math.random() * innerHeight;
};
this.init();
},
createFlake: function() {
snow.flakeImage = document.createElement('canvas');
snow.flakeImage.width = snow.flakeImage.height = 40;
var c = snow.flakeImage.getContext('2d');
c.fillStyle = '#fff';
c.translate(20,20);
c.beginPath();
c.rect(-5,-20,10,40);
c.rotate(Math.PI / 3.0);
c.rect(-5,-20,10,40);
c.rotate(Math.PI / 3.0);
c.rect(-5,-20,10,40);
c.closePath();
c.fill();
},
};
答案 0 :(得分:1)
20ms太快了。 50FPS对于雪效果来说太多了。 20fps 是典型的眼睛,但 25fps ,如果您想节省处理费用。
30FPS 或更高,以获得高质量。
最终答案:您应该将其设置为 30ms 。如果您希望图形接近最快的人眼,那不是浪费。尝试在40毫秒(25fps),如果你喜欢它将节省你的过程,而不是妥协视觉效果。
答案 1 :(得分:1)
我认为每秒30帧是合理的。传统胶片库存大约为24fps。大多数现代视频游戏大约30fps(60个高端显卡)。
人眼实际上平均每秒处理大约20帧,当生存本能或恐慌发作时,最多可处理60帧。
1000 / 30ms略高于30fps。
答案 2 :(得分:1)
普通人可以看到24-30 fps。网络动画中典型的是15 fps。高品质电影使用约30 fps。高质量的电视动画大约是24帧/秒。
所以
window.setInterval(snow.draw,your choice);
如果依赖功能有很多,那么你可能想要使用行业标准作为平均值来玩你的fps并且不会偏离很大。 24 fps看起来对我很好。
但是,您也可以使用多次刷新率,如48 fps,重复帧次数为2次,如果您不满意。
尽管如此,正在进行的处理量会对资源变化很大的网络浏览器产生巨大影响。在过去,几年前,这可能会对包括动画在内的任何流动产生巨大影响。尽可能减少它的好处。你可以结合任何东西吗?
Wikipedia has a good article关于帧速率并说明以下内容。
The human eye and its brain interface, the human visual system, can process 10 to 12 separate images per second, perceiving them individually.
和 电影和视频制作人使用24p,即使他们的作品不会转移到电影,只是因为屏幕上的“低”帧速率“看起来”与原生电影相匹配。
以下是一些信息on animation fps.
答案 3 :(得分:0)
动画看起来“平滑”的关键之一是帧速率常量。对于计算机,这意味着帧率需要是监视器帧率的均匀除数:对于目前常用的60Hz监视器,这意味着60FPS,30FPS,15FPS等。
大多数人可以感知15FPS帧速率的各个帧,有些人可以感知到30FPS。如果你的程序可以设法快速绘制(特别是如果它涉及快速运动),那么我会去60FPS(16ms),如果不能,我会去30FPS(33ms)。