JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/87/three.min.js"></script>
<canvas id="c"></canvas>
<input type="range" min="-1" max="1" value="0" step="0.01" id="center">
<input type="range" min="0" max="100" value="0" step="1" id="color">
CSS
html, body {
margin: 0;
padding: 0;
line-height: 0;
}
input {
position: absolute;
top: 0;
left: 0;
}
#color {
top: 20px;
}
JavaScript
let W = c.width = window.innerWidth;
let H = c.height = window.innerHeight;
let r = Math.min(W, H) / 2;
let segments = 20;
let mouse = new THREE.Vector3(0, 0, 200);
c.addEventListener("mousemove", function(e) {
console.log(e);
mouse.x = e.clientX || e.layerX;
mouse.y = e.clientY || e.layerY;
});
let points = [new THREE.Vector3(W / 2, H / 2, 0)];
let triangles = [];
for (let idx = 0; idx < segments; idx++) {
points.push(new THREE.Vector3(
W / 2 + Math.cos(2 * Math.PI / segments * idx) * r,
H / 2 + Math.sin(2 * Math.PI / segments * idx) * r,
0
));
triangles.push([0, idx + 1, (idx + 1) % segments + 1]);
}
points.forEach(p => p.speed = Math.random());
let ctx = c.getContext("2d");
function draw(time) {
points[0].z = parseFloat(center.value) * r;
for (let tri of triangles) {
let a = points[tri[0]];
let b = points[tri[1]];
let c = points[tri[2]];
let ab = new THREE.Vector3();
ab.subVectors(a, b);
let ac = new THREE.Vector3();
ac.subVectors(a, c);
let cr = new THREE.Vector3();
cr.crossVectors(ab, ac).normalize();
let reflection = new THREE.Vector3();
let centroid = new THREE.Vector3();
centroid.addVectors(a, b).add(c).multiplyScalar(1/3);
reflection.subVectors(mouse, centroid);
reflection.applyAxisAngle( cr, -Math.PI ).normalize();
let angle = Math.abs(Math.atan2(cr.y, cr.x) / 8) + Math.PI * 1.1;
let hsl = `hsl(${Math.PI * 2 / 100 * color.value}rad, 100%, ${10 + (50 + reflection.z * 50) * 0.9}%)`;
ctx.fillStyle = hsl;
ctx.beginPath();
ctx.moveTo(a.x, a.y);
ctx.lineTo(b.x, b.y);
ctx.lineTo(c.x, c.y);
ctx.closePath();
ctx.fill();
ctx.stroke();
}
window.requestAnimationFrame(draw);
}
window.requestAnimationFrame(draw);