Mercurial > hg > webaudioevaluationtool
comparison interfaces/horizontal-sliders.js @ 2538:464c6c6692d6
Beautified entire project.
author | Nicholas Jillings <nicholas.jillings@mail.bcu.ac.uk> |
---|---|
date | Mon, 14 Nov 2016 14:17:03 +0000 |
parents | 1647bb807186 |
children | 342ef7948c47 |
comparison
equal
deleted
inserted
replaced
2536:527020a63203 | 2538:464c6c6692d6 |
---|---|
1 // Once this is loaded and parsed, begin execution | 1 // Once this is loaded and parsed, begin execution |
2 loadInterface(); | 2 loadInterface(); |
3 | 3 |
4 function loadInterface() { | 4 function loadInterface() { |
5 // Use this to do any one-time page / element construction. For instance, placing any stationary text objects, | 5 // Use this to do any one-time page / element construction. For instance, placing any stationary text objects, |
6 // holding div's, or setting up any nodes which are present for the entire test sequence | 6 // holding div's, or setting up any nodes which are present for the entire test sequence |
7 | 7 |
8 // The injection point into the HTML page | 8 // The injection point into the HTML page |
9 interfaceContext.insertPoint = document.getElementById("topLevelBody"); | 9 interfaceContext.insertPoint = document.getElementById("topLevelBody"); |
10 var testContent = document.createElement('div'); | 10 var testContent = document.createElement('div'); |
11 testContent.id = 'testContent'; | 11 testContent.id = 'testContent'; |
12 | 12 |
13 // Create the top div for the Title element | 13 // Create the top div for the Title element |
14 var titleAttr = specification.title; | 14 var titleAttr = specification.title; |
15 var title = document.createElement('div'); | 15 var title = document.createElement('div'); |
16 title.className = "title"; | 16 title.className = "title"; |
17 title.align = "center"; | 17 title.align = "center"; |
18 var titleSpan = document.createElement('span'); | 18 var titleSpan = document.createElement('span'); |
19 titleSpan.id="test-title"; | 19 titleSpan.id = "test-title"; |
20 | 20 |
21 // Set title to that defined in XML, else set to default | 21 // Set title to that defined in XML, else set to default |
22 if (titleAttr != undefined) { | 22 if (titleAttr != undefined) { |
23 titleSpan.textContent = titleAttr; | 23 titleSpan.textContent = titleAttr; |
24 } else { | 24 } else { |
25 titleSpan.textContent = 'Listening test'; | 25 titleSpan.textContent = 'Listening test'; |
26 } | 26 } |
27 // Insert the titleSpan element into the title div element. | 27 // Insert the titleSpan element into the title div element. |
28 title.appendChild(titleSpan); | 28 title.appendChild(titleSpan); |
29 | 29 |
30 var pagetitle = document.createElement('div'); | 30 var pagetitle = document.createElement('div'); |
31 pagetitle.className = "pageTitle"; | 31 pagetitle.className = "pageTitle"; |
32 pagetitle.align = "center"; | 32 pagetitle.align = "center"; |
33 var titleSpan = document.createElement('span'); | 33 var titleSpan = document.createElement('span'); |
34 titleSpan.id = "pageTitle"; | 34 titleSpan.id = "pageTitle"; |
35 pagetitle.appendChild(titleSpan); | 35 pagetitle.appendChild(titleSpan); |
36 | 36 |
37 // Create Interface buttons! | 37 // Create Interface buttons! |
38 var interfaceButtons = document.createElement('div'); | 38 var interfaceButtons = document.createElement('div'); |
39 interfaceButtons.id = 'interface-buttons'; | 39 interfaceButtons.id = 'interface-buttons'; |
40 interfaceButtons.style.height = '25px'; | 40 interfaceButtons.style.height = '25px'; |
41 | 41 |
42 // Create playback start/stop points | 42 // Create playback start/stop points |
43 var playback = document.createElement("button"); | 43 var playback = document.createElement("button"); |
44 playback.innerHTML = 'Stop'; | 44 playback.innerHTML = 'Stop'; |
45 playback.id = 'playback-button'; | 45 playback.id = 'playback-button'; |
46 playback.style.float = 'left'; | 46 playback.style.float = 'left'; |
47 // onclick function. Check if it is playing or not, call the correct function in the | 47 // onclick function. Check if it is playing or not, call the correct function in the |
48 // audioEngine, change the button text to reflect the next state. | 48 // audioEngine, change the button text to reflect the next state. |
49 playback.onclick = function() { | 49 playback.onclick = function () { |
50 if (audioEngineContext.status == 1) { | 50 if (audioEngineContext.status == 1) { |
51 audioEngineContext.stop(); | 51 audioEngineContext.stop(); |
52 this.innerHTML = 'Stop'; | 52 this.innerHTML = 'Stop'; |
53 var time = audioEngineContext.timer.getTestTime(); | 53 var time = audioEngineContext.timer.getTestTime(); |
54 console.log('Stopped at ' + time); // DEBUG/SAFETY | 54 console.log('Stopped at ' + time); // DEBUG/SAFETY |
55 } | 55 } |
56 }; | 56 }; |
57 // Create Submit (save) button | 57 // Create Submit (save) button |
58 var submit = document.createElement("button"); | 58 var submit = document.createElement("button"); |
59 submit.innerHTML = 'Next'; | 59 submit.innerHTML = 'Next'; |
60 submit.onclick = buttonSubmitClick; | 60 submit.onclick = buttonSubmitClick; |
61 submit.id = 'submit-button'; | 61 submit.id = 'submit-button'; |
62 submit.style.float = 'left'; | 62 submit.style.float = 'left'; |
63 // Append the interface buttons into the interfaceButtons object. | 63 // Append the interface buttons into the interfaceButtons object. |
64 interfaceButtons.appendChild(playback); | 64 interfaceButtons.appendChild(playback); |
65 interfaceButtons.appendChild(submit); | 65 interfaceButtons.appendChild(submit); |
66 | 66 |
67 // Create outside reference holder | 67 // Create outside reference holder |
68 var outsideRef = document.createElement("div"); | 68 var outsideRef = document.createElement("div"); |
69 outsideRef.id = "outside-reference-holder"; | 69 outsideRef.id = "outside-reference-holder"; |
70 | 70 |
71 // Create a slider box | 71 // Create a slider box |
72 var sliderBox = document.createElement('div'); | 72 var sliderBox = document.createElement('div'); |
73 sliderBox.style.width = "100%"; | 73 sliderBox.style.width = "100%"; |
74 sliderBox.style.height = window.innerHeight - 200+12 + 'px'; | 74 sliderBox.style.height = window.innerHeight - 200 + 12 + 'px'; |
75 sliderBox.style.marginBottom = '10px'; | 75 sliderBox.style.marginBottom = '10px'; |
76 sliderBox.id = 'slider'; | 76 sliderBox.id = 'slider'; |
77 var scaleHolder = document.createElement('div'); | 77 var scaleHolder = document.createElement('div'); |
78 scaleHolder.id = "scale-holder"; | 78 scaleHolder.id = "scale-holder"; |
79 scaleHolder.style.marginLeft = "107px"; | 79 scaleHolder.style.marginLeft = "107px"; |
80 sliderBox.appendChild(scaleHolder); | 80 sliderBox.appendChild(scaleHolder); |
81 var scaleText = document.createElement('div'); | 81 var scaleText = document.createElement('div'); |
82 scaleText.id = "scale-text-holder"; | 82 scaleText.id = "scale-text-holder"; |
83 scaleText.style.height = "25px"; | 83 scaleText.style.height = "25px"; |
84 scaleText.style.width = "100%"; | 84 scaleText.style.width = "100%"; |
85 scaleHolder.appendChild(scaleText); | 85 scaleHolder.appendChild(scaleText); |
86 var scaleCanvas = document.createElement('canvas'); | 86 var scaleCanvas = document.createElement('canvas'); |
87 scaleCanvas.id = "scale-canvas"; | 87 scaleCanvas.id = "scale-canvas"; |
88 scaleCanvas.style.marginLeft = "100px"; | 88 scaleCanvas.style.marginLeft = "100px"; |
89 scaleHolder.appendChild(scaleCanvas); | 89 scaleHolder.appendChild(scaleCanvas); |
90 var sliderObjectHolder = document.createElement('div'); | 90 var sliderObjectHolder = document.createElement('div'); |
91 sliderObjectHolder.id = 'slider-holder'; | 91 sliderObjectHolder.id = 'slider-holder'; |
92 sliderObjectHolder.align = "center"; | 92 sliderObjectHolder.align = "center"; |
93 sliderBox.appendChild(sliderObjectHolder); | 93 sliderBox.appendChild(sliderObjectHolder); |
94 | 94 |
95 // Global parent for the comment boxes on the page | 95 // Global parent for the comment boxes on the page |
96 var feedbackHolder = document.createElement('div'); | 96 var feedbackHolder = document.createElement('div'); |
97 feedbackHolder.id = 'feedbackHolder'; | 97 feedbackHolder.id = 'feedbackHolder'; |
98 | 98 |
99 testContent.style.zIndex = 1; | 99 testContent.style.zIndex = 1; |
100 interfaceContext.insertPoint.innerHTML = ""; // Clear the current schema | 100 interfaceContext.insertPoint.innerHTML = ""; // Clear the current schema |
101 | 101 |
102 // Inject into HTML | 102 // Inject into HTML |
103 testContent.appendChild(title); // Insert the title | 103 testContent.appendChild(title); // Insert the title |
104 testContent.appendChild(pagetitle); | 104 testContent.appendChild(pagetitle); |
105 testContent.appendChild(interfaceButtons); | 105 testContent.appendChild(interfaceButtons); |
106 testContent.appendChild(outsideRef); | 106 testContent.appendChild(outsideRef); |
107 testContent.appendChild(sliderBox); | 107 testContent.appendChild(sliderBox); |
108 testContent.appendChild(feedbackHolder); | 108 testContent.appendChild(feedbackHolder); |
109 interfaceContext.insertPoint.appendChild(testContent); | 109 interfaceContext.insertPoint.appendChild(testContent); |
110 | 110 |
111 // Load the full interface | 111 // Load the full interface |
112 testState.initialise(); | 112 testState.initialise(); |
113 testState.advanceState(); | 113 testState.advanceState(); |
114 }; | 114 }; |
115 | 115 |
116 function loadTest(page) | 116 function loadTest(page) { |
117 { | 117 // Called each time a new test page is to be build. The page specification node is the only item passed in |
118 // Called each time a new test page is to be build. The page specification node is the only item passed in | 118 var id = page.id; |
119 var id = page.id; | 119 |
120 | 120 var feedbackHolder = document.getElementById('feedbackHolder'); |
121 var feedbackHolder = document.getElementById('feedbackHolder'); | |
122 feedbackHolder.innerHTML = ""; | 121 feedbackHolder.innerHTML = ""; |
123 | 122 |
124 var interfaceObj = page.interfaces; | 123 var interfaceObj = page.interfaces; |
125 if (interfaceObj.length > 1) | 124 if (interfaceObj.length > 1) { |
126 { | 125 console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node"); |
127 console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node"); | 126 } |
128 } | 127 interfaceObj = interfaceObj[0]; |
129 interfaceObj = interfaceObj[0]; | 128 |
130 | |
131 // Set the page title | 129 // Set the page title |
132 if (typeof page.title == "string" && page.title.length > 0) { | 130 if (typeof page.title == "string" && page.title.length > 0) { |
133 document.getElementById("test-title").textContent = page.title | 131 document.getElementById("test-title").textContent = page.title |
134 } | 132 } |
135 | 133 |
136 if(interfaceObj.title != null) | 134 if (interfaceObj.title != null) { |
137 { | 135 document.getElementById("pageTitle").textContent = interfaceObj.title; |
138 document.getElementById("pageTitle").textContent = interfaceObj.title; | 136 } |
139 } | 137 |
140 | 138 // Delete outside reference |
141 // Delete outside reference | 139 document.getElementById("outside-reference-holder").innerHTML = ""; |
142 document.getElementById("outside-reference-holder").innerHTML = ""; | 140 |
143 | 141 var sliderBox = document.getElementById('slider-holder'); |
144 var sliderBox = document.getElementById('slider-holder'); | 142 sliderBox.innerHTML = ""; |
145 sliderBox.innerHTML = ""; | 143 |
146 | 144 var commentBoxPrefix = "Comment on track"; |
147 var commentBoxPrefix = "Comment on track"; | 145 if (interfaceObj.commentBoxPrefix != undefined) { |
148 if (interfaceObj.commentBoxPrefix != undefined) { | 146 commentBoxPrefix = interfaceObj.commentBoxPrefix; |
149 commentBoxPrefix = interfaceObj.commentBoxPrefix; | 147 } |
150 } | 148 var loopPlayback = page.loop; |
151 var loopPlayback = page.loop; | 149 |
152 | 150 $(page.commentQuestions).each(function (index, element) { |
153 $(page.commentQuestions).each(function(index,element) { | 151 var node = interfaceContext.createCommentQuestion(element); |
154 var node = interfaceContext.createCommentQuestion(element); | 152 feedbackHolder.appendChild(node.holder); |
155 feedbackHolder.appendChild(node.holder); | 153 }); |
156 }); | 154 |
157 | 155 // Find all the audioElements from the audioHolder |
158 // Find all the audioElements from the audioHolder | 156 var index = 0; |
159 var index = 0; | 157 $(page.audioElements).each(function (index, element) { |
160 $(page.audioElements).each(function(index,element){ | 158 // Find URL of track |
161 // Find URL of track | 159 // In this jQuery loop, variable 'this' holds the current audioElement. |
162 // In this jQuery loop, variable 'this' holds the current audioElement. | 160 |
163 | 161 var audioObject = audioEngineContext.newTrack(element); |
164 var audioObject = audioEngineContext.newTrack(element); | 162 if (element.type == 'outside-reference') { |
165 if (element.type == 'outside-reference') | 163 // Construct outside reference; |
166 { | 164 var orNode = new interfaceContext.outsideReferenceDOM(audioObject, index, document.getElementById("outside-reference-holder")); |
167 // Construct outside reference; | 165 audioObject.bindInterface(orNode); |
168 var orNode = new interfaceContext.outsideReferenceDOM(audioObject,index,document.getElementById("outside-reference-holder")); | 166 } else { |
169 audioObject.bindInterface(orNode); | 167 // Create a slider per track |
170 } else { | 168 switch (audioObject.specification.parent.label) { |
171 // Create a slider per track | |
172 switch(audioObject.specification.parent.label) { | |
173 case "none": | 169 case "none": |
174 label = ""; | 170 label = ""; |
175 break; | 171 break; |
176 case "letter": | 172 case "letter": |
177 label = String.fromCharCode(97 + index); | 173 label = String.fromCharCode(97 + index); |
178 break; | 174 break; |
179 case "capital": | 175 case "capital": |
180 label = String.fromCharCode(65 + index); | 176 label = String.fromCharCode(65 + index); |
181 break; | 177 break; |
182 default: | 178 default: |
183 label = ""+index; | 179 label = "" + index; |
184 break; | 180 break; |
185 } | 181 } |
186 var sliderObj = new sliderObject(audioObject,label); | 182 var sliderObj = new sliderObject(audioObject, label); |
187 | 183 |
188 if (typeof page.initialPosition === "number") | 184 if (typeof page.initialPosition === "number") { |
189 { | 185 // Set the values |
190 // Set the values | 186 sliderObj.slider.value = page.initalPosition; |
191 sliderObj.slider.value = page.initalPosition; | 187 } else { |
192 } else { | 188 // Distribute it randomnly |
193 // Distribute it randomnly | 189 sliderObj.slider.value = Math.random(); |
194 sliderObj.slider.value = Math.random(); | 190 } |
195 } | 191 sliderBox.appendChild(sliderObj.holder); |
196 sliderBox.appendChild(sliderObj.holder); | 192 audioObject.bindInterface(sliderObj); |
197 audioObject.bindInterface(sliderObj); | |
198 interfaceContext.commentBoxes.createCommentBox(audioObject); | 193 interfaceContext.commentBoxes.createCommentBox(audioObject); |
199 index += 1; | 194 index += 1; |
200 } | 195 } |
201 | 196 |
202 }); | 197 }); |
203 var interfaceOptions = specification.interfaces.options.concat(interfaceObj.options); | 198 var interfaceOptions = specification.interfaces.options.concat(interfaceObj.options); |
204 for (var option of interfaceOptions) | 199 for (var option of interfaceOptions) { |
205 { | 200 if (option.type == "show") { |
206 if (option.type == "show") | 201 switch (option.name) { |
207 { | |
208 switch(option.name) { | |
209 case "playhead": | 202 case "playhead": |
210 var playbackHolder = document.getElementById('playback-holder'); | 203 var playbackHolder = document.getElementById('playback-holder'); |
211 if (playbackHolder == null) | 204 if (playbackHolder == null) { |
212 { | |
213 playbackHolder = document.createElement('div'); | 205 playbackHolder = document.createElement('div'); |
214 playbackHolder.style.width = "100%"; | 206 playbackHolder.style.width = "100%"; |
215 playbackHolder.align = 'center'; | 207 playbackHolder.align = 'center'; |
216 playbackHolder.appendChild(interfaceContext.playhead.object); | 208 playbackHolder.appendChild(interfaceContext.playhead.object); |
217 feedbackHolder.appendChild(playbackHolder); | 209 feedbackHolder.appendChild(playbackHolder); |
218 } | 210 } |
219 break; | 211 break; |
220 case "page-count": | 212 case "page-count": |
221 var pagecountHolder = document.getElementById('page-count'); | 213 var pagecountHolder = document.getElementById('page-count'); |
222 if (pagecountHolder == null) | 214 if (pagecountHolder == null) { |
223 { | |
224 pagecountHolder = document.createElement('div'); | 215 pagecountHolder = document.createElement('div'); |
225 pagecountHolder.id = 'page-count'; | 216 pagecountHolder.id = 'page-count'; |
226 } | 217 } |
227 pagecountHolder.innerHTML = '<span>Page '+(testState.stateIndex+1)+' of '+testState.stateMap.length+'</span>'; | 218 pagecountHolder.innerHTML = '<span>Page ' + (testState.stateIndex + 1) + ' of ' + testState.stateMap.length + '</span>'; |
228 var inject = document.getElementById('interface-buttons'); | 219 var inject = document.getElementById('interface-buttons'); |
229 inject.appendChild(pagecountHolder); | 220 inject.appendChild(pagecountHolder); |
230 break; | 221 break; |
231 case "volume": | 222 case "volume": |
232 if (document.getElementById('master-volume-holder') == null) | 223 if (document.getElementById('master-volume-holder') == null) { |
233 { | |
234 feedbackHolder.appendChild(interfaceContext.volume.object); | 224 feedbackHolder.appendChild(interfaceContext.volume.object); |
235 } | 225 } |
236 break; | 226 break; |
237 case "comments": | 227 case "comments": |
238 interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder,true); | 228 interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder, true); |
239 break; | 229 break; |
240 } | 230 } |
241 } | 231 } |
242 } | 232 } |
243 // Auto-align | 233 // Auto-align |
244 resizeWindow(null); | 234 resizeWindow(null); |
245 } | 235 } |
246 | 236 |
247 function sliderObject(audioObject,label) | 237 function sliderObject(audioObject, label) { |
248 { | 238 // An example node, you can make this however you want for each audioElement. |
249 // An example node, you can make this however you want for each audioElement. | 239 // However, every audioObject (audioEngineContext.audioObject) MUST have an interface object with the following |
250 // However, every audioObject (audioEngineContext.audioObject) MUST have an interface object with the following | 240 // You attach them by calling audioObject.bindInterface( ) |
251 // You attach them by calling audioObject.bindInterface( ) | 241 this.parent = audioObject; |
252 this.parent = audioObject; | 242 |
253 | 243 this.holder = document.createElement('div'); |
254 this.holder = document.createElement('div'); | 244 this.title = document.createElement('div'); |
255 this.title = document.createElement('div'); | 245 this.slider = document.createElement('input'); |
256 this.slider = document.createElement('input'); | 246 this.play = document.createElement('button'); |
257 this.play = document.createElement('button'); | 247 |
258 | 248 this.holder.className = 'track-slider'; |
259 this.holder.className = 'track-slider'; | 249 this.holder.style.width = window.innerWidth - 200 + 'px'; |
260 this.holder.style.width = window.innerWidth-200 + 'px'; | 250 this.holder.appendChild(this.title); |
261 this.holder.appendChild(this.title); | 251 this.holder.appendChild(this.slider); |
262 this.holder.appendChild(this.slider); | 252 this.holder.appendChild(this.play); |
263 this.holder.appendChild(this.play); | 253 this.holder.setAttribute('trackIndex', audioObject.id); |
264 this.holder.setAttribute('trackIndex',audioObject.id); | 254 this.title.textContent = label; |
265 this.title.textContent = label; | 255 this.title.className = 'track-slider-title'; |
266 this.title.className = 'track-slider-title'; | 256 |
267 | 257 this.slider.type = "range"; |
268 this.slider.type = "range"; | 258 this.slider.className = "track-slider-range track-slider-not-moved"; |
269 this.slider.className = "track-slider-range track-slider-not-moved"; | 259 this.slider.min = "0"; |
270 this.slider.min = "0"; | 260 this.slider.max = "1"; |
271 this.slider.max = "1"; | 261 this.slider.step = "0.01"; |
272 this.slider.step = "0.01"; | 262 this.slider.style.width = window.innerWidth - 420 + 'px'; |
273 this.slider.style.width = window.innerWidth-420 + 'px'; | 263 this.slider.onchange = function () { |
274 this.slider.onchange = function() | 264 var time = audioEngineContext.timer.getTestTime(); |
275 { | 265 var id = Number(this.parentNode.getAttribute('trackIndex')); |
276 var time = audioEngineContext.timer.getTestTime(); | 266 audioEngineContext.audioObjects[id].metric.moved(time, this.value); |
277 var id = Number(this.parentNode.getAttribute('trackIndex')); | 267 console.log('slider ' + id + ' moved to ' + this.value + ' (' + time + ')'); |
278 audioEngineContext.audioObjects[id].metric.moved(time,this.value); | 268 $(this).removeClass('track-slider-not-moved'); |
279 console.log('slider '+id+' moved to '+this.value+' ('+time+')'); | 269 }; |
280 $(this).removeClass('track-slider-not-moved'); | 270 |
281 }; | 271 this.play.className = 'track-slider-button'; |
282 | 272 this.play.textContent = "Loading..."; |
283 this.play.className = 'track-slider-button'; | 273 this.play.value = audioObject.id; |
284 this.play.textContent = "Loading..."; | 274 this.play.disabled = true; |
285 this.play.value = audioObject.id; | 275 this.play.setAttribute("playstate", "ready"); |
286 this.play.disabled = true; | 276 this.play.onclick = function (event) { |
287 this.play.setAttribute("playstate","ready"); | 277 var id = Number(event.currentTarget.value); |
288 this.play.onclick = function(event) | 278 //audioEngineContext.metric.sliderPlayed(id); |
289 { | 279 if (event.currentTarget.getAttribute("playstate") == "ready") { |
290 var id = Number(event.currentTarget.value); | 280 audioEngineContext.play(id); |
291 //audioEngineContext.metric.sliderPlayed(id); | 281 } else if (event.currentTarget.getAttribute("playstate") == "playing") { |
292 if (event.currentTarget.getAttribute("playstate") == "ready") | 282 audioEngineContext.stop(); |
293 {audioEngineContext.play(id);} | 283 } |
294 else if (event.currentTarget.getAttribute("playstate") == "playing") | 284 }; |
295 {audioEngineContext.stop();} | 285 this.resize = function (event) { |
296 }; | 286 this.holder.style.width = window.innerWidth - 200 + 'px'; |
297 this.resize = function(event) | 287 this.slider.style.width = window.innerWidth - 420 + 'px'; |
298 { | 288 }; |
299 this.holder.style.width = window.innerWidth-200 + 'px'; | 289 this.enable = function () { |
300 this.slider.style.width = window.innerWidth-420 + 'px'; | 290 // This is used to tell the interface object that playback of this node is ready |
301 }; | 291 this.play.disabled = false; |
302 this.enable = function() | 292 this.play.textContent = "Play"; |
303 { | 293 $(this.slider).removeClass('track-slider-disabled'); |
304 // This is used to tell the interface object that playback of this node is ready | 294 }; |
305 this.play.disabled = false; | 295 this.updateLoading = function (progress) { |
306 this.play.textContent = "Play"; | 296 // progress is a value from 0 to 100 indicating the current download state of media files |
307 $(this.slider).removeClass('track-slider-disabled'); | 297 }; |
308 }; | 298 this.startPlayback = function () { |
309 this.updateLoading = function(progress) | |
310 { | |
311 // progress is a value from 0 to 100 indicating the current download state of media files | |
312 }; | |
313 this.startPlayback = function() | |
314 { | |
315 // Called when playback has begun | 299 // Called when playback has begun |
316 this.play.setAttribute("playstate","playing"); | 300 this.play.setAttribute("playstate", "playing"); |
317 $(".track-slider").removeClass('track-slider-playing'); | 301 $(".track-slider").removeClass('track-slider-playing'); |
318 $(this.holder).addClass('track-slider-playing'); | 302 $(this.holder).addClass('track-slider-playing'); |
319 var outsideReference = document.getElementById('outside-reference'); | 303 var outsideReference = document.getElementById('outside-reference'); |
320 if (outsideReference != null) { | 304 if (outsideReference != null) { |
321 $(outsideReference).removeClass('track-slider-playing'); | 305 $(outsideReference).removeClass('track-slider-playing'); |
322 } | 306 } |
323 }; | 307 }; |
324 this.stopPlayback = function() | 308 this.stopPlayback = function () { |
325 { | |
326 // Called when playback has stopped. This gets called even if playback never started! | 309 // Called when playback has stopped. This gets called even if playback never started! |
327 this.play.setAttribute("playstate","ready"); | 310 this.play.setAttribute("playstate", "ready"); |
328 $(this.holder).removeClass('track-slider-playing'); | 311 $(this.holder).removeClass('track-slider-playing'); |
329 }; | 312 }; |
330 this.getValue = function() | 313 this.getValue = function () { |
331 { | 314 // Return the current value of the object. If there is no value, return 0 |
332 // Return the current value of the object. If there is no value, return 0 | 315 return this.slider.value; |
333 return this.slider.value; | 316 }; |
334 }; | 317 this.getPresentedId = function () { |
335 this.getPresentedId = function() | 318 // Return the presented ID of the object. For instance, the APE has sliders starting from 0. Whilst AB has alphabetical scale |
336 { | 319 return this.title.textContent; |
337 // Return the presented ID of the object. For instance, the APE has sliders starting from 0. Whilst AB has alphabetical scale | 320 }; |
338 return this.title.textContent; | 321 this.canMove = function () { |
339 }; | 322 // Return either true or false if the interface object can be moved. AB / Reference cannot, whilst sliders can and therefore have a continuous scale. |
340 this.canMove = function() | 323 // These are checked primarily if the interface check option 'fragmentMoved' is enabled. |
341 { | 324 return true; |
342 // Return either true or false if the interface object can be moved. AB / Reference cannot, whilst sliders can and therefore have a continuous scale. | 325 }; |
343 // These are checked primarily if the interface check option 'fragmentMoved' is enabled. | 326 this.exportXMLDOM = function (audioObject) { |
344 return true; | 327 // Called by the audioObject holding this element to export the interface <value> node. |
345 }; | 328 // If there is no value node (such as outside reference), return null |
346 this.exportXMLDOM = function(audioObject) { | 329 // If there are multiple value nodes (such as multiple scale / 2D scales), return an array of nodes with each value node having an 'interfaceName' attribute |
347 // Called by the audioObject holding this element to export the interface <value> node. | 330 // Use storage.document.createElement('value'); to generate the XML node. |
348 // If there is no value node (such as outside reference), return null | 331 var node = storage.document.createElement('value'); |
349 // If there are multiple value nodes (such as multiple scale / 2D scales), return an array of nodes with each value node having an 'interfaceName' attribute | |
350 // Use storage.document.createElement('value'); to generate the XML node. | |
351 var node = storage.document.createElement('value'); | |
352 node.textContent = this.slider.value; | 332 node.textContent = this.slider.value; |
353 return node; | 333 return node; |
354 }; | 334 }; |
355 this.error = function() { | 335 this.error = function () { |
356 // audioObject has an error!! | 336 // audioObject has an error!! |
357 this.playback.textContent = "Error"; | 337 this.playback.textContent = "Error"; |
358 $(this.playback).addClass("error-colour"); | 338 $(this.playback).addClass("error-colour"); |
359 } | 339 } |
360 }; | 340 }; |
361 | 341 |
362 function resizeWindow(event) | 342 function resizeWindow(event) { |
363 { | 343 // Called on every window resize event, use this to scale your page properly |
364 // Called on every window resize event, use this to scale your page properly | 344 |
365 | 345 var numObj = document.getElementsByClassName('track-slider').length; |
366 var numObj = document.getElementsByClassName('track-slider').length; | 346 var totalHeight = (numObj * 125) - 25; |
367 var totalHeight = (numObj * 125)-25; | 347 document.getElementById('scale-holder').style.width = window.innerWidth - 220 + 'px'; |
368 document.getElementById('scale-holder').style.width = window.innerWidth-220 + 'px'; | 348 // Cheers edge for making me delete a canvas every resize. |
369 // Cheers edge for making me delete a canvas every resize. | 349 var canvas = document.getElementById('scale-canvas'); |
370 var canvas = document.getElementById('scale-canvas'); | |
371 var new_canvas = document.createElement("canvas"); | 350 var new_canvas = document.createElement("canvas"); |
372 new_canvas.id = 'scale-canvas'; | 351 new_canvas.id = 'scale-canvas'; |
373 new_canvas.style.marginLeft = "100px"; | 352 new_canvas.style.marginLeft = "100px"; |
374 canvas.parentElement.appendChild(new_canvas); | 353 canvas.parentElement.appendChild(new_canvas); |
375 canvas.parentElement.removeChild(canvas); | 354 canvas.parentElement.removeChild(canvas); |
376 new_canvas.width = window.innerWidth-420; | 355 new_canvas.width = window.innerWidth - 420; |
377 new_canvas.height = totalHeight; | 356 new_canvas.height = totalHeight; |
378 for (var i in audioEngineContext.audioObjects) | 357 for (var i in audioEngineContext.audioObjects) { |
379 { | 358 if (audioEngineContext.audioObjects[i].specification.type != 'outside-reference') { |
380 if (audioEngineContext.audioObjects[i].specification.type != 'outside-reference'){ | 359 audioEngineContext.audioObjects[i].interfaceDOM.resize(event); |
381 audioEngineContext.audioObjects[i].interfaceDOM.resize(event); | 360 } |
382 } | 361 } |
383 } | 362 document.getElementById("slider").style.height = totalHeight + 50 + 'px'; |
384 document.getElementById("slider").style.height = totalHeight+50+'px'; | 363 drawScale(); |
385 drawScale(); | |
386 } | 364 } |
387 | 365 |
388 function drawScale() | 366 function drawScale() { |
389 { | 367 var interfaceObj = testState.currentStateMap.interfaces[0]; |
390 var interfaceObj = testState.currentStateMap.interfaces[0]; | 368 var scales = testState.currentStateMap.interfaces[0].scales; |
391 var scales = testState.currentStateMap.interfaces[0].scales; | 369 scales = scales.sort(function (a, b) { |
392 scales = scales.sort(function(a,b) { | 370 return a.position - b.position; |
393 return a.position - b.position; | 371 }); |
394 }); | 372 var canvas = document.getElementById('scale-canvas'); |
395 var canvas = document.getElementById('scale-canvas'); | 373 var ctx = canvas.getContext("2d"); |
396 var ctx = canvas.getContext("2d"); | 374 var height = canvas.height; |
397 var height = canvas.height; | 375 var width = canvas.width; |
398 var width = canvas.width; | 376 var textHolder = document.getElementById('scale-text-holder'); |
399 var textHolder = document.getElementById('scale-text-holder'); | 377 textHolder.innerHTML = ""; |
400 textHolder.innerHTML = ""; | 378 ctx.fillStyle = "#000000"; |
401 ctx.fillStyle = "#000000"; | 379 ctx.setLineDash([1, 4]); |
402 ctx.setLineDash([1,4]); | 380 for (var scale of scales) { |
403 for (var scale of scales) | 381 var posPercent = scale.position / 100.0; |
404 { | 382 var posPix = Math.round(width * posPercent); |
405 var posPercent = scale.position / 100.0; | 383 if (posPix <= 0) { |
406 var posPix = Math.round(width * posPercent); | 384 posPix = 1; |
407 if(posPix<=0){posPix=1;} | 385 } |
408 if(posPix>=width){posPix=width-1;} | 386 if (posPix >= width) { |
409 ctx.moveTo(posPix,0); | 387 posPix = width - 1; |
410 ctx.lineTo(posPix,height); | 388 } |
411 ctx.stroke(); | 389 ctx.moveTo(posPix, 0); |
412 | 390 ctx.lineTo(posPix, height); |
413 var text = document.createElement('div'); | 391 ctx.stroke(); |
414 text.align = "center"; | 392 |
415 var textC = document.createElement('span'); | 393 var text = document.createElement('div'); |
416 textC.textContent = scale.text; | 394 text.align = "center"; |
417 text.appendChild(textC); | 395 var textC = document.createElement('span'); |
418 text.className = "scale-text"; | 396 textC.textContent = scale.text; |
419 textHolder.appendChild(text); | 397 text.appendChild(textC); |
420 text.style.width = Math.ceil($(text).width())+'px'; | 398 text.className = "scale-text"; |
421 text.style.left = (posPix+100-($(text).width()/2)) +'px'; | 399 textHolder.appendChild(text); |
422 } | 400 text.style.width = Math.ceil($(text).width()) + 'px'; |
401 text.style.left = (posPix + 100 - ($(text).width() / 2)) + 'px'; | |
402 } | |
423 } | 403 } |
424 | 404 |
425 function buttonSubmitClick() // TODO: Only when all songs have been played! | 405 function buttonSubmitClick() // TODO: Only when all songs have been played! |
426 { | 406 { |
427 var checks = []; | 407 var checks = []; |
428 checks = checks.concat(testState.currentStateMap.interfaces[0].options); | 408 checks = checks.concat(testState.currentStateMap.interfaces[0].options); |
429 checks = checks.concat(specification.interfaces.options); | 409 checks = checks.concat(specification.interfaces.options); |
430 var canContinue = true; | 410 var canContinue = true; |
431 | 411 |
432 // Check that the anchor and reference objects are correctly placed | 412 // Check that the anchor and reference objects are correctly placed |
433 if (interfaceContext.checkHiddenAnchor() == false) {return;} | 413 if (interfaceContext.checkHiddenAnchor() == false) { |
434 if (interfaceContext.checkHiddenReference() == false) {return;} | 414 return; |
435 | 415 } |
436 for (var i=0; i<checks.length; i++) { | 416 if (interfaceContext.checkHiddenReference() == false) { |
437 if (checks[i].type == 'check') | 417 return; |
438 { | 418 } |
439 switch(checks[i].name) { | 419 |
440 case 'fragmentPlayed': | 420 for (var i = 0; i < checks.length; i++) { |
441 // Check if all fragments have been played | 421 if (checks[i].type == 'check') { |
442 var checkState = interfaceContext.checkAllPlayed(); | 422 switch (checks[i].name) { |
443 if (checkState == false) {canContinue = false;} | 423 case 'fragmentPlayed': |
444 break; | 424 // Check if all fragments have been played |
445 case 'fragmentFullPlayback': | 425 var checkState = interfaceContext.checkAllPlayed(); |
446 // Check all fragments have been played to their full length | 426 if (checkState == false) { |
447 var checkState = interfaceContext.checkAllPlayed(); | 427 canContinue = false; |
448 if (checkState == false) {canContinue = false;} | 428 } |
449 console.log('NOTE: fragmentFullPlayback not currently implemented, performing check fragmentPlayed instead'); | 429 break; |
450 break; | 430 case 'fragmentFullPlayback': |
451 case 'fragmentMoved': | 431 // Check all fragments have been played to their full length |
452 // Check all fragment sliders have been moved. | 432 var checkState = interfaceContext.checkAllPlayed(); |
453 var checkState = interfaceContext.checkAllMoved(); | 433 if (checkState == false) { |
454 if (checkState == false) {canContinue = false;} | 434 canContinue = false; |
455 break; | 435 } |
456 case 'fragmentComments': | 436 console.log('NOTE: fragmentFullPlayback not currently implemented, performing check fragmentPlayed instead'); |
457 // Check all fragment sliders have been moved. | 437 break; |
458 var checkState = interfaceContext.checkAllCommented(); | 438 case 'fragmentMoved': |
459 if (checkState == false) {canContinue = false;} | 439 // Check all fragment sliders have been moved. |
460 break; | 440 var checkState = interfaceContext.checkAllMoved(); |
461 case 'scalerange': | 441 if (checkState == false) { |
462 // Check the scale has been used effectively | 442 canContinue = false; |
463 var checkState = interfaceContext.checkScaleRange(checks[i].min,checks[i].max); | 443 } |
464 if (checkState == false) {canContinue = false;} | 444 break; |
465 break; | 445 case 'fragmentComments': |
466 default: | 446 // Check all fragment sliders have been moved. |
467 console.log("WARNING - Check option "+checks[i].check+" is not supported on this interface"); | 447 var checkState = interfaceContext.checkAllCommented(); |
468 break; | 448 if (checkState == false) { |
469 } | 449 canContinue = false; |
470 | 450 } |
471 } | 451 break; |
472 if (!canContinue) {break;} | 452 case 'scalerange': |
473 } | 453 // Check the scale has been used effectively |
474 | 454 var checkState = interfaceContext.checkScaleRange(checks[i].min, checks[i].max); |
455 if (checkState == false) { | |
456 canContinue = false; | |
457 } | |
458 break; | |
459 default: | |
460 console.log("WARNING - Check option " + checks[i].check + " is not supported on this interface"); | |
461 break; | |
462 } | |
463 | |
464 } | |
465 if (!canContinue) { | |
466 break; | |
467 } | |
468 } | |
469 | |
475 if (canContinue) { | 470 if (canContinue) { |
476 if (audioEngineContext.status == 1) { | 471 if (audioEngineContext.status == 1) { |
477 var playback = document.getElementById('playback-button'); | 472 var playback = document.getElementById('playback-button'); |
478 playback.click(); | 473 playback.click(); |
479 // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options | 474 // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options |
480 } else | 475 } else { |
481 { | 476 if (audioEngineContext.timer.testStarted == false) { |
482 if (audioEngineContext.timer.testStarted == false) | 477 interfaceContext.lightbox.post("Warning", 'You have not started the test! Please press start to begin the test!'); |
483 { | 478 return; |
484 interfaceContext.lightbox.post("Warning",'You have not started the test! Please press start to begin the test!'); | 479 } |
485 return; | 480 } |
486 } | 481 testState.advanceState(); |
487 } | 482 } |
488 testState.advanceState(); | |
489 } | |
490 } | 483 } |
491 | 484 |
492 function pageXMLSave(store, pageSpecification) | 485 function pageXMLSave(store, pageSpecification) { |
493 { | 486 // MANDATORY |
494 // MANDATORY | 487 // Saves a specific test page |
495 // Saves a specific test page | 488 // You can use this space to add any extra nodes to your XML <audioHolder> saves |
496 // You can use this space to add any extra nodes to your XML <audioHolder> saves | 489 // Get the current <page> information in store (remember to appendChild your data to it) |
497 // Get the current <page> information in store (remember to appendChild your data to it) | 490 // pageSpecification is the current page node configuration |
498 // pageSpecification is the current page node configuration | 491 // To create new XML nodes, use storage.document.createElement(); |
499 // To create new XML nodes, use storage.document.createElement(); | |
500 } | 492 } |