feat(effects): polish 8 effects and add 7 new engines with parallax
Build, Test & Push Frontend / quality-check (push) Successful in 32s
Build, Test & Push Frontend / docker (push) Successful in 26s

Synthwave, fireflies, snow, sakura, nebula: CSS/SVG. Matrix and
constellation: canvas. Existing engines gain depth, color, glow, and
parallax (mouse and device tilt, opt-in on iOS)
This commit is contained in:
lobo committed 2026-10-03 17:31:19 +02:00
1 parent d7810fbf94
commit ed5df8c40d
21 files changed
+1510 -211

No files matched your search

+1 -1
View File
@@ -180,7 +180,7 @@ function Preview({code}) {
if (look.effect) {
return (
<span ref={ref} className={cn('relative h-8 w-14 shrink-0 overflow-hidden rounded-md bg-background', !inView && 'fx-paused')}>
<EffectBackground effect={look.effect} className="absolute inset-0"/>
<EffectBackground effect={look.effect} parallax={false} className="absolute inset-0"/>
</span>
);
}
+18 -1
View File
@@ -19,6 +19,8 @@ const wallet = (extra = {}) => ({
{code: 'FX_GOLD_SHINE', slot: 'COMPLETED_EFFECT', price: 300},
{code: 'BG_GRID', slot: 'PAGE_BACKGROUND', price: 450},
{code: 'BN_GRID', slot: 'BANNER_BACKGROUND', price: 300},
{code: 'BG_SNOW', slot: 'PAGE_BACKGROUND', price: 400},
{code: 'BN_MATRIX', slot: 'BANNER_BACKGROUND', price: 300},
{code: 'BADGE_FINISH_10', slot: 'BADGE', price: 0, track: 'GAMES_FINISHED', target: 10},
{code: 'BADGE_STREAK_4', slot: 'BADGE', price: 0, track: 'FINISH_WEEKS', target: 4},
{code: 'SKIN_PASTEL', slot: 'SKIN', price: 600},
@@ -47,7 +49,11 @@ const renderPage = async (routes = {}) => {
await screen.findByText('POINTS.SHOP');
};
beforeEach(() => localStorage.setItem('tbp_session', '1'));
beforeEach(() => {
localStorage.setItem('tbp_session', '1');
// jsdom has no canvas: the matrix preview renders, draws nothing.
vi.spyOn(HTMLCanvasElement.prototype, 'getContext').mockReturnValue(null);
});
afterEach(() => {
cleanup();
localStorage.clear();
@@ -65,6 +71,17 @@ describe('PointsPage', () => {
expect(card('BANNER_BACKGROUND').querySelector('[data-effect="grid"]')).not.toBeNull();
});
it('previews the new CSS and canvas looks without parallax listeners', async () => {
const add = vi.spyOn(window, 'addEventListener');
await renderPage();
const card = (slot) => screen.getByText(`POINTS.SLOTS.${slot}`).closest('[data-slot="card"]');
expect(card('PAGE_BACKGROUND').querySelector('[data-effect="snow"]')).not.toBeNull();
expect(card('BANNER_BACKGROUND').querySelector('[data-effect="matrix"] canvas')).not.toBeNull();
expect(add.mock.calls.filter(([type]) => type === 'pointermove')).toHaveLength(0);
add.mockRestore();
});
it('shows a locked unlock item with its progress, a progress bar and no price or Buy button', async () => {
await renderPage();