diff --git a/src/parallax-css-testpage/particles.js b/src/parallax-css-testpage/particles.js
index b7dd7f68ba67ceb5f94eec0b11b0d439477eccc2..9b59090b193984fe4fcce64139585d4dac07453a 100644
--- a/src/parallax-css-testpage/particles.js
+++ b/src/parallax-css-testpage/particles.js
@@ -2,25 +2,64 @@
  *  Particles.js
  */
 
+const Debug = false
+const Static = true
+
+// Needed for fps calculation.
+let Then = Date.now() // Argh.. Global, mutable, variable..!
+
 
 //
 //  Helper
 //
 
 
-// Variables needed for fps calculation.
-let Then = Date.now() // Argh.. Global, mutable, variable..!
-
+// Random Value without zero
 function randomValue(min, max) {
-    return (Math.random() * (+max - +min) + +min)
+    const value = (Math.random() * (+max - +min) + +min)
+    return (value === 0) ? randomValue(min, max) : value
 }
 
-function initCanvas(id) {
-    const canvas = document.getElementById(id)
+function getNodeYOffset(node) {
+    const dimensions = node.getBoundingClientRect()
+    return (dimensions) ? dimensions.y : 0
+}
+
+function getNodeHeight(node) {
+    const dimensions = node.getBoundingClientRect()
+    return (dimensions) ? dimensions.height : window.innerHeight
+}
+
+function getScene(canvasId, height) {
+    const width  = window.innerWidth
+    const fov = 0.8
+    const perspective = width * fov
+    const yOffset = 0
+    const canvas = document.getElementById(canvasId)
     const ctx = canvas.getContext('2d')
-    ctx.canvas.width = window.innerWidth
+
+    ctx.canvas.width = width
     ctx.canvas.height = window.innerHeight
-    return ctx
+
+    return { width, height, yOffset, perspective, ctx }
+}
+
+// function to2dParticle(scene, particle) {
+//     const perspective = scene.perspective
+//     const scale = perspective / (perspective + particle.position.z)
+//     const yOffset = scene.yOffset * scale
+//     const offset = particle.size.value * 0.5
+//     const x = particle.position.x - offset
+//     const y = (yOffset + (particle.position.y - offset))
+//     const size = particle.size.value
+//     // const y = (yOffset + (particle.position.y - offset)) * scale
+//     // const size = particle.size.value * scale
+//     return { x, y, size }
+// }
+
+function calcScrolledYPos(ctx, yPos, yOffset) {
+    const y = (yPos + yOffset)
+    return (y <= 0) ? ctx.canvas.height - y : y
 }
 
 
@@ -33,6 +72,10 @@ function Point2D(x, y) {
     return { x, y }
 }
 
+function Point3D(x, y, z) {
+    return { x, y, z }
+}
+
 function MinMax(min, max) {
     return { min, max }
 }
@@ -47,6 +90,16 @@ function RandomPoint2D(minMaxX, minMaxY) {
     return Point2D(x, y)
 }
 
+function RandomPoint3D(minMaxX, minMaxY, minMaxZ) {
+    const x = randomValue(minMaxX.min, minMaxX.max)
+    const y = randomValue(minMaxY.min, minMaxY.max)
+    const z =
+        (typeof minMaxZ === 'number')
+            ? minMaxZ
+            : randomValue(minMaxZ.min, minMaxZ.max)
+    return Point3D(x, y, z)
+}
+
 function Particle({ position, direction, size, color }) {
     return { position, direction, size, color }
 }
@@ -57,7 +110,11 @@ function Particle({ position, direction, size, color }) {
 //
 
 
-function Update(canvas, particle) {
+function Update(scene, particle) {
+    // Cache object access
+    const width = scene.width
+    const height = scene.height
+
     // Animate the pulse effect of the particle
     //
     const isMaxSize = particle.size.value >= particle.size.bound.max
@@ -83,85 +140,100 @@ function Update(canvas, particle) {
     // Animate the movement of the particle
     // 
     const sizeOffset = particle.size.value * 0.5
-    const xCenter    = particle.position.x - sizeOffset
-    const yCenter    = particle.position.y - sizeOffset
-    const isRightEdge  =
-        (particle.position.x + particle.size.value >= canvas.width)
-    const isLeftEdge   = (particle.position.x <= 0)
-    const isTopEdge    = (yCenter <= 0)
-    const isBottomEdge = (yCenter >= canvas.height)
-    const scrollOffset = window.pageYOffset
+    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)
 
     const updateDirection =
         Object.assign({}, updateSize, {
             direction:
                 Point2D(
+                    // Bounce of the right and left edges of the screen.
                     (isRightEdge || isLeftEdge)
                         ? updateSize.direction.x * -1
                         : updateSize.direction.x,
-                    // (isTopEdge || isBottomEdge)
-                    //     ? particle.direction.y * -1
-                    //     : particle.direction.y
-                    updateSize.direction.y
+                    (isTopEdge || isBottomEdge)
+                        ? particle.direction.y * -1
+                        : particle.direction.y,
                 )
         })
     const updatePosition =
         Object.assign({}, updateDirection, {
             position:
-                Point2D(
+                Point3D(
                     updateDirection.position.x + updateDirection.direction.x,
-                    (isTopEdge)
-                        ? (canvas.height - 1) + updateDirection.direction.y
-                        : (isBottomEdge)
-                            ? sizeOffset + 1
-                            : updateDirection.position.y + updateDirection.direction.y,
+                    updateDirection.position.y + updateDirection.direction.y,
+                    // (isTopEdge)
+                    //     ? height + sizeOffset
+                    //     : (isBottomEdge)
+                    //         ? -sizeOffset
+                    //         : (updateDirection.position.y + updateDirection.direction.y),
+                    updateDirection.position.z
                 )
         })
 
- 
     const updatedParticle = Particle(updatePosition)
     return updatedParticle
 }
 
-function Clear(ctx) {
-    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height)
+function Draw(scene, particle) {
+    // Cache object access
+    const size = particle.size.value
+
+    const perspective = scene.perspective
+    const scale = perspective / (perspective + particle.position.z)
+    const yOffset = scene.yOffset * scale
+    const drawOffset = size * 0.5
+    const y = yOffset + (particle.position.y - drawOffset)
+    const ctx = scene.ctx
+
+    const isVisible = (size > 0) && (y < window.innerHeight) && (y > 0)
+    if (isVisible) {
+        ctx.fillStyle = particle.color
+        ctx.fillRect(particle.position.x - drawOffset, y, size, size)
+    }
+}
+
+function Clear(scene) {
+    scene.ctx.clearRect(0, 0, scene.width, scene.height)
 }
 
-function Render(ctx, particles) {
+function Render(scene, particles) {
+    Clear(scene)
     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
-                )
-            }
+            Draw(scene, particle)
         }
     )
 }
 
-function Animate(ctx, fpsInterval, particles) {
+function Animate({ scene, fpsInterval, particles, anchorNode }) {
+    scene.yOffset = getNodeYOffset(anchorNode)
+
     // Update particle positions and register for the next frame
     // to render. 
     requestAnimationFrame(() => {
         const updatedParticles = 
             particles.map(function (p) {
-                return Update(ctx.canvas, p)
+                return Update(scene, p)
             })
-        Animate(ctx, fpsInterval, updatedParticles)
+        Animate({ scene, fpsInterval, particles: updatedParticles, anchorNode })
     }) 
 
-    // Render particles to canvas
+    // Render particles to canvas and do some fps calculations
     const now = Date.now()
     const elapsed = now - Then
     if (elapsed > fpsInterval) {
         Then = now - (elapsed % fpsInterval)
-        Clear(ctx)
-        Render(ctx, particles)  
+        Render(scene, particles)
     }
 }
 
@@ -171,50 +243,88 @@ function Animate(ctx, fpsInterval, particles) {
 //
 
 
-function Particles({ canvasId, fps, amount, color, size, lifespan, speed }) {
+function Particles({
+    canvasId,
+    contentId,
+    fps,
+    amount,
+    color,
+    size,
+    speed,
+    depth,
+    lifespan,
+}) {
+    const contentNode = document.getElementById(contentId)
+    const height = getNodeHeight(contentNode)
+
     // Init the canvas for rendering.
     //
-    const ctx = initCanvas(canvasId)
-    if (!ctx) {
+    const scene  = getScene(canvasId, height)
+    if (!scene.ctx) {
         console.error("Particles: Can't find Canvas ", canvasId)
         return
     }
 
+ 
     // Generate some particles
     //
+
+    const z = depth * -1000
     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(-speed, speed),
-                        MinMax(-speed, speed)
-                    ),
-                size: {
-                    value: randomValue(-size, size),
-                    bound: MinMax(-size, size),
-                    step: size / ((lifespan) / fps),
+        (Debug)
+            ? (Static)
+                ? [ Particle({
+                        position:  Point3D(100, 500, z),
+                        direction: Point2D(0, 0),
+                        size: {
+                            value: 15,
+                            bound: MinMax(100, 100),
+                            step:  0,
+                            direction: 1
+                        },
+                        color: 'white'
+                }) ]
+                : [ Particle({
+                        position:  Point3D(100, 100, z),
+                        direction: Point2D(0, +1),
+                        size: {
+                            value: 100,
+                            bound: MinMax(100, 100),
+                            step:  0,
+                            direction: 1
+                        },
+                        color: 'white'
+                }) ]
+            : Array.from(
+                { length: amount },
+                () => Particle({
+                    position:
+                        RandomPoint3D(
+                            MinMax(0, (scene.width  - (size*2))),
+                            MinMax(0, (scene.height - (size*2))),
+                            z
+                        ),
                     direction:
-                        (randomValue(0, 100) < 50)
-                            ? -1
-                            : +1,
-                },
-                color
-            })
-        )
+                        RandomPoint2D(
+                            MinMax(-speed, speed),
+                            MinMax(-speed, speed)
+                        ),
+                    size: {
+                        value: randomValue(-size, size),
+                        bound: MinMax(-size, size),
+                        step:  size / ((lifespan) / fps),
+                        direction:
+                            (randomValue(0, 100) < 50)
+                                ? -1
+                                : +1,
+                    },
+                    color
+                })
+            )
      
     // Prepare Animation and animate
     const fpsInterval = 1000 / fps
     Then = Date.now()
-    Animate(ctx, fpsInterval, particles)
+    Animate({ scene, fpsInterval, particles, anchorNode: contentNode })
     return
 }
-
-
-
diff --git a/src/parallax-css-testpage/template.html b/src/parallax-css-testpage/template.html
index e2eb3e6d1f6cf7dd712b19f946bba56d0a7279c5..7819f5ee959fac5ff3efdd0ea3746e17793251a7 100644
--- a/src/parallax-css-testpage/template.html
+++ b/src/parallax-css-testpage/template.html
@@ -83,11 +83,17 @@
 
     <script>
         var bgParticles = {
+            // Id of the canvas to render to
             canvasId: 'bg-particles',
-            fps: 14,
-            amount: 100,
+
+            // Id of the content container, we're using it to get the 
+            // rendering height and it's the anchor to get the y offset
+            // to simulate scrolling.
+            contentId: 'content',
+            fps: 16,
+            amount: 120,
             color: 'white',
-            size: 5,
+            size: 10,
             speed: 0.2,
             depth: -8,
             lifespan: 4000 // in milliseconds
@@ -96,7 +102,8 @@
 
         var fgParticles = {
             canvasId: 'fg-particles',
-            fps: 20,
+            contentId: 'content',
+            fps: 24,
             amount: 20,
             color: 'white',
             size: 30,