SREAL commited on
Commit
5b87570
·
verified ·
1 Parent(s): d44a87b

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +435 -19
index.html CHANGED
@@ -1,19 +1,435 @@
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>MS1-X MOUSE MODULATION INDEX</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&family=Share+Tech+Mono&display=swap" rel="stylesheet">
8
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/tone/14.8.49/Tone.js"></script>
9
+ <style>
10
+ body {
11
+ margin: 0;
12
+ background: radial-gradient(circle at center, #0f1419 0%, #080a0c 100%);
13
+ color: #39ff14;
14
+ font-family: 'Share Tech Mono', monospace;
15
+ min-height: 100vh;
16
+ display: flex;
17
+ flex-direction: column;
18
+ align-items: center;
19
+ overflow: hidden;
20
+ }
21
+
22
+ .container {
23
+ width: 100%;
24
+ max-width: 1200px;
25
+ padding: 20px;
26
+ }
27
+
28
+ .header {
29
+ text-align: center;
30
+ margin-bottom: 30px;
31
+ position: relative;
32
+ }
33
+
34
+ .header:after {
35
+ content: '';
36
+ position: absolute;
37
+ bottom: -10px;
38
+ left: 50%;
39
+ transform: translateX(-50%);
40
+ width: 300px;
41
+ height: 2px;
42
+ background: linear-gradient(90deg, transparent, #39ff14, transparent);
43
+ }
44
+
45
+ .title {
46
+ font-family: 'Orbitron', sans-serif;
47
+ font-size: 48px;
48
+ margin: 0;
49
+ text-shadow: 0 0 20px #39ff1480;
50
+ letter-spacing: 5px;
51
+ background: linear-gradient(180deg, #39ff14, #2ba80d);
52
+ -webkit-background-clip: text;
53
+ -webkit-text-fill-color: transparent;
54
+ }
55
+
56
+ .subtitle {
57
+ font-size: 14px;
58
+ opacity: 0.8;
59
+ margin: 5px 0;
60
+ letter-spacing: 2px;
61
+ }
62
+
63
+ .xy-container {
64
+ position: relative;
65
+ width: 500px;
66
+ height: 500px;
67
+ margin: 0 auto;
68
+ padding: 20px;
69
+ background: linear-gradient(45deg, #111417, #1a1e23);
70
+ border-radius: 20px;
71
+ box-shadow:
72
+ inset 0 0 50px rgba(57, 255, 20, 0.1),
73
+ 0 0 20px rgba(0,0,0,0.5);
74
+ }
75
+
76
+ .xy-pad {
77
+ width: 100%;
78
+ height: 100%;
79
+ background: #0a0c0e;
80
+ border: 2px solid #39ff14;
81
+ border-radius: 15px;
82
+ position: relative;
83
+ box-shadow:
84
+ 0 0 20px #39ff1440,
85
+ inset 0 0 50px rgba(57, 255, 20, 0.1);
86
+ overflow: hidden;
87
+ }
88
+
89
+ .xy-cursor {
90
+ width: 16px;
91
+ height: 16px;
92
+ background: #39ff14;
93
+ border-radius: 50%;
94
+ position: absolute;
95
+ transform: translate(-50%, -50%);
96
+ pointer-events: none;
97
+ box-shadow:
98
+ 0 0 20px #39ff14,
99
+ 0 0 40px #39ff14,
100
+ 0 0 60px #39ff14;
101
+ z-index: 10;
102
+ }
103
+
104
+ .grid-lines {
105
+ position: absolute;
106
+ width: 100%;
107
+ height: 100%;
108
+ background-image:
109
+ radial-gradient(circle, rgba(57, 255, 20, 0.1) 1px, transparent 1px),
110
+ linear-gradient(rgba(57, 255, 20, 0.1) 1px, transparent 1px),
111
+ linear-gradient(90deg, rgba(57, 255, 20, 0.1) 1px, transparent 1px);
112
+ background-size:
113
+ 20px 20px,
114
+ 50px 50px,
115
+ 50px 50px;
116
+ opacity: 0.5;
117
+ }
118
+
119
+ .controls {
120
+ display: flex;
121
+ justify-content: center;
122
+ gap: 15px;
123
+ margin: 20px 0;
124
+ flex-wrap: wrap;
125
+ }
126
+
127
+ .toggle {
128
+ background: linear-gradient(180deg, #1a1e23, #141719);
129
+ border: 1px solid #39ff14;
130
+ color: #39ff14;
131
+ padding: 12px 24px;
132
+ font-family: 'Share Tech Mono', monospace;
133
+ cursor: pointer;
134
+ transition: all 0.3s;
135
+ border-radius: 5px;
136
+ text-shadow: 0 0 5px #39ff14;
137
+ box-shadow:
138
+ 0 0 10px rgba(57, 255, 20, 0.2),
139
+ inset 0 0 20px rgba(57, 255, 20, 0.1);
140
+ }
141
+
142
+ .toggle:hover {
143
+ background: linear-gradient(180deg, #39ff14, #2ba80d);
144
+ color: #0a0c0e;
145
+ text-shadow: none;
146
+ }
147
+
148
+ .toggle.active {
149
+ background: #39ff14;
150
+ color: #0a0c0e;
151
+ box-shadow:
152
+ 0 0 20px #39ff14,
153
+ inset 0 0 10px rgba(0,0,0,0.2);
154
+ }
155
+
156
+ .piano {
157
+ display: flex;
158
+ justify-content: center;
159
+ margin: 20px auto;
160
+ height: 120px;
161
+ max-width: 800px;
162
+ perspective: 1000px;
163
+ transform: rotateX(5deg);
164
+ }
165
+
166
+ .key {
167
+ width: 35px;
168
+ height: 100%;
169
+ background: linear-gradient(180deg, #1a1e23, #141719);
170
+ border: 1px solid #39ff14;
171
+ margin: 0 2px;
172
+ transition: all 0.1s;
173
+ box-shadow:
174
+ 0 5px 15px rgba(0,0,0,0.5),
175
+ inset 0 0 20px rgba(57, 255, 20, 0.1);
176
+ }
177
+
178
+ .key.active {
179
+ background: #39ff14;
180
+ transform: scale(0.98);
181
+ box-shadow:
182
+ 0 0 30px #39ff14,
183
+ inset 0 0 10px rgba(0,0,0,0.2);
184
+ }
185
+
186
+ .instructions {
187
+ text-align: center;
188
+ opacity: 0.7;
189
+ margin: 20px 0;
190
+ padding: 15px;
191
+ border: 1px solid rgba(57, 255, 20, 0.3);
192
+ border-radius: 10px;
193
+ background: rgba(57, 255, 20, 0.05);
194
+ }
195
+
196
+ .oscilloscope {
197
+ position: absolute;
198
+ width: 100%;
199
+ height: 100%;
200
+ z-index: 5;
201
+ }
202
+
203
+ @keyframes scanline {
204
+ 0% {
205
+ transform: translateY(0);
206
+ }
207
+ 100% {
208
+ transform: translateY(100%);
209
+ }
210
+ }
211
+
212
+ .scanline {
213
+ position: absolute;
214
+ width: 100%;
215
+ height: 2px;
216
+ background: rgba(57, 255, 20, 0.1);
217
+ animation: scanline 2s linear infinite;
218
+ z-index: 4;
219
+ pointer-events: none;
220
+ }
221
+
222
+ </style>
223
+ </head>
224
+ <body>
225
+ <div class="container">
226
+ <div class="header">
227
+ <h1 class="title">MS1-X</h1>
228
+ <p class="subtitle">MOUSE MODULATION INDEX</p>
229
+ <p class="subtitle">CREATED BY SREAL</p>
230
+ </div>
231
+
232
+ <div class="xy-container">
233
+ <div class="xy-pad">
234
+ <div class="grid-lines"></div>
235
+ <div class="scanline"></div>
236
+ <canvas class="oscilloscope"></canvas>
237
+ <div class="xy-cursor"></div>
238
+ </div>
239
+ </div>
240
+
241
+ <div class="controls">
242
+ <button class="toggle" data-effect="bitcrusher">BITCRUSHER</button>
243
+ <button class="toggle" data-effect="delay">DELAY</button>
244
+ <button class="toggle" data-effect="distortion">DISTORTION</button>
245
+ <button class="toggle" data-effect="chorus">CHORUS</button>
246
+ </div>
247
+
248
+ <div class="piano"></div>
249
+
250
+ <div class="instructions">
251
+ USE QWERTY KEYBOARD TO PLAY (Z TO =)<br>
252
+ CLICK AND DRAG ON SCREEN TO MODIFY SOUND
253
+ </div>
254
+ </div>
255
+
256
+ <script>
257
+ const synth = new Tone.FMSynth({
258
+ modulationIndex: 10,
259
+ harmonicity: 3,
260
+ envelope: {
261
+ attack: 0.01,
262
+ decay: 0.2,
263
+ sustain: 0.8,
264
+ release: 1
265
+ }
266
+ }).toDestination();
267
+
268
+ const delay = new Tone.FeedbackDelay({
269
+ delayTime: 0.3,
270
+ feedback: 0.4,
271
+ wet: 0
272
+ });
273
+
274
+ const chorus = new Tone.Chorus({
275
+ frequency: 4,
276
+ delayTime: 2.5,
277
+ depth: 0.5,
278
+ wet: 0
279
+ }).start();
280
+
281
+ const crusher = new Tone.BitCrusher({
282
+ bits: 4,
283
+ wet: 0
284
+ });
285
+
286
+ const distortion = new Tone.Distortion({
287
+ distortion: 0.8,
288
+ wet: 0
289
+ });
290
+
291
+ // Effects chain
292
+ synth.chain(crusher, distortion, chorus, delay, Tone.Destination);
293
+
294
+ // Analyzer for oscilloscope
295
+ const analyzer = new Tone.Analyser('waveform', 256);
296
+ synth.connect(analyzer);
297
+
298
+ const keyMap = {
299
+ 'z': 'C2', 'x': 'D2', 'c': 'E2', 'v': 'F2', 'b': 'G2', 'n': 'A2', 'm': 'B2',
300
+ 'a': 'C3', 's': 'D3', 'd': 'E3', 'f': 'F3', 'g': 'G3', 'h': 'A3', 'j': 'B3',
301
+ 'q': 'C4', 'w': 'D4', 'e': 'E4', 'r': 'F4', 't': 'G4', 'y': 'A4', 'u': 'B4',
302
+ 'i': 'C5', 'o': 'D5', 'p': 'E5', '[': 'F5', ']': 'G5', '\\': 'A5'
303
+ };
304
+
305
+ const activeKeys = new Set();
306
+ const piano = document.querySelector('.piano');
307
+
308
+ // Create piano keys
309
+ Object.keys(keyMap).forEach(key => {
310
+ const keyEl = document.createElement('div');
311
+ keyEl.className = 'key';
312
+ keyEl.dataset.key = key;
313
+ piano.appendChild(keyEl);
314
+ });
315
+
316
+ // Oscilloscope
317
+ const canvas = document.querySelector('.oscilloscope');
318
+ const ctx = canvas.getContext('2d');
319
+
320
+ function resizeCanvas() {
321
+ canvas.width = canvas.offsetWidth;
322
+ canvas.height = canvas.offsetHeight;
323
+ }
324
+ resizeCanvas();
325
+ window.addEventListener('resize', resizeCanvas);
326
+
327
+ function drawOscilloscope() {
328
+ requestAnimationFrame(drawOscilloscope);
329
+ const values = analyzer.getValue();
330
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
331
+
332
+ ctx.beginPath();
333
+ ctx.strokeStyle = '#39ff14';
334
+ ctx.lineWidth = 2;
335
+
336
+ for(let i = 0; i < values.length; i++) {
337
+ const x = (i / values.length) * canvas.width;
338
+ const y = ((values[i] + 1) / 2) * canvas.height;
339
+
340
+ if(i === 0) {
341
+ ctx.moveTo(x, y);
342
+ } else {
343
+ ctx.lineTo(x, y);
344
+ }
345
+ }
346
+
347
+ ctx.stroke();
348
+ ctx.strokeStyle = '#39ff1440';
349
+ ctx.lineWidth = 1;
350
+ ctx.stroke();
351
+ }
352
+ drawOscilloscope();
353
+
354
+ // XY Pad
355
+ const xyPad = document.querySelector('.xy-pad');
356
+ const cursor = document.querySelector('.xy-cursor');
357
+ let isDrawing = false;
358
+
359
+ function updateXY(e) {
360
+ const rect = xyPad.getBoundingClientRect();
361
+ const x = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
362
+ const y = Math.max(0, Math.min(1, (e.clientY - rect.top) / rect.height));
363
+
364
+ cursor.style.left = `${x * rect.width}px`;
365
+ cursor.style.top = `${y * rect.height}px`;
366
+
367
+ synth.modulationIndex.value = x * 100;
368
+ synth.harmonicity.value = y * 10;
369
+ delay.delayTime.value = x;
370
+ delay.feedback.value = y;
371
+ distortion.distortion = y * 2;
372
+ chorus.frequency.value = x * 10;
373
+ }
374
+
375
+ xyPad.addEventListener('mousedown', (e) => {
376
+ isDrawing = true;
377
+ updateXY(e);
378
+ });
379
+
380
+ window.addEventListener('mousemove', (e) => {
381
+ if (isDrawing) updateXY(e);
382
+ });
383
+
384
+ window.addEventListener('mouseup', () => {
385
+ isDrawing = false;
386
+ });
387
+
388
+ // Keyboard Events
389
+ window.addEventListener('keydown', (e) => {
390
+ const key = e.key.toLowerCase();
391
+ if (keyMap[key] && !activeKeys.has(key)) {
392
+ synth.triggerAttack(keyMap[key]);
393
+ activeKeys.add(key);
394
+ document.querySelector(`.key[data-key="${key}"]`)?.classList.add('active');
395
+ }
396
+ });
397
+
398
+ window.addEventListener('keyup', (e) => {
399
+ const key = e.key.toLowerCase();
400
+ if (keyMap[key]) {
401
+ synth.triggerRelease();
402
+ activeKeys.delete(key);
403
+ document.querySelector(`.key[data-key="${key}"]`)?.classList.remove('active');
404
+ }
405
+ });
406
+
407
+ // Effect Toggles
408
+ document.querySelectorAll('.toggle').forEach(btn => {
409
+ btn.addEventListener('click', () => {
410
+ btn.classList.toggle('active');
411
+ const effect = btn.dataset.effect;
412
+ switch(effect) {
413
+ case 'bitcrusher':
414
+ crusher.wet.value = btn.classList.contains('active') ? 1 : 0;
415
+ break;
416
+ case 'delay':
417
+ delay.wet.value = btn.classList.contains('active') ? 0.5 : 0;
418
+ break;
419
+ case 'distortion':
420
+ distortion.wet.value = btn.classList.contains('active') ? 0.5 : 0;
421
+ break;
422
+ case 'chorus':
423
+ chorus.wet.value = btn.classList.contains('active') ? 0.5 : 0;
424
+ break;
425
+ }
426
+ });
427
+ });
428
+
429
+ // Start audio context on first interaction
430
+ document.body.addEventListener('click', () => {
431
+ Tone.start();
432
+ }, { once: true });
433
+ </script>
434
+ </body>
435
+ </html>