amirpoorazima commited on
Commit
a6c7a66
·
verified ·
1 Parent(s): ec8ba28

Add 3 files

Browse files
Files changed (3) hide show
  1. README.md +6 -4
  2. index.html +330 -19
  3. prompts.txt +1 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Virtual Spring
3
- emoji: 💻
4
  colorFrom: gray
5
- colorTo: indigo
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: virtual-spring
3
+ emoji: 🐳
4
  colorFrom: gray
5
+ colorTo: red
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,330 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Virtual Spring Simulation</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/js/all.min.js"></script>
9
+ <style>
10
+ .spring-container {
11
+ position: relative;
12
+ height: 400px;
13
+ overflow: hidden;
14
+ }
15
+ .spring {
16
+ position: absolute;
17
+ left: 50%;
18
+ transform: translateX(-50%);
19
+ width: 8px;
20
+ background-color: #3b82f6;
21
+ border-radius: 4px;
22
+ transition: height 0.1s ease-out;
23
+ }
24
+ .mass {
25
+ position: absolute;
26
+ left: 50%;
27
+ transform: translateX(-50%);
28
+ width: 80px;
29
+ height: 80px;
30
+ background-color: #10b981;
31
+ border-radius: 8px;
32
+ display: flex;
33
+ align-items: center;
34
+ justify-content: center;
35
+ color: white;
36
+ font-weight: bold;
37
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
38
+ }
39
+ .controls {
40
+ background-color: #f3f4f6;
41
+ border-radius: 12px;
42
+ padding: 1.5rem;
43
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
44
+ }
45
+ .slider-container {
46
+ display: flex;
47
+ align-items: center;
48
+ gap: 1rem;
49
+ margin-bottom: 1rem;
50
+ }
51
+ .slider {
52
+ flex-grow: 1;
53
+ -webkit-appearance: none;
54
+ height: 8px;
55
+ border-radius: 4px;
56
+ background: #d1d5db;
57
+ outline: none;
58
+ }
59
+ .slider::-webkit-slider-thumb {
60
+ -webkit-appearance: none;
61
+ appearance: none;
62
+ width: 20px;
63
+ height: 20px;
64
+ border-radius: 50%;
65
+ background: #3b82f6;
66
+ cursor: pointer;
67
+ }
68
+ .slider::-moz-range-thumb {
69
+ width: 20px;
70
+ height: 20px;
71
+ border-radius: 50%;
72
+ background: #3b82f6;
73
+ cursor: pointer;
74
+ }
75
+ .spring-anchor {
76
+ position: absolute;
77
+ top: 0;
78
+ left: 50%;
79
+ transform: translateX(-50%);
80
+ width: 100px;
81
+ height: 20px;
82
+ background-color: #6b7280;
83
+ border-radius: 0 0 10px 10px;
84
+ }
85
+ </style>
86
+ </head>
87
+ <body class="bg-gray-100 min-h-screen">
88
+ <div class="container mx-auto px-4 py-8">
89
+ <header class="text-center mb-8">
90
+ <h1 class="text-4xl font-bold text-indigo-700 mb-2">Virtual Spring Simulator</h1>
91
+ <p class="text-gray-600">Explore Hooke's Law with this interactive spring-mass system</p>
92
+ </header>
93
+
94
+ <div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
95
+ <div class="lg:col-span-2">
96
+ <div class="bg-white rounded-xl shadow-lg overflow-hidden">
97
+ <div class="spring-container relative">
98
+ <div class="spring-anchor"></div>
99
+ <div id="spring" class="spring bg-blue-500"></div>
100
+ <div id="mass" class="mass bg-emerald-500">1 kg</div>
101
+ </div>
102
+ <div class="p-4 bg-gray-50 border-t border-gray-200">
103
+ <button id="startBtn" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg mr-3 transition">
104
+ <i class="fas fa-play mr-2"></i> Start Oscillation
105
+ </button>
106
+ <button id="stopBtn" class="bg-gray-600 hover:bg-gray-700 text-white px-4 py-2 rounded-lg transition">
107
+ <i class="fas fa-stop mr-2"></i> Stop
108
+ </button>
109
+ <button id="resetBtn" class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg float-right transition">
110
+ <i class="fas fa-undo mr-2"></i> Reset
111
+ </button>
112
+ </div>
113
+ </div>
114
+ </div>
115
+
116
+ <div class="controls">
117
+ <h2 class="text-xl font-semibold text-gray-800 mb-4">Spring Parameters</h2>
118
+
119
+ <div class="slider-container">
120
+ <span class="text-gray-700 w-24">Mass (kg)</span>
121
+ <input type="range" id="massSlider" class="slider" min="0.1" max="5" step="0.1" value="1">
122
+ <span id="massValue" class="text-gray-700 w-12">1.0</span>
123
+ </div>
124
+
125
+ <div class="slider-container">
126
+ <span class="text-gray-700 w-24">Spring Constant (N/m)</span>
127
+ <input type="range" id="kSlider" class="slider" min="1" max="50" step="1" value="10">
128
+ <span id="kValue" class="text-gray-700 w-12">10</span>
129
+ </div>
130
+
131
+ <div class="slider-container">
132
+ <span class="text-gray-700 w-24">Damping</span>
133
+ <input type="range" id="dampingSlider" class="slider" min="0" max="0.5" step="0.01" value="0.05">
134
+ <span id="dampingValue" class="text-gray-700 w-12">0.05</span>
135
+ </div>
136
+
137
+ <div class="slider-container">
138
+ <span class="text-gray-700 w-24">Initial Displacement (cm)</span>
139
+ <input type="range" id="displacementSlider" class="slider" min="0" max="50" step="1" value="20">
140
+ <span id="displacementValue" class="text-gray-700 w-12">20</span>
141
+ </div>
142
+
143
+ <div class="mt-6 p-4 bg-indigo-50 rounded-lg">
144
+ <h3 class="font-medium text-indigo-800 mb-2">Physics Information</h3>
145
+ <p class="text-sm text-gray-700 mb-1"><span class="font-medium">Natural Frequency:</span> <span id="frequency">1.58</span> Hz</p>
146
+ <p class="text-sm text-gray-700 mb-1"><span class="font-medium">Period:</span> <span id="period">3.97</span> s</p>
147
+ <p class="text-sm text-gray-700"><span class="font-medium">Current Position:</span> <span id="position">20.0</span> cm</p>
148
+ </div>
149
+ </div>
150
+ </div>
151
+
152
+ <div class="mt-8 bg-white rounded-xl shadow-lg p-6">
153
+ <h2 class="text-2xl font-bold text-gray-800 mb-4">About Spring Systems</h2>
154
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
155
+ <div>
156
+ <h3 class="text-lg font-semibold text-indigo-700 mb-2">Hooke's Law</h3>
157
+ <p class="text-gray-600 mb-4">Hooke's Law states that the force exerted by a spring is proportional to its displacement from equilibrium: F = -kx, where k is the spring constant and x is the displacement.</p>
158
+ <div class="bg-gray-100 p-3 rounded-lg text-center">
159
+ <p class="font-mono text-gray-800">F = -k × x</p>
160
+ </div>
161
+ </div>
162
+ <div>
163
+ <h3 class="text-lg font-semibold text-indigo-700 mb-2">Simple Harmonic Motion</h3>
164
+ <p class="text-gray-600 mb-4">When a mass is attached to a spring, it exhibits simple harmonic motion. The period T of oscillation depends on the mass m and spring constant k:</p>
165
+ <div class="bg-gray-100 p-3 rounded-lg text-center">
166
+ <p class="font-mono text-gray-800">T = 2π√(m/k)</p>
167
+ </div>
168
+ </div>
169
+ </div>
170
+ </div>
171
+ </div>
172
+
173
+ <script>
174
+ // DOM elements
175
+ const spring = document.getElementById('spring');
176
+ const mass = document.getElementById('mass');
177
+ const startBtn = document.getElementById('startBtn');
178
+ const stopBtn = document.getElementById('stopBtn');
179
+ const resetBtn = document.getElementById('resetBtn');
180
+
181
+ // Sliders and values
182
+ const massSlider = document.getElementById('massSlider');
183
+ const kSlider = document.getElementById('kSlider');
184
+ const dampingSlider = document.getElementById('dampingSlider');
185
+ const displacementSlider = document.getElementById('displacementSlider');
186
+
187
+ const massValue = document.getElementById('massValue');
188
+ const kValue = document.getElementById('kValue');
189
+ const dampingValue = document.getElementById('dampingValue');
190
+ const displacementValue = document.getElementById('displacementValue');
191
+
192
+ // Physics info
193
+ const frequencyEl = document.getElementById('frequency');
194
+ const periodEl = document.getElementById('period');
195
+ const positionEl = document.getElementById('position');
196
+
197
+ // Simulation variables
198
+ let animationId;
199
+ let isOscillating = false;
200
+ let equilibriumY = 150; // Equilibrium position in pixels
201
+ let currentY = equilibriumY;
202
+ let velocity = 0;
203
+ let lastTime = 0;
204
+ let initialDisplacement = 20; // cm
205
+
206
+ // Constants
207
+ const pixelsPerCm = 3; // Conversion factor
208
+ const g = 9.81; // gravity in m/s²
209
+
210
+ // Initialize the simulation
211
+ function init() {
212
+ updateParameters();
213
+ updatePhysicsInfo();
214
+ render();
215
+ }
216
+
217
+ // Update parameters from sliders
218
+ function updateParameters() {
219
+ const mass = parseFloat(massSlider.value);
220
+ const k = parseFloat(kSlider.value);
221
+ const damping = parseFloat(dampingSlider.value);
222
+ initialDisplacement = parseFloat(displacementSlider.value);
223
+
224
+ massValue.textContent = mass.toFixed(1);
225
+ kValue.textContent = k;
226
+ dampingValue.textContent = damping.toFixed(2);
227
+ displacementValue.textContent = initialDisplacement;
228
+
229
+ // Reset position to initial displacement
230
+ currentY = equilibriumY + initialDisplacement * pixelsPerCm;
231
+ velocity = 0;
232
+
233
+ updatePhysicsInfo();
234
+ render();
235
+ }
236
+
237
+ // Update physics information display
238
+ function updatePhysicsInfo() {
239
+ const mass = parseFloat(massSlider.value);
240
+ const k = parseFloat(kSlider.value);
241
+
242
+ // Calculate natural frequency (rad/s)
243
+ const omega = Math.sqrt(k / mass);
244
+ // Convert to Hz
245
+ const freq = omega / (2 * Math.PI);
246
+ // Calculate period
247
+ const period = 2 * Math.PI / omega;
248
+
249
+ // Current position in cm (relative to equilibrium)
250
+ const positionCm = (currentY - equilibriumY) / pixelsPerCm;
251
+
252
+ frequencyEl.textContent = freq.toFixed(2);
253
+ periodEl.textContent = period.toFixed(2);
254
+ positionEl.textContent = positionCm.toFixed(1);
255
+ }
256
+
257
+ // Render the spring and mass
258
+ function render() {
259
+ // Spring height is from anchor to mass top
260
+ const springHeight = currentY - 20; // 20 is anchor height
261
+
262
+ spring.style.height = `${springHeight}px`;
263
+ spring.style.top = '20px'; // Below anchor
264
+
265
+ mass.style.top = `${currentY}px`;
266
+ mass.textContent = `${parseFloat(massSlider.value).toFixed(1)} kg`;
267
+ }
268
+
269
+ // Animation loop
270
+ function animate(timestamp) {
271
+ if (!lastTime) lastTime = timestamp;
272
+ const deltaTime = (timestamp - lastTime) / 1000; // Convert to seconds
273
+ lastTime = timestamp;
274
+
275
+ if (isOscillating) {
276
+ // Get current parameters
277
+ const mass = parseFloat(massSlider.value);
278
+ const k = parseFloat(kSlider.value);
279
+ const damping = parseFloat(dampingSlider.value);
280
+
281
+ // Calculate acceleration (F = ma = -kx - damping*v)
282
+ const displacement = (currentY - equilibriumY) / pixelsPerCm / 100; // Convert to meters
283
+ const acceleration = (-k * displacement - damping * velocity) / mass;
284
+
285
+ // Update velocity and position
286
+ velocity += acceleration * deltaTime;
287
+ currentY += velocity * pixelsPerCm * 100 * deltaTime; // Convert back to pixels
288
+
289
+ updatePhysicsInfo();
290
+ render();
291
+ }
292
+
293
+ animationId = requestAnimationFrame(animate);
294
+ }
295
+
296
+ // Event listeners
297
+ startBtn.addEventListener('click', () => {
298
+ if (!isOscillating) {
299
+ isOscillating = true;
300
+ lastTime = 0;
301
+ animationId = requestAnimationFrame(animate);
302
+ }
303
+ });
304
+
305
+ stopBtn.addEventListener('click', () => {
306
+ isOscillating = false;
307
+ if (animationId) {
308
+ cancelAnimationFrame(animationId);
309
+ }
310
+ });
311
+
312
+ resetBtn.addEventListener('click', () => {
313
+ isOscillating = false;
314
+ if (animationId) {
315
+ cancelAnimationFrame(animationId);
316
+ }
317
+ updateParameters();
318
+ });
319
+
320
+ // Slider event listeners
321
+ massSlider.addEventListener('input', updateParameters);
322
+ kSlider.addEventListener('input', updateParameters);
323
+ dampingSlider.addEventListener('input', updateParameters);
324
+ displacementSlider.addEventListener('input', updateParameters);
325
+
326
+ // Initialize
327
+ init();
328
+ </script>
329
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=amirpoorazima/virtual-spring" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
330
+ </html>
prompts.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ virtual spring