UNPKG

houdini-doom-fire

Version:

A Doom Fire CSS Paint Worklet.

76 lines (67 loc) 2.6 kB
/* * Copyright 2021 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const HTML_COLOR_SCALE = [ '#070707', '#1f0707', '#2f0f07', '#470f07', '#571707', '#671f07', '#771f07', '#8f2707', '#9f2f07', '#af3f07', '#bf4707', '#c74707', '#DF4F07', '#DF5707', '#DF5707', '#D75F07', '#D7670F', '#cf6f0f', '#cf770f', '#cf7f0f', '#CF8717', '#C78717', '#C78F17', '#C7971F', '#BF9F1F', '#BF9F1F', '#BFA727', '#BFA727', '#BFAF2F', '#B7AF2F', '#B7B72F', '#B7B737', '#CFCF6F', '#DFDF9F', '#EFEFC7', '#FFFFFF', ]; const PROPERTY_PIXEL_SIZE = '--doomfire-pixel-size'; class DoomFire { static get inputProperties() { return [ PROPERTY_PIXEL_SIZE, ]; } paint(ctx, geom, properties) { const size = Math.max(parseInt(properties.get(PROPERTY_PIXEL_SIZE)), 1); const num_rows = Math.trunc(geom.height / size); const num_cols = Math.trunc(geom.width / size); const num_pixels = num_rows * num_cols; let flames = []; for (let i = 0; i < num_pixels; i++) { flames[i] = 0; } ctx.fillStyle = HTML_COLOR_SCALE[HTML_COLOR_SCALE.length - 1]; const bottom_row = (num_rows - 1) * num_cols; for (let x = 0; x < num_cols; x++) { flames[bottom_row + x] = HTML_COLOR_SCALE.length - 1; ctx.fillRect(x * size, bottom_row * size, size + 1, size + 1); } for (let y = num_rows - 2; y > 0; y--) { const row_start = y * num_cols; const previous_row_start = (y + 1) * num_cols; for (let x = 0; x < num_cols; x++) { const rand = Math.trunc(Math.random() * 3); const src_x = Math.min(Math.max(x + rand - 1, 0), num_cols - 1); const src_color = flames[previous_row_start + src_x]; const dst_color = Math.max(src_color - (rand & 1), 0); flames[row_start + x] = dst_color; ctx.fillStyle = HTML_COLOR_SCALE[dst_color]; ctx.fillRect(x * size, y * size, size + 1, size + 1); } } } } registerPaint('doomfire', DoomFire);