diff --git a/src/parallax-css-testpage/particles.js b/src/parallax-css-testpage/particles.js index a9202cb0dfd4cede0d8cf8326d62a0b32289a8b2..9ea117afe0f78af474d540dc21c1bb7651d490bb 100644 --- a/src/parallax-css-testpage/particles.js +++ b/src/parallax-css-testpage/particles.js @@ -165,12 +165,18 @@ return exports // Create the Particles Module | Namespace. var Particles = (function () { + // // Helper // +var MathRandom = Math.random +var MathAbs = Math.abs +var MathTrunc = Math.trunc +var MathPow = Math.pow + function randomValue(min, max) { - var value = (Math.random() * (+max - +min) + +min) + var value = (MathRandom() * (+max - +min) + +min) // Prevent values that can be possible boring return (min !== 0 && max !== 0 && (value === 0 || value === 1)) ? randomValue(min, max) @@ -192,35 +198,40 @@ function calcParticleCount(scene, particleDensity) { var sceneVolume = scene.width * scene.height var scale = 100 var particleFactor = (sceneVolume / referenceArea) / scale - var particleCount = Math.abs(Math.trunc( + var particleCount = MathAbs(MathTrunc( particleFactor * particleDensity )) return particleCount || 0 } -function normalize(val) { - var min = 0 - var max = 1 - var delta = max - min - return (val - min) / delta -} +var normalize = Memoize( + function doNormalize(val) { + var min = 0 + var max = 1 + var delta = max - min + return (val - min) / delta + } +) // Easing functions from: https://easings.net/ -function easeOutQuint(x) { - return 1 - Math.pow(1 - x, 5); -} - -function easeInQuint(x) { - return x * x * x * x * x; -} +var easeOutQuint = Memoize( + function doEaseOutQuint(x) { + return 1 - MathPow(1 - x, 5); + } +) -function easeOutExpo(x) { - return x === 1 ? 1 : 1 - Math.pow(2, -10 * x); -} +var easeOutExpo = Memoize( + function easeOutExpo(x) { + return x >= 1 ? 1 : 1 - MathPow(2, -10 * x); + } +) -function easeInExpo(x) { - return x === 0 ? 0 : Math.pow(2, 10 * x - 10); + +function easing(value) { + return (value < 0) + ? -easeOutExpo(-value) + : easeOutExpo(value) } @@ -237,10 +248,6 @@ function MinMax(min, max) { return { min, max } } -function MaxValue(value, max) { - return { value, max } -} - function RandomPoint2D(minMaxX, minMaxY) { var x = randomValue(minMaxX.min, minMaxX.max) var y = randomValue(minMaxY.min, minMaxY.max) @@ -257,13 +264,11 @@ function Update(scene, particle) { // Cache object access -> Performance var width = scene.width var height = scene.height - var color = particle.color - var particleSize = particle.size - var particleSizeValue = particleSize.value - var particleSizeBound = particleSize.bound - var particleSizeBoundMin = particleSizeBound.min - var particleSizeBoundMax = particleSizeBound.max - var particleSizeStep = particleSize.step + var color = particle.color + var particleSize = particle.size + var particleSizeStep = particleSize.step + var particleSizeAnimValue = particleSize.animValue + var particleSizeScale = particleSize.scale var particleSizeDirection = particleSize.direction var particlePosition = particle.position var particlePositionX = particlePosition.x @@ -274,14 +279,18 @@ function Update(scene, particle) { // Animate the pulse effect of the particle // - var isMaxSize = particleSizeValue > particleSizeBoundMax - var isMinSize = particleSizeValue < particleSizeBoundMin + // var absSizeAnimValue = particleSizeAnimValue * particleSizeDirection + var isMaxSize = particleSizeAnimValue > 1 + var isMinSize = particleSizeAnimValue < -1 var sizeDirection = (isMaxSize || isMinSize) ? -particleSizeDirection : particleSizeDirection - var sizeValue = - particleSizeValue + particleSizeStep * sizeDirection + var animValue = particleSizeAnimValue + (particleSizeStep * sizeDirection) + // The operator ~~ is a more performant shorthand for Math.trunc() + var sizeValue = ~~( + easing(animValue) * particleSizeScale + ) // Animate the movement of the particle // @@ -316,9 +325,11 @@ function Update(scene, particle) { direction: particleDirection, size: { value: sizeValue, - bound: particleSizeBound, + animValue: animValue, step: particleSizeStep, - direction: sizeDirection + scale: particleSizeScale, + direction: sizeDirection, + offset: sizeOffset }, color: color } @@ -326,14 +337,16 @@ function Update(scene, particle) { function Draw(scene, particle) { // Cache object access - var particlePosition = particle.position + var particlePosition = particle.position var particlePositionX = particlePosition.x var particlePositionY = particlePosition.y + var particleSize = particle.size + var particleSizeValue = particleSize.value + var drawOffset = particleSize.offset // Draw calculations -- var yOffset = scene.yOffset * scene.depthScale - var size = particle.size.value - var drawOffset = size * 0.5 + var size = particleSizeValue var x = particlePositionX - drawOffset var y = yOffset + (particlePositionY - drawOffset) @@ -412,15 +425,15 @@ function CreateScene(cfg) { ctx.canvas.height = window.innerHeight return { - width, + width: width, height: depthScaledHeight, - yOffset, + yOffset: yOffset, depthScale: depth, - ctx, - fps, - fpsInterval, + fps: fps, + fpsInterval: fpsInterval, then: performance.now(), - anchorNode: contentNode + anchorNode: contentNode, + ctx: ctx, } } @@ -432,8 +445,11 @@ function CreateParticles(scene, cfg) { speed = cfg.speed, lifespan = cfg.lifespan + var initAnimValue = randomValue(-1, 1) + return Array.from( { + // length: 1 length: calcParticleCount(scene, density) }, function Particle() { @@ -449,15 +465,20 @@ function CreateParticles(scene, cfg) { MinMax(-speed, speed) ), size: { - value: randomValue(-size, size), - bound: MinMax(-size, size), - step: size / ((lifespan) / scene.fps), + value: size * initAnimValue, + animValue: initAnimValue, + scale: size, + step: 1 / ((lifespan) / scene.fps), direction: // 50% Chance for the particle floating in one // direction or the other. (randomValue(0, 100) < 50) ? -1 : +1, + // Offset is needed for boundary calculation and for + // drawing the pixels. We cache it here, to prevent + // double calculation of the same value. + offset: size * initAnimValue * 0.5 }, color } diff --git a/src/parallax-css-testpage/template.html b/src/parallax-css-testpage/template.html index f924691a067a60e6feb359f433c4c438cd394f29..fbcfd9449f40c72ba4ecafe38898d7af453aeb64 100644 --- a/src/parallax-css-testpage/template.html +++ b/src/parallax-css-testpage/template.html @@ -95,11 +95,11 @@ depth: 2.5, }, particles: { - density: 15, + density: 5, color: 'white', size: 40, - speed: 0.5, - lifespan: 12000 // in milliseconds + speed: 0.7, + lifespan: 4000 // in milliseconds } } var bgParticleConfig = { @@ -116,9 +116,9 @@ particles: { density: 100, color: 'white', - size: 7, + size: 5, speed: 0.2, - lifespan: 8000 // in milliseconds + lifespan: 4000 // in milliseconds } } var animation = Particles([