class Player { constructor(wrapperEl) { this.wrapperEl = wrapperEl; this.svgEl = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); this.wrapperEl.appendChild(this.svgEl); this.resize(); } playlist(url) { const request = new Request(url, { method: 'GET', }); fetch(request) .then(response => response.json()) .then(data => { let playlist = this.wrapperEl.querySelector('.playlist'); if(!playlist) { playlist = document.createElement('nav'); playlist.classList.add('playlist'); this.wrapperEl.appendChild(playlist) } else{ playlist.innerHTML = ""; } const listEl = document.createElement("ul"); for(let fileUrl of data) { const liEl = document.createElement("li"); liEl.innerText = fileUrl liEl.addEventListener('click', (e) => { this.play(fileUrl); }); listEl.appendChild(liEl); } playlist.appendChild(listEl); // do something with the data sent in the request }); } play(file) { const request = new Request(file, { method: 'GET', }); fetch(request) .then(response => response.json()) .then(data => { this.playStrokes(data) // do something with the data sent in the request }); } playStrokes(drawing){ this.strokes = drawing.shape; this.currentPath = null; this.dimensions = drawing.dimensions; this.svgEl.setAttributeNS('http://www.w3.org/2000/svg', 'viewBox', `0 0 ${this.dimensions.width} ${this.dimensions.height}`) this.startTime = window.performance.now() - this.strokes[0].points[0][3]; this.playStroke(0,1); } playStroke(path_i, point_i){ const path = this.strokes[path_i]; // console.log(path); let pathEl = this.svgEl.querySelector(`.path${path_i}`); if(!pathEl){ pathEl = document.createElementNS('http://www.w3.org/2000/svg', 'path'); pathEl.style.stroke = path.color; pathEl.classList.add('path'+path_i) this.svgEl.appendChild(pathEl) } const d = this.strokes2D(path.points.slice(0, point_i)); pathEl.setAttribute('d', d); let next_path, next_point,t; if(path.points.length > point_i + 1){ next_path = path_i; next_point = point_i + 1; t = path.points[next_point][3];// - path.points[point_i][3]; // setTimeout(() => this.playStroke(next_path, next_point), dt); } else if(this.strokes.length > path_i + 1) { next_path = path_i + 1; next_point = 1; t = this.strokes[next_path].points[next_point][3];// - path.points[point_i][3]; // use starttime instead of diff, to prevent floating } else { console.log('done'); return } const dt = t - (window.performance.now() - this.startTime); setTimeout(() => this.playStroke(next_path, next_point), dt); } playUntil(path_i){ // for scrubber } resize() { this.width = window.innerWidth; this.height = window.innerHeight; const viewBox = `0 0 ${this.width} ${this.height}`; this.svgEl.setAttribute('viewBox', viewBox); this.svgEl.setAttribute('width', this.width + 'mm'); this.svgEl.setAttribute('height', this.height + 'mm'); } requestResize() { alert('Resize not implemented yet. Please reloade the page'); } strokes2D(strokes) { // strokes to a d attribute for a path let d = ""; let last_stroke = undefined; let cmd = ""; for (let stroke of strokes) { if (!last_stroke) { d += `M${stroke[0] * this.width},${stroke[1] * this.height} `; cmd = 'M'; } else { if (last_stroke[2] == 1) { d += " m"; cmd = 'm'; } else if (cmd != 'l') { d += ' l '; cmd = 'l'; } let rel_stroke = [stroke[0] - last_stroke[0], stroke[1] - last_stroke[1]]; d += `${rel_stroke[0] * this.width},${rel_stroke[1] * this.height} `; } last_stroke = stroke; } return d; } }