47 lines
1.5 KiB
JavaScript
47 lines
1.5 KiB
JavaScript
|
|
"use strict";
|
||
|
|
// Shade.ts -> Shade.js
|
||
|
|
// Constants
|
||
|
|
const SHADOW_UPDATE_INTERVAL = 4;
|
||
|
|
const SHADOW_BLUR_RADIUS = 5;
|
||
|
|
const SHADOW_INTENSITY = 128;
|
||
|
|
// Canvases
|
||
|
|
let shadowCanvas1;
|
||
|
|
let shadowCanvasCtx1;
|
||
|
|
let shadowCanvas2;
|
||
|
|
let shadowCanvasCtx2;
|
||
|
|
|
||
|
|
function initializeShade() {
|
||
|
|
shadowCanvas1 = new OffscreenCanvas(width + 1, height + 1);
|
||
|
|
shadowCanvasCtx1 = shadowCanvas1.getContext('2d');
|
||
|
|
shadowCanvas2 = new OffscreenCanvas(width + 1, height + 1);
|
||
|
|
shadowCanvasCtx2 = shadowCanvas2.getContext("2d");
|
||
|
|
}
|
||
|
|
|
||
|
|
function updateShadows() {
|
||
|
|
if (pixelTicks % SHADOW_UPDATE_INTERVAL !== 0)
|
||
|
|
return;
|
||
|
|
const shadowCanvasImageData1 = shadowCanvasCtx1.createImageData(width + 1, height + 1);
|
||
|
|
const shadowCanvasData1 = shadowCanvasImageData1.data;
|
||
|
|
for (let pixel of currentPixels) {
|
||
|
|
const exposed = getNeighbors(pixel).length !== 4;
|
||
|
|
const alphaIndex = (pixel.y * (width + 1) + pixel.x) * 4 + 3;
|
||
|
|
shadowCanvasData1[alphaIndex] = exposed ? 0 : SHADOW_INTENSITY;
|
||
|
|
}
|
||
|
|
shadowCanvasCtx1.putImageData(shadowCanvasImageData1, 0, 0);
|
||
|
|
// Blur the shadows
|
||
|
|
shadowCanvasCtx2.clearRect(0, 0, shadowCanvas2.width, shadowCanvas2.height);
|
||
|
|
shadowCanvasCtx2.filter = `blur(${SHADOW_BLUR_RADIUS}px)`;
|
||
|
|
shadowCanvasCtx2.drawImage(shadowCanvas1, 0, 0, shadowCanvas2.width, shadowCanvas2.height);
|
||
|
|
shadowCanvasCtx2.filter = "none";
|
||
|
|
}
|
||
|
|
|
||
|
|
function drawShadows(ctx) {
|
||
|
|
ctx.globalAlpha = 1.0;
|
||
|
|
ctx.drawImage(shadowCanvas2, 0, 0, canvas.width, canvas.height);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Hooks
|
||
|
|
runAfterReset(initializeShade);
|
||
|
|
runEveryTick(updateShadows);
|
||
|
|
renderPostPixel(drawShadows);
|