awacke1 commited on
Commit
99c2646
1 Parent(s): ef16635

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +130 -186
index.html CHANGED
@@ -1,219 +1,163 @@
1
  <!DOCTYPE html>
2
- <html>
3
  <head>
4
- <meta charset="utf-8">
5
- <title>A-Frame 3D Editor with Animated Rotation and Color Picker</title>
6
- <script src="https://cdnjs.cloudflare.com/ajax/libs/aframe/1.2.0/aframe.min.js"></script>
 
7
  <style>
8
- .ui-panel {
9
- position: fixed;
10
- top: 20px;
11
- left: 20px;
12
- z-index: 9999;
13
- background: rgba(0,0,0,0.7);
14
- padding: 10px;
15
- border-radius: 5px;
16
- color: white;
17
  font-family: Arial, sans-serif;
 
 
 
 
 
 
 
18
  }
19
- .ui-panel button {
20
- display: block;
21
- margin: 5px 0;
22
- padding: 5px 10px;
23
  }
24
- .control-panel {
25
- position: fixed;
26
- top: 20px;
27
- right: 20px;
28
- z-index: 9999;
29
- background: rgba(0,0,0,0.7);
30
- padding: 10px;
31
- border-radius: 5px;
32
- color: white;
33
- font-family: Arial, sans-serif;
34
- }
35
- .control-panel input {
36
- width: 50px;
37
- margin-right: 5px;
38
  }
39
- .color-picker {
 
 
 
 
 
 
 
 
40
  display: flex;
 
 
41
  align-items: center;
42
- margin-top: 10px;
43
  }
44
- .color-picker input[type="color"] {
45
- margin-right: 10px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  }
47
  </style>
48
  </head>
49
  <body>
50
- <div class="ui-panel">
51
- <button onclick="addPrimitive('box')">Add Box</button>
52
- <button onclick="addPrimitive('sphere')">Add Sphere</button>
53
- <button onclick="addPrimitive('cylinder')">Add Cylinder</button>
54
- <button onclick="addPrimitive('cone')">Add Cone</button>
55
- <button onclick="addPrimitive('torus')">Add Torus</button>
56
  </div>
57
 
58
- <div class="control-panel">
59
- <h3>Object Controls</h3>
60
- <p>Position:</p>
61
- <input id="px" type="number" step="0.1" placeholder="X">
62
- <input id="py" type="number" step="0.1" placeholder="Y">
63
- <input id="pz" type="number" step="0.1" placeholder="Z">
64
- <p>Rotation (degrees):</p>
65
- <input id="rx" type="number" step="1" placeholder="X">
66
- <input id="ry" type="number" step="1" placeholder="Y">
67
- <input id="rz" type="number" step="1" placeholder="Z">
68
- <p>Rotation Velocity (degrees/second):</p>
69
- <input id="rvx" type="number" step="1" placeholder="X">
70
- <input id="rvy" type="number" step="1" placeholder="Y">
71
- <input id="rvz" type="number" step="1" placeholder="Z">
72
- <button onclick="applyTransform()">Apply Transform</button>
73
- <button onclick="placeInFrontOfCamera()">Place in Front of Camera</button>
74
- <div class="color-picker">
75
- <input type="color" id="colorPicker" value="#4CC3D9">
76
- <button onclick="applyColor()">Apply Color</button>
77
- </div>
78
- </div>
79
-
80
- <a-scene>
81
- <a-sky color="#ECECEC"></a-sky>
82
- <a-entity id="rig" position="0 1.6 0">
83
- <a-camera look-controls wasd-controls>
84
- <a-cursor></a-cursor>
85
- </a-camera>
86
- </a-entity>
87
- </a-scene>
88
-
89
  <script>
90
- let selectedObject = null;
91
- let objects = [];
92
-
93
- function addPrimitive(type) {
94
- const scene = document.querySelector('a-scene');
95
- const newEntity = document.createElement('a-entity');
96
- newEntity.setAttribute('geometry', `primitive: ${type}`);
97
- newEntity.setAttribute('material', 'color: #4CC3D9');
98
- newEntity.setAttribute('class', 'editable');
99
- newEntity.addEventListener('click', function() { selectObject(this); });
100
- newEntity.rotationVelocity = { x: 0, y: 30, z: 0 }; // Default rotation velocity
101
- scene.appendChild(newEntity);
102
- objects.push(newEntity);
103
- placeInFrontOfCamera(newEntity);
104
- }
105
-
106
- function selectObject(obj) {
107
- if (selectedObject) {
108
- selectedObject.setAttribute('material', 'color', selectedObject.getAttribute('material').color);
109
- }
110
- selectedObject = obj;
111
- document.getElementById('colorPicker').value = selectedObject.getAttribute('material').color;
112
- selectedObject.setAttribute('material', 'color', '#FF0000');
113
- updateTransformInputs(selectedObject);
114
- }
115
-
116
- function updateTransformInputs(obj) {
117
- const position = obj.getAttribute('position');
118
- document.getElementById('px').value = position.x.toFixed(2);
119
- document.getElementById('py').value = position.y.toFixed(2);
120
- document.getElementById('pz').value = position.z.toFixed(2);
121
 
122
- const rotation = obj.getAttribute('rotation');
123
- document.getElementById('rx').value = rotation.x.toFixed(2);
124
- document.getElementById('ry').value = rotation.y.toFixed(2);
125
- document.getElementById('rz').value = rotation.z.toFixed(2);
126
-
127
- document.getElementById('rvx').value = obj.rotationVelocity.x;
128
- document.getElementById('rvy').value = obj.rotationVelocity.y;
129
- document.getElementById('rvz').value = obj.rotationVelocity.z;
130
- }
131
-
132
- function applyTransform() {
133
- if (!selectedObject) {
134
- alert('Please select an object first');
135
- return;
136
- }
137
-
138
- const px = parseFloat(document.getElementById('px').value) || 0;
139
- const py = parseFloat(document.getElementById('py').value) || 0;
140
- const pz = parseFloat(document.getElementById('pz').value) || 0;
141
- const rx = parseFloat(document.getElementById('rx').value) || 0;
142
- const ry = parseFloat(document.getElementById('ry').value) || 0;
143
- const rz = parseFloat(document.getElementById('rz').value) || 0;
144
- const rvx = parseFloat(document.getElementById('rvx').value) || 0;
145
- const rvy = parseFloat(document.getElementById('rvy').value) || 0;
146
- const rvz = parseFloat(document.getElementById('rvz').value) || 0;
147
-
148
- selectedObject.setAttribute('position', `${px} ${py} ${pz}`);
149
- selectedObject.setAttribute('rotation', `${rx} ${ry} ${rz}`);
150
- selectedObject.rotationVelocity = { x: rvx, y: rvy, z: rvz };
151
- }
152
-
153
- function placeInFrontOfCamera(obj = null) {
154
- const targetObject = obj || selectedObject;
155
- if (!targetObject) {
156
- alert('Please select an object first');
157
- return;
158
- }
159
-
160
- const camera = document.querySelector('[camera]');
161
- const cameraPosition = camera.object3D.position;
162
- const cameraRotation = camera.object3D.rotation;
163
-
164
- // Calculate the direction the camera is looking
165
- const direction = new THREE.Vector3(0, 0, -1);
166
- direction.applyQuaternion(camera.object3D.quaternion);
167
-
168
- // Set the distance to be 3 units away from the camera
169
- const distance = 3;
170
 
171
- // Calculate the new position
172
- const newPosition = new THREE.Vector3(
173
- cameraPosition.x + direction.x * distance,
174
- cameraPosition.y + direction.y * distance,
175
- cameraPosition.z + direction.z * distance
176
- );
177
-
178
- targetObject.setAttribute('position', newPosition);
179
 
180
- // Update position inputs if the object is selected
181
- if (targetObject === selectedObject) {
182
- updateTransformInputs(targetObject);
183
- }
184
- }
 
 
 
 
 
 
 
 
 
 
185
 
186
- function applyColor() {
187
- if (!selectedObject) {
188
- alert('Please select an object first');
189
- return;
 
 
 
 
 
 
 
 
 
190
  }
191
- const color = document.getElementById('colorPicker').value;
192
- selectedObject.setAttribute('material', 'color', color);
193
  }
194
 
195
- function animateObjects() {
196
- objects.forEach(obj => {
197
- const currentRotation = obj.getAttribute('rotation');
198
- const newRotation = {
199
- x: (currentRotation.x + obj.rotationVelocity.x * 0.016) % 360, // 0.016 is approximately 1/60, assuming 60 FPS
200
- y: (currentRotation.y + obj.rotationVelocity.y * 0.016) % 360,
201
- z: (currentRotation.z + obj.rotationVelocity.z * 0.016) % 360
202
- };
203
- obj.setAttribute('rotation', newRotation);
204
  });
205
- requestAnimationFrame(animateObjects);
206
  }
207
 
208
- // Event listener for object selection
209
- document.querySelector('a-scene').addEventListener('click', (event) => {
210
- if (event.detail.intersectedEl && event.detail.intersectedEl.classList.contains('editable')) {
211
- selectObject(event.detail.intersectedEl);
212
  }
213
  });
214
 
215
- // Start the animation loop
216
- animateObjects();
 
 
 
 
 
217
  </script>
218
  </body>
219
  </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>Chord Arpeggio Pad</title>
7
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/tone/14.8.49/Tone.js"></script>
8
  <style>
9
+ body {
 
 
 
 
 
 
 
 
10
  font-family: Arial, sans-serif;
11
+ display: flex;
12
+ justify-content: center;
13
+ align-items: center;
14
+ height: 100vh;
15
+ margin: 0;
16
+ background-color: #121212;
17
+ color: #ffffff;
18
  }
19
+ .container {
20
+ text-align: center;
 
 
21
  }
22
+ .arpeggio-pad {
23
+ display: grid;
24
+ grid-template-columns: repeat(4, 1fr);
25
+ gap: 10px;
26
+ margin-bottom: 20px;
 
 
 
 
 
 
 
 
 
27
  }
28
+ .pad {
29
+ width: 80px;
30
+ height: 80px;
31
+ font-size: 14px;
32
+ border: none;
33
+ color: white;
34
+ cursor: pointer;
35
+ transition: all 0.3s;
36
+ border-radius: 8px;
37
  display: flex;
38
+ flex-direction: column;
39
+ justify-content: center;
40
  align-items: center;
 
41
  }
42
+ .pad:hover {
43
+ opacity: 0.8;
44
+ }
45
+ .pad:active, .pad.active {
46
+ transform: scale(0.95);
47
+ box-shadow: 0 0 15px rgba(255, 255, 255, 0.5);
48
+ }
49
+ h1 {
50
+ margin-bottom: 20px;
51
+ }
52
+ #effectsButton {
53
+ font-size: 18px;
54
+ padding: 10px 20px;
55
+ background-color: #4CAF50;
56
+ border: none;
57
+ color: white;
58
+ cursor: pointer;
59
+ border-radius: 5px;
60
+ transition: background-color 0.3s;
61
+ }
62
+ #effectsButton:hover {
63
+ background-color: #45a049;
64
+ }
65
+ #effectsButton.active {
66
+ background-color: #e91e63;
67
  }
68
  </style>
69
  </head>
70
  <body>
71
+ <div class="container">
72
+ <h1>Chord Arpeggio Pad</h1>
73
+ <div class="arpeggio-pad" id="arpeggiopad"></div>
74
+ <button id="effectsButton">Effects: OFF</button>
 
 
75
  </div>
76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  <script>
78
+ const arpeggiopad = document.getElementById('arpeggiopad');
79
+ const effectsButton = document.getElementById('effectsButton');
80
+ const synth = new Tone.PolySynth(Tone.Synth).toDestination();
81
+
82
+ // Effects chain
83
+ const distortion = new Tone.Distortion(0.8).toDestination();
84
+ const reverb = new Tone.Reverb(2).toDestination();
85
+ let effectsOn = false;
86
+
87
+ const arpeggios = [
88
+ // C Major (I)
89
+ { chord: 'C', notes: ['C4', 'E4', 'G4', 'C5'], color: '#FF0000' },
90
+ { chord: 'C', notes: ['E4', 'G4', 'C5', 'E5'], color: '#FF4000' },
91
+ { chord: 'C', notes: ['G4', 'C5', 'E5', 'G5'], color: '#FF8000' },
92
+ { chord: 'C', notes: ['C5', 'E5', 'G5', 'C6'], color: '#FFC000' },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
 
94
+ // F Major (IV)
95
+ { chord: 'F', notes: ['F4', 'A4', 'C5', 'F5'], color: '#FFFF00' },
96
+ { chord: 'F', notes: ['A4', 'C5', 'F5', 'A5'], color: '#C0FF00' },
97
+ { chord: 'F', notes: ['C5', 'F5', 'A5', 'C6'], color: '#80FF00' },
98
+ { chord: 'F', notes: ['F5', 'A5', 'C6', 'F6'], color: '#40FF00' },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
 
100
+ // G Major (V)
101
+ { chord: 'G', notes: ['G4', 'B4', 'D5', 'G5'], color: '#00FF00' },
102
+ { chord: 'G', notes: ['B4', 'D5', 'G5', 'B5'], color: '#00FF40' },
103
+ { chord: 'G', notes: ['D5', 'G5', 'B5', 'D6'], color: '#00FF80' },
104
+ { chord: 'G', notes: ['G5', 'B5', 'D6', 'G6'], color: '#00FFC0' },
 
 
 
105
 
106
+ // Am (vi)
107
+ { chord: 'Am', notes: ['A4', 'C5', 'E5', 'A5'], color: '#00FFFF' },
108
+ { chord: 'Am', notes: ['C5', 'E5', 'A5', 'C6'], color: '#00C0FF' },
109
+ { chord: 'Am', notes: ['E5', 'A5', 'C6', 'E6'], color: '#0080FF' },
110
+ { chord: 'Am', notes: ['A5', 'C6', 'E6', 'A6'], color: '#0040FF' }
111
+ ];
112
+
113
+ arpeggios.forEach(({ chord, notes, color }, index) => {
114
+ const pad = document.createElement('button');
115
+ pad.innerHTML = `${chord}<br>${notes[0]}-${notes[3]}`;
116
+ pad.className = 'pad';
117
+ pad.dataset.notes = JSON.stringify(notes);
118
+ pad.style.backgroundColor = color;
119
+ arpeggiopad.appendChild(pad);
120
+ });
121
 
122
+ function toggleEffects() {
123
+ effectsOn = !effectsOn;
124
+ if (effectsOn) {
125
+ synth.disconnect();
126
+ synth.connect(distortion);
127
+ synth.connect(reverb);
128
+ effectsButton.textContent = 'Effects: ON';
129
+ effectsButton.classList.add('active');
130
+ } else {
131
+ synth.disconnect();
132
+ synth.toDestination();
133
+ effectsButton.textContent = 'Effects: OFF';
134
+ effectsButton.classList.remove('active');
135
  }
 
 
136
  }
137
 
138
+ function playArpeggio(notes, pad) {
139
+ pad.classList.add('active');
140
+ const now = Tone.now();
141
+ notes.forEach((note, index) => {
142
+ synth.triggerAttackRelease(note, "8n", now + index * 0.2);
 
 
 
 
143
  });
144
+ setTimeout(() => pad.classList.remove('active'), notes.length * 200);
145
  }
146
 
147
+ arpeggiopad.addEventListener('mousedown', (e) => {
148
+ if (e.target.classList.contains('pad')) {
149
+ const notes = JSON.parse(e.target.dataset.notes);
150
+ playArpeggio(notes, e.target);
151
  }
152
  });
153
 
154
+ effectsButton.addEventListener('click', toggleEffects);
155
+
156
+ // Start audio context on user interaction
157
+ document.addEventListener('click', async () => {
158
+ await Tone.start();
159
+ console.log('Audio is ready');
160
+ }, { once: true });
161
  </script>
162
  </body>
163
  </html>