From db9b62979bf497314912b3ecbc147cbda03a168e Mon Sep 17 00:00:00 2001 From: George Satellite Date: Sat, 18 Nov 2023 19:06:34 +0200 Subject: [PATCH] Sprites setting: packs selection --- .../Generator/CanvasSection/CanvasSection.tsx | 34 +- .../Generator/CanvasSection/utils/draw.ts | 11 +- .../SettingsSection/SettingsSection.tsx | 48 ++- src/components/pages/Generator/constants.ts | 10 + src/components/pages/Generator/store.ts | 366 +++++++++++------- 5 files changed, 282 insertions(+), 187 deletions(-) diff --git a/src/components/pages/Generator/CanvasSection/CanvasSection.tsx b/src/components/pages/Generator/CanvasSection/CanvasSection.tsx index 5856681..4c82c99 100644 --- a/src/components/pages/Generator/CanvasSection/CanvasSection.tsx +++ b/src/components/pages/Generator/CanvasSection/CanvasSection.tsx @@ -67,38 +67,11 @@ export function CanvasSection() { linesBrightness, linesAlpha, linesWidth, + spritesEnabled, + getSprites, } = useStore.getState(); - const spritesBaseUrl = '/sprites'; - const sprites: HTMLImageElement[] = []; - - // Set: classic - for (let i = 1; i <= 17; i++) { - const sprite = new Image(); - sprite.src = `${spritesBaseUrl}/classic/${i}.svg`; - sprites.push(sprite); - } - - // Set: bigdata - for (let i = 1; i <= 5; i++) { - const sprite = new Image(); - sprite.src = `${spritesBaseUrl}/bigdata/${i}.svg`; - sprites.push(sprite); - } - - // Set: aggromaxx - for (let i = 1; i <= 12; i++) { - const sprite = new Image(); - sprite.src = `${spritesBaseUrl}/aggromaxx/${i}.svg`; - sprites.push(sprite); - } - - // Set: crappack - for (let i = 1; i <= 27; i++) { - const sprite = new Image(); - sprite.src = `${spritesBaseUrl}/crappack/${i}.svg`; - sprites.push(sprite); - } + const sprites = getSprites(); void draw({ ctx2d, @@ -131,6 +104,7 @@ export function CanvasSection() { linesBrightness, linesAlpha, linesWidth, + spritesEnabled, sprites, }, onEnd(renderTimeMs) { diff --git a/src/components/pages/Generator/CanvasSection/utils/draw.ts b/src/components/pages/Generator/CanvasSection/utils/draw.ts index bb49ca2..30dd950 100644 --- a/src/components/pages/Generator/CanvasSection/utils/draw.ts +++ b/src/components/pages/Generator/CanvasSection/utils/draw.ts @@ -37,6 +37,7 @@ export const draw = async ({ linesBrightness, linesAlpha, linesWidth, + spritesEnabled, sprites: _sprites, }, }: { @@ -71,6 +72,7 @@ export const draw = async ({ linesBrightness: NumberDual; linesAlpha: NumberDual; linesWidth: NumberDual; + spritesEnabled: boolean; sprites: HTMLImageElement[]; }; }): Promise => { @@ -80,7 +82,7 @@ export const draw = async ({ drawBackground({ctx2d, backgroundBrightness}); - const sprites = await loadSprites(_sprites); + const sprites = spritesEnabled ? await loadSprites(_sprites) : []; animateWithSubIterations({ iterations, @@ -139,6 +141,7 @@ export const draw = async ({ }); break; case 5: + if (!spritesEnabled) break; drawSprite({ ctx2d, sprites, @@ -350,8 +353,12 @@ const drawSprite = ({ ctx2d: CanvasRenderingContext2D; sprites: HTMLImageElement[]; }): void => { - const {w, h} = getCanvasDimensions(ctx2d); + if (sprites.length <= 0) return; + const sprite = sprites[randomInteger(0, sprites.length - 1)]; + if (!sprite.complete) return; + + const {w, h} = getCanvasDimensions(ctx2d); const size = randomInteger(Math.round(w / 32), Math.round(w / 2)); const x = randomInteger(Math.round(-w / 16), Math.round(w)); const y = randomInteger(Math.round(-h / 16), Math.round(h)); diff --git a/src/components/pages/Generator/SettingsSection/SettingsSection.tsx b/src/components/pages/Generator/SettingsSection/SettingsSection.tsx index 1a7c876..648fecf 100644 --- a/src/components/pages/Generator/SettingsSection/SettingsSection.tsx +++ b/src/components/pages/Generator/SettingsSection/SettingsSection.tsx @@ -1,6 +1,7 @@ 'use client'; import {Slider} from '@/components/ui/Slider'; import {Button} from '@/components/ui/Button'; +import {Checkbox} from '@/components/ui/Checkbox'; import {useStore} from '../store'; import {SectionTitle} from '../SectionTitle'; import {type NumberDual} from '@/types'; @@ -30,9 +31,9 @@ import { linesWidth as linesWidthConst, type SettingConstant, type SettingDualConstant, + type SpritesPack, } from '../constants'; import {Group} from './Group'; -import {useState} from 'react'; export function SettingsSection() { const iterations = useStore((state) => state.iterations); @@ -69,6 +70,9 @@ export function SettingsSection() { const linesAlpha = useStore((state) => state.linesAlpha); const linesWidth = useStore((state) => state.linesWidth); + const spritesEnabled = useStore((state) => state.spritesEnabled); + const spritesPacks = useStore((state) => state.spritesPacks); + const setIterations = useStore((state) => state.setIterations); const setBackgroundBrightness = useStore( (state) => state.setBackgroundBrightness, @@ -105,7 +109,14 @@ export function SettingsSection() { const setLinesAlpha = useStore((state) => state.setLinesAlpha); const setLinesWidth = useStore((state) => state.setLinesWidth); - const [spritesEnabled, setSpritesEnabled] = useState(false); + const setSpritesEnabled = useStore((state) => state.setSpritesEnabled); + const setSpritesPacks = useStore((state) => state.setSpritesPacks); + const setSpritesPackEnabled = (pack: SpritesPack) => (value: boolean) => { + setSpritesPacks([ + ...spritesPacks.filter((p) => p !== pack), + ...(value ? [pack] : []), + ]); + }; const randomize = useStore((state) => state.randomize); @@ -293,13 +304,35 @@ export function SettingsSection() { - 🚧 - 🚧 - 🚧 +
+
Packs:
+
+ + + + +
+
@@ -352,3 +385,6 @@ function SliderDualWrapper({ /> ); } + +const spritesPackEnabled = (packs: SpritesPack[], pack: SpritesPack): boolean => + packs.includes(pack); diff --git a/src/components/pages/Generator/constants.ts b/src/components/pages/Generator/constants.ts index 9949ba1..ec472ff 100644 --- a/src/components/pages/Generator/constants.ts +++ b/src/components/pages/Generator/constants.ts @@ -22,11 +22,18 @@ export type SettingBooleanConstant = { default: boolean; }; +export type SettingSpritesPacksConstant = { + default: SpritesPack[]; +}; + +export type SpritesPack = 'classic' | 'bigdata' | 'aggromaxx' | 'crappack'; + // ------------------- // HELPER CONSTANTS // ------------------- const _booleanTrue: SettingBooleanConstant = {default: true}; +const _booleanFalse: SettingBooleanConstant = {default: false}; const _brightnessRange: SettingDualConstant = { min: 0, max: 255, @@ -116,3 +123,6 @@ export const linesWidth: SettingDualConstant = { default: [5, 10], step: 1, }; + +export const spritesEnabled: SettingBooleanConstant = _booleanFalse; +export const spritesPacks: SettingSpritesPacksConstant = {default: ['classic']}; diff --git a/src/components/pages/Generator/store.ts b/src/components/pages/Generator/store.ts index bc415a4..217462b 100644 --- a/src/components/pages/Generator/store.ts +++ b/src/components/pages/Generator/store.ts @@ -28,8 +28,11 @@ import { linesBrightness, linesAlpha, linesWidth, + spritesEnabled, + spritesPacks, type SettingConstant, type SettingDualConstant, + type SpritesPack, } from './constants'; import {randomBoolean, randomInteger} from '@/utils/random'; import {type NumberDual} from '@/types'; @@ -63,9 +66,11 @@ type Values = { linesBrightness: NumberDual; linesAlpha: NumberDual; linesWidth: NumberDual; + spritesEnabled: boolean; + spritesPacks: SpritesPack[]; }; -type Actions = { +type Setters = { setIterations: (iterations: Values['iterations']) => void; setBackgroundBrightness: ( backgroundBrightness: Values['backgroundBrightness'], @@ -96,157 +101,211 @@ type Actions = { setLinesBrightness: (linesBrightness: Values['linesBrightness']) => void; setLinesAlpha: (linesAlpha: Values['linesAlpha']) => void; setLinesWidth: (linesWidth: Values['linesWidth']) => void; + setSpritesEnabled: (spritesEnabled: Values['spritesEnabled']) => void; + setSpritesPacks: (spritesPacks: Values['spritesPacks']) => void; +}; + +type ComputedValues = { + getSprites: () => HTMLImageElement[]; +}; + +type Actions = { randomize: () => void; }; -export const useStore = create((set) => ({ - iterations: iterations.default, - backgroundBrightness: backgroundBrightness.default, - rectEnabled: rectEnabled.default, - rectBrightness: rectBrightness.default, - rectAlpha: rectAlpha.default, - rectScale: rectScale.default, - gridEnabled: gridEnabled.default, - gridBrightness: gridBrightness.default, - gridAlpha: gridAlpha.default, - gridScale: gridScale.default, - gridAmount: gridAmount.default, - gridGap: gridGap.default, - colsEnabled: colsEnabled.default, - colsBrightness: colsBrightness.default, - colsAlpha: colsAlpha.default, - colsScale: colsScale.default, - colsAmount: colsAmount.default, - colsGap: colsGap.default, - rowsEnabled: rowsEnabled.default, - rowsBrightness: rowsBrightness.default, - rowsAlpha: rowsAlpha.default, - rowsScale: rowsScale.default, - rowsAmount: rowsAmount.default, - rowsGap: rowsGap.default, - linesEnabled: linesEnabled.default, - linesBrightness: linesBrightness.default, - linesAlpha: linesAlpha.default, - linesWidth: linesWidth.default, - setIterations(iterations: Values['iterations']) { - set(() => ({iterations})); - }, - setBackgroundBrightness( - backgroundBrightness: Values['backgroundBrightness'], - ) { - set(() => ({backgroundBrightness})); - }, - setRectEnabled(rectEnabled: Values['rectEnabled']) { - set(() => ({rectEnabled})); - }, - setRectBrightness(rectBrightness: Values['rectBrightness']) { - set(() => ({rectBrightness})); - }, - setRectAlpha(rectAlpha: Values['rectAlpha']) { - set(() => ({rectAlpha})); - }, - setRectScale(rectScale: Values['rectScale']) { - set(() => ({rectScale})); - }, - setGridEnabled(gridEnabled: Values['gridEnabled']) { - set(() => ({gridEnabled})); - }, - setGridBrightness(gridBrightness: Values['gridBrightness']) { - set(() => ({gridBrightness})); - }, - setGridAlpha(gridAlpha: Values['gridAlpha']) { - set(() => ({gridAlpha})); - }, - setGridScale(gridScale: Values['gridScale']) { - set(() => ({gridScale})); - }, - setGridAmount(gridAmount: Values['gridAmount']) { - set(() => ({gridAmount})); - }, - setGridGap(gridGap: Values['gridGap']) { - set(() => ({gridGap})); - }, - setColsEnabled(colsEnabled: Values['colsEnabled']) { - set(() => ({colsEnabled})); - }, - setColsBrightness(colsBrightness: Values['colsBrightness']) { - set(() => ({colsBrightness})); - }, - setColsAlpha(colsAlpha: Values['colsAlpha']) { - set(() => ({colsAlpha})); - }, - setColsScale(colsScale: Values['colsScale']) { - set(() => ({colsScale})); - }, - setColsAmount(colsAmount: Values['colsAmount']) { - set(() => ({colsAmount})); - }, - setColsGap(colsGap: Values['colsGap']) { - set(() => ({colsGap})); - }, - setRowsEnabled(rowsEnabled: Values['rowsEnabled']) { - set(() => ({rowsEnabled})); - }, - setRowsBrightness(rowsBrightness: Values['rowsBrightness']) { - set(() => ({rowsBrightness})); - }, - setRowsAlpha(rowsAlpha: Values['rowsAlpha']) { - set(() => ({rowsAlpha})); - }, - setRowsScale(rowsScale: Values['rowsScale']) { - set(() => ({rowsScale})); - }, - setRowsAmount(rowsAmount: Values['rowsAmount']) { - set(() => ({rowsAmount})); - }, - setRowsGap(rowsGap: Values['rowsGap']) { - set(() => ({rowsGap})); - }, - setLinesEnabled(linesEnabled: Values['linesEnabled']) { - set(() => ({linesEnabled})); - }, - setLinesBrightness(linesBrightness: Values['linesBrightness']) { - set(() => ({linesBrightness})); - }, - setLinesAlpha(linesAlpha: Values['linesAlpha']) { - set(() => ({linesAlpha})); - }, - setLinesWidth(linesWidth: Values['linesWidth']) { - set(() => ({linesWidth})); - }, - randomize() { - set(() => ({ - iterations: randSetting(iterations), - backgroundBrightness: randSetting(backgroundBrightness), - rectEnabled: randomBoolean(), - rectBrightness: randDualSetting(rectBrightness), - rectAlpha: randDualSetting(rectAlpha), - rectScale: randSetting(rectScale), - gridEnabled: randomBoolean(), - gridBrightness: randDualSetting(gridBrightness), - gridAlpha: randDualSetting(gridAlpha), - gridScale: randSetting(gridScale), - gridAmount: randDualSetting(gridAmount), - gridGap: randSetting(gridGap), - colsEnabled: randomBoolean(), - colsBrightness: randDualSetting(colsBrightness), - colsAlpha: randDualSetting(colsAlpha), - colsScale: randSetting(colsScale), - colsAmount: randDualSetting(colsAmount), - colsGap: randSetting(colsGap), - rowsEnabled: randomBoolean(), - rowsBrightness: randDualSetting(rowsBrightness), - rowsAlpha: randDualSetting(rowsAlpha), - rowsScale: randSetting(rowsScale), - rowsAmount: randDualSetting(rowsAmount), - rowsGap: randSetting(rowsGap), - linesEnabled: randomBoolean(), - linesBrightness: randDualSetting(linesBrightness), - linesAlpha: randDualSetting(linesAlpha), - linesWidth: randDualSetting(linesWidth), - })); - }, -})); +export const useStore = create( + (set, get) => ({ + // Values + // --- + iterations: iterations.default, + backgroundBrightness: backgroundBrightness.default, + rectEnabled: rectEnabled.default, + rectBrightness: rectBrightness.default, + rectAlpha: rectAlpha.default, + rectScale: rectScale.default, + gridEnabled: gridEnabled.default, + gridBrightness: gridBrightness.default, + gridAlpha: gridAlpha.default, + gridScale: gridScale.default, + gridAmount: gridAmount.default, + gridGap: gridGap.default, + colsEnabled: colsEnabled.default, + colsBrightness: colsBrightness.default, + colsAlpha: colsAlpha.default, + colsScale: colsScale.default, + colsAmount: colsAmount.default, + colsGap: colsGap.default, + rowsEnabled: rowsEnabled.default, + rowsBrightness: rowsBrightness.default, + rowsAlpha: rowsAlpha.default, + rowsScale: rowsScale.default, + rowsAmount: rowsAmount.default, + rowsGap: rowsGap.default, + linesEnabled: linesEnabled.default, + linesBrightness: linesBrightness.default, + linesAlpha: linesAlpha.default, + linesWidth: linesWidth.default, + spritesEnabled: spritesEnabled.default, + spritesPacks: spritesPacks.default, + // Setters + // --- + setIterations(iterations: Values['iterations']) { + set(() => ({iterations})); + }, + setBackgroundBrightness( + backgroundBrightness: Values['backgroundBrightness'], + ) { + set(() => ({backgroundBrightness})); + }, + setRectEnabled(rectEnabled: Values['rectEnabled']) { + set(() => ({rectEnabled})); + }, + setRectBrightness(rectBrightness: Values['rectBrightness']) { + set(() => ({rectBrightness})); + }, + setRectAlpha(rectAlpha: Values['rectAlpha']) { + set(() => ({rectAlpha})); + }, + setRectScale(rectScale: Values['rectScale']) { + set(() => ({rectScale})); + }, + setGridEnabled(gridEnabled: Values['gridEnabled']) { + set(() => ({gridEnabled})); + }, + setGridBrightness(gridBrightness: Values['gridBrightness']) { + set(() => ({gridBrightness})); + }, + setGridAlpha(gridAlpha: Values['gridAlpha']) { + set(() => ({gridAlpha})); + }, + setGridScale(gridScale: Values['gridScale']) { + set(() => ({gridScale})); + }, + setGridAmount(gridAmount: Values['gridAmount']) { + set(() => ({gridAmount})); + }, + setGridGap(gridGap: Values['gridGap']) { + set(() => ({gridGap})); + }, + setColsEnabled(colsEnabled: Values['colsEnabled']) { + set(() => ({colsEnabled})); + }, + setColsBrightness(colsBrightness: Values['colsBrightness']) { + set(() => ({colsBrightness})); + }, + setColsAlpha(colsAlpha: Values['colsAlpha']) { + set(() => ({colsAlpha})); + }, + setColsScale(colsScale: Values['colsScale']) { + set(() => ({colsScale})); + }, + setColsAmount(colsAmount: Values['colsAmount']) { + set(() => ({colsAmount})); + }, + setColsGap(colsGap: Values['colsGap']) { + set(() => ({colsGap})); + }, + setRowsEnabled(rowsEnabled: Values['rowsEnabled']) { + set(() => ({rowsEnabled})); + }, + setRowsBrightness(rowsBrightness: Values['rowsBrightness']) { + set(() => ({rowsBrightness})); + }, + setRowsAlpha(rowsAlpha: Values['rowsAlpha']) { + set(() => ({rowsAlpha})); + }, + setRowsScale(rowsScale: Values['rowsScale']) { + set(() => ({rowsScale})); + }, + setRowsAmount(rowsAmount: Values['rowsAmount']) { + set(() => ({rowsAmount})); + }, + setRowsGap(rowsGap: Values['rowsGap']) { + set(() => ({rowsGap})); + }, + setLinesEnabled(linesEnabled: Values['linesEnabled']) { + set(() => ({linesEnabled})); + }, + setLinesBrightness(linesBrightness: Values['linesBrightness']) { + set(() => ({linesBrightness})); + }, + setLinesAlpha(linesAlpha: Values['linesAlpha']) { + set(() => ({linesAlpha})); + }, + setLinesWidth(linesWidth: Values['linesWidth']) { + set(() => ({linesWidth})); + }, + setSpritesEnabled(spritesEnabled: Values['spritesEnabled']) { + set(() => ({spritesEnabled})); + }, + setSpritesPacks(spritesPacks: Values['spritesPacks']) { + set(() => ({spritesPacks})); + }, + // ComputedValues + // --- + getSprites() { + const spritesBaseUrl = '/sprites'; + const {spritesPacks} = get(); + const sprites: HTMLImageElement[] = []; + + const hasClassic = spritesPacks.includes('classic'); + const hasBigdata = spritesPacks.includes('bigdata'); + const hasAggromaxx = spritesPacks.includes('aggromaxx'); + const hasCrappack = spritesPacks.includes('crappack'); + + const addSprites = (pack: SpritesPack, n: number) => { + for (let i = 1; i <= n; i++) { + const sprite = new Image(); + sprite.src = `${spritesBaseUrl}/${pack}/${i}.svg`; + sprites.push(sprite); + } + }; + + if (hasClassic) addSprites('classic', 17); + if (hasBigdata) addSprites('bigdata', 5); + if (hasAggromaxx) addSprites('aggromaxx', 12); + if (hasCrappack) addSprites('crappack', 27); + + return sprites; + }, + // Actions + // --- + randomize() { + set(() => ({ + iterations: randSetting(iterations), + backgroundBrightness: randSetting(backgroundBrightness), + rectEnabled: randomBoolean(), + rectBrightness: randDualSetting(rectBrightness), + rectAlpha: randDualSetting(rectAlpha), + rectScale: randSetting(rectScale), + gridEnabled: randomBoolean(), + gridBrightness: randDualSetting(gridBrightness), + gridAlpha: randDualSetting(gridAlpha), + gridScale: randSetting(gridScale), + gridAmount: randDualSetting(gridAmount), + gridGap: randSetting(gridGap), + colsEnabled: randomBoolean(), + colsBrightness: randDualSetting(colsBrightness), + colsAlpha: randDualSetting(colsAlpha), + colsScale: randSetting(colsScale), + colsAmount: randDualSetting(colsAmount), + colsGap: randSetting(colsGap), + rowsEnabled: randomBoolean(), + rowsBrightness: randDualSetting(rowsBrightness), + rowsAlpha: randDualSetting(rowsAlpha), + rowsScale: randSetting(rowsScale), + rowsAmount: randDualSetting(rowsAmount), + rowsGap: randSetting(rowsGap), + linesEnabled: randomBoolean(), + linesBrightness: randDualSetting(linesBrightness), + linesAlpha: randDualSetting(linesAlpha), + linesWidth: randDualSetting(linesWidth), + spritesEnabled: randomBoolean(), + spritesPacks: randSpritesPacks(), + })); + }, + }), +); const randSetting = (setting: SettingConstant) => randomInteger(setting.min, setting.max); @@ -255,3 +314,12 @@ const randDualSetting = (setting: SettingDualConstant): NumberDual => [ randomInteger(setting.min, setting.max), randomInteger(setting.min, setting.max), ]; + +const randSpritesPacks = (): SpritesPack[] => { + const packs: SpritesPack[] = []; + if (randomBoolean()) packs.push('classic'); + if (randomBoolean()) packs.push('bigdata'); + if (randomBoolean()) packs.push('aggromaxx'); + if (randomBoolean()) packs.push('crappack'); + return packs; +};