Add settings sliders

This commit is contained in:
Andras Schmelczer 2023-05-27 15:00:04 +01:00
commit 752e1ae425
No known key found for this signature in database
GPG key ID: FC8F2C3D3D1A718C
9 changed files with 170 additions and 48 deletions

View file

@ -18,12 +18,12 @@
"plugins": ["unused-imports", "@typescript-eslint", "prettier"],
"rules": {
"prettier/prettier": "error",
"no-unused-vars": "off",
"unused-imports/no-unused-imports-ts": "error",
"@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }],
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/ban-ts-comment": "off"
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-empty-function": "off"
}
}

View file

@ -49,16 +49,18 @@
<button class="restart"></button>
</nav>
<main class="pages hidden info-page">
<main class="pages info-page">
<section>
<h1>Title</h1>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Eaque itaque
perspiciatis nesciunt, molestiae officiis dignissimos porro! Provident totam sit
enim, dolores dicta possimus ex assumenda earum, ea tempore, aut quidem?
perspiciatis nesciunt, molestiae officiis dignissimos porro! Provident totam
sit enim, dolores dicta possimus ex assumenda earum, ea tempore, aut quidem?
</p>
</section>
</main>
<main class="pages hidden settings-page"></main>
<main class="pages hidden settings-page"><section></section></main>
</aside>
<script inline inline-asset="index.js" inline-asset-delete></script>
</body>

View file

@ -31,7 +31,6 @@ p {
html {
height: 100%;
-webkit-font-smooth: antialiased;
> body {
width: 100%;
height: 100%;
@ -89,6 +88,7 @@ html {
top: 50%;
left: 0;
transform: translateY(-50%);
height: 400px;
}
@include on-small-screen {
@ -133,10 +133,20 @@ html {
}
> main.pages {
overflow: hidden;
overflow-x: hidden;
overflow-y: auto;
&::-webkit-scrollbar-track,
&::-webkit-scrollbar {
background-color: transparent;
width: 6px;
}
&::-webkit-scrollbar-thumb {
background-color: var(--main-color);
border-radius: var(--border-radius);
}
&,
* {
> * {
transition: width var(--transition-time-long),
height var(--transition-time-long);
@ -160,7 +170,50 @@ html {
}
> section {
margin: var(--normal-margin);
padding: var(--normal-margin);
.slider {
$track-height: 12px;
margin-bottom: var(--small-margin);
p {
display: flex;
justify-content: space-between;
}
input[type='range'] {
width: 100%;
height: $track-height;
appearance: none;
background: transparent;
outline: none;
border-radius: 1000px;
&::-webkit-slider-runnable-track {
appearance: none;
cursor: pointer;
border-radius: 1000px;
@include square(15px);
background: var(--accent-color);
}
&::-webkit-slider-thumb {
appearance: none;
cursor: pointer;
border-radius: 1000px;
$size: 24px;
@include square($size);
background: white;
box-shadow: 0 0 5px 1px var(--accent-color);
transform: translateY(-5px);
transition: transform var(--transition-time);
&:hover {
transform: translateY(-5px) scale(1.1);
}
}
}
}
}
}
}

View file

@ -67,14 +67,17 @@ const main = async () => {
const infoPageHandler = new CollapsiblePanelAnimator(
elements.infoButton,
elements.infoElement
elements.infoElement,
elements.aside
);
const settingsPageHandler = new CollapsiblePanelAnimator(
elements.settingsButton,
elements.settingsPage
elements.settingsPage,
elements.aside
);
settingsPageHandler.onOpen = infoPageHandler.close.bind(infoPageHandler);
infoPageHandler.onOpen = settingsPageHandler.close.bind(settingsPageHandler);
infoPageHandler.open();
new MenuHider(elements.aside, FullScreenHandler.isInFullScreenMode);
new FullScreenHandler(
@ -103,9 +106,7 @@ next gen: ${formatNumber(game?.aliveAgentCounts.nextGenerationCount ?? 0)}`;
game = new GameLoop(elements.canvas, gpu, deltaTimeCalculator, gameRules);
if (!isSettingsPageSetUp) {
isSettingsPageSetUp = true;
setUpSettingsPage(elements.settingsPage, game.maxAgentCount, () =>
game?.destroy()
);
setUpSettingsPage(elements.settingsPage, game.maxAgentCount);
}
await game.start();

View file

@ -6,20 +6,14 @@ export class CollapsiblePanelAnimator {
public constructor(
infoButton: HTMLButtonElement,
private readonly infoPage: HTMLElement
private readonly infoPage: HTMLElement,
ignoreForCloseOnClick: HTMLElement
) {
infoButton.addEventListener('click', this.toggle.bind(this));
window.addEventListener('click', (event) => {
if ([infoButton, this.infoPage].includes(event.target as HTMLElement)) {
return;
}
if (this.infoPage.contains(event.target as Node)) {
return;
}
this.close();
});
window.addEventListener(
'click',
(event) => !ignoreForCloseOnClick.contains(event.target as Node) && this.close()
);
}
public open() {

View file

@ -0,0 +1,65 @@
import { settings } from '../settings';
import { SettingsSlider, ValueScaling } from '../utils/settings-slider';
export const setUpSettingsPage = (
settingsPage: HTMLDivElement,
maxAgentCount: number
) => {
const sliders = [
[
new SettingsSlider(settings, 'agentCount', {
min: 1,
max: maxAgentCount,
scaling: ValueScaling.Logarithmic,
rounding: Math.round,
}),
new SettingsSlider(settings, 'aggressionFactor', {
min: 0,
max: 10,
}),
new SettingsSlider(settings, 'nextGenerationSpawnRadius', {
min: 1,
max: 1000,
}),
new SettingsSlider(settings, 'nextGenerationSpawnInterval', {
min: 0.1,
max: 600,
}),
new SettingsSlider(settings, 'moveSpeed', {
min: 10,
max: 500,
}),
],
[
new SettingsSlider(settings, 'brushWidth', {
min: 1,
max: 60,
}),
new SettingsSlider(settings, 'brushWidthRandomness', {
min: 0,
max: 1,
}),
],
[
new SettingsSlider(settings, 'clarity', {
min: 0.1,
max: 8,
}),
],
];
sliders.forEach((sliderContainer) => {
const sliderContainerElement = document.createElement('div');
sliderContainer.forEach((slider) => {
sliderContainerElement.appendChild(slider.element);
});
settingsPage.querySelector('section').appendChild(sliderContainerElement);
});
};

View file

@ -3,23 +3,21 @@ import { AgentSettings } from './pipelines/agents/agent-settings';
import { BrushSettings } from './pipelines/brush/brush-settings';
import { DiffusionSettings } from './pipelines/diffusion/diffusion-settings';
import { RenderSettings } from './pipelines/render/render-settings';
import { persist } from './utils/persist';
export const settings: GameLoopSettings &
export const settings: { [key: string]: number } & GameLoopSettings &
AgentSettings &
BrushSettings &
DiffusionSettings &
RenderSettings = {
agentCount: 4_000_000, // requires restart
RenderSettings = persist({
agentCount: 1_000_000,
brushWidth: 12,
brushWidthRandomness: 0.5,
aggressionFactor: 3,
nextGenerationSpawnRadius: 5,
nextGenerationSpawnInterval: 1,
renderSpeed: 2,
simulatedDelayMs: 0,
brushWidth: 12,
brushWidthRandomness: 5.5,
nextGenerationSpawnInterval: 600,
brushTrailWeight: 5,
moveSpeed: 80,
@ -37,5 +35,12 @@ export const settings: GameLoopSettings &
decayRateBrush: 0.003,
clarity: 2,
startColorHue: 200,
};
maxAgentCountUpperLimit: 64_000_000, // requires restart
// debug options
renderSpeed: 1,
simulatedDelayMs: 0,
});

View file

@ -5,12 +5,10 @@
--transition-time-long: 350ms;
--line-width: 4px;
--line-height: 1.125rem;
--accent-color: #ff6b6b;
--sun-color: #f7f78c;
--accent-color: rgb(6.39851188659668, 70.28645324707031, 102.23043060302734);
--very-light-text-color: #ffffff;
--background: #ffffff;
--main-color: #aaa;
--normal-text-color: #31343f;
--card-color: #ffffff;
--blurred-card-color: transparent;
--blur-radius: 12px;
--special-text-color: var(--accent-color);

View file

@ -63,11 +63,15 @@ export class SettingsSlider<T extends Record<string, number>> {
valueDisplay: HTMLSpanElement
) {
const wrapper = document.createElement('div');
wrapper.classList.add('slider');
const label = document.createElement('label');
label.innerText = SettingsSlider.formatLabel(name);
const title = document.createElement('p');
title.innerText = SettingsSlider.formatLabel(name);
title.appendChild(valueDisplay);
label.appendChild(title);
label.appendChild(slider);
label.appendChild(valueDisplay);
wrapper.appendChild(label);
return wrapper;