Поскольку я добавил o: Math.random()*(1 - 0.1) + 0.1//opacity
для значений случайной непрозрачности заряда, анимация не работает плавно. Что я могу сделать, чтобы предотвратить это? Как сделать мой скрипт более эффективным в отношении производительности?
window.onload = function () {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var W = canvas.width = window.innerWidth;
var H = 550;
var mp = 45; //max particles
var particles = [];
//var rotate = 180;
reqAnimFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame;
for ( var i = 0; i < mp; i++ )
{
particles.push({
x: Math.floor(Math.random()*W), //x-coordinate
y: Math.floor(Math.random()*H), //y-coordinate
d: Math.floor(Math.random()*(12 - 1) + 1), //density
r: Math.floor(Math.random()*(70 - 10) + 10), //radius
o: Math.random()*(1 - 0.1) + 0.1 //opacity
})
}
function animate() {
reqAnimFrame(animate);
for ( var i = 0; i < mp; i++ )
{
var p = particles[i];
p.x += p.d;
if(p.x >= W + p.r){
p.x = -300;
p.y = Math.floor(Math.random()*H);
}
draw();
}
}
function draw() {
ctx.clearRect(0, 0, W, H);
for ( var i = 0; i < mp; i++ )
{
var p = particles[i];
ctx.fillStyle = "rgba(51,51,51," + p.o + ")";
ctx.beginPath();
ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2, false);
ctx.fill();
//ctx.moveTo(p.x,p.y);
//ctx.lineTo(p.x + 150, p.y + (-180));
//ctx.lineTo(p.x + 300, p.y);
}
}
animate();
};//onload function
вы вызываете draw внутри цикла обновления один раз для каждой частицы, что приводит к стоимости mp * mp вместо стоимости mp.
Первое, что нужно сделать, - это нарисовать только один раз на частицу, поэтому не вызывайте его в цикле обновления, а только один раз в конце обновления.
Обратите внимание, что вы можете получить некоторые результаты, изменив контекст globalAlpha вместо создания нового цвета.
В первой closePath
нет функции функции closePath
, во второй скрипке она вызывает.
В первой скрипте график времени devtools показывает дополнительное использование памяти 7 МБ в секунду (после того, как 1-й вызов CG в вашем случае, IMHO): от 10 МБ до 17 МБ
Во второй временной шкале beginPath
показано дополнительное использование памяти 2 МБ от beginPath
to closePath
(около 130 мс): от 10 МБ до 12 МБ. Но в этом случае CG не звонит.
Я думаю, будет лучше добавить функцию closePath
, чтобы предотвратить вызов GC. И используйте меньшее количество частиц для старых браузеров, потому что для меня (MacBook Pro, Chrome) все работает отлично, а fps - 60 (максимум).
beginPath
: он запускает только подпуть. Каждый новый beginPath будет создавать только еще один подпуть. НоclosePath
добавляет текущий подпуть к основному пути и закрывает подпуть, то есть освобождает часть памяти.