Flash will be permanently retired at the end of the year. As a tribute to a bygone era, I have tried to recreate this animation.
Source: http://fluid.nl/content/designengaged/index.htm
A Pen by Gerard Ferrandez on CodePen.
Flash will be permanently retired at the end of the year. As a tribute to a bygone era, I have tried to recreate this animation.
Source: http://fluid.nl/content/designengaged/index.htm
A Pen by Gerard Ferrandez on CodePen.
<canvas></canvas> |
"use strict"; | |
// adapted from http://fluid.nl/content/designengaged/index.htm | |
/////////////////////////////////////////////////////////// | |
const canvas = { | |
init() { | |
this.elem = document.querySelector("canvas"); | |
this.resize(); | |
window.addEventListener("resize", () => this.resize(), false); | |
return this.elem.getContext("2d"); | |
}, | |
resize() { | |
this.width = this.elem.width = this.elem.offsetWidth; | |
this.height = this.elem.height = this.elem.offsetHeight; | |
this.centerX = this.width / 2; | |
this.centerY = this.height / 2; | |
this.size = 1.25 * Math.sqrt(this.width * this.width + this.height * this.height); | |
}, | |
clear() { | |
ctx.clearRect(0, 0, this.width, this.height); | |
} | |
}; | |
/////////////////////////////////////////////////////////// | |
const pointer = { | |
x: 0, | |
y: 0, | |
init(x, y) { | |
window.addEventListener("pointermove", (e) => this.move(e), false); | |
this.x = canvas.centerX; | |
this.y = canvas.centerY + 100; | |
}, | |
move(e) { | |
this.x = e.clientX; | |
this.y = e.clientY; | |
} | |
}; | |
/////////////////////////////////////////////////////////////// | |
const Sprite = class { | |
constructor(x) { | |
this.x = x * 10; | |
this.rot = 0; | |
this.scale = 1; | |
} | |
update() { | |
const x = Math.cos(rot) * this.x; | |
const y = Math.sin(rot) * this.x; | |
const dx = Math.abs(pointer.x - canvas.centerX + x); | |
const dy = Math.abs(pointer.y - canvas.centerY + y); | |
const dist = Math.sqrt(dx * dx + dy * dy); | |
const scale = Math.max(0, (0.5 * canvas.size - dist)); | |
this.scale += (scale - this.scale) * 0.1; | |
this.rot += ((dy / 120) * Math.PI - this.rot) * 0.1; | |
this.draw(x, y, rot + this.rot, this.scale); | |
} | |
draw(x, y, r, s) { | |
ctx.save(); | |
ctx.translate(canvas.centerX + x, canvas.centerY + y); | |
ctx.rotate(r); | |
ctx.scale(s, s); | |
ctx.drawImage(sprite, -0.75, -0.25, 1, 0.5); | |
ctx.restore(); | |
} | |
}; | |
/////////////////////////////////////////////////////////// | |
const run = () => { | |
requestAnimationFrame(run); | |
canvas.clear(); | |
rot += 0.01; | |
for (const sprite of sprites) sprite.update(); | |
}; | |
/////////////////////////////////////////////////////////// | |
const ctx = canvas.init(); | |
pointer.init(); | |
console.clear(); | |
let rot = 0; | |
const sprite = new Image(); | |
sprite.src = "https://assets.codepen.io/222599/sprite.PNG"; | |
const sprites = []; | |
for (let i = -60; i < 60; i++) { | |
sprites.push(new Sprite(i)); | |
} | |
run(); |
body, html { | |
position: absolute; | |
margin: 0; | |
padding: 0; | |
width: 100%; | |
height: 100%; | |
overflow: hidden; | |
background: #000; | |
touch-action: none; | |
} | |
canvas { | |
position: absolute; | |
width: 100%; | |
height: 100%; | |
background: hsl(193, 86%, 10%); | |
cursor: crosshair; | |
} |