diff --git a/src/parallax-css-testpage/particles.js b/src/parallax-css-testpage/particles.js new file mode 100644 index 0000000000000000000000000000000000000000..e9db1870a7bba9b80fda53483daa20d453ffe6ad --- /dev/null +++ b/src/parallax-css-testpage/particles.js @@ -0,0 +1,213 @@ +/* + * Particle.js + */ + + +// +// Config +// + + +const Fps = 16 + + +// +// Helper +// + + +// Variables needed for fps calculation. +const FpsInterval = 1000 / Fps +let Then = Date.now() // Argh.. Global, mutable, variable..! + +function randomValue(min, max) { + return (Math.random() * (+max - +min) + +min) +} + + + +// +// Data +// + + + +function Point2D(x, y) { + return { x, y } +} + +function MinMax(min, max) { + return { min, max } +} + +function MaxValue(value, max) { + return { value, max } +} + +function RandomPoint2D(minMaxX, minMaxY) { + const x = randomValue(minMaxX.min, minMaxX.max) + const y = randomValue(minMaxY.min, minMaxY.max) + return Point2D(x, y) +} + +function Particle({ position, direction, size, color }) { + return { position, direction, size, color } +} + + + +// +// Transformations | Actions +// + + + +function Update(canvas, particle) { + // Animate the movement of the particle + // + const isRightEdge = + (particle.position.x + particle.size.value >= canvas.width) + const isLeftEdge = (particle.position.x <= 0) + const isBottomEdge = + (particle.position.y + particle.size.value >= canvas.height) + const isTopEdge = (particle.position.y <= 0) + + const updateDirection = + Object.assign({}, particle, { + direction: + Point2D( + (isRightEdge || isLeftEdge) + ? particle.direction.x * -1 + : particle.direction.x, + (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, + ) + }) + + // Animate the pulse effect of the particle + // + const isMaxSize = updatePosition.size.value >= updatePosition.size.bound.max + const isMinSize = updatePosition.size.value <= updatePosition.size.bound.min + const updateSizeStep = + Object.assign({}, updatePosition, { + size: Object.assign({}, updatePosition.size, { + direction: + (isMaxSize || isMinSize) + ? updatePosition.size.direction * -1 + : updatePosition.size.direction + }) + }) + const updateSize = + Object.assign({}, updateSizeStep, { + size: Object.assign({}, updateSizeStep.size, { + value: + // Todo: Animate puls effect with the help of Math.sin() + updateSizeStep.size.value + updateSizeStep.size.step * updateSizeStep.size.direction, + }) + }) + + const updatedParticle = Particle(updateSize) + return updatedParticle +} + +function Clear(ctx) { + ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height) +} + +function Render(ctx, particles) { + particles.forEach( + function (particle) { + if (particle.size.value > 0) { + const offset = (particle.size.value*0.5) + ctx.fillStyle = particle.color + ctx.fillRect( + particle.position.x - offset, + particle.position.y - offset, + particle.size.value, + particle.size.value + ) + } + } + ) +} + +function Animate(ctx, particles) { + // Update particle positions and register for the next + // frame to render. + requestAnimationFrame(() => { + const updatedParticles = + particles.map(function (p) { + return Update(ctx.canvas, p) + }) + Animate(ctx, updatedParticles) + }) + + + // Render particles to canvas + const now = Date.now() + const elapsed = now - Then + if (elapsed > FpsInterval) { + Then = now - (elapsed % FpsInterval) + Clear(ctx) + Render(ctx, particles) + } +} + + + +// +// Api +// + + + +function Particles({ canvasId, amount, color, size, lifespan }) { + // Init the canvas for rendering. + const canvas = document.getElementById(canvasId) + const ctx = canvas.getContext('2d') + ctx.canvas.width = window.innerWidth + ctx.canvas.height = window.innerHeight + + // Generate random particles + const particles = + Array.from( + { length: amount }, + () => Particle({ + position: + RandomPoint2D( + MinMax(0, (ctx.canvas.width - (size*2))), + MinMax(0, (ctx.canvas.height - (size*2))) + ), + direction: + RandomPoint2D( + MinMax(-0.2, 0.2), + MinMax(-0.2, 0.2) + ), + size: { + value: randomValue(-size, size), + bound: MinMax(-size, size), + step: size / ((lifespan) / Fps), + direction: + (randomValue(0, 100) < 50) + ? -1 + : +1 + }, + color + }) + ) + + Then = Date.now() + Animate(ctx, particles) +} + + + diff --git a/src/parallax-css-testpage/template.css b/src/parallax-css-testpage/template.css index b7f4e359591e3ea07a764819eea016e0d4cb905e..58ec1a4b2086e0db3dbdae3ee4f676163c6e3b50 100644 --- a/src/parallax-css-testpage/template.css +++ b/src/parallax-css-testpage/template.css @@ -59,8 +59,6 @@ div { * Elements */ - - .vignette { background-image: url("03_Vignette/RC3_vignette.png"); } @@ -92,13 +90,16 @@ div { opacity: 0.5; } +.particles { + /* background-color: transparent; */ +} + /* * Parallax layer */ - .z-0 { transform: translateZ(0.5px) scale(-1.5); } diff --git a/src/parallax-css-testpage/template.html b/src/parallax-css-testpage/template.html index 7127045b19fd037516415729f699599063931235..c0a11ab14a9b02d5d67231a5850487e7be4c18b9 100644 --- a/src/parallax-css-testpage/template.html +++ b/src/parallax-css-testpage/template.html @@ -9,6 +9,7 @@ <!-- <link rel="stylesheet" href="parallax.css"> --> <link rel="stylesheet" href="template.css"> <!-- <script src="/rellax.min.js"></script> --> + <script src="particles.js"></script> </head> <body> @@ -25,6 +26,7 @@ <div class="static full-bg bg-image"></div> <div class="static full-bg vcr-overlay"></div> <div class="static full-bg grid"></div> + <canvas id="particles" class="static full-bg particles"></canvas> <div class="static full-bg vignette"></div> </div> @@ -33,8 +35,8 @@ <!-- <div class="parallax bg-image"></div> --> <div class="layer z-1 scroll-bg gradient"></div> - <div class="layer z-0 scroll-bg fg-pixels"></div> - <div class="layer z-6 scroll-bg bg-pixels"></div> + <!-- <div class="layer z-0 scroll-bg fg-pixels"></div> --> + <!-- <div class="layer z-6 scroll-bg bg-pixels"></div> --> <div id="content" class="content"> <h1>This is a Parallax Scroll Example</h1> @@ -79,8 +81,16 @@ </div> - - + <script> + var bgParticles = { + canvasId: 'particles', + amount: 75, + color: 'white', + size: 7, + lifespan: 4000 // in milliseconds + } + Particles(bgParticles) + </script> </body>