more cleaning up
This commit is contained in:
parent
2c7d72a699
commit
560398fefb
110 changed files with 931 additions and 2645 deletions
104
src/index.ts
104
src/index.ts
|
|
@ -2,12 +2,7 @@ import GameLoop from './game-loop/game-loop';
|
|||
|
||||
import './index.scss';
|
||||
|
||||
import {
|
||||
initAnalytics,
|
||||
trackExport,
|
||||
trackSettingsOpen,
|
||||
trackVibeChange,
|
||||
} from './analytics';
|
||||
import { initAnalytics, trackExport, trackVibeChange } from './analytics';
|
||||
import { preloadPianoSamples } from './audio/piano-samples';
|
||||
import { appConfig } from './config';
|
||||
import { CollapsiblePanelAnimator } from './page/collapsible-panel-animator';
|
||||
|
|
@ -131,7 +126,6 @@ const queryAppElements = () => ({
|
|||
export4k: queryRequiredElement('.export-4k', HTMLButtonElement),
|
||||
exportStatus: queryRequiredElement('.export-status', HTMLSpanElement),
|
||||
prompt: queryRequiredElement('.garden-prompt', HTMLDivElement),
|
||||
loadingIndicator: queryRequiredElement('.loading-indicator', HTMLDivElement),
|
||||
loadingStatus: queryRequiredElement('.loading-status', HTMLDivElement),
|
||||
loadingProgress: queryRequiredElement('.loading-progress', HTMLDivElement),
|
||||
});
|
||||
|
|
@ -143,11 +137,12 @@ let elements: AppElements;
|
|||
const setLoadingStage = (label: string, ratio: number) => {
|
||||
const percent = Math.round(Math.max(0, Math.min(1, ratio)) * 100);
|
||||
elements.loadingStatus.textContent = label;
|
||||
elements.loadingIndicator.style.setProperty('--loading-progress', `${percent}%`);
|
||||
elements.loadingProgress.style.setProperty('--loading-progress', `${percent}%`);
|
||||
elements.loadingProgress.setAttribute('aria-valuenow', String(percent));
|
||||
};
|
||||
|
||||
let isAudioMuted = readBrowserStorage(appConfig.storage.audioMutedKey) === '1';
|
||||
let isEraserActive = false;
|
||||
|
||||
const renderAudioUi = (game: GameLoop | null) => {
|
||||
elements.soundButton.classList.toggle('muted', isAudioMuted);
|
||||
|
|
@ -161,21 +156,19 @@ const renderAudioUi = (game: GameLoop | null) => {
|
|||
};
|
||||
|
||||
const renderPaletteUi = (game: GameLoop | null) => {
|
||||
const isErasing = elements.eraserSizeControl.dataset.active === '1';
|
||||
elements.swatches.forEach((swatch, index) => {
|
||||
swatch.style.backgroundColor = activeVibe.colors[index];
|
||||
swatch.classList.toggle(
|
||||
'active',
|
||||
settings.selectedColorIndex === index && !isErasing
|
||||
settings.selectedColorIndex === index && !isEraserActive
|
||||
);
|
||||
});
|
||||
elements.eraserSizeControl.classList.toggle('active', isErasing);
|
||||
game?.setEraseMode(isErasing);
|
||||
elements.eraserSizeControl.classList.toggle('active', isEraserActive);
|
||||
game?.setEraseMode(isEraserActive);
|
||||
document.documentElement.style.setProperty(
|
||||
'--garden-background',
|
||||
activeVibe.backgroundColor
|
||||
);
|
||||
game?.onVibeChanged();
|
||||
};
|
||||
|
||||
const renderEraserSizeUi = (game: GameLoop | null) => {
|
||||
|
|
@ -234,11 +227,11 @@ const main = async () => {
|
|||
|
||||
let shouldStop = false;
|
||||
let game: GameLoop | null = null;
|
||||
let wasConfigPaneOpen = false;
|
||||
let configPane: ConfigPane | null = null;
|
||||
|
||||
elements = queryAppElements();
|
||||
elements.errorContainer.setAttribute('aria-live', 'assertive');
|
||||
ErrorHandler.addOnErrorListener((error, _metadata) => {
|
||||
ErrorHandler.addOnErrorListener((error) => {
|
||||
renderRuntimeMessage(elements.errorContainer, error);
|
||||
if (error.severity === Severity.ERROR) {
|
||||
document.body.classList.remove('is-loading');
|
||||
|
|
@ -248,10 +241,10 @@ const main = async () => {
|
|||
});
|
||||
hasRuntimeErrorListener = true;
|
||||
|
||||
const syncRuntimeUi = () => {
|
||||
const syncRuntimeUi = (activeGame = game) => {
|
||||
renderEraserSizeUi(game);
|
||||
renderMirrorSegmentUi();
|
||||
renderPaletteUi(game);
|
||||
renderPaletteUi(activeGame);
|
||||
};
|
||||
|
||||
const infoPageHandler = new CollapsiblePanelAnimator(
|
||||
|
|
@ -259,29 +252,33 @@ const main = async () => {
|
|||
elements.infoElement,
|
||||
elements.aside
|
||||
);
|
||||
const configPane = new ConfigPane({
|
||||
configPane = new ConfigPane({
|
||||
settingsButton: elements.settingsButton,
|
||||
onConfigChange: syncRuntimeUi,
|
||||
onOpenChange: (isOpen) => {
|
||||
game?.setStatsOverlayPinned(isOpen);
|
||||
if (isOpen && !wasConfigPaneOpen) {
|
||||
trackSettingsOpen();
|
||||
}
|
||||
wasConfigPaneOpen = isOpen;
|
||||
onConfigChange: () => {
|
||||
game?.onVibeChanged();
|
||||
syncRuntimeUi();
|
||||
},
|
||||
onOpenChange: () => undefined,
|
||||
onRuntimeChange: syncRuntimeUi,
|
||||
onRuntimeReset: () => {
|
||||
resetSettings();
|
||||
game?.onVibeChanged();
|
||||
syncRuntimeUi();
|
||||
},
|
||||
onRestart: () => game?.destroy(),
|
||||
onVibeChange: (vibeId) => {
|
||||
const vibe = applyVibeSettings(vibeId);
|
||||
const vibe = VIBE_PRESETS.find((candidate) => candidate.id === vibeId);
|
||||
if (!vibe) {
|
||||
return;
|
||||
}
|
||||
|
||||
const activePreset = applyVibeSettings(vibe);
|
||||
trackVibeChange({
|
||||
vibeId: vibe.id,
|
||||
vibeName: vibe.name,
|
||||
vibeId: activePreset.id,
|
||||
vibeName: activePreset.name,
|
||||
source: 'settings',
|
||||
});
|
||||
game?.onVibeChanged();
|
||||
syncRuntimeUi();
|
||||
game?.playVibeChangeAudio(false);
|
||||
},
|
||||
|
|
@ -292,7 +289,7 @@ const main = async () => {
|
|||
elements.aside,
|
||||
() =>
|
||||
FullScreenHandler.isInFullScreenMode() &&
|
||||
!configPane.isOpen &&
|
||||
!configPane?.isOpen &&
|
||||
!infoPageHandler.isOpen
|
||||
);
|
||||
new FullScreenHandler(
|
||||
|
|
@ -333,47 +330,41 @@ const main = async () => {
|
|||
}
|
||||
});
|
||||
|
||||
elements.previousVibe.addEventListener('click', () => {
|
||||
const selectRelativeVibe = (offset: number, source: string) => {
|
||||
const current = VIBE_PRESETS.findIndex((vibe) => vibe.id === activeVibe.id);
|
||||
const vibe =
|
||||
VIBE_PRESETS[(current + VIBE_PRESETS.length - 1) % VIBE_PRESETS.length];
|
||||
const activePreset = applyVibeSettings(vibe.id);
|
||||
VIBE_PRESETS[(current + VIBE_PRESETS.length + offset) % VIBE_PRESETS.length];
|
||||
const activePreset = applyVibeSettings(vibe);
|
||||
trackVibeChange({
|
||||
vibeId: activePreset.id,
|
||||
vibeName: activePreset.name,
|
||||
source: 'previous-button',
|
||||
source,
|
||||
});
|
||||
configPane.refresh();
|
||||
game?.onVibeChanged();
|
||||
syncRuntimeUi();
|
||||
configPane?.refresh();
|
||||
game?.playVibeChangeAudio(true);
|
||||
});
|
||||
};
|
||||
|
||||
elements.nextVibe.addEventListener('click', () => {
|
||||
const current = VIBE_PRESETS.findIndex((vibe) => vibe.id === activeVibe.id);
|
||||
const vibe = VIBE_PRESETS[(current + 1) % VIBE_PRESETS.length];
|
||||
const activePreset = applyVibeSettings(vibe.id);
|
||||
trackVibeChange({
|
||||
vibeId: activePreset.id,
|
||||
vibeName: activePreset.name,
|
||||
source: 'next-button',
|
||||
});
|
||||
configPane.refresh();
|
||||
syncRuntimeUi();
|
||||
game?.playVibeChangeAudio(true);
|
||||
});
|
||||
elements.previousVibe.addEventListener('click', () =>
|
||||
selectRelativeVibe(-1, 'previous-button')
|
||||
);
|
||||
|
||||
elements.nextVibe.addEventListener('click', () =>
|
||||
selectRelativeVibe(1, 'next-button')
|
||||
);
|
||||
|
||||
elements.swatches.forEach((swatch, index) => {
|
||||
swatch.addEventListener('click', () => {
|
||||
settings.selectedColorIndex = index;
|
||||
elements.eraserSizeControl.dataset.active = '0';
|
||||
game?.setEraseMode(false);
|
||||
isEraserActive = false;
|
||||
renderPaletteUi(game);
|
||||
configPane.refresh();
|
||||
configPane?.refresh();
|
||||
});
|
||||
});
|
||||
|
||||
const activateEraser = () => {
|
||||
elements.eraserSizeControl.dataset.active = '1';
|
||||
isEraserActive = true;
|
||||
renderPaletteUi(game);
|
||||
};
|
||||
|
||||
|
|
@ -383,20 +374,20 @@ const main = async () => {
|
|||
|
||||
elements.eraserSizeSlider.addEventListener('input', () => {
|
||||
settings.eraserSize = clampEraserSize(Number(elements.eraserSizeSlider.value));
|
||||
elements.eraserSizeControl.dataset.active = '1';
|
||||
isEraserActive = true;
|
||||
renderEraserSizeUi(game);
|
||||
renderPaletteUi(game);
|
||||
configPane.refresh();
|
||||
configPane?.refresh();
|
||||
});
|
||||
|
||||
elements.mirrorSegmentSlider.addEventListener('input', () => {
|
||||
settings.mirrorSegmentCount = clampMirrorSegmentCount(
|
||||
Number(elements.mirrorSegmentSlider.value)
|
||||
);
|
||||
elements.eraserSizeControl.dataset.active = '0';
|
||||
isEraserActive = false;
|
||||
renderMirrorSegmentUi();
|
||||
renderPaletteUi(game);
|
||||
configPane.refresh();
|
||||
configPane?.refresh();
|
||||
});
|
||||
|
||||
elements.export4k.addEventListener('click', async () => {
|
||||
|
|
@ -450,7 +441,6 @@ const main = async () => {
|
|||
eraserPreview: elements.eraserPreview,
|
||||
exportStatus: elements.exportStatus,
|
||||
});
|
||||
game.setStatsOverlayPinned(configPane.isOpen);
|
||||
renderPaletteUi(game);
|
||||
renderEraserSizeUi(game);
|
||||
renderMirrorSegmentUi();
|
||||
|
|
|
|||
Loading…
Reference in a new issue