Add settings sliders

This commit is contained in:
Andras Schmelczer 2023-05-27 15:00:04 +01:00
parent cd9aff0362
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

@ -49,16 +49,18 @@
<button class="restart"></button>
</nav>
<main class="pages hidden info-page">
<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?
</p>
<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?
</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;