function HotsPlayer(){ var self = this, pl = this, sm = soundManager; // soundManager instance this.files = []; this.sounds = []; this.graphicPaths = {}; this.ready = false; this.listeners = []; this.config = { playerDomID: '#player', playerWidth: 200, playerHeight: 100, canvasHeight:200, canvasWidth:300, autoPlay: true, filesDomID: '#track-list', buttonHeight: 10, volume: 80, random: false, graphic: { circleWidth: 20, waitColor: 'white', loadedColor: 'red', playedColor: 'green', controlsColor: '#333333', } }; this.currentTime = 0; this.currentDuration = 0; this.currentBytes = 0; this.currentTotalBytes = 0; this.state = 'waiting'; this.currentIndex = -1; this.events = { onfinish: function() { self.playNext(); }, whileplaying: function() { self.currentTime = this.position; self.currentDuration = this.durationEstimate; self.redrawPlay(); }, whileloading: function() { self.currentBytes = this.bytesLoaded; self.currentTotalBytes = this.bytesTotal; self.redrawLoad(); }, }; this.playNext = function() { var pos = self.currentIndex + 1; if (pos == self.sounds.length){ pos = 0; } if (self.config.random){ pos = Math.floor((Math.random()*(self.sounds.length -1 )) + 0); } self.startPlay(pos); }; this.playPrevious = function() { var pos = self.currentIndex - 1; if (pos == -1 ){ pos = self.sounds.length - 1; } if (self.config.random){ pos = Math.floor((Math.random()*(self.sounds.length -1 )) + 0); } self.startPlay(pos); }; this.redrawLoad = function() { var graphics = self.config.graphic; var path = self.config.graphic.loadingBar; var radius = self.config.graphic.loadingRadius; path.remove(); if(self.currentBytes ==self.currentTotalBytes ){ //path = self.drawArc(radius, 100, 100); }else{ path = self.drawArc(radius, self.currentBytes, self.currentTotalBytes); path.strokeColor = graphics.loadedColor; path.strokeWidth = graphics.circleWidth - 5; path.opacity = 0.6; self.config.graphic.loadingBar = path; } paper.view.draw(); }; this.redrawPlay = function() { var graphics = self.config.graphic; var angle = (2 * Math.PI) / self.currentDuration; var path = self.config.graphic.playingBar; var radius = self.config.graphic.playingRadius; path.remove(); paper.view.draw(); path = self.drawArc(radius, self.currentTime, self.currentDuration); path.strokeColor = graphics.playedColor; path.strokeWidth = graphics.circleWidth - 5 ; path.opacity = 0.6; self.config.graphic.playingBar = path; paper.view.draw(); }; this.init = function() { self.loadSongs(self.config.filesDomID); self.loadSounds(); self.autoStart(); self.ready = true; }; this.startPlay = function(index){ var song = self.files[index]; self.clearBars(); sm.play(song.id, {volume:self.config.volume}); self.currentIndex = index; self.state = 'playing'; var uri = song.file; jQuery('.hotsPlayer-controls-down a', self.config.playerDomID).attr('href', uri); var evt = {}; evt.target = self.activeFile(song.id); self.trigger('startPlay', evt); jQuery('.hotsPlayer-controls-play', self.config.playerDomID).addClass('pause'); }; this.activeFile = function(songID) { jQuery(self.config.filesDomID + ' a').removeClass('active'); var idRoto = songID.split('_'); var active = jQuery(self.config.filesDomID + ' a[data-id="' + idRoto[1] + '"]'); active.addClass('active'); return active[0]; } this.clearBars = function() { var path = self.config.graphic.playingBar; var loadPath = self.config.graphic.loadingBar; path.remove(); loadPath.remove(); paper.view.draw(); }; this.starPlayByID = function(songID){ sm.play(songID, {volume:self.config.volume}); var index = self.searchByIndex(songID); self.clearBars(); self.currentIndex = index; self.state = 'playing'; var song = self.files[index]; var uri = song.file; jQuery('.hotsPlayer-controls-down a', self.config.playerDomID).attr('href', uri); jQuery('.hotsPlayer-controls-play', self.config.playerDomID).addClass('pause'); var evt = {}; evt.target = self.activeFile(song.id); self.trigger('startPlay', evt); }; this.searchByIndex = function(id) { var salir = false; var pos = 0; while(!salir && pos < self.files.length){ if (self.files[pos].id == id){ salir = true; }else{ pos += 1; } }; return pos; }; this.stop = function(){ if (self.state == "playing" || self.state == "paused"){ var song = self.files[self.currentIndex]; sm.stop(song.id); self.state = 'waiting'; jQuery('.hotsPlayer-controls-play', self.config.playerDomID).removeClass('pause'); } }; this.handleClick = function(e){ var elemento = e.currentTarget; var tipoControl = elemento.dataset.controlType; switch (tipoControl){ case 'play': e.preventDefault(); if (self.state == 'waiting'){ if (self.currentIndex == -1){ self.startPlay(0); }else{ self.startPlay(self.currentIndex); } }else if (self.state == "playing"){ self.pause(); }else if (self.state == 'paused'){ self.resume(); } break; case 'random': e.preventDefault(); if (self.config.random){ jQuery('.hotsPlayer-controls-random', self.config.playerDomID).removeClass('active'); self.config.random = false; }else{ jQuery('.hotsPlayer-controls-random', self.config.playerDomID).addClass('active'); self.config.random = true; } break; case 'next': e.preventDefault(); self.stop(); self.playNext(); break; case 'prev': e.preventDefault(); self.stop(); self.playPrevious(); case 'down': break; }; }; this.resume = function() { var song = self.files[self.currentIndex]; sm.resume(song.id); self.state = 'playing'; jQuery('.hotsPlayer-controls-play', self.config.playerDomID).addClass('pause'); } this.pause = function() { var song = self.files[self.currentIndex]; sm.pause(song.id); self.state = 'paused'; jQuery('.hotsPlayer-controls-play', self.config.playerDomID).removeClass('pause'); }; this.draw = function() { // Create an empty project and a view for the canvas: self.insertDomElements(); var t =jQuery('canvas', self.config.playerDomID); paper.setup(jQuery('canvas', self.config.playerDomID)[0]); var graphics = self.config.graphic; var centerX = self.config.canvasWidth / 2; var centerY = self.config.canvasHeight / 2; var radius = (((self.config.playerWidth < self.config.playerHeight) ? self.config.playerWidth : self.config.playerHeight ) / 2) - (graphics.circleWidth/2); graphics.radius = radius; graphics.centerX = centerX; graphics.centerY = centerY; var waitCircle = new paper.Path.Circle(new paper.Point(centerX,centerY), radius); waitCircle.strokeColor ='white'; waitCircle.strokeWidth = graphics.circleWidth; //Positioning Controls var alturaCirculo = (radius * 2) + 24; var espacio = (alturaCirculo - (self.config.buttonHeight * 4)) / 3; jQuery(self.config.playerDomID).width(self.config.canvasWidth).height(self.config.canvasHeight).css('position', 'relative'); jQuery('.hotsPlayer-controls').width(self.config.canvasWidth).height(self.config.canvasHeight); jQuery('.hotsPlayer-controls-play', self.config.playerDomID).css('top', centerY-10).css('left',centerX-10).height(20).width(20); var top = centerY - radius - self.config.buttonHeight; var left = centerX + radius + 18; jQuery('.hotsPlayer-controls-random', self.config.playerDomID).css('top',top).css('left', left - 15); if (self.config.random){ jQuery('.hotsPlayer-controls-random', self.config.playerDomID).addClass('active'); } top += espacio + self.config.buttonHeight; jQuery('.hotsPlayer-controls-next', self.config.playerDomID).css('top',top).css('left', left); top += espacio + self.config.buttonHeight; jQuery('.hotsPlayer-controls-prev', self.config.playerDomID).css('top',top).css('left', left); top += espacio + self.config.buttonHeight; jQuery('.hotsPlayer-controls-down', self.config.playerDomID).css('top',top).css('left', left - 15); left = centerX - radius - 18 - self.config.buttonHeight; top = centerY - radius - 10; jQuery('.hotsPlayer-controls-vol-up', self.config.playerDomID).css('top',top).css('left', left); top += espacio * 3 + self.config.buttonHeight * 3; jQuery('.hotsPlayer-controls-vol-down', self.config.playerDomID).css('top',top).css('left', left); jQuery('.hotsPlayer-controls>div>a').click(self.handleClick); var volumenBackBar = new paper.Path.Line(new paper.Point(left + 5, centerY - radius + 10 ), new paper.Point(left + 5,centerY + radius - 10)); volumenBackBar.strokeWidth = 8; volumenBackBar.strokeColor = 'white'; volumenBackBar.opacity = 0.4; var distanciaVolumen = (centerY + radius - 10) - (centerY - radius + 10); var longitudBarra = (distanciaVolumen / 100) * self.config.volume; var volumenBar = new paper.Path.Line(new paper.Point(left + 5, centerY + radius - 10), new paper.Point(left + 5, centerY + radius - 10 - longitudBarra)); volumenBar.strokeWidth = 8; volumenBar.strokeColor = 'white'; volumenBar.opacity = 0.6; var playRadius = radius -10; var start = new paper.Point(centerX, centerY - playRadius); var pR = new paper.Path.Arc(start, start, start); pR.strokeColor = 'red'; pR.strokeWidth = 25; pR.opacity = 0.6; graphics.loadingBar = pR; graphics.loadingRadius = radius - 10; var sR = radius +5 ; start = new paper.Point(centerX, centerY - sR); //end = new paper.Point(centerX, centerY + sR); //through = new paper.Point(centerX + sR, centerY); var nn = new paper.Path.Arc(start, start, start); nn.strokeColor = 'green'; nn.strokeWidth = 15; nn.opacity = 0.6; graphics.playingBar = nn; graphics.playingRadius = radius + 6; paper.view.draw(); self.autoStart(); self.ready = true; }; this.drawArc = function(radio, valor, total){ var centerX = self.config.graphic.centerX; var centerY = self.config.graphic.centerY; var ratio = (valor % total)/ total; var angulo =Math.round(360 * ratio); var vPoint = new paper.Point({length: radio, angle:-90}); var start = new paper.Point(centerX + vPoint.x, centerY + vPoint.y); var middle = vPoint.rotate(angulo/2); var end = vPoint.rotate(angulo); var middlePoint = new paper.Point(centerX + middle.x, centerY + middle.y); var endPoint = new paper.Point(centerX + end.x, centerY + end.y); return new paper.Path.Arc(start, middlePoint, endPoint); } this.autoStart = function() { if (self.ready && self.config.autoPlay) { self.startPlay(0); //window.setInterval(function(){self.currentTime = self.currentTime + 2; self.currentDuration = 50; self.redrawPlay();},1000); }; }; this.insertDomElements = function() { var playerDom = jQuery(self.config.playerDomID); var canvas = document.createElement('canvas'); canvas.height = self.config.canvasHeight; canvas.width = self.config.canvasWidth; var controls = document.createElement('div'); controls.className="hotsPlayer-controls"; var controlPlay = document.createElement('div'); controlPlay.className="hotsPlayer-controls-play hotsControl"; var controlPlayLink = document.createElement('a'); controlPlayLink.dataset.controlType = "play"; controlPlayLink.href="#"; controlPlay.appendChild(controlPlayLink); var controlRandom = document.createElement('div'); controlRandom.className = 'hotsPlayer-controls-random hotsControl'; var controlRandomLink = document.createElement('a'); controlRandomLink.dataset.controlType = "random"; controlRandomLink.href="#"; controlRandom.appendChild(controlRandomLink); var controlNext = document.createElement('div'); controlNext.className = 'hotsPlayer-controls-next hotsControl' var controlNextLink = document.createElement('a'); controlNextLink.dataset.controlType = "next"; controlNextLink.href="#"; controlNext.appendChild(controlNextLink); var controlPrev = document.createElement('div'); controlPrev.className = 'hotsPlayer-controls-prev hotsControl' var controlPrevLink = document.createElement('a'); controlPrevLink.dataset.controlType = "prev"; controlPrevLink.href="#"; controlPrev.appendChild(controlPrevLink); var controlDown = document.createElement('div'); controlDown.className = 'hotsPlayer-controls-down hotsControl' var controlDownLink = document.createElement('a'); controlDownLink.dataset.controlType = "down"; controlDownLink.href="#"; controlDown.appendChild(controlDownLink); var controlVolDown = document.createElement('div'); controlVolDown.className = 'hotsPlayer-controls-vol-down hotsControl' var controlVolDownLink = document.createElement('a'); controlVolDownLink.dataset.controlType = "vol-down"; controlVolDownLink.href="#"; controlVolDown.appendChild(controlVolDownLink); var controlVolUp = document.createElement('div'); controlVolUp.className = 'hotsPlayer-controls-vol-up hotsControl' var controlVolUpLink = document.createElement('a'); controlVolUpLink.dataset.controlType = "vol-up"; controlVolUpLink.href="#"; controlVolUp.appendChild(controlVolUpLink); controls.appendChild(controlPlay); controls.appendChild(controlRandom); controls.appendChild(controlNext); controls.appendChild(controlPrev); controls.appendChild(controlDown); controls.appendChild(controlVolDown); controls.appendChild(controlVolUp); playerDom.append(canvas); playerDom.append(controls); }; this.loadSounds = function() { this.sounds = []; for(var i in this.files) { var song = this.files[i]; this.sounds.push(sm.createSound({ id: song.id, url: song.file, volume: self.config.volume, onfinish: self.events.onfinish, whileplaying: self.events.whileplaying, whileloading: self.events.whileloading })); } }; this.handleFileClick = function(e) { e.preventDefault(); var elemento = e.currentTarget; var id = elemento.dataset.id; self.changeSong('hotsPlayer_' + id); }; this.changeSong = function(songID) { self.stop(); self.starPlayByID(songID); }; this.loadSongs = function(filesDomID) { var files = []; if(filesDomID == null){ return; } jQuery(filesDomID + ' a').click(self.handleFileClick); jQuery(filesDomID + ' a').each(function (index, Element){ var link = Element.href; var songID = Element.dataset.id; self.files.push({ file : link, id : 'hotsPlayer_' + songID }); }); }; this.registerEvent = function(type, func){ if (func != null) { var listeners = self.listeners[type]; if (!listeners) { listeners = []; self.listeners[type] = listeners; } var listener = {func: func}; listeners.push(listener); } }; this.trigger = function(type, obj) { var listeners = self.listeners[type]; if (listeners) { var callback = listeners[0]; var evt = {}; evt.obj = self; evt.info = obj; callback.func.apply(self, [evt]); } }; } // Function HostsPlayer paper.install(window); var hotsPlayer; hotsPlayer = new HotsPlayer(); // hook into SM2 init soundManager.onready(hotsPlayer.init);