Skip to content

Instantly share code, notes, and snippets.

@Garciat
Created August 25, 2018 14:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Garciat/8f0f4a8d9b40f172e8de74b0bf8dbfde to your computer and use it in GitHub Desktop.
Save Garciat/8f0f4a8d9b40f172e8de74b0bf8dbfde to your computer and use it in GitHub Desktop.
<body style="margin:0">
<canvas></canvas>
</body>
<script>
let SCRW = document.body.clientWidth;
let SCRH = document.body.clientHeight;
let canvas = document.querySelector('canvas');
canvas.width = SCRW;
canvas.height = SCRH;
let mouse = {x: 0, y: 0};
canvas.addEventListener('mousemove', ev => {
mouse.x = ev.clientX;
mouse.y = ev.clientY;
});
let ctx = canvas.getContext('2d');
function makeTile() {
let d = 0.05;
return [
[
{x: 0, y: 0},
{x: 1, y: 0},
{x: 1-d, y: d},
{x: d, y: d}
],
[
{x: 1, y: 0},
{x: 1, y: 1},
{x: 1-d, y: 1-d},
{x: 1-d, y: d}
],
[
{x: 1, y: 1},
{x: 0, y: 1},
{x: d, y: 1-d},
{x: 1-d, y: 1-d}
],
[
{x: 0, y: 1},
{x: 0, y: 0},
{x: d, y: d},
{x: d, y: 1-d}
],
[
{x: d, y: d},
{x: 1-d, y: d},
{x: 1-d, y: 1-d},
{x: d, y: 1-d}
]
];
}
function scaledGroup(group, kx, ky) {
return group.map(s => s.map(({x, y}) => ({x: x*kx, y: y*ky})));
}
function displacedGroup(group, dx, dy) {
return group.map(s => s.map(({x, y}) => ({x: x+dx, y: y+dy})));
}
function fillShape(shape) {
ctx.beginPath();
ctx.moveTo(shape[shape.length-1].x, shape[shape.length-1].y);
for (let p of shape) {
ctx.lineTo(p.x, p.y);
}
ctx.fill();
}
let lights = [
{x: 0, y: 0, z: 50}
];
class Vec3 {
static make(x, y, z) {
return {x, y, z};
}
static sub(u, v) {
return Vec3.make(u.x-v.x, u.y-v.y, u.z-v.z);
}
static lengthSq(u) {
return u.x*u.x + u.y*u.y + u.z*u.z;
}
static length(u) {
return Math.sqrt(Vec3.lengthSq(u));
}
static normalize(u) {
let n = Vec3.length(u);
return Vec3.make(u.x/n, u.y/n, u.z/n);
}
static dot(u, v) {
return u.x*v.y + u.y*v.y + u.z*v.z;
}
static angle(u, v) {
return Math.acos(Vec3.dot(u, v) / (Vec3.length(u) * Vec3.length(v)));
}
}
function draw() {
let tw = 50;
let th = 20;
let nx = Math.ceil(SCRW / tw) + 1;
let ny = Math.ceil(SCRH / th) + 1;
let normals = [
{x: 0.3, y: 0, z: 0},
{x: 0, y: 0.3, z: 0},
{x: -0.3, y: 0, z: 0},
{x: 0, y: -0.3, z: 0},
{x: 0, y: 0, z: 1}
];
lights[0].x = mouse.x;
lights[0].y = mouse.y;
for (let i = 0; i < ny; ++i) {
for (let j = 0; j < nx; ++j) {
let x = tw*j - tw/2*(i%2);
let y = th*i;
let group = displacedGroup(scaledGroup(makeTile(), tw, th), x, y);
let v = {x: x + tw/2, y: y + th/2, z: 0};
for (let i = 0; i < group.length; ++i) {
let shape = group[i];
let L = 0;
let a = Vec3.angle(normals[i], Vec3.sub(lights[0], v));
L += 60 * (1 - Math.max(a, Math.PI/2)/Math.PI/2) * Vec3.length(Vec3.sub(lights[0], v))/300;
ctx.fillStyle = `hsl(0, 10%, ${100-L}%)`;
fillShape(shape);
}
}
}
}
function loop(t) {
draw(t);
requestAnimationFrame(loop);
}
loop();
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment