-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Real Time Animations and Maximum FPS Limiter #366
base: master
Are you sure you want to change the base?
Changes from all commits
16e0c32
d28b4fe
80b6e6e
2647389
5c25d65
66d0038
eec12b4
2b9321f
df6c857
949cf69
2397140
bfafa84
1b2d33f
cb9eed3
17b927a
7ef9796
0d1c2df
f00eca0
b2a0e35
3b552b6
5119154
98dd36b
6c454f0
029285e
625de2b
a67285e
6f3e03e
e194cb9
704ae40
c174558
2fde687
c7b09df
a7cf07a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,9 +10,13 @@ | |
var pJS = function(tag_id, params){ | ||
|
||
var canvas_el = document.querySelector('#'+tag_id+' > .particles-js-canvas-el'); | ||
var lastFrameTime = 0; | ||
var pageHidden = false; | ||
|
||
/* particles.js variables with default values */ | ||
this.pJS = { | ||
this.pJS = { | ||
// Default FPS limit implementation (see line 1314 for codified change). | ||
fps_limit: 60, | ||
canvas: { | ||
el: canvas_el, | ||
w: canvas_el.offsetWidth, | ||
|
@@ -213,7 +217,7 @@ var pJS = function(tag_id, params){ | |
if(!pJS.particles.move.enable){ | ||
pJS.fn.particlesEmpty(); | ||
pJS.fn.particlesCreate(); | ||
pJS.fn.particlesDraw(); | ||
pJS.fn.particlesDraw(0); | ||
pJS.fn.vendors.densityAutoParticles(); | ||
} | ||
|
||
|
@@ -503,7 +507,7 @@ var pJS = function(tag_id, params){ | |
} | ||
}; | ||
|
||
pJS.fn.particlesUpdate = function(){ | ||
pJS.fn.particlesUpdate = function(delta){ | ||
|
||
for(var i = 0; i < pJS.particles.array.length; i++){ | ||
|
||
|
@@ -520,9 +524,9 @@ var pJS = function(tag_id, params){ | |
|
||
/* move the particle */ | ||
if(pJS.particles.move.enable){ | ||
var ms = pJS.particles.move.speed/2; | ||
p.x += p.vx * ms; | ||
p.y += p.vy * ms; | ||
var ms = pJS.particles.move.speed/10; | ||
p.x += p.vx * ms * delta; | ||
p.y += p.vy * ms * delta; | ||
} | ||
|
||
/* change opacity status */ | ||
|
@@ -634,13 +638,13 @@ var pJS = function(tag_id, params){ | |
|
||
}; | ||
|
||
pJS.fn.particlesDraw = function(){ | ||
pJS.fn.particlesDraw = function(delta){ | ||
|
||
/* clear canvas */ | ||
pJS.canvas.ctx.clearRect(0, 0, pJS.canvas.w, pJS.canvas.h); | ||
|
||
/* update each particles param */ | ||
pJS.fn.particlesUpdate(); | ||
pJS.fn.particlesUpdate(delta); | ||
|
||
/* draw each particle */ | ||
for(var i = 0; i < pJS.particles.array.length; i++){ | ||
|
@@ -767,7 +771,7 @@ var pJS = function(tag_id, params){ | |
) | ||
if(i == nb-1){ | ||
if(!pJS.particles.move.enable){ | ||
pJS.fn.particlesDraw(); | ||
pJS.fn.particlesDraw(0); | ||
} | ||
pJS.tmp.pushing = false; | ||
} | ||
|
@@ -780,7 +784,7 @@ var pJS = function(tag_id, params){ | |
|
||
pJS.particles.array.splice(0, nb); | ||
if(!pJS.particles.move.enable){ | ||
pJS.fn.particlesDraw(); | ||
pJS.fn.particlesDraw(0); | ||
} | ||
|
||
}; | ||
|
@@ -1309,42 +1313,50 @@ var pJS = function(tag_id, params){ | |
}; | ||
|
||
|
||
pJS.fn.vendors.draw = function(){ | ||
pJS.fn.vendors.draw = function (timestamp) { | ||
|
||
if(pJS.particles.shape.type == 'image'){ | ||
|
||
if(pJS.tmp.img_type == 'svg'){ | ||
|
||
if(pJS.tmp.count_svg >= pJS.particles.number.value){ | ||
pJS.fn.particlesDraw(); | ||
if(!pJS.particles.move.enable) cancelRequestAnimFrame(pJS.fn.drawAnimFrame); | ||
else pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw); | ||
}else{ | ||
//console.log('still loading...'); | ||
if(!pJS.tmp.img_error) pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw); | ||
} | ||
|
||
}else{ | ||
//if (pageHidden) { | ||
// return; | ||
//} | ||
|
||
if(pJS.tmp.img_obj != undefined){ | ||
pJS.fn.particlesDraw(); | ||
if(!pJS.particles.move.enable) cancelRequestAnimFrame(pJS.fn.drawAnimFrame); | ||
else pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw); | ||
}else{ | ||
if(!pJS.tmp.img_error) pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw); | ||
} | ||
|
||
} | ||
|
||
}else{ | ||
pJS.fn.particlesDraw(); | ||
if(!pJS.particles.move.enable) cancelRequestAnimFrame(pJS.fn.drawAnimFrame); | ||
else pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw); | ||
// FPS limit logic | ||
// If we are too fast, just draw without updating | ||
var fps_limit = pJS.fps_limit; | ||
if(timestamp < lastFrameTime + (1000 / fps_limit)) { | ||
requestAnimFrame(pJS.fn.vendors.draw); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I may be wrong but I think requestAnimationFrame MUST be called on each loop but you can then check if the function is not suppose to run and just return. So basically but the requestAnimFrame(...) before the if statement. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the code below it's called the function, it's handled by other The issue solved by this PR is that this library doesn't handle well different frequencies, on my MBP 2021 when I use Chrome I have 120FPS I see faster animations than Safari, limited to 60FPS. Every speed is doubled on Chrome, and this is a bad behavior. |
||
return; | ||
} | ||
|
||
delta = timestamp - lastFrameTime; | ||
lastFrameTime = timestamp; | ||
|
||
if (pJS.particles.shape.type == 'image') { | ||
if (pJS.tmp.img_type == 'svg') { | ||
if (pJS.tmp.count_svg >= pJS.particles.number.value) { | ||
pJS.fn.particlesDraw(delta); | ||
if (!pJS.particles.move.enable) cancelRequestAnimFrame(pJS.fn.drawAnimFrame); | ||
else pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw); | ||
} else { | ||
//console.log('still loading...'); | ||
if (!pJS.tmp.img_error) pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw); | ||
} | ||
} else { | ||
if (pJS.tmp.img_obj != undefined) { | ||
pJS.fn.particlesDraw(delta); | ||
if (!pJS.particles.move.enable) cancelRequestAnimFrame(pJS.fn.drawAnimFrame); | ||
else pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw); | ||
} else { | ||
if (!pJS.tmp.img_error) pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw); | ||
} | ||
} | ||
} else { | ||
pJS.fn.particlesDraw(delta); | ||
if (!pJS.particles.move.enable) cancelRequestAnimFrame(pJS.fn.drawAnimFrame); | ||
else pJS.fn.drawAnimFrame = requestAnimFrame(pJS.fn.vendors.draw); | ||
} | ||
}; | ||
|
||
|
||
|
||
pJS.fn.vendors.checkBeforeDraw = function(){ | ||
|
||
// if shape is image | ||
|
@@ -1364,7 +1376,7 @@ var pJS = function(tag_id, params){ | |
|
||
}else{ | ||
pJS.fn.vendors.init(); | ||
pJS.fn.vendors.draw(); | ||
pJS.fn.vendors.draw(0); | ||
} | ||
|
||
}; | ||
|
@@ -1408,6 +1420,22 @@ var pJS = function(tag_id, params){ | |
pJS.fn.vendors.start(); | ||
|
||
|
||
/* Cancel animation if page is not in focus | ||
Browsers will do this anyway, however the | ||
Delta time must also be reset, so canceling | ||
the old frame and starting a new one is necessary */ | ||
function handleVisibilityChange() { | ||
if (document.hidden) { | ||
pageHidden = true; | ||
cancelRequestAnimFrame(pJS.fn.drawAnimFrame); | ||
} else { | ||
pageHidden = false; | ||
lastFrameTime = performance.now(); | ||
pJS.fn.vendors.draw(0); | ||
} | ||
} | ||
|
||
document.addEventListener("visibilitychange", handleVisibilityChange, false); | ||
|
||
}; | ||
|
||
|
@@ -1435,6 +1463,7 @@ window.requestAnimFrame = (function(){ | |
function(callback){ | ||
window.setTimeout(callback, 1000 / 60); | ||
}; | ||
|
||
})(); | ||
|
||
window.cancelRequestAnimFrame = ( function() { | ||
|
@@ -1538,4 +1567,5 @@ window.particlesJS.load = function(tag_id, path_config_json, callback){ | |
}; | ||
xhr.send(); | ||
|
||
}; | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be 60?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be merged is what it should be!