diff --git a/src/index.ts b/src/index.ts index 39fa6cc..a81d882 100644 --- a/src/index.ts +++ b/src/index.ts @@ -21,7 +21,7 @@ import { RainScene } from './scenes/rain/rain-scene'; import { TunnelScene } from './scenes/tunnel-scene'; import './styles/index.scss'; -const scenes = [TunnelScene, MetaballScene, RainScene, RainScene, BlobScene, OrbitScene]; +const scenes = [TunnelScene, MetaballScene, OrbitScene, RainScene, BlobScene]; Random.seed = 2; glMatrix.setMatrixArrayType(Array); @@ -82,7 +82,7 @@ const main = async () => { try { let i = 0; - for (; ;) { + for (;;) { const currentScene = new scenes[i++ % scenes.length](); await currentScene.run(canvas, overlay); diff --git a/src/scenes/orbit/body.ts b/src/scenes/orbit/body.ts index b7d1a30..43b7d0d 100644 --- a/src/scenes/orbit/body.ts +++ b/src/scenes/orbit/body.ts @@ -2,159 +2,47 @@ import { mat2d, vec2 } from 'gl-matrix'; import { Drawable, DrawableDescriptor } from 'sdf-2d'; /** - * Every visual style a body can take. The style selects both the outline - * (smooth disc, jagged asteroid, ring annulus) and the per-fragment surface - * colouring inside the SDF shader — gradients, bands, continents — instead of - * a single flat palette colour. - */ -export const BodyStyle = { - sun: 0, // radial white-hot → gold → ember gradient with simmering granules - rocky: 1, // two-tone continent blotches - banded: 2, // wavy gas-giant stripes - ice: 3, // swirling azure sheen - asteroid: 4, // jagged outline, speckled surface - rings: 5, // two concentric annuli (drawn around a planet) - moon: 6, // small cratered grey - star: 7, // tiny twinkle, colour boosted far above 1 to stay bright after - // being multiplied by the dim ambient lighting -} as const; -export type BodyStyleName = keyof typeof BodyStyle; - -/** - * One celestial body: sun, planet, moon, ring system, asteroid, comet - * particle, or background star. A single descriptor renders all of them. - * - * Each instance carries two palette colour indices (mixed per fragment by its - * style), a `seed` that animates its surface, and `litAngle` — the direction - * towards the sun — used to shade a day/night terminator. Outline roughness is - * derived from the style inside the shader. + * A rocky celestial body: a circle whose radius is modulated by a few angular + * harmonics so its outline looks bumpy. One descriptor renders every body in + * the scene (sun, planets, asteroids) — each instance carries its own palette + * colour, size, surface `seed` (rotate it over time to make the body spin) and + * `roughness` (how jagged the outline is: ~0.5 for a planet, ~2.5 for an + * asteroid). */ export class Body extends Drawable { - // The outline harmonics can push the surface outward by at most - // 0.12 × roughness, and the roughest style (asteroid) uses 2.6. - private static readonly MAX_OUTLINE_GROWTH = 1.45; + // The peak fraction by which the harmonics below can push the outline + // outward (0.06 + 0.04 + 0.02), used for a conservative culling bound. + private static readonly MAX_WOBBLE = 0.12; public static descriptor: DrawableDescriptor = { sdf: { shader: ` uniform vec2 bodyCenters[BODY_COUNT]; uniform float bodyRadii[BODY_COUNT]; - uniform float bodyColors[BODY_COUNT]; + uniform float bodyColorIndices[BODY_COUNT]; uniform float bodySeeds[BODY_COUNT]; - uniform float bodyStyles[BODY_COUNT]; - uniform float bodyLitAngles[BODY_COUNT]; - - float bodyNoise(vec2 p) { - return sin(p.x) * sin(p.y); - } - - vec3 bodySurfaceColor( - int style, - vec2 d, - float radius, - float seed, - float litAngle, - vec3 colorA, - vec3 colorB - ) { - vec2 q = d / radius; - float r01 = length(q); - - if (style == ${BodyStyle.sun}) { - // Three drifting interference lattices; the first two sit at - // nearby frequencies and slide in opposite directions, so the - // convection cells continuously merge, split and boil instead of - // gliding across the disc as one rigid pattern. - float granules = - 0.8 * bodyNoise(q * 8.0 + vec2(seed, -seed * 0.6)) + - 0.55 * bodyNoise(q * 8.9 - vec2(seed * 0.8, seed * 1.1)) + - 0.45 * bodyNoise(q * 15.0 + vec2(seed * 1.4, -seed * 0.9)); - vec3 c = mix(vec3(1.4, 1.32, 1.1), colorA, smoothstep(0.0, 0.6, r01)); - c = mix(c, colorB, smoothstep(0.5, 1.0, r01 + granules * 0.15)); - return c * (1.0 + 0.2 * granules); - } - - if (style == ${BodyStyle.star}) { - return colorA * (3.75 + 1.75 * sin(seed)); - } - - // Every world shares one recipe: its surface coordinates rotate - // with the body's spin (seed grows over time), so stripes and - // blotches visibly roll around the disc, then a single field — - // radial ripples for rings, stripes for the banded and ice giants, - // blotches for everything rocky — mixes the two colours. The - // terminator and limb shading below use the unrotated coordinates, - // keeping the lighting locked to the sun while the surface turns. - vec2 qr = vec2( - q.x * cos(seed) - q.y * sin(seed), - q.x * sin(seed) + q.y * cos(seed) - ); - float field; - if (style == ${BodyStyle.rings}) { - field = sin(r01 * 26.0 + seed); - } else if (style == ${BodyStyle.banded} || style == ${BodyStyle.ice}) { - field = sin(qr.y * 5.0 + seed * 0.3); - } else { - field = bodyNoise(qr * 3.4) + 0.6 * bodyNoise(qr * 7.3 + vec2(2.7, 1.3)); - } - vec3 c = mix(colorB, colorA, smoothstep(-0.6, 0.6, field)); - - vec2 toSun = vec2(cos(litAngle), sin(litAngle)); - float dayside = smoothstep(-0.85, 0.55, dot(q / max(r01, 1e-4), toSun)); - c *= mix(0.22, 1.1, dayside); - if (style != ${BodyStyle.rings}) { - c *= 1.0 - 0.45 * smoothstep(0.5, 1.0, r01); - } - return c; - } + uniform float bodyRoughness[BODY_COUNT]; float bodyMinDistance(vec2 target, out vec4 color) { - color = vec4(0.0, 0.0, 0.0, 1.0); + color = readFromPalette(0); float minDistance = 1000.0; for (int i = 0; i < BODY_COUNT; i++) { vec2 d = target - bodyCenters[i]; - float radius = max(bodyRadii[i], 1e-5); - int style = int(bodyStyles[i] + 0.5); + float angle = atan(d.y, d.x); float seed = bodySeeds[i]; - float dist; - if (style == ${BodyStyle.rings}) { - float len = length(d); - dist = min( - abs(len - radius * 0.68) - radius * 0.1, - abs(len - radius * 0.9) - radius * 0.06 - ); - } else { - float angle = atan(d.y, d.x); - float roughness = style == ${BodyStyle.sun} - ? 0.5 - : style == ${BodyStyle.asteroid} - ? 2.6 - : style == ${BodyStyle.rocky} - ? 0.25 - : style == ${BodyStyle.moon} - ? 0.35 - : 0.06; - float wobble = - sin(angle * 3.0 + seed) * 0.06 + - sin(angle * 7.0 + seed * 1.7) * 0.04 + - sin(angle * 17.0 - seed * 0.5) * 0.02; - dist = length(d) - radius * (1.0 + wobble * roughness); - } + float wobble = + sin(angle * 3.0 + seed) * 0.06 + + sin(angle * 7.0 + seed * 1.7) * 0.04 + + sin(angle * 17.0 - seed * 0.5) * 0.02; + + float dist = + length(d) - bodyRadii[i] * (1.0 + wobble * bodyRoughness[i]); if (dist < minDistance) { minDistance = dist; - float packedColor = bodyColors[i]; - float indexA = floor(packedColor / 32.0); - vec3 colorA = readFromPalette(int(indexA + 0.5)).rgb; - vec3 colorB = readFromPalette(int(packedColor - indexA * 32.0 + 0.5)).rgb; - color = vec4( - bodySurfaceColor( - style, d, radius, seed, bodyLitAngles[i], colorA, colorB - ), - 1.0 - ); + color = readFromPalette(int(bodyColorIndices[i] + 0.5)); } } @@ -166,50 +54,41 @@ export class Body extends Drawable { propertyUniformMapping: { center: 'bodyCenters', radius: 'bodyRadii', - colors: 'bodyColors', + colorIndex: 'bodyColorIndices', seed: 'bodySeeds', - style: 'bodyStyles', - litAngle: 'bodyLitAngles', + roughness: 'bodyRoughness', }, uniformCountMacroName: 'BODY_COUNT', shaderCombinationSteps: [0, 4, 8, 16, 32], - empty: new Body(vec2.create(), 0, 'star', 0, 0, 0), + empty: new Body(vec2.create(), 0, 0, 0, 0), }; constructor( public center: vec2, public radius: number, - public style: BodyStyleName, - public colorA: number, - public colorB: number, + public colorIndex: number, public seed: number, - public litAngle = 0 + public roughness: number ) { super(); } public minDistance(target: vec2): number { - // Conservative: bound by the most outward the bumpiest outline can reach - // so a body is never culled from a tile its surface might poke into. - return vec2.dist(this.center, target) - this.radius * Body.MAX_OUTLINE_GROWTH; + // Conservative: bound by the most outward the bumpy outline can reach so a + // body is never culled from a tile its surface might poke into. + return ( + vec2.dist(this.center, target) - + this.radius * (1 + Body.MAX_WOBBLE * this.roughness) + ); } protected getObjectToSerialize(transform2d: mat2d, transform1d: number): any { - // litAngle is a world-space direction: push it through the linear part of - // the transform so it survives the view mapping's scale and y-flip. - const dx = Math.cos(this.litAngle); - const dy = Math.sin(this.litAngle); - return { center: vec2.transformMat2d(vec2.create(), this.center, transform2d), radius: this.radius * transform1d, - colors: this.colorA * 32 + this.colorB, + colorIndex: this.colorIndex, seed: this.seed, - style: BodyStyle[this.style], - litAngle: Math.atan2( - transform2d[1] * dx + transform2d[3] * dy, - transform2d[0] * dx + transform2d[2] * dy - ), + roughness: this.roughness, }; } } diff --git a/src/scenes/orbit/orbit-scene.ts b/src/scenes/orbit/orbit-scene.ts index 6a877eb..e494c75 100644 --- a/src/scenes/orbit/orbit-scene.ts +++ b/src/scenes/orbit/orbit-scene.ts @@ -4,201 +4,91 @@ import { prettyPrint } from '../../helper/pretty-print'; import { Random } from '../../helper/random'; import { settings } from '../../settings'; import { Scene } from '../scene'; -import { Body, BodyStyleName } from './body'; +import { Body } from './body'; -// Every colour the scene uses; bodies reference entries by name and mix their -// two colours per fragment in the shader, so nothing renders as a flat fill. -const palette = { - white: rgb(1, 1, 1), - sunGold: hsl(38, 100, 62), - sunEmber: hsl(14, 95, 46), - scorchedTan: hsl(32, 22, 60), - scorchedBrown: hsl(20, 25, 38), - venusCream: hsl(46, 85, 78), - venusAmber: hsl(33, 75, 58), - earthLand: hsl(135, 50, 45), - earthOcean: hsl(213, 85, 52), - marsRust: hsl(16, 80, 55), - marsShadow: hsl(22, 65, 34), - jovianCream: hsl(36, 70, 75), - jovianRust: hsl(16, 65, 52), - saturnSand: hsl(45, 65, 76), - saturnDust: hsl(36, 50, 58), - ringGold: hsl(44, 40, 70), - ringShadow: hsl(40, 28, 42), - iceAzure: hsl(200, 90, 68), - iceDeep: hsl(232, 70, 50), - moonGrey: hsl(220, 10, 68), - moonShadow: hsl(225, 12, 44), -}; -type PaletteColor = keyof typeof palette; -const paletteIndex = (name: PaletteColor): number => Object.keys(palette).indexOf(name); +const PLANET_COUNT = 6; +const ASTEROID_COUNT = 18; -interface MoonSpec { - orbit: number; // around the parent planet, as a fraction of the system radius - size: number; - speed: number; // rad/s -} - -interface PlanetSpec { - orbit: number; // fraction of the system radius - size: number; - style: BodyStyleName; - colors: [PaletteColor, PaletteColor]; - spin: number; // how fast the surface pattern drifts - ringSize?: number; - moons?: Array; -} - -// A miniature solar system: small rocky worlds inside, then the giants — -// banded, ringed, and an ice giant — spread roughly evenly from the sun's -// doorstep to the screen edge. Planets all orbit prograde at Kepler speeds -// (∝ orbit⁻¹·⁵). -const PLANETS: Array = [ - { - orbit: 0.165, - size: 0.026, - style: 'rocky', - colors: ['scorchedTan', 'scorchedBrown'], - spin: 0.55, - }, - { - orbit: 0.27, - size: 0.036, - style: 'banded', - colors: ['venusCream', 'venusAmber'], - spin: 0.4, - }, - { - orbit: 0.385, - size: 0.04, - style: 'rocky', - colors: ['earthLand', 'earthOcean'], - spin: 0.45, - moons: [{ orbit: 0.06, size: 0.01, speed: 2.4 }], - }, - { - orbit: 0.49, - size: 0.03, - style: 'rocky', - colors: ['marsRust', 'marsShadow'], - spin: 0.5, - }, - { - orbit: 0.7, - size: 0.06, - style: 'banded', - colors: ['jovianCream', 'jovianRust'], - spin: 0.3, - moons: [ - { orbit: 0.085, size: 0.011, speed: 1.8 }, - { orbit: 0.108, size: 0.009, speed: 1.2 }, - ], - }, - { - orbit: 0.825, - size: 0.042, - style: 'banded', - colors: ['saturnSand', 'saturnDust'], - spin: 0.32, - ringSize: 0.082, - }, - { orbit: 0.95, size: 0.036, style: 'ice', colors: ['iceAzure', 'iceDeep'], spin: 0.45 }, -]; - -const ORBITAL_SPEED = 0.26; // rad/s at orbit = 1; scaled by Kepler's third law +// Palette indices used for the bodies (see colorPalette below). +const SUN_COLOR = 5; // warm gold +const ROCK_COLOR = 7; // brown-grey rock +const PLANET_COLORS = [1, 2, 3, 4, 6]; // red, green, blue, purple, pink interface OrbitingBody { - drawable: Body; - orbit: number; // around the sun — or around `parent`, for moons and rings + drawable: InstanceType; + radiusRatio: number; // orbit radius as a fraction of the system radius phase: number; speed: number; - size: number; - spin: number; + sizeRatio: number; // body radius as a fraction of the system radius + spin: number; // how fast the surface seed rotates seedPhase: number; - parent?: OrbitingBody; } export class OrbitScene implements Scene { private overlay: HTMLDivElement; public insights?: any; - // The sun's visible disc carries its own white-hot → ember gradient; these - // lights add the blown-out core, the warm corona reflecting off the lifted - // background, and the sunlight (plus shadows) on everything orbiting. - private sunCore = new CircleLight(vec2.create(), rgb(1.0, 0.96, 0.88), 0.1); - private sunGlow = new CircleLight(vec2.create(), rgb(1.35, 0.58, 0.18), 0.5); - - private sun: OrbitingBody = { - drawable: new Body( - vec2.create(), - 0, - 'sun', - paletteIndex('sunGold'), - paletteIndex('sunEmber'), - 0 - ), - orbit: 0, - phase: 0, - speed: 0, - size: 0.115, - spin: 0.9, - seedPhase: Random.getRandom() * 10, - }; + // The sun is a bright solid body so it's actually visible: in this engine a + // light only shows where it reflects off a surface, so a bare light over the + // near-black "space" background would be invisible. The light sources sit at + // its centre and illuminate the orbiting bodies. Because the sun is small + // relative to the orbits, it only mildly occludes its own light. + private sun = new Body(vec2.create(), 0, SUN_COLOR, 0, 0.6); + private sunCore = new CircleLight(vec2.create(), rgb(1.0, 0.96, 0.85), 0.05); + private sunGlow = new CircleLight(vec2.create(), rgb(1.0, 0.62, 0.26), 0.55); private bodies: Array = []; public async run(canvas: HTMLCanvasElement, overlay: HTMLDivElement): Promise { this.overlay = overlay; - this.bodies.push(this.sun); - - PLANETS.forEach((spec) => { - const planet = this.createOrbitingBody( - spec.orbit, - spec.size, - spec.style, - spec.colors, - spec.spin - ); - this.bodies.push(planet); - - if (spec.ringSize) { - this.bodies.push({ - ...this.createOrbitingBody( - 0, - spec.ringSize, - 'rings', - ['ringGold', 'ringShadow'], - 0 - ), - parent: planet, - }); - } - - spec.moons?.forEach((moon) => { - this.bodies.push({ - ...this.createOrbitingBody( - moon.orbit, - moon.size, - 'moon', - ['moonGrey', 'moonShadow'], - 0.8 - ), - speed: moon.speed, - parent: planet, - }); + for (let i = 0; i < PLANET_COUNT; i++) { + const radiusRatio = 0.26 + (0.64 / PLANET_COUNT) * i; + this.bodies.push({ + drawable: new Body( + vec2.create(), + 0, + PLANET_COLORS[i % PLANET_COLORS.length], + Random.getRandom() * 10, + 1.0 + ), + radiusRatio, + phase: Random.getRandom() * Math.PI * 2, + speed: 0.5 / Math.pow(radiusRatio, 1.5), + sizeRatio: 0.04 + 0.022 * (i % 3), + spin: Random.getRandomInRange(-0.5, 0.5), + seedPhase: Random.getRandom() * 10, }); - }); + } - const bodyCount = this.bodies.length; + // An asteroid belt: a ring of small, jagged, fast-tumbling rocks. + for (let i = 0; i < ASTEROID_COUNT; i++) { + const radiusRatio = Random.getRandomInRange(0.5, 0.62); + this.bodies.push({ + drawable: new Body( + vec2.create(), + 0, + ROCK_COLOR, + Random.getRandom() * 10, + 2.6 + ), + radiusRatio, + phase: Random.getRandom() * Math.PI * 2, + speed: 0.5 / Math.pow(radiusRatio, 1.5), + sizeRatio: Random.getRandomInRange(0.014, 0.026), + spin: (Random.getRandom() > 0.5 ? 1 : -1) * Random.getRandomInRange(0.8, 2.2), + seedPhase: Random.getRandom() * 10, + }); + } + + const bodyCount = this.bodies.length + 1; // + the sun await runAnimation( canvas, [ { ...Body.descriptor, - shaderCombinationSteps: [...new Set([0, 4, 8, 16, 32, bodyCount])], + shaderCombinationSteps: [0, 4, 8, 16, bodyCount], }, { ...CircleLight.descriptor, @@ -208,40 +98,23 @@ export class OrbitScene implements Scene { this.drawNextFrame.bind(this), { enableHighDpiRendering: true, - motionBlur: 0.5, - lightPenetrationRatio: 0.8, - ambientLight: rgb(0.07, 0.075, 0.145), - backgroundColor: rgb(0.035, 0.035, 0.07), - colorPalette: Object.values(palette), + motionBlur: 0.6, + ambientLight: rgb(0.17, 0.17, 0.23), + backgroundColor: rgb(0.02, 0.02, 0.05), + colorPalette: [ + rgb(1, 1, 1), // 0 white (unused fallback) + hsl(8, 85, 62), // 1 red + hsl(150, 65, 55), // 2 green + hsl(205, 85, 62), // 3 blue + hsl(275, 70, 68), // 4 purple + hsl(40, 95, 60), // 5 gold (sun) + hsl(330, 80, 65), // 6 pink + hsl(28, 25, 45), // 7 brown-grey rock + ], } ); } - private createOrbitingBody( - orbit: number, - size: number, - style: BodyStyleName, - colors: [PaletteColor, PaletteColor], - spin: number - ): OrbitingBody { - return { - drawable: new Body( - vec2.create(), - 0, - style, - paletteIndex(colors[0]), - paletteIndex(colors[1]), - 0 - ), - orbit, - phase: Random.getRandom() * Math.PI * 2, - speed: orbit > 0 ? ORBITAL_SPEED / Math.pow(orbit, 1.5) : 0, - size, - spin, - seedPhase: Random.getRandom() * 10, - }; - } - private drawNextFrame( renderer: Renderer, currentTime: DOMHighResTimeStamp, @@ -266,30 +139,27 @@ export class OrbitScene implements Scene { const maxRadius = Math.min(viewAreaWidth, viewAreaHeight) / 2; const time = currentTime / 1000; + // The sun sits in the middle; the light sources live at its centre and a + // gentle pulse makes the corona breathe. + vec2.copy(this.sun.center, center); + this.sun.radius = maxRadius * 0.13; + this.sun.seed = time * 0.15; vec2.copy(this.sunCore.center, center); vec2.copy(this.sunGlow.center, center); - this.sunGlow.intensity = 0.5 + 0.05 * Math.sin(time * 1.7); + this.sunGlow.intensity = 0.55 + 0.05 * Math.sin(time * 1.7); - // Parents are pushed before their moons and rings, so each parent's - // position is already up to date when its satellites read it. this.bodies.forEach((body) => { const angle = body.phase + time * body.speed; - const origin = body.parent?.drawable.center ?? center; vec2.set( body.drawable.center, - origin[0] + Math.cos(angle) * body.orbit * maxRadius, - origin[1] + Math.sin(angle) * body.orbit * maxRadius + center.x + Math.cos(angle) * body.radiusRatio * maxRadius, + center.y + Math.sin(angle) * body.radiusRatio * maxRadius ); - // The sun breathes gently; everything else keeps its size. - const pulse = body === this.sun ? 1 + 0.015 * Math.sin(time * 2.4) : 1; - body.drawable.radius = body.size * maxRadius * pulse; + body.drawable.radius = body.sizeRatio * maxRadius; body.drawable.seed = body.seedPhase + time * body.spin; - body.drawable.litAngle = Math.atan2( - center[1] - body.drawable.center[1], - center[0] - body.drawable.center[0] - ); }); + renderer.addDrawable(this.sun); this.bodies.forEach((body) => renderer.addDrawable(body.drawable)); renderer.addDrawable(this.sunCore); renderer.addDrawable(this.sunGlow); diff --git a/src/scenes/rain/rain-scene.ts b/src/scenes/rain/rain-scene.ts index 03c6db9..6198fe3 100644 --- a/src/scenes/rain/rain-scene.ts +++ b/src/scenes/rain/rain-scene.ts @@ -9,9 +9,11 @@ const WIND_SLANT = 0.2; export class RainScene implements Scene { private droplets: Array = []; - // The moon: a single pale, cold light hanging high in the sky and the scene's - // only light source — the falling rain only shows where its streaks catch it. - private moon = new CircleLight(vec2.create(), rgb255(200, 214, 255), 2.5); + private lights = [ + new CircleLight(vec2.create(), rgb255(184, 41, 255), 1.5), + new CircleLight(vec2.create(), rgb255(255, 31, 109), 1.5), + new CircleLight(vec2.create(), rgb255(64, 110, 255), 1.5), + ]; private overlay: HTMLDivElement; public insights?: any; @@ -39,18 +41,14 @@ export class RainScene implements Scene { }, { ...CircleLight.descriptor, - shaderCombinationSteps: [0, 1], + shaderCombinationSteps: [0, 3], }, ], this.drawNextFrame.bind(this), { - // A dark night sky so the moon is the dominant light. - backgroundColor: rgb(0.09, 0.12, 0.19), - ambientLight: rgb(0.2, 0.22, 0.28), + backgroundColor: rgb(0.5, 0.5, 0.5), + ambientLight: rgb(0.2, 0.2, 0.23), enableHighDpiRendering: true, - // Keep most of the previous frame each render so the droplets smear - // into long streaks of rain. - motionBlur: 0.9, // More, smaller tiles keep the droplet count per tile low. tileMultiplier: 12, } @@ -72,17 +70,19 @@ export class RainScene implements Scene { const viewAreaSize = renderer.viewAreaSize; - // The moon drifts back and forth along the top edge; the rain falls past - // it and lights up. - vec2.set( - this.moon.center, - viewAreaSize.x * (0.5 + 0.5 * Math.sin(currentTime / 2500)), - viewAreaSize.y * 0.95 - ); + // each light sweeps within its own third of the screen + this.lights.forEach((light, i) => { + vec2.set( + light.center, + viewAreaSize.x * + ((i + 0.5) / 3 + (1 / 6) * Math.sin(currentTime / 900 + (i * Math.PI * 2) / 3)), + 0 + ); + }); this.droplets.forEach((d) => d.animate(currentTime, viewAreaSize, WIND_SLANT)); - [...this.droplets.map((d) => d.drawable), this.moon].forEach((d) => + [...this.droplets.map((d) => d.drawable), ...this.lights].forEach((d) => renderer.addDrawable(d) ); diff --git a/webpack.config.js b/webpack.config.js index 4656d1a..3d181a6 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -20,7 +20,7 @@ const htmlLoaderOptions = JSON.stringify({ minimize: false, }); -module.exports = (env, argv) => ({ +module.exports = { entry: { index: PATHS.entryPoint, }, @@ -41,7 +41,6 @@ module.exports = (env, argv) => ({ }, devServer: { host: '0.0.0.0', - port: 9999, allowedHosts: 'all', }, plugins: [ @@ -62,9 +61,8 @@ module.exports = (env, argv) => ({ useShortDoctype: true, }, }), - ...(argv.mode === 'production' - ? [new HtmlInlineScriptPlugin(), new HTMLInlineCSSWebpackPlugin()] - : []), + new HtmlInlineScriptPlugin(), + new HTMLInlineCSSWebpackPlugin(), ], module: { rules: [ @@ -129,4 +127,4 @@ module.exports = (env, argv) => ({ resolve: { extensions: ['.ts', '.js'], }, -}); +};