Add floating goal messages
This commit is contained in:
67
src/ui.js
67
src/ui.js
@@ -1,6 +1,7 @@
|
||||
(() => {
|
||||
const create = () => {
|
||||
const sceneEl = document.getElementById("scene-wrapper");
|
||||
const floatingMessagesEl = document.getElementById("floating-messages");
|
||||
const activeColorEl = document.getElementById("active-color");
|
||||
const chainLenEl = document.getElementById("chain-length");
|
||||
const spawnRateEl = document.getElementById("spawn-rate");
|
||||
@@ -20,6 +21,10 @@
|
||||
const winMessageEl = document.getElementById("win-message");
|
||||
const winNextBtn = document.getElementById("win-next");
|
||||
const winRestartBtn = document.getElementById("win-restart");
|
||||
let messageDefaults = {
|
||||
durationMs: 4200,
|
||||
position: { xPercent: 50, yPercent: 12 },
|
||||
};
|
||||
|
||||
const handlers = {
|
||||
onPauseToggle: null,
|
||||
@@ -196,6 +201,66 @@
|
||||
});
|
||||
};
|
||||
|
||||
const setMessageDefaults = (overrides = {}) => {
|
||||
messageDefaults = {
|
||||
...messageDefaults,
|
||||
...overrides,
|
||||
position: {
|
||||
...messageDefaults.position,
|
||||
...(overrides.position || {}),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const renderFloatingMessage = (el, text, colors) => {
|
||||
el.innerHTML = "";
|
||||
if (Array.isArray(colors) && colors.length > 0) {
|
||||
colors.forEach((color) => {
|
||||
const swatch = document.createElement("span");
|
||||
swatch.style.background = color;
|
||||
swatch.style.display = "inline-block";
|
||||
swatch.style.width = "14px";
|
||||
swatch.style.height = "14px";
|
||||
swatch.style.borderRadius = "50%";
|
||||
swatch.style.border = "1px solid rgba(255,255,255,0.2)";
|
||||
swatch.style.marginRight = "6px";
|
||||
el.appendChild(swatch);
|
||||
});
|
||||
}
|
||||
const textSpan = document.createElement("span");
|
||||
textSpan.textContent = text;
|
||||
el.appendChild(textSpan);
|
||||
};
|
||||
|
||||
const showFloatingMessage = (message, options = {}) => {
|
||||
if (!floatingMessagesEl) return;
|
||||
const msgObj =
|
||||
typeof message === "string" ? { text: message } : message || {};
|
||||
const text = (msgObj.text || "").trim();
|
||||
if (!text) return;
|
||||
const colors = Array.isArray(msgObj.colors) ? msgObj.colors : null;
|
||||
const durationMs = Number.isFinite(options.durationMs)
|
||||
? options.durationMs
|
||||
: messageDefaults.durationMs;
|
||||
const position = {
|
||||
...messageDefaults.position,
|
||||
...(options.position || {}),
|
||||
};
|
||||
const el = document.createElement("div");
|
||||
el.className = "floating-message";
|
||||
renderFloatingMessage(el, text, colors);
|
||||
el.style.left = `${position.xPercent ?? 50}%`;
|
||||
el.style.top = `${position.yPercent ?? 10}%`;
|
||||
floatingMessagesEl.appendChild(el);
|
||||
requestAnimationFrame(() => {
|
||||
el.classList.add("visible");
|
||||
});
|
||||
setTimeout(() => {
|
||||
el.classList.remove("visible");
|
||||
setTimeout(() => el.remove(), 260);
|
||||
}, durationMs);
|
||||
};
|
||||
|
||||
return {
|
||||
sceneEl,
|
||||
updateHud,
|
||||
@@ -210,6 +275,8 @@
|
||||
setSceneSelection,
|
||||
setHandlers,
|
||||
setGoal,
|
||||
showFloatingMessage,
|
||||
setMessageDefaults,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user