// DOM particle effects inside #fx (UI_UX.md ยง8) import { G } from "./state.js"; export function floatText(x, y, text, color, down = false) { const el = document.createElement("div"); el.className = "float-text" + (down ? " down" : ""); el.style.left = `${x}px`; el.style.top = `${y}px`; el.style.color = color; el.textContent = text; G.els.fx.appendChild(el); setTimeout(() => el.remove(), 1700); } function pixel(x, y, color, size = 4) { const el = document.createElement("div"); el.className = "pixel-part"; el.style.cssText += `;left:${x}px;top:${y}px;width:${size}px;height:${size}px; background:${color};`; G.els.fx.appendChild(el); return el; } export function heartFloat(x, y) { const el = document.createElement("div"); el.className = "pixel-part"; el.appendChild(window.BDSChibi.pixelGlyph( window.BDSChibi.GLYPHS.heart, 3, "var(--bds-neon-magenta)", true)); el.style.left = `${x}px`; el.style.top = `${y}px`; el.animate([{ transform: "translateY(0)", opacity: 1 }, { transform: "translateY(-34px)", opacity: 0 }], { duration: 1100, easing: "steps(6)" }); G.els.fx.appendChild(el); setTimeout(() => el.remove(), 1100); } export function confettiBurst() { const colors = ["var(--bds-brad)", "var(--bds-stacey)", "var(--bds-kevin)", "var(--bds-janet)", "var(--bds-derek)"]; for (let i = 0; i < 36; i++) { const el = pixel(320, 200, colors[i % 5]); const dx = (Math.random() - 0.5) * 420; const dy = 120 + Math.random() * 260; el.animate( [{ transform: "translate(0,0)" }, { transform: `translate(${dx}px,${dy}px)`, opacity: 0.2 }], { duration: 1400 + Math.random() * 600, easing: "steps(10)" }); setTimeout(() => el.remove(), 2000); } } export function revenueRain() { for (let i = 0; i < 14; i++) { setTimeout(() => { const x = 30 + Math.random() * 580; const el = document.createElement("div"); el.className = "pixel-part"; el.textContent = "$"; el.style.cssText += `;left:${x}px;top:-12px;color:var(--bds-neon-lime); font-size:10px;text-shadow:0 0 6px var(--bds-neon-lime);`; el.animate([{ transform: "translateY(0)" }, { transform: "translateY(500px)" }], { duration: 1500, easing: "steps(12)" }); G.els.fx.appendChild(el); setTimeout(() => el.remove(), 1500); }, i * 120); } } export function moraleWave(npcObjs) { const ordered = Object.values(npcObjs).sort((a, b) => a.x - b.x); ordered.forEach((npc, i) => { setTimeout(() => { if (!npc.sprite) return; npc.sprite.animate( [{ transform: "translateY(0)" }, { transform: "translateY(5px)" }, { transform: "translateY(0)" }], { duration: 360, easing: "steps(4)" }); }, i * 130); }); } export function zzz(x, y) { const el = document.createElement("div"); el.className = "pixel-part"; el.appendChild(window.BDSChibi.pixelGlyph( window.BDSChibi.GLYPHS.z, 2, "var(--bds-derek)", false)); el.style.left = `${x}px`; el.style.top = `${y}px`; el.animate([{ transform: "translate(0,0)", opacity: 1 }, { transform: "translate(10px,-18px)", opacity: 0 }], { duration: 2200, easing: "steps(6)" }); G.els.fx.appendChild(el); setTimeout(() => el.remove(), 2200); } export function steam(x, y) { const el = pixel(x + (Math.random() * 6 - 3), y, "rgba(244,241,255,.5)", 3); el.animate([{ transform: "translateY(0)", opacity: 0.6 }, { transform: "translateY(-16px)", opacity: 0 }], { duration: 1400, easing: "steps(5)" }); setTimeout(() => el.remove(), 1400); }