Mercurial
diff mrjunejune/src/public/dog-game.js @ 240:c345083cd8a7
[mrjunejune] Show star animation in light mode
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Mon, 03 Aug 2026 10:48:59 -0700 |
| parents | 84826b3c655b |
| children | 9c2eec61a152 |
line wrap: on
line diff
--- a/mrjunejune/src/public/dog-game.js Mon Aug 03 10:36:12 2026 -0700 +++ b/mrjunejune/src/public/dog-game.js Mon Aug 03 10:48:59 2026 -0700 @@ -20,18 +20,52 @@ treatImage.src = "/public/dog-treat.png"; // Load star images for background +const lightStarColors = ["#315a91", "#8f3f63", "#34705f", "#76519b"]; let starImages = [ - { src: "/public/start-large.png", img: new Image() }, - { src: "/public/start-small-1.png", img: new Image() }, - { src: "/public/start-small-2.png", img: new Image() }, - { src: "/public/start-small-3.png", img: new Image() } + { src: "/public/start-large.png", img: new Image(), lightImg: null }, + { src: "/public/start-small-1.png", img: new Image(), lightImg: null }, + { src: "/public/start-small-2.png", img: new Image(), lightImg: null }, + { src: "/public/start-small-3.png", img: new Image(), lightImg: null } ]; -starImages.forEach(star => star.img.src = star.src); +starImages.forEach((star, index) => { + star.img.onload = () => { + const tinted = document.createElement("canvas"); + tinted.width = star.img.naturalWidth; + tinted.height = star.img.naturalHeight; + const tintedCtx = tinted.getContext("2d"); + tintedCtx.drawImage(star.img, 0, 0); + tintedCtx.globalCompositeOperation = "source-in"; + tintedCtx.fillStyle = lightStarColors[index]; + tintedCtx.fillRect(0, 0, tinted.width, tinted.height); + star.lightImg = tinted; + updateStarPalette(); + }; + star.img.src = star.src; +}); const background = document.getElementById('background'); const bgCtx = background.getContext("2d"); const ctx = game.getContext("2d"); const uiCtx = gameUI.getContext("2d"); +const darkModePreference = window.matchMedia("(prefers-color-scheme: dark)"); + +function isDarkMode() { + const root = document.documentElement; + if (root.classList.contains("dark")) return true; + if (root.classList.contains("light-mode")) return false; + return darkModePreference.matches; +} + +function starImageForTheme(imageIndex) { + const star = starImages[imageIndex]; + return isDarkMode() ? star.img : star.lightImg || star.img; +} + +function updateStarPalette() { + stars.forEach(star => { + star.image = starImageForTheme(star.imageIndex); + }); +} // Dog initial position and movement @@ -66,7 +100,8 @@ const starCount = window.innerWidth * 0.05; for (let i = 0; i < starCount; i++) { - const starType = starImages[Math.floor(Math.random() * starImages.length)]; + const imageIndex = Math.floor(Math.random() * starImages.length); + const starType = starImages[imageIndex]; const scale = 0.5 + Math.random() * 0.8; // Random scale stars.push({ @@ -76,7 +111,8 @@ vy: (Math.random() - 0.5) * 0.5, rotation: Math.random() * Math.PI * 2, rotationSpeed: (Math.random() - 0.5) * 0.02, - image: starType.img, + imageIndex: imageIndex, + image: starImageForTheme(imageIndex), size: starType.img.width, scale: scale, opacity: 0.3 + Math.random() * 0.4 // Random opacity @@ -286,10 +322,14 @@ } resizeCanvas(); window.addEventListener('resize', resizeCanvas); +new MutationObserver(updateStarPalette).observe( + document.documentElement, + { attributes: true, attributeFilter: ["class"] } +); +darkModePreference.addEventListener("change", updateStarPalette); window.onload = () => { resizeCanvas(); // ensure canvas has real size createStars(); // stars need correct canvas size animateBackground(); // safe to start background animation }; -