1
- import { Dot } from "./dot-physics .js"
2
- import { getWordType , addWordToCanvas } from "./word-processing .js"
3
- import { playDotSound , playBaseSound } from "./scene- audio.js" ;
4
- import { loadIntsruments , instruments } from "./scene- audio.js" ;
1
+ import { Dot } from "./dot.js"
2
+ import { getWordType , addWordToCanvas } from "./words .js"
3
+ import { playDotSound , playBaseSound } from "./audio.js" ;
4
+ import { loadIntsruments , instruments , metroSynth } from "./audio.js" ;
5
5
6
6
let fontStyles = { } ;
7
7
let scales = { } ; // where all scales will be stored
8
8
let currentScale = [ ] ; // active scale during playback
9
+
9
10
export class ScrollingScene {
10
11
constructor ( canvas , inputElement ) {
11
12
this . mainCtx = canvas . getContext ( "2d" ) ;
@@ -23,39 +24,10 @@ export class ScrollingScene {
23
24
this . wordsCanvas . width = this . width * 5 ;
24
25
this . wordsCanvas . height = this . height ;
25
26
this . wordsCtx = this . wordsCanvas . getContext ( "2d" , { willReadFrequently : true } ) ;
26
- // document.body.appendChild(this.wordsCanvas);
27
27
this . inputElement = inputElement ;
28
28
this . dot = new Dot ( 1 , 5 ) ;
29
- this . dotXTarget = this . dot . x ;
30
-
29
+ this . dotXTarget = this . dot . x ; // where the dot should be
31
30
this . clearSentenceBuffer = false ;
32
- this . inputElement . addEventListener ( "input" , e => {
33
- const value = e . target . value ;
34
- const lastChar = value [ value . length - 1 ] ;
35
-
36
- if ( this . clearSentenceBuffer ) {
37
- this . sentenceBuffer = "" ;
38
- this . clearSentenceBuffer = false ;
39
- }
40
-
41
- if ( ( lastChar === " " || lastChar === "\n" ) ) {
42
- this . wordNeedsUpdate = true ;
43
- this . sentenceBuffer = this . sentenceBuffer + " " + value ;
44
- input . value = "" ;
45
- const punctuationRegex = / [ . , ! ? ; : ] / ;
46
- if ( punctuationRegex . test ( this . wordBuffer ) ) {
47
- this . clearSentenceBuffer = true ;
48
- }
49
- } else {
50
- this . wordBuffer = value ;
51
- }
52
-
53
- const wordBufferContainer = document . getElementById ( "word-buffer-container" ) ;
54
- wordBufferContainer . innerText = `Word: ${ this . wordBuffer } ` ;
55
- const sentenceBufferContainer = document . getElementById ( "sentence-buffer-container" ) ;
56
- sentenceBufferContainer . innerText = `Sentence: ${ this . sentenceBuffer } ` ;
57
- } ) ;
58
-
59
31
this . updateScene = false ;
60
32
}
61
33
@@ -70,10 +42,14 @@ export class ScrollingScene {
70
42
}
71
43
72
44
addWordToCanvas ( this . wordsCtx , this . wordBuffer , this , this . fontStyle ) ;
73
- const wordTypeContainer = document . getElementById ( "word-type-container" ) ;
74
- wordTypeContainer . innerText = wordType ;
75
45
this . wordBuffer = "" ;
76
46
this . wordNeedsUpdate = false ;
47
+
48
+ // Debugging info
49
+ const wordTypeContainer = document . getElementById ( "word-type-container" ) ;
50
+ if ( wordTypeContainer ) {
51
+ wordTypeContainer . innerText = wordType ;
52
+ }
77
53
}
78
54
79
55
const wordsImgBuffer = this . wordsCtx . getImageData ( 0 , 0 , this . width , this . height ) ;
@@ -97,24 +73,17 @@ export class ScrollingScene {
97
73
Tone . Transport . start ( ) ;
98
74
this . metronomeStarted = true ;
99
75
}
76
+
100
77
// Handle dot effects
101
- // const soundOn = document.getElementById("toggleSound").checked;
102
- // if (soundOn) {
103
78
if ( this . dot . hasCollidedWithGround ) {
104
- try {
105
- // playBaseSound(this.dot);
106
- playDotSound ( this . dot , "piano" , 0 , currentScale , "4n" ) ;
107
- } catch ( e ) {
108
- console . warning ( "Error playing sound:" , e ) ;
109
- }
79
+ // Ground bounce
80
+ this . dot . colour = "red" ;
110
81
} else if ( this . dot . inFloatingMode ) {
111
82
// Floating mode
112
83
this . dot . colour = "green" ;
113
- playDotSound ( this . dot , "guitar-nylon" , - 20 , currentScale , "16n" ) ;
114
84
} else if ( this . dot . hasCollided ) {
115
85
// Collision
116
86
this . dot . colour = "red" ;
117
- playDotSound ( this . dot , "piano" , 0 , currentScale , "8n" ) ;
118
87
} else {
119
88
// Normal mode
120
89
this . dot . colour = "blue" ;
@@ -124,6 +93,24 @@ export class ScrollingScene {
124
93
this . mainCtx . fillStyle = "black" ;
125
94
// drawCursor(this.mainCtx, this.cursorX, this.cursorY);
126
95
}
96
+
97
+ play ( ) {
98
+ if ( this . dot . hasCollidedWithGround ) {
99
+ // Ground bounce
100
+ try {
101
+ playDotSound ( this . dot , "piano" , "C2" , "2n" , - 10 , "4n" ) ;
102
+ } catch ( e ) {
103
+ console . warning ( "Error playing sound:" , e ) ;
104
+ }
105
+ } else if ( this . dot . inFloatingMode ) {
106
+ // Floating mode
107
+ playDotSound ( this . dot , new Tone . MembraneSynth ( ) . toDestination ( ) ,
108
+ "all" , "16n" , - 20 , "16n" ) ;
109
+ } else if ( this . dot . hasCollided ) {
110
+ // Collision
111
+ playDotSound ( this . dot , "piano" , currentScale , "8n" , 0 , "8n" ) ;
112
+ }
113
+ }
127
114
}
128
115
129
116
function drawCursor ( ctx , cursorX , cursorY ) {
@@ -213,9 +200,46 @@ function traceWordOutline(startX, startY, word) {
213
200
}
214
201
215
202
export async function setupScene ( scene , bpm = 120 ) {
216
- // Hide start button
217
- const startButton = document . getElementById ( "updateScene" ) ;
218
- startButton . style . display = "none" ;
203
+ // User input
204
+ scene . inputElement . addEventListener ( "input" , e => {
205
+ const value = e . target . value ;
206
+ const lastChar = value [ value . length - 1 ] ;
207
+
208
+ if ( scene . clearSentenceBuffer ) {
209
+ scene . sentenceBuffer = "" ;
210
+ scene . clearSentenceBuffer = false ;
211
+ }
212
+
213
+ if ( ( lastChar === " " || lastChar === "\n" ) ) {
214
+ scene . wordNeedsUpdate = true ;
215
+ scene . sentenceBuffer = scene . sentenceBuffer + " " + value ;
216
+ input . value = "" ;
217
+ const punctuationRegex = / [ . , ! ? ; : ] / ;
218
+ if ( punctuationRegex . test ( scene . wordBuffer ) ) {
219
+ scene . clearSentenceBuffer = true ;
220
+ }
221
+ } else {
222
+ scene . wordBuffer = value ;
223
+ }
224
+
225
+ // Debugging info
226
+ const wordBufferContainer = document . getElementById ( "word-buffer-container" ) ;
227
+ if ( wordBufferContainer ) {
228
+ wordBufferContainer . innerText = `Word: ${ scene . wordBuffer } ` ;
229
+ }
230
+ const sentenceBufferContainer = document . getElementById ( "sentence-buffer-container" ) ;
231
+ if ( sentenceBufferContainer ) {
232
+ sentenceBufferContainer . innerText = `Sentence: ${ scene . sentenceBuffer } ` ;
233
+ }
234
+ } ) ;
235
+
236
+ scene . inputElement . addEventListener ( "keydown" , ( e ) => {
237
+ if ( ! ( e . key === "Backspace" || e . key === "Delete" ) ) {
238
+ return ;
239
+ }
240
+ playDotSound ( null , "piano" , "C7" , "4n" , - 10 , "8n" ) ;
241
+ } ) ;
242
+
219
243
// Scene & audio
220
244
scene . bpm = bpm ;
221
245
scene . lastTimestamp = null ;
@@ -233,11 +257,10 @@ export async function setupScene(scene, bpm = 120) {
233
257
Object . assign ( instruments , loaded ) ;
234
258
console . log ( "SampleLibrary loaded: " , Object . keys ( instruments ) ) ;
235
259
await Tone . loaded ( ) ;
236
- instruments [ "piano" ] . toDestination ( ) ;
237
- instruments [ "piano" ] . triggerAttackRelease ( "C4" , "8n" , Tone . now ( ) ) ;
238
- const metroSynth = new Tone . MembraneSynth ( ) . toDestination ( ) ;
260
+
239
261
Tone . Transport . scheduleRepeat ( ( time ) => {
240
- metroSynth . triggerAttackRelease ( "C3" , "8n" , time ) ;
262
+ metroSynth . triggerAttackRelease ( "G2" , "8n" , time ) ;
263
+ // metroSynth.triggerAttackRelease(currentScale[0], "8n", time);
241
264
} , "4n" ) ;
242
265
Tone . Transport . scheduleRepeat ( ( ) => {
243
266
const pos = Tone . Transport . position . split ( '.' ) [ 0 ] ;
@@ -285,9 +308,6 @@ export async function setupScene(scene, bpm = 120) {
285
308
scene . dot . maxSpeed =
286
309
Math . sqrt ( 2 * Math . abs ( scene . dot . g ) * ( scene . dot . height - scene . dot . y - scene . dot . r / scene . dot . yScale ) ) ;
287
310
console . log ( "max speed:" , scene . dot . maxSpeed ) ;
288
-
289
- // Show start button
290
- startButton . style . display = "inline" ;
291
311
}
292
312
293
313
async function loadFontStyles ( src ) {
0 commit comments