Skip to content
Snippets Groups Projects
Commit b001137f authored by Dj's avatar Dj
Browse files

fix(parallax-css-testpage): Performance Optimization

parent 7940e7c0
Branches
No related tags found
No related merge requests found
......@@ -4,8 +4,19 @@
* Particle emitter and renderer.
*/
const Debug = false
const Static = true
// Polyfill: requestAnimationFrame()
//
// window.requestAnimationFrame = function() {
// return window.requestAnimationFrame ||
// window.webkitRequestAnimationFrame ||
// window.mozRequestAnimationFrame ||
// window.msRequestAnimationFrame ||
// window.oRequestAnimationFrame ||
// function(f) {
// window.setTimeout(f,1e3/60);
// }
// }();
//
......@@ -50,8 +61,8 @@ function MaxValue(value, max) {
}
function RandomPoint2D(minMaxX, minMaxY) {
const x = randomValue(minMaxX.min, minMaxX.max)
const y = randomValue(minMaxY.min, minMaxY.max)
var x = randomValue(minMaxX.min, minMaxX.max)
var y = randomValue(minMaxY.min, minMaxY.max)
return Point2D( x, y )
}
......@@ -69,87 +80,85 @@ function Update(scene, particle) {
// Cache object access
var width = scene.width
var height = scene.height
var particleSize = particle.size
var particleSizeValue = particleSize.value
var particleSizeBound = particleSize.bound
var particleSizeStep = particleSize.step
var particlePosition = particle.position
var particlePositionX = particlePosition.x
var particlePositionY = particlePosition.y
var particleDirection = particle.direction
var particleDirectionX = particleDirection.x
var particleDirectionY = particleDirection.y
// Animate the pulse effect of the particle
//
const isMaxSize = particle.size.value >= particle.size.bound.max
const isMinSize = particle.size.value <= particle.size.bound.min
const updateSizeStep =
Object.assign({}, particle, {
size: Object.assign({}, particle.size, {
direction:
var isMaxSize = particleSizeValue >= particleSizeBound.max
var isMinSize = particleSizeValue <= particleSizeBound.min
var sizeDirection =
(isMaxSize || isMinSize)
? particle.size.direction * -1
: particle.size.direction
})
})
const updateSize =
Object.assign({}, updateSizeStep, {
size: Object.assign({}, updateSizeStep.size, {
value:
updateSizeStep.size.value + updateSizeStep.size.step * updateSizeStep.size.direction,
// updateSizeStep.size.value
})
})
? particleSize.direction * -1
: particleSize.direction
var sizeValue =
particleSizeValue + particleSizeStep * sizeDirection
// Animate the movement of the particle
//
const sizeOffset = particle.size.value * 0.5
const y = particle.position.y
const top = y + sizeOffset
const bottom = y - sizeOffset
const left = particle.position.x - sizeOffset
const right = particle.position.x + sizeOffset
const isRightEdge = (right >= width)
const isLeftEdge = (left <= 0)
const isTopEdge = (bottom < 0)
const isBottomEdge = (top > height)
var sizeOffset = sizeValue * 0.5
var top = particlePositionY + sizeOffset
var bottom = particlePositionY - sizeOffset
var left = particlePositionX - sizeOffset
var right = particlePositionX + sizeOffset
var isRightEdge = (left > width)
var isLeftEdge = (right < 0)
var isTopEdge = (bottom < 0)
var isBottomEdge = (top > height)
var positionX =
(isRightEdge)
? -sizeOffset
: (isLeftEdge)
? width + sizeOffset
: particlePositionX + particleDirectionX
var positionY =
(isBottomEdge)
? -sizeOffset
: (isTopEdge)
? height + sizeOffset
: particlePositionY + particleDirectionY
const updateDirection =
Object.assign({}, updateSize, {
direction:
Point2D(
// Bounce of the right and left edges of the scene
(isRightEdge || isLeftEdge)
? updateSize.direction.x * -1
: updateSize.direction.x,
// Bounce from the top and bottom edges of the scene
(isTopEdge || isBottomEdge)
? particle.direction.y * -1
: particle.direction.y,
)
})
const updatePosition =
Object.assign({}, updateDirection, {
position:
Point2D(
updateDirection.position.x + updateDirection.direction.x,
updateDirection.position.y + updateDirection.direction.y,
// (isTopEdge)
// ? height + sizeOffset
// : (isBottomEdge)
// ? -sizeOffset
// : (updateDirection.position.y + updateDirection.direction.y),
)
return Particle({
position: {
x: positionX,
y: positionY,
},
direction: {
x: particleDirectionX,
y: particleDirectionY,
},
size: {
value: sizeValue,
bound: particleSizeBound,
step: particleSizeStep,
direction: sizeDirection
},
color: particle.color
})
const updatedParticle = Particle(updatePosition)
return updatedParticle
}
function Draw(scene, particle) {
// Cache object access
const size = particle.size.value
const position = particle.position
var size = particle.size.value
var position = particle.position
// Draw calculations
const yOffset = scene.yOffset * scene.depthScale
const drawOffset = size * 0.5
const y = yOffset + (position.y - drawOffset)
const ctx = scene.ctx
const isVisible = (size > 0) && (y < window.innerHeight) && (y > 0)
var yOffset = scene.yOffset * scene.depthScale
var drawOffset = size * 0.5
var y = yOffset + (position.y - drawOffset)
var ctx = scene.ctx
var isVisible = (size > 0) && (y < window.innerHeight) && (y > 0)
// Draw
if (isVisible) {
......@@ -172,39 +181,43 @@ function Render(scene, particles) {
}
function Animate(scene, particles) {
var fpsInterval = scene.fpsInterval
var now = Date.now()
var then = scene.then
var elapsed = now - then
var updatedParticles = [],
fpsInterval = scene.fpsInterval,
now = performance.now(),
then = scene.then,
elapsed = now - then,
tolerance = 0.1
// Just render when we're reaching the configured fps
if (elapsed > scene.fpsInterval) {
if (elapsed >= (scene.fpsInterval - tolerance)) {
scene.yOffset = getNodeYOffset(scene.anchorNode)
scene.then = now - (elapsed % fpsInterval)
Render(scene, particles)
}
// Update particle positions for the next render call
const updatedParticles = particles.map(function doUpdate(p) {
updatedParticles = particles.map(function doUpdate(p) {
return Update(scene, p)
})
// Function to animate the next frame
return function () {
return Animate(scene, updatedParticles)
return Animate(
scene,
updatedParticles
)
}
}
function CreateScene({ canvasId, contentId, depth, fps }) {
const contentNode = document.getElementById(contentId)
const height = getNodeHeight(contentNode)
const fpsInterval = 1000 / fps
const width = window.innerWidth
const yOffset = 0
const canvas = document.getElementById(canvasId)
const ctx = canvas.getContext('2d')
const depthScaledHeight = height * (depth+1)
var contentNode = document.getElementById(contentId),
height = getNodeHeight(contentNode),
width = window.innerWidth,
fpsInterval = 1000 / fps,
yOffset = 0,
canvas = document.getElementById(canvasId),
ctx = canvas.getContext('2d'),
depthScaledHeight = height * (depth+1)
ctx.canvas.width = width
ctx.canvas.height = window.innerHeight
......@@ -217,7 +230,7 @@ function CreateScene({ canvasId, contentId, depth, fps }) {
ctx,
fps,
fpsInterval,
then: Date.now(),
then: performance.now(),
anchorNode: contentNode
}
}
......@@ -268,9 +281,16 @@ function CreateParticles(scene, {
function Particles(configs) {
var particles = []
var isRunning = false
var throttled = false
var delay = 25
var rafId = undefined
function animate(rendererList) {
if (isRunning) {
requestAnimationFrame(function () {
rafId = requestAnimationFrame(function () {
animate(
rendererList.map(function doRender(render) {
return render()
......@@ -281,43 +301,38 @@ function Particles(configs) {
}
function init() {
return configs.map(function (particleConfig) {
particles = configs.map(function (particleConfig) {
var scene = CreateScene(particleConfig.scene)
var particles = CreateParticles(scene, particleConfig.particles)
return Animate(scene, particles)
})
return particles
}
var particles = []
var isRunning = false
var throttled = false
var delay = 250
return {
init: function () {
particles = init()
},
run: function () {
function run() {
if (particles.length === 0) {
particles = init()
}
isRunning = true
animate(particles)
},
}
stop: function () {
function stop() {
isRunning = false
},
cancelAnimationFrame(rafId)
}
return {
init: init,
run: run,
stop: stop,
onScreenSizeChange: function () {
isRunning = false
stop()
if (!throttled) {
throttled = true
setTimeout(function () {
particles = init()
isRunning = true
animate(particles)
run()
throttled = false
}, delay)
}
......
......@@ -109,7 +109,7 @@
// rendering height and it's the anchor to get the y offset
// to simulate scrolling.
contentId: 'content',
fps: 14,
fps: 16,
depth: 0.08,
},
particles: {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment