@buggles - I am 99% close to getting this effect finished:
The full code is here:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Zooming Tunnel</title>
<style>
body {
padding: 100px;
}
h1 {
font-family: sans-serif;
color: #333;
}
#myCanvas {
width: 800px;
height: 400px;
border: 5px solid black;
border-radius: 10px;
}
</style>
</head>
<body>
<h1>Zooming Tunnel</h1>
<canvas id="myCanvas">
</canvas>
<script>
let canvasElement = document.querySelector("#myCanvas");
let context = canvasElement.getContext("2d");
let mouseX = 0;
let mouseY = 0;
normalizeCanvasSize(canvasElement);
canvasElement.addEventListener("mousemove", mouseMoving, false);
function mouseMoving(e) {
let mousePosition = getPosition(canvasElement);
mouseX = e.clientX - mousePosition.x;
mouseY = e.clientY - mousePosition.y;
}
let rectangles = [];
class Rectangle {
constructor(context, color, delay) {
this.context = context;
this.step = 0;
this.color = color;
this.rectangleWidth = 10;
this.rectangleHeight = 50;
this.running = true;
}
draw(xPos, yPos) {
if (this.running) {
this.step += 5;
if (this.step > 2000) {
this.stop();
}
// the rectangle
this.context.beginPath();
this.context.rect(xPos - (this.rectangleWidth / 2) - this.step / 2, yPos - (this.rectangleHeight / 2) - this.step / 2, this.rectangleWidth + this.step, this.rectangleHeight + this.step);
this.context.fillStyle = this.color;
this.context.fill();
}
}
stop() {
this.running = false;
}
}
function animate() {
context.clearRect(0, 0, canvasElement.width, canvasElement.height);
for (let i = 0; i < rectangles.length; i++) {
let r = rectangles[i];
r.draw(mouseX, mouseY);
}
requestAnimationFrame(animate);
}
let count = 0;
//let colors = ["#FFAF87", "#FF8E72", "#ED6A5E", "#4CE0B3", "#377771", "#0D0221", "#0F084B", "#26408B"];
let h_range = [0, 45];
let s_range = [70, 90];
let l_range = [0, 90];
let a_range = [1, 1];
function addRectangle() {
let delay = 0;
//let index = count % colors.length;
let color = getRandomColor(h_range, s_range, l_range, a_range);
console.log(color);
let myRectangle = new Rectangle(context, color.hslaValue, delay);
rectangles.push(myRectangle);
count++;
}
function setup() {
setInterval(addRectangle, 200);
requestAnimationFrame(animate);
}
setup();
function normalizeCanvasSize(canvas) {
// look up the size the canvas is being displayed
let rect = canvas.getBoundingClientRect();
// increase the actual size of our canvas
canvas.width = rect.width * devicePixelRatio;
canvas.height = rect.height * devicePixelRatio;
// ensure all drawing operations are scaled
context.scale(devicePixelRatio, devicePixelRatio);
// scale everything down using CSS
canvas.style.width = rect.width + 'px';
canvas.style.height = rect.height + 'px';
}
// Helper function to get an element's exact position
function getPosition(el) {
let xPos = 0;
let yPos = 0;
while (el) {
if (el.tagName == "BODY") {
// deal with browser quirks with body/window/document and page scroll
let xScroll = el.scrollLeft || document.documentElement.scrollLeft;
let yScroll = el.scrollTop || document.documentElement.scrollTop;
xPos += (el.offsetLeft - xScroll + el.clientLeft);
yPos += (el.offsetTop - yScroll + el.clientTop);
} else {
// for all other non-BODY elements
xPos += (el.offsetLeft - el.scrollLeft + el.clientLeft);
yPos += (el.offsetTop - el.scrollTop + el.clientTop);
}
el = el.offsetParent;
}
return {
x: xPos,
y: yPos
};
}
function getRandomColor(h, s, l, a) {
let hue = getRandomNumber(h[0], h[1]);
let saturation = getRandomNumber(s[0], s[1]);
let lightness = getRandomNumber(l[0], l[1]);
let alpha = getRandomNumber(a[0] * 100, a[1] * 100) / 100;
return {
h: hue,
s: saturation,
l: lightness,
a: alpha,
hslaValue: getHSLAColor(hue, saturation, lightness, alpha)
}
}
function getRandomNumber(low, high) {
let r = Math.floor(Math.random() * (high - low + 1)) + low;
return r;
}
function getHSLAColor(h, s, l, a) {
return `hsl(${h}, ${s}%, ${l}%, ${a})`;
}
</script>
</body>
</html>
I am not happy about the infinitely growing rectangles
array, but that is something I will deal with later. The code isn’t commenting, so do let me know if I can clarify anything there.
Cheers,
Kirupa