Skip to content

Commit 2d094f2

Browse files
committed
Add real-time parameter sliders to web UI
1 parent b14b9ac commit 2d094f2

5 files changed

Lines changed: 119 additions & 16 deletions

File tree

src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,16 @@ impl WebSimulation {
7676
self.simulation.world_size()
7777
}
7878

79+
pub fn update_param(&mut self, name: &str, value: f32) {
80+
match name {
81+
"max_velocity" => self.config.physics.max_velocity = value,
82+
"center_pressure" => self.config.physics.center_pressure_strength = value,
83+
"death_chance" => self.config.reproduction.death_chance_factor = value,
84+
_ => {}
85+
}
86+
self.simulation.update_config(self.config.clone());
87+
}
88+
7989
pub fn get_step(&self) -> u32 {
8090
self.simulation.step()
8191
}

src/simulation/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,10 @@ impl Simulation {
502502
pub fn step(&self) -> u32 {
503503
self.step
504504
}
505+
506+
pub fn update_config(&mut self, config: SimulationConfig) {
507+
self.config = config;
508+
}
505509
}
506510

507511
#[cfg(test)]

web/css/style.css

Lines changed: 66 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ body {
2424
position: absolute;
2525
top: 10px;
2626
right: 10px;
27-
background: rgba(255,255,255,0.1);
27+
background: rgba(255, 255, 255, 0.1);
2828
padding: 16px;
2929
border-radius: 12px;
3030
min-width: 200px;
3131
backdrop-filter: blur(10px);
3232
z-index: 100;
3333
transition: opacity 0.3s ease;
34-
border: 1px solid rgba(255,255,255,0.1);
34+
border: 1px solid rgba(255, 255, 255, 0.1);
3535
}
3636

3737
header {
@@ -42,7 +42,7 @@ header {
4242
h1 {
4343
font-size: 1.1rem;
4444
margin: 0 0 12px 0;
45-
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
45+
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
4646
opacity: 0.9;
4747
}
4848

@@ -58,7 +58,7 @@ button {
5858
padding: 6px 12px;
5959
border: none;
6060
border-radius: 4px;
61-
background: rgba(255,255,255,0.15);
61+
background: rgba(255, 255, 255, 0.15);
6262
color: white;
6363
cursor: pointer;
6464
transition: all 0.2s ease;
@@ -67,7 +67,7 @@ button {
6767
}
6868

6969
button:hover {
70-
background: rgba(255,255,255,0.25);
70+
background: rgba(255, 255, 255, 0.25);
7171
transform: translateY(-1px);
7272
}
7373

@@ -90,7 +90,7 @@ main {
9090
width: 100%;
9191
height: 100%;
9292
border: none;
93-
background: rgba(0,0,0,0.1);
93+
background: rgba(0, 0, 0, 0.1);
9494
}
9595

9696
.stats-panel {
@@ -119,19 +119,21 @@ main {
119119
opacity: 0;
120120
transform: scale(0.8);
121121
}
122+
122123
50% {
123124
opacity: 1;
124125
transform: scale(1.1);
125126
}
127+
126128
100% {
127129
opacity: 1;
128130
transform: scale(1);
129131
}
130132
}
131133

132134
.ui-toggle-corner button {
133-
background: rgba(255,255,255,0.08);
134-
border: 1px solid rgba(255,255,255,0.15);
135+
background: rgba(255, 255, 255, 0.08);
136+
border: 1px solid rgba(255, 255, 255, 0.15);
135137
border-radius: 50%;
136138
width: 36px;
137139
height: 36px;
@@ -140,21 +142,21 @@ main {
140142
cursor: pointer;
141143
backdrop-filter: blur(15px);
142144
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
143-
color: rgba(255,255,255,0.7);
145+
color: rgba(255, 255, 255, 0.7);
144146
display: flex;
145147
align-items: center;
146148
justify-content: center;
147-
box-shadow: 0 2px 8px rgba(0,0,0,0.2);
149+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
148150
line-height: 1;
149151
letter-spacing: -1px;
150152
}
151153

152154
.ui-toggle-corner button:hover {
153-
background: rgba(255,255,255,0.15);
154-
border-color: rgba(255,255,255,0.25);
155+
background: rgba(255, 255, 255, 0.15);
156+
border-color: rgba(255, 255, 255, 0.25);
155157
transform: scale(1.15);
156-
color: rgba(255,255,255,0.9);
157-
box-shadow: 0 4px 16px rgba(0,0,0,0.3);
158+
color: rgba(255, 255, 255, 0.9);
159+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
158160
}
159161

160162
.ui-toggle-corner button:active {
@@ -187,13 +189,61 @@ main {
187189
color: #4CAF50;
188190
}
189191

192+
.params-panel {
193+
margin-top: 12px;
194+
padding-top: 12px;
195+
border-top: 1px solid rgba(255, 255, 255, 0.1);
196+
}
197+
198+
.params-panel h3 {
199+
margin: 0 0 8px 0;
200+
text-align: center;
201+
font-size: 0.9rem;
202+
}
203+
204+
.slider-group {
205+
margin-bottom: 8px;
206+
}
207+
208+
.slider-group label {
209+
display: flex;
210+
justify-content: space-between;
211+
font-size: 0.75rem;
212+
margin-bottom: 4px;
213+
color: rgba(255, 255, 255, 0.8);
214+
}
215+
216+
.slider-group input[type="range"] {
217+
width: 100%;
218+
height: 4px;
219+
-webkit-appearance: none;
220+
appearance: none;
221+
background: rgba(255, 255, 255, 0.2);
222+
border-radius: 2px;
223+
outline: none;
224+
}
225+
226+
.slider-group input[type="range"]::-webkit-slider-thumb {
227+
-webkit-appearance: none;
228+
width: 14px;
229+
height: 14px;
230+
background: #4CAF50;
231+
border-radius: 50%;
232+
cursor: pointer;
233+
transition: background 0.2s;
234+
}
235+
236+
.slider-group input[type="range"]::-webkit-slider-thumb:hover {
237+
background: #66BB6A;
238+
}
239+
190240
@media (max-width: 768px) {
191241
main {
192242
flex-direction: column;
193243
}
194-
244+
195245
#simulation-canvas {
196246
width: 100%;
197247
height: auto;
198248
}
199-
}
249+
}

web/index.html

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,22 @@ <h3>Stats</h3>
3333
<div>FPS: <span id="fps">0</span></div>
3434
</div>
3535
</div>
36+
37+
<div class="params-panel">
38+
<h3>Parameters</h3>
39+
<div class="slider-group">
40+
<label>Speed: <span id="velocity-value">2.0</span></label>
41+
<input type="range" id="max-velocity" min="0.5" max="5" step="0.1" value="2.0">
42+
</div>
43+
<div class="slider-group">
44+
<label>Pressure: <span id="pressure-value">0.3</span></label>
45+
<input type="range" id="center-pressure" min="0" max="1" step="0.05" value="0.3">
46+
</div>
47+
<div class="slider-group">
48+
<label>Death Rate: <span id="death-value">0.1</span></label>
49+
<input type="range" id="death-chance" min="0" max="0.5" step="0.01" value="0.1">
50+
</div>
51+
</div>
3652
</div>
3753
</main>
3854
</div>

web/js/app.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,29 @@ class EvolutionApp {
9090
toggleUiBtn.addEventListener("click", () => this.toggleUI());
9191
showUiBtn.addEventListener("click", () => this.toggleUI());
9292

93+
// Parameter sliders
94+
const velocitySlider = document.getElementById("max-velocity");
95+
const pressureSlider = document.getElementById("center-pressure");
96+
const deathSlider = document.getElementById("death-chance");
97+
98+
velocitySlider.addEventListener("input", (e) => {
99+
const value = parseFloat(e.target.value);
100+
document.getElementById("velocity-value").textContent = value.toFixed(1);
101+
this.simulation.update_param("max_velocity", value);
102+
});
103+
104+
pressureSlider.addEventListener("input", (e) => {
105+
const value = parseFloat(e.target.value);
106+
document.getElementById("pressure-value").textContent = value.toFixed(2);
107+
this.simulation.update_param("center_pressure", value);
108+
});
109+
110+
deathSlider.addEventListener("input", (e) => {
111+
const value = parseFloat(e.target.value);
112+
document.getElementById("death-value").textContent = value.toFixed(2);
113+
this.simulation.update_param("death_chance", value);
114+
});
115+
93116
// Keyboard shortcuts
94117
document.addEventListener("keydown", (e) => {
95118
if (e.key === "h" || e.key === "H") {

0 commit comments

Comments
 (0)