diff --git a/APlayer.css b/APlayer.css index d34e686..542166e 100644 --- a/APlayer.css +++ b/APlayer.css @@ -77,20 +77,24 @@ user-select: none; } -.aplayer-pic { +.aplayer span { + cursor: default; +} + +.aplayer .aplayer-pic { position: relative; float: left; height: 100%; width: 66px; } -.aplayer-pic img { +.aplayer .aplayer-pic img { height: 100%; width: 100%; border-radius: 2px 0 0 2px; } -.aplayer-mask { +.aplayer .aplayer-mask { position: absolute; top: 0; left: 0; @@ -99,7 +103,7 @@ background: rgba(0, 0, 0, 0.2); } -.aplayer-button { +.aplayer .aplayer-button { position: absolute; color: #fff; border-radius: 50%; @@ -110,15 +114,15 @@ background: rgba(0, 0, 0, 0.2); } -.aplayer-button:hover { +.aplayer .aplayer-button:hover { opacity: 1; } -.aplayer-hide { +.aplayer .aplayer-hide { display: none; } -.aplayer-play { +.aplayer .aplayer-play { width: 26px; height: 26px; border: 2px solid #fff; @@ -127,14 +131,14 @@ margin: -15px 0 0 -15px; } -.aplayer-play .icon-play { +.aplayer .aplayer-play .icon-play { position: absolute; top: 2px; left: 4px; font-size: 20px; } -.aplayer-pause { +.aplayer .aplayer-pause { width: 16px; height: 16px; border: 2px solid #fff; @@ -142,50 +146,50 @@ right: 4px; } -.aplayer-pause .icon-pause { +.aplayer .aplayer-pause .icon-pause { position: absolute; top: 2px; left: 2px; font-size: 12px; } -.aplayer-info { +.aplayer .aplayer-info { margin-left: 66px; padding: 17px 7px 0 10px; } -.aplayer-music { +.aplayer .aplayer-music { margin-bottom: 17px; } -.aplayer-title { +.aplayer .aplayer-title { font-size: 14px; } -.aplayer-author { +.aplayer .aplayer-author { font-size: 12px; color: #666; } -.aplayer-music a { +.aplayer .aplayer-music a { margin-left: 20px; font-size: 14px; color: #000; } -.aplayer-music a:hover { +.aplayer .aplayer-music a:hover { color: #E90F24; } -.aplayer-controller { +.aplayer .aplayer-controller { position: relative; } -.aplayer-bar-wrap { - margin-right: 110px; +.aplayer .aplayer-bar-wrap { + margin-right: 120px; } -.aplayer-bar { +.aplayer .aplayer-bar { position: relative; height: 2px; width: 100%; @@ -193,7 +197,7 @@ cursor: pointer; } -.aplayer-loaded { +.aplayer .aplayer-loaded { position: absolute; left: 0; top: 0; @@ -203,7 +207,7 @@ transition: all 0.5s ease; } -.aplayer-played { +.aplayer .aplayer-played { position: absolute; left: 0; top: 0; @@ -212,7 +216,7 @@ height: 2px; } -.aplayer-thumb { +.aplayer .aplayer-thumb { position: absolute; top: 0; right: 0; @@ -226,20 +230,56 @@ cursor: pointer; } -.aplayer-thumb:hover { +.aplayer .aplayer-thumb:hover { background: #b7daff; } -.aplayer-time { +.aplayer .aplayer-time { position: absolute; right: 0; bottom: -5px; + height: 17px; color: #999; font-size: 11px; } -.icon-volume-down { +.aplayer .aplayer-time i { color: #666; font-size: 15px; +} + +.aplayer .aplayer-volume-wrap { + display: inline-block; margin-left: 7px; + cursor: pointer; +} + +.aplayer .aplayer-volume-wrap:hover .aplayer-volume-bar-wrap { + display: block; +} + +.aplayer .aplayer-volume-bar-wrap { + display: none; + position: absolute; + bottom: 17px; + right: -5px; + width: 25px; + height: 40px; +} + +.aplayer .aplayer-volume-bar { + position: absolute; + bottom: 0; + right: 10px; + width: 5px; + height: 35px; + background: #aaa; +} + +.aplayer .aplayer-volume { + position: absolute; + bottom: 0; + right: 0; + width: 5px; + background: #b7daff; } \ No newline at end of file diff --git a/APlayer.js b/APlayer.js index a87c958..afe8702 100644 --- a/APlayer.js +++ b/APlayer.js @@ -1,9 +1,9 @@ function APlayer(option) { this.option = option; - this.init(); } APlayer.prototype.init = function () { + // 填充HTML this.option.element.innerHTML = '' + '
' + '' @@ -23,34 +23,49 @@ APlayer.prototype.init = function () { + '
' + '
' + '
' - + '
' - + '
' + + '
' + + '
' + '' + '
' + '
' + '
' - + ' - 00:00/00:00' + + '' + + ' - 00:00 / 00:00' + + '
' + + '' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + '
' + '
'; - var _self = this; + // 创建audio元素 this.audio = document.createElement("audio"); this.audio.src = this.option.music.url; this.audio.loop = true; + // 显示音频总时间 + var _self = this; this.audio.addEventListener('durationchange', function() { _self.option.element.getElementsByClassName('aplayer-dtime')[0].innerHTML = _self.secondToTime(_self.audio.duration); }); + + // 显示加载进度条 this.audio.addEventListener('canplay', function() { _self.loadedTime = setInterval(function () { var percentage = _self.audio.buffered.end(_self.audio.buffered.length - 1) / _self.audio.duration; - _self.updateBar.call(_self, 'loaded', percentage); + _self.updateBar.call(_self, 'loaded', percentage, 'width'); if (percentage === 1) { clearInterval(_self.loadedTime); } }, 500); }); + // 播放暂停按钮 this.playButton = this.option.element.getElementsByClassName('aplayer-play')[0]; this.pauseButton = this.option.element.getElementsByClassName('aplayer-pause')[0]; this.playButton.addEventListener('click', function () { @@ -60,27 +75,22 @@ APlayer.prototype.init = function () { _self.pause.call(_self); }); + // 播放进度控制(拖拽滑块 点击进度条) this.playedBar = this.option.element.getElementsByClassName('aplayer-played')[0]; this.loadedBar = this.option.element.getElementsByClassName('aplayer-loaded')[0]; - if (this.option.autoplay) { - this.play(); - } - this.thumb = this.option.element.getElementsByClassName('aplayer-thumb')[0]; this.bar = this.option.element.getElementsByClassName('aplayer-bar')[0]; var barWidth; - this.bar.addEventListener('click', function (event) { var e = event || window.event; barWidth = _self.bar.clientWidth; var percentage = (e.clientX - getElementLeft(_self.bar)) / barWidth; - _self.updateBar.call(_self, 'played', percentage); + _self.updateBar.call(_self, 'played', percentage, 'width'); _self.option.element.getElementsByClassName('aplayer-ptime')[0].innerHTML = _self.secondToTime(percentage * _self.audio.duration); _self.audio.currentTime = parseFloat(_self.playedBar.style.width) / 100 * _self.audio.duration; }); - this.thumb.addEventListener('mousedown', function (event) { - var e = event || window.event; + this.thumb.addEventListener('mousedown', function () { barWidth = _self.bar.clientWidth; clearInterval(_self.playedTime); document.addEventListener('mousemove', thumbMove); @@ -92,7 +102,7 @@ APlayer.prototype.init = function () { var percentage = (e.clientX - getElementLeft(_self.bar)) / barWidth; percentage = percentage > 0 ? percentage : 0; percentage = percentage < 1 ? percentage : 1; - _self.updateBar.call(_self, 'played', percentage); + _self.updateBar.call(_self, 'played', percentage, 'width'); _self.option.element.getElementsByClassName('aplayer-ptime')[0].innerHTML = _self.secondToTime(percentage * _self.audio.duration); } @@ -101,11 +111,45 @@ APlayer.prototype.init = function () { document.removeEventListener('mousemove', thumbMove); _self.audio.currentTime = parseFloat(_self.playedBar.style.width) / 100 * _self.audio.duration; _self.playedTime = setInterval(function () { - _self.updateBar.call(_self, 'played', _self.audio.currentTime / _self.audio.duration); + _self.updateBar.call(_self, 'played', _self.audio.currentTime / _self.audio.duration, 'width'); _self.option.element.getElementsByClassName('aplayer-ptime')[0].innerHTML = _self.secondToTime(_self.audio.currentTime); }, 100); } + // 音量控制 + this.audio.volume = 0.8; + this.volumeBar = this.option.element.getElementsByClassName('aplayer-volume')[0]; + var volumeBarWrap = this.option.element.getElementsByClassName('aplayer-volume-bar')[0]; + var volumeicon = _self.option.element.getElementsByClassName('aplayer-time')[0].getElementsByTagName('i')[0]; + var barHeight = 35; + this.option.element.getElementsByClassName('aplayer-volume-bar-wrap')[0].addEventListener('click', function (event) { + var e = event || window.event; + var percentage = (barHeight - e.clientY + getElementTop(volumeBarWrap)) / barHeight; + percentage = percentage > 0 ? percentage : 0; + percentage = percentage < 1 ? percentage : 1; + _self.updateBar.call(_self, 'volume', percentage, 'height'); + _self.audio.volume = percentage; + if (percentage === 1) { + volumeicon.className = 'demo-icon icon-volume-up'; + } + else { + volumeicon.className = 'demo-icon icon-volume-down'; + } + }); + volumeicon.addEventListener('click', function () { + if (_self.audio.muted) { + _self.audio.muted = false; + volumeicon.className = _self.audio.volume === 1 ? 'demo-icon icon-volume-up' : 'demo-icon icon-volume-down'; + _self.updateBar.call(_self, 'volume', _self.audio.volume, 'height'); + } + else { + _self.audio.muted = true; + volumeicon.className = 'demo-icon icon-volume-off'; + _self.updateBar.call(_self, 'volume', 0, 'height'); + } + }); + + // 获取元素相对窗口位置 function getElementLeft (element){ var actualLeft = element.offsetLeft; var current = element.offsetParent; @@ -115,19 +159,35 @@ APlayer.prototype.init = function () { } return actualLeft; } + function getElementTop(element){ + var actualTop = element.offsetTop; + var current = element.offsetParent; + while (current !== null){ + actualTop += current.offsetTop; + current = current.offsetParent; + } + return actualTop; + } + + // 自动播放 + if (this.option.autoplay) { + this.play(); + } }; +// 播放 APlayer.prototype.play = function () { this.playButton.classList.add('aplayer-hide'); this.pauseButton.classList.remove('aplayer-hide'); this.audio.play(); var _self = this; this.playedTime = setInterval(function () { - _self.updateBar.call(_self, 'played', _self.audio.currentTime / _self.audio.duration); + _self.updateBar.call(_self, 'played', _self.audio.currentTime / _self.audio.duration, 'width'); _self.option.element.getElementsByClassName('aplayer-ptime')[0].innerHTML = _self.secondToTime(_self.audio.currentTime); }, 100); }; +// 暂停 APlayer.prototype.pause = function () { this.pauseButton.classList.add('aplayer-hide'); this.playButton.classList.remove('aplayer-hide'); @@ -135,12 +195,14 @@ APlayer.prototype.pause = function () { clearInterval(this.playedTime); }; -APlayer.prototype.updateBar = function (type, percentage) { +// 更新进度条(加载进度条 播放进度条) +APlayer.prototype.updateBar = function (type, percentage, direction) { percentage = percentage > 0 ? percentage : 0; percentage = percentage < 1 ? percentage : 1; - this[type + 'Bar'].style.width = percentage * 100 + '%'; + this[type + 'Bar'].style[direction] = percentage * 100 + '%'; }; +// 将秒数整理为 00:00 格式 APlayer.prototype.secondToTime = function (second) { var add0 = function (num) { return num < 10 ? '0' + num : '' + num; diff --git a/README.md b/README.md index f48ccc0..f09c9f5 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ var ap = new APlayer({ pic: 'Preparation.jpg' } }); +ap.init(); ``` The following options are available: @@ -73,7 +74,7 @@ API ## Todo - [x] 播放进度拖拽控制 -- [ ] 音量控制 +- [x] 音量控制 - [ ] 分享到微博 - [ ] 播放列表 - [ ] 歌词展示 diff --git a/demo/index.html b/demo/index.html index 2c59740..eed2a48 100644 --- a/demo/index.html +++ b/demo/index.html @@ -21,6 +21,7 @@ pic: 'Preparation.jpg' } }); + ap.init(); \ No newline at end of file diff --git a/package.json b/package.json index 606001d..426d2a6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "aplayer", - "version": "1.0.1", + "version": "1.0.2", "description": "Wow, such a beautiful html5 music player", "main": "APlayer.js", "scripts": {