newraina 7 éve
szülő
commit
ae65e6b349
7 módosított fájl, 448 hozzáadás és 395 törlés
  1. 13 12
      demo/main.js
  2. 5 5
      src/js/constants.js
  3. 55 49
      src/js/lyric.js
  4. 260 217
      src/js/main.js
  5. 22 22
      src/js/selector.js
  6. 64 59
      src/js/spectrum.js
  7. 29 31
      src/js/utils.js

+ 13 - 12
demo/main.js

@@ -1,18 +1,19 @@
 mePlayer({
-    music: {
-        src: './晚风.mp3',
-        title: '晚风',
-        author: '好妹妹乐队',
-        loop: true,
-        cover: './cover.jpg',
-        lrc: '[00:24.600]温柔的晚风\n[00:27.830]轻轻吹过 爱人的梦中\n[00:36.690]温柔的晚风\n[00:39.129]轻轻吹过 故乡的天空\n[00:47.690]温柔的晚风\n[00:50.749]轻轻吹过 城市的灯火\n[00:59.119]今夜的晚风\n[01:02.439]你去哪里 请告诉我\n[01:08.249]\n[01:10.879]温柔的晚风\n[01:14.590]轻轻吹过 爱人的梦中\n[01:22.179]温柔的晚风\n[01:25.549]轻轻吹过 故乡的天空\n[01:33.809]温柔的晚风\n[01:37.539]轻轻地吹过 城市的灯火\n[01:46.509]今夜的晚风\n[01:49.919]你要去哪里 请告诉我\n[01:56.419]\n[02:37.140]温柔的晚风\n[02:40.740]轻轻吹过 爱人的梦中\n[02:49.060]温柔的晚风\n[02:52.370]轻轻吹过 故乡的天空\n[03:00.680]温柔的晚风\n[03:03.860]轻轻吹过 城市的灯火\n[03:12.190]今夜的晚风\n[03:15.440]你要去哪里 请告诉我\n[03:21.370]\n[03:23.620]温柔的晚风\n[03:27.090]轻轻吹过 爱人的梦中\n[03:35.280]温柔的晚风\n[03:39.570]轻轻吹过 故乡的天空\n[03:47.620]温柔的晚风\n[03:50.880]轻轻地吹过 城市的灯火\n[03:59.180]今夜的晚风\n[04:02.680]你要去哪里 请告诉我\n[04:08.800]\n[04:33.830]温柔的晚风\n[04:37.350]请你带走 我昨天的梦\n[04:45.350]今夜的晚风\n[04:48.960]我要去哪里 请告诉我\n[04:59.690]\n',
-    },
-    target: '.music',
-    autoplay: false,
+  music: {
+    src: './晚风.mp3',
+    title: '晚风',
+    author: '好妹妹乐队',
+    loop: true,
+    cover: './cover.jpg',
+    lrc:
+      '[00:24.600]温柔的晚风\n[00:27.830]轻轻吹过 爱人的梦中\n[00:36.690]温柔的晚风\n[00:39.129]轻轻吹过 故乡的天空\n[00:47.690]温柔的晚风\n[00:50.749]轻轻吹过 城市的灯火\n[00:59.119]今夜的晚风\n[01:02.439]你去哪里 请告诉我\n[01:08.249]\n[01:10.879]温柔的晚风\n[01:14.590]轻轻吹过 爱人的梦中\n[01:22.179]温柔的晚风\n[01:25.549]轻轻吹过 故乡的天空\n[01:33.809]温柔的晚风\n[01:37.539]轻轻地吹过 城市的灯火\n[01:46.509]今夜的晚风\n[01:49.919]你要去哪里 请告诉我\n[01:56.419]\n[02:37.140]温柔的晚风\n[02:40.740]轻轻吹过 爱人的梦中\n[02:49.060]温柔的晚风\n[02:52.370]轻轻吹过 故乡的天空\n[03:00.680]温柔的晚风\n[03:03.860]轻轻吹过 城市的灯火\n[03:12.190]今夜的晚风\n[03:15.440]你要去哪里 请告诉我\n[03:21.370]\n[03:23.620]温柔的晚风\n[03:27.090]轻轻吹过 爱人的梦中\n[03:35.280]温柔的晚风\n[03:39.570]轻轻吹过 故乡的天空\n[03:47.620]温柔的晚风\n[03:50.880]轻轻地吹过 城市的灯火\n[03:59.180]今夜的晚风\n[04:02.680]你要去哪里 请告诉我\n[04:08.800]\n[04:33.830]温柔的晚风\n[04:37.350]请你带走 我昨天的梦\n[04:45.350]今夜的晚风\n[04:48.960]我要去哪里 请告诉我\n[04:59.690]\n'
+  },
+  target: '.music',
+  autoplay: false
 })
 
-document.querySelector('button').addEventListener('click', function () {
-    mePlayer.toggleTheme()
+document.querySelector('button').addEventListener('click', function() {
+  mePlayer.toggleTheme()
 })
 
 window.setTimeout(mePlayer.play, 1500)

+ 5 - 5
src/js/constants.js

@@ -2,9 +2,9 @@
  * 全局常量声明
  */
 
-const THEME_DEFAULT = 'default';
-const THEME_MINI    = 'mini';
-const LYRIC_CURRENT_CLASS = 'meplayer-lyric-current';
-const LYRIC_NEXT_CLASS = 'meplayer-lyric-next';
+const THEME_DEFAULT = 'default'
+const THEME_MINI = 'mini'
+const LYRIC_CURRENT_CLASS = 'meplayer-lyric-current'
+const LYRIC_NEXT_CLASS = 'meplayer-lyric-next'
 
-export {THEME_DEFAULT, THEME_MINI, LYRIC_CURRENT_CLASS, LYRIC_NEXT_CLASS};
+export { THEME_DEFAULT, THEME_MINI, LYRIC_CURRENT_CLASS, LYRIC_NEXT_CLASS }

+ 55 - 49
src/js/lyric.js

@@ -1,66 +1,72 @@
-import {LYRIC_CURRENT_CLASS, LYRIC_NEXT_CLASS} from './constants';
+import { LYRIC_CURRENT_CLASS, LYRIC_NEXT_CLASS } from './constants'
 
-var lyrics;
+var lyrics
 
 // 歌词解析脚本
 // 修改自:https://github.com/DIYgod/APlayer
 function parse(text) {
-    var lyric = text.split('\n');
-    var lrc   = [];
-    var len   = lyric.length;
-    var reg1  = /\[(\d{2}):(\d{2})\.(\d{2,3})]/g;
-    var reg2  = /\[(\d{2}):(\d{2})\.(\d{2,3})]/;
-    for (var i = 0; i < len; i++) {
-        var time    = lyric[i].match(reg1);
-        var lrcText = lyric[i].replace(reg1, '').replace(/^\s+|\s+$/g, '');
-        // 排除空行
-        if (!lrcText) {
-            continue;
-        }
-        if (time != null) {
-            var timeLen = time.length;
-            for (var j = 0; j < timeLen; j++) {
-                var oneTime = reg2.exec(time[j]);
-                var lrcTime = (oneTime[1]) * 60 + parseInt(oneTime[2]) + parseInt(oneTime[3]) / ((oneTime[3] + '').length === 2 ? 100 : 1000);
-                lrc.push({
-                    time: lrcTime,
-                    text: lrcText
-                });
-            }
-        }
+  var lyric = text.split('\n')
+  var lrc = []
+  var len = lyric.length
+  var reg1 = /\[(\d{2}):(\d{2})\.(\d{2,3})]/g
+  var reg2 = /\[(\d{2}):(\d{2})\.(\d{2,3})]/
+  for (var i = 0; i < len; i++) {
+    var time = lyric[i].match(reg1)
+    var lrcText = lyric[i].replace(reg1, '').replace(/^\s+|\s+$/g, '')
+    // 排除空行
+    if (!lrcText) {
+      continue
     }
-    lrc.sort(function (a, b) {
-        return a.time - b.time;
-    });
+    if (time != null) {
+      var timeLen = time.length
+      for (var j = 0; j < timeLen; j++) {
+        var oneTime = reg2.exec(time[j])
+        var lrcTime =
+          oneTime[1] * 60 +
+          parseInt(oneTime[2]) +
+          parseInt(oneTime[3]) / ((oneTime[3] + '').length === 2 ? 100 : 1000)
+        lrc.push({
+          time: lrcTime,
+          text: lrcText
+        })
+      }
+    }
+  }
+  lrc.sort(function(a, b) {
+    return a.time - b.time
+  })
 
-    lyrics = lrc;
-    return this;
+  lyrics = lrc
+  return this
 }
 
 // 歌词文本解析成DOM结构
 function renderTo(target) {
-    if (!lyrics) {
-        console.error('未指定歌词文本!');
-        return;
-    }
-    var lyricHTML = '';
-    for (let i = 0; i < lyrics.length; i++) {
-        lyricHTML += `<p>${lyrics[i].text}</p>`;
-    }
-    target.innerHTML                        = lyricHTML;
-    target.querySelector('p').className     = LYRIC_CURRENT_CLASS;
-    target.querySelector('p + p').className = LYRIC_NEXT_CLASS;
-    return this;
+  if (!lyrics) {
+    console.error('未指定歌词文本!')
+    return
+  }
+  var lyricHTML = ''
+  for (let i = 0; i < lyrics.length; i++) {
+    lyricHTML += `<p>${lyrics[i].text}</p>`
+  }
+  target.innerHTML = lyricHTML
+  target.querySelector('p').className = LYRIC_CURRENT_CLASS
+  target.querySelector('p + p').className = LYRIC_NEXT_CLASS
+  return this
 }
 
 function currentIndex(time) {
-    if (time < lyrics[0].time) return 0;
-    for (var i = 0, l = lyrics.length; i < l; i++) {
-        if (time >= lyrics[i].time && (!(lyrics[i + 1]) || time <= lyrics[i + 1].time)) {
-            break;
-        }
+  if (time < lyrics[0].time) return 0
+  for (var i = 0, l = lyrics.length; i < l; i++) {
+    if (
+      time >= lyrics[i].time &&
+      (!lyrics[i + 1] || time <= lyrics[i + 1].time)
+    ) {
+      break
     }
-    return i;
+  }
+  return i
 }
 
-export {parse, renderTo, currentIndex};
+export { parse, renderTo, currentIndex }

+ 260 - 217
src/js/main.js

@@ -1,37 +1,46 @@
-import {THEME_DEFAULT, THEME_MINI} from './constants';
-import * as lyric from './lyric';
-import * as utils from './utils';
-import * as spectrum from './spectrum';
-import * as selector from './selector';
-
-var root = typeof window == 'object' && window.window === window ? window :
-    typeof global == 'object' && global.global === global ? global : this;
-
-root.mePlayer = function (options) {
-    // 检查必填选项
-    if (!(options.music && options.music.src)) {
-        console.error('必须指定音乐地址哦~');
-        return;
-    }
-
-    var musicConf         = options.music,
-        target            = selector.$(options.target) || document.querySelector('.meplayer'),
-        theme             = options.theme || THEME_DEFAULT,
-        hasLrc            = musicConf.lrc ? true : false,
-        coverSrc          = musicConf.cover || 'https://unsplash.it/78/?random',
-        loop              = musicConf.loop || false,
-        autoplay          = options.autoplay,
-
-        currentThemeClass = theme === THEME_DEFAULT ? 'meplayer-container' : 'meplayer-container-mini',
-        containerClass    = `${currentThemeClass} ${hasLrc ? 'meplayer-haslrc' : ''} meplayer-isloading`,
-
-        playerHTMLContent = `<div class="${containerClass}">
+import { THEME_DEFAULT, THEME_MINI } from './constants'
+import * as lyric from './lyric'
+import * as utils from './utils'
+import * as spectrum from './spectrum'
+import * as selector from './selector'
+
+var root =
+  typeof window == 'object' && window.window === window
+    ? window
+    : typeof global == 'object' && global.global === global ? global : this
+
+root.mePlayer = function(options) {
+  // 检查必填选项
+  if (!(options.music && options.music.src)) {
+    console.error('必须指定音乐地址哦~')
+    return
+  }
+
+  var musicConf = options.music,
+    target = selector.$(options.target) || document.querySelector('.meplayer'),
+    theme = options.theme || THEME_DEFAULT,
+    hasLrc = musicConf.lrc ? true : false,
+    coverSrc = musicConf.cover || 'https://unsplash.it/78/?random',
+    loop = musicConf.loop || false,
+    autoplay = options.autoplay,
+    currentThemeClass =
+      theme === THEME_DEFAULT
+        ? 'meplayer-container'
+        : 'meplayer-container-mini',
+    containerClass = `${currentThemeClass} ${
+      hasLrc ? 'meplayer-haslrc' : ''
+    } meplayer-isloading`,
+    playerHTMLContent = `<div class="${containerClass}">
                              <audio src=${musicConf.src} preload="auto"></audio>
                              <div class="meplayer-info">
                              <div class="meplayer-info-cover"><img src=${coverSrc} alt="cd-cover"></div>
                              <div class="meplayer-meta">
-                             <div class="meplayer-meta-title">${musicConf.title}</div>
-                             <div class="meplayer-meta-author">${musicConf.author}</div>
+                             <div class="meplayer-meta-title">${
+                               musicConf.title
+                             }</div>
+                             <div class="meplayer-meta-author">${
+                               musicConf.author
+                             }</div>
                              <div class="meplayer-meta-time-tick"><span class="meplayer-meta-time-tick-text"></span></div>
                              </div>
                              </div>
@@ -42,205 +51,239 @@ root.mePlayer = function (options) {
                              <div class="meplayer-duration"><i class="icon-clock"></i><span class="meplayer-duration-text">loading</span></div>
                              <div class="meplayer-loadingsign"><i class="icon-spin animate-spin"></i>loading</div>
                              <div class="meplayer-timeline-bg"><div class="meplayer-timeline"><div class="meplayer-timeline-passed"></div></div></div>
-                             </div>`;
-
-    target.innerHTML = playerHTMLContent;
-
-    var meplayerContainer = target.querySelector(`.${currentThemeClass}`),
-        [audio, playBtn, timeTick, timeCount, timeLine, timePassed, volumeArea, volumeProgress, lyricArea, canvas] = selector.init(meplayerContainer)
-            .select(['audio', '.meplayer-control-play', '.meplayer-meta-time-tick-text', '.meplayer-duration', '.meplayer-timeline',
-                '.meplayer-timeline-passed', '.meplayer-volume', '.meplayer-volume-progress', '.meplayer-lyric-area', '.meplayer-spectrum']),
-
-        duration;
-
-    if (hasLrc) {
-        lyric.parse(musicConf.lrc)
-            .renderTo(lyricArea);
+                             </div>`
+
+  target.innerHTML = playerHTMLContent
+
+  var meplayerContainer = target.querySelector(`.${currentThemeClass}`),
+    [
+      audio,
+      playBtn,
+      timeTick,
+      timeCount,
+      timeLine,
+      timePassed,
+      volumeArea,
+      volumeProgress,
+      lyricArea,
+      canvas
+    ] = selector
+      .init(meplayerContainer)
+      .select([
+        'audio',
+        '.meplayer-control-play',
+        '.meplayer-meta-time-tick-text',
+        '.meplayer-duration',
+        '.meplayer-timeline',
+        '.meplayer-timeline-passed',
+        '.meplayer-volume',
+        '.meplayer-volume-progress',
+        '.meplayer-lyric-area',
+        '.meplayer-spectrum'
+      ]),
+    duration
+
+  if (hasLrc) {
+    lyric.parse(musicConf.lrc).renderTo(lyricArea)
+  } else {
+    // 频谱动画初始化
+    spectrum.init(canvas)
+  }
+
+  eventInit()
+
+  if (autoplay) {
+    handlePlayClick()
+  }
+
+  // 重定义meplayer
+  root.mePlayer = {
+    play: play,
+    pause: pause,
+    toggleTheme: toggleTheme
+  }
+
+  // 给播放器绑定各种事件
+  function eventInit() {
+    audio.addEventListener('ended', handleAudioEnd)
+    audio.addEventListener('canplaythrough', handleCanPlayThrough)
+    audio.addEventListener('durationchange', handleDurationChange)
+    audio.addEventListener('timeupdate', handleTimeUpdate)
+    playBtn.addEventListener('click', handlePlayClick)
+    timeLine.addEventListener('click', handleTimeLineClick)
+  }
+
+  function handleAudioEnd() {
+    if (loop) {
+      audio.play()
     } else {
-        // 频谱动画初始化
-        spectrum.init(canvas);
-    }
-
-    eventInit();
-    
-    if (autoplay) {
-        handlePlayClick()
-    }
-
-    // 重定义meplayer
-    root.mePlayer = {
-        play       : play,
-        pause      : pause,
-        toggleTheme: toggleTheme
-    };
-
-
-    // 给播放器绑定各种事件
-    function eventInit() {
-        audio.addEventListener('ended', handleAudioEnd);
-        audio.addEventListener('canplaythrough', handleCanPlayThrough);
-        audio.addEventListener('durationchange', handleDurationChange);
-        audio.addEventListener('timeupdate', handleTimeUpdate);
-        playBtn.addEventListener('click', handlePlayClick);
-        timeLine.addEventListener('click', handleTimeLineClick);
+      utils.removeClass(meplayerContainer, 'meplayer-isplaying')
     }
-
-
-    function handleAudioEnd() {
-        if(loop){
-            audio.play();
-        }else{
-            utils.removeClass(meplayerContainer, 'meplayer-isplaying');
+  }
+
+  function handleCanPlayThrough() {
+    duration = this.duration
+    setTimeout(function() {
+      utils.removeClass(meplayerContainer, 'meplayer-isloading')
+      timeCount.querySelector(
+        '.meplayer-duration-text'
+      ).innerText = utils.parseSec(duration.toFixed(0))
+    }, 1000)
+  }
+
+  function handleDurationChange() {
+    duration = this.duration
+  }
+
+  function handleTimeUpdate() {
+    var curTime = audio.currentTime
+    var curTimeForLrc = audio.currentTime.toFixed(3)
+    var playPercent = 100 * (curTime / duration)
+
+    timePassed.style.width = playPercent.toFixed(2) + '%'
+    timeTick.innerText = utils.parseSec(curTime)
+
+    if (hasLrc && theme === THEME_DEFAULT) {
+      var tempLrcIndex = lyric.currentIndex(curTimeForLrc)
+      var tempLrcLines = lyricArea.querySelectorAll('p')
+      var tempLrcLinePre = tempLrcLines[tempLrcIndex - 1]
+      var tempLrcLine = tempLrcLines[tempLrcIndex]
+      var tempLrcLineNext = tempLrcLines[tempLrcIndex + 1]
+
+      if (!tempLrcLine.className.includes('meplayer-lyric-current')) {
+        utils.removeClass(
+          lyricArea.querySelector('.meplayer-lyric-current'),
+          'meplayer-lyric-current'
+        )
+        if (lyricArea.querySelector('.meplayer-lyric-pre')) {
+          utils.removeClass(
+            lyricArea.querySelector('.meplayer-lyric-pre'),
+            'meplayer-lyric-pre'
+          )
         }
-    }
-
-    function handleCanPlayThrough() {
-        duration = this.duration;
-        setTimeout(function () {
-            utils.removeClass(meplayerContainer, 'meplayer-isloading');
-            timeCount.querySelector('.meplayer-duration-text').innerText = utils.parseSec(duration.toFixed(0));
-        }, 1000);
-    }
-
-    function handleDurationChange() {
-        duration = this.duration;
-    }
-
-    function handleTimeUpdate() {
-        var curTime       = audio.currentTime;
-        var curTimeForLrc = (audio.currentTime).toFixed(3);
-        var playPercent   = 100 * (curTime / duration);
-
-        timePassed.style.width = playPercent.toFixed(2) + '%';
-        timeTick.innerText     = utils.parseSec(curTime);
-
-        if (hasLrc && theme === THEME_DEFAULT) {
-            var tempLrcIndex    = lyric.currentIndex(curTimeForLrc);
-            var tempLrcLines    = lyricArea.querySelectorAll('p');
-            var tempLrcLinePre  = tempLrcLines[tempLrcIndex - 1];
-            var tempLrcLine     = tempLrcLines[tempLrcIndex];
-            var tempLrcLineNext = tempLrcLines[tempLrcIndex + 1];
-
-            if (!tempLrcLine.className.includes('meplayer-lyric-current')) {
-                utils.removeClass(lyricArea.querySelector('.meplayer-lyric-current'), 'meplayer-lyric-current');
-                if (lyricArea.querySelector('.meplayer-lyric-pre')) {
-                    utils.removeClass(lyricArea.querySelector('.meplayer-lyric-pre'), 'meplayer-lyric-pre');
-                }
-                if (lyricArea.querySelector('.meplayer-lyric-next')) {
-                    utils.removeClass(lyricArea.querySelector('.meplayer-lyric-next'), 'meplayer-lyric-next');
-                }
-                utils.addClass(tempLrcLine, 'meplayer-lyric-current');
-                if (tempLrcLinePre) {
-                    utils.addClass(tempLrcLinePre, 'meplayer-lyric-pre');
-                }
-                if (tempLrcLineNext) {
-                    utils.addClass(tempLrcLineNext, 'meplayer-lyric-next');
-                }
-
-                lyricArea.style.webkitTransform = 'translateY(-' + 20 * tempLrcIndex + 'px)';
-                lyricArea.style.transform       = 'translateY(-' + 20 * tempLrcIndex + 'px)';
-            }
+        if (lyricArea.querySelector('.meplayer-lyric-next')) {
+          utils.removeClass(
+            lyricArea.querySelector('.meplayer-lyric-next'),
+            'meplayer-lyric-next'
+          )
         }
-    }
-
-    function handlePlayClick() {
-        var _handleMouseWheel;
-
-        if (audio.paused) {
-            audio.play();
-            if (theme === THEME_DEFAULT && !hasLrc) {
-                spectrum.draw();
-            }
-            // 播放状态中可以用滑轮调节音量
-            meplayerContainer.addEventListener('mousewheel', function handleMouseWheel() {
-                var timer         = null;
-                var step          = 0.05;
-                _handleMouseWheel = function (event) {
-                    if (timer) {
-                        clearTimeout(timer);
-                    }
-                    if (!meplayerContainer.className.includes('meplayer-adjusting-volume')) {
-                        utils.addClass(meplayerContainer, 'meplayer-adjusting-volume');
-                    }
-                    if (event.wheelDeltaY < 0 && audio.volume > step) {
-                        audio.volume -= step;
-                    }
-                    if (event.wheelDeltaY > 0 && audio.volume < 1 - step) {
-                        audio.volume += step;
-                    }
-                    if (theme === THEME_DEFAULT) {
-                        volumeProgress.style.width = audio.volume * 100 + '%';
-                    } else {
-                        volumeArea.querySelector('i').style.opacity = audio.volume;
-                    }
-                    event.preventDefault();
-
-                    timer = setTimeout(function () {
-                        utils.removeClass(meplayerContainer, 'meplayer-adjusting-volume');
-                    }, 1000);
-                };
-                return _handleMouseWheel;
-            }());
-        } else {
-            audio.pause();
-            spectrum.stop();
-            meplayerContainer.removeEventListener('mousewheel', _handleMouseWheel);
+        utils.addClass(tempLrcLine, 'meplayer-lyric-current')
+        if (tempLrcLinePre) {
+          utils.addClass(tempLrcLinePre, 'meplayer-lyric-pre')
         }
-        utils.toggleClass(meplayerContainer, 'meplayer-isplaying');
-    }
-
-    function handleTimeLineClick() {
-        var clickPercent       = (event.pageX - utils.getAbsLeft(this)) / this.offsetWidth;
-        timePassed.style.width = clickPercent * 100 + '%';
-        audio.currentTime      = (clickPercent * duration).toFixed(0);
-    }
-
-
-    function play() {
-        if (audio.paused) {
-	        utils.addClass(meplayerContainer, 'meplayer-isplaying');
-            audio.play();
+        if (tempLrcLineNext) {
+          utils.addClass(tempLrcLineNext, 'meplayer-lyric-next')
         }
-    }
 
-    function pause() {
-        if (!audio.paused) {
-	        utils.removeClass(meplayerContainer, 'meplayer-isplaying');
-            audio.pause();
-        }
+        lyricArea.style.webkitTransform =
+          'translateY(-' + 20 * tempLrcIndex + 'px)'
+        lyricArea.style.transform = 'translateY(-' + 20 * tempLrcIndex + 'px)'
+      }
     }
-
-    function toggleTheme() {
-        var step     = 0.03;
-        var count    = 0;
-        var maxCount = 200;
-
-        utils.addClass(meplayerContainer, 'meplayer-changing-theme');
-
-        theme = theme === THEME_DEFAULT ? THEME_MINI : THEME_DEFAULT;
-
-        loop();
-
-        function loop() {
-            count++;
-            meplayerContainer.style.opacity -= step;
-            if (meplayerContainer.style.opacity <= 0) {
-                step *= -1;
-                meplayerContainer.style.opacity = 0;
-                utils.toggleClass(meplayerContainer, 'meplayer-container-mini');
-                utils.toggleClass(meplayerContainer, 'meplayer-container');
+  }
+
+  function handlePlayClick() {
+    var _handleMouseWheel
+
+    if (audio.paused) {
+      audio.play()
+      if (theme === THEME_DEFAULT && !hasLrc) {
+        spectrum.draw()
+      }
+      // 播放状态中可以用滑轮调节音量
+      meplayerContainer.addEventListener(
+        'mousewheel',
+        (function handleMouseWheel() {
+          var timer = null
+          var step = 0.05
+          _handleMouseWheel = function(event) {
+            if (timer) {
+              clearTimeout(timer)
+            }
+            if (
+              !meplayerContainer.className.includes('meplayer-adjusting-volume')
+            ) {
+              utils.addClass(meplayerContainer, 'meplayer-adjusting-volume')
+            }
+            if (event.wheelDeltaY < 0 && audio.volume > step) {
+              audio.volume -= step
             }
-            if (meplayerContainer.style.opacity < 1 && count < maxCount) {
-                requestAnimationFrame(loop);
+            if (event.wheelDeltaY > 0 && audio.volume < 1 - step) {
+              audio.volume += step
+            }
+            if (theme === THEME_DEFAULT) {
+              volumeProgress.style.width = audio.volume * 100 + '%'
             } else {
-                setTimeout(function () {
-                    utils.removeClass(meplayerContainer, 'meplayer-changing-theme');
-                }, 500);
+              volumeArea.querySelector('i').style.opacity = audio.volume
             }
-        }
+            event.preventDefault()
+
+            timer = setTimeout(function() {
+              utils.removeClass(meplayerContainer, 'meplayer-adjusting-volume')
+            }, 1000)
+          }
+          return _handleMouseWheel
+        })()
+      )
+    } else {
+      audio.pause()
+      spectrum.stop()
+      meplayerContainer.removeEventListener('mousewheel', _handleMouseWheel)
     }
-};
+    utils.toggleClass(meplayerContainer, 'meplayer-isplaying')
+  }
+
+  function handleTimeLineClick() {
+    var clickPercent = (event.pageX - utils.getAbsLeft(this)) / this.offsetWidth
+    timePassed.style.width = clickPercent * 100 + '%'
+    audio.currentTime = (clickPercent * duration).toFixed(0)
+  }
+
+  function play() {
+    if (audio.paused) {
+      utils.addClass(meplayerContainer, 'meplayer-isplaying')
+      audio.play()
+    }
+  }
+
+  function pause() {
+    if (!audio.paused) {
+      utils.removeClass(meplayerContainer, 'meplayer-isplaying')
+      audio.pause()
+    }
+  }
+
+  function toggleTheme() {
+    var step = 0.03
+    var count = 0
+    var maxCount = 200
+
+    utils.addClass(meplayerContainer, 'meplayer-changing-theme')
+
+    theme = theme === THEME_DEFAULT ? THEME_MINI : THEME_DEFAULT
+
+    loop()
+
+    function loop() {
+      count++
+      meplayerContainer.style.opacity -= step
+      if (meplayerContainer.style.opacity <= 0) {
+        step *= -1
+        meplayerContainer.style.opacity = 0
+        utils.toggleClass(meplayerContainer, 'meplayer-container-mini')
+        utils.toggleClass(meplayerContainer, 'meplayer-container')
+      }
+      if (meplayerContainer.style.opacity < 1 && count < maxCount) {
+        requestAnimationFrame(loop)
+      } else {
+        setTimeout(function() {
+          utils.removeClass(meplayerContainer, 'meplayer-changing-theme')
+        }, 500)
+      }
+    }
+  }
+}
 
 if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
-    module.exports = root.mePlayer;
+  module.exports = root.mePlayer
 }

+ 22 - 22
src/js/selector.js

@@ -5,37 +5,37 @@
  * $     : 辅助功能,使得无论传入选择器字符串还是元素本身,都能返回正确的元素
  */
 
-var container;
+var container
 
 function init(element) {
-    container = $(element);
-    return this;
+  container = $(element)
+  return this
 }
 
 function select(element) {
-    var result;
-    if (Array.isArray(element)) {
-        let tempResults = [];
-        for (let value of element) {
-            tempResults.push($(value, container));
-        }
-        result = tempResults;
-    } else {
-        result = $(element, container);
+  var result
+  if (Array.isArray(element)) {
+    let tempResults = []
+    for (let value of element) {
+      tempResults.push($(value, container))
     }
-    return result;
+    result = tempResults
+  } else {
+    result = $(element, container)
+  }
+  return result
 }
 
 function $(element, context) {
-    var result;
-    context = context || document;
-    if (typeof element === 'string') {
-        result = context.querySelector(element);
-    } else if (element.toString().includes('HTMLDivElement')) {
-        result = element;
-    }
+  var result
+  context = context || document
+  if (typeof element === 'string') {
+    result = context.querySelector(element)
+  } else if (element.toString().includes('HTMLDivElement')) {
+    result = element
+  }
 
-    return result;
+  return result
 }
 
-export {init, select, $};
+export { init, select, $ }

+ 64 - 59
src/js/spectrum.js

@@ -1,83 +1,88 @@
 /*
  * 频谱动画模拟
  * */
-var canvas, ctx,
-    specItems = [],
-    needStop  = false,
-    timer     = null,
-
-    random    = Math.random;
+var canvas,
+  ctx,
+  specItems = [],
+  needStop = false,
+  timer = null,
+  random = Math.random
 
 function randHeight() {
-    if (random() > 0.8) {
-        return random() * 8 + 11;
-    } else {
-        return random() * 6 + 2;
-    }
+  if (random() > 0.8) {
+    return random() * 8 + 11
+  } else {
+    return random() * 6 + 2
+  }
 }
 
-var randHeightGenerator = function (base) {
-    var max        = base * 1.5 > 28 ? 28 : base * 1.5,
-        min        = 1,
-        direction  = random() > 0.5 ? 1 : -1,
-        tempHeight = base,
-        curStep;
-    return function () {
-        curStep = direction;
-        tempHeight += curStep;
-        if (tempHeight >= max) {
-            direction *= -1;
-            tempHeight = max;
-        } else if (tempHeight <= min) {
-            direction *= -1;
-            tempHeight = min;
-        }
-        if (random() > 0.9) {
-            direction *= -1;
-        }
-        return tempHeight;
+var randHeightGenerator = function(base) {
+  var max = base * 1.5 > 28 ? 28 : base * 1.5,
+    min = 1,
+    direction = random() > 0.5 ? 1 : -1,
+    tempHeight = base,
+    curStep
+  return function() {
+    curStep = direction
+    tempHeight += curStep
+    if (tempHeight >= max) {
+      direction *= -1
+      tempHeight = max
+    } else if (tempHeight <= min) {
+      direction *= -1
+      tempHeight = min
+    }
+    if (random() > 0.9) {
+      direction *= -1
     }
-};
+    return tempHeight
+  }
+}
 
 function loop() {
-    ctx.clearRect(0, -canvas.height / 2, canvas.width, canvas.height);
-    for (var i = 0; i < specItems.length; i++) {
-        var item   = specItems[i];
-        var height = item.getHeight();
-        ctx.fillRect(i + specItems[i].xSpace, -height / 2, specItems[i].width, height);
-    }
+  ctx.clearRect(0, -canvas.height / 2, canvas.width, canvas.height)
+  for (var i = 0; i < specItems.length; i++) {
+    var item = specItems[i]
+    var height = item.getHeight()
+    ctx.fillRect(
+      i + specItems[i].xSpace,
+      -height / 2,
+      specItems[i].width,
+      height
+    )
+  }
 
-    if (!needStop) {
-        timer = requestAnimationFrame(loop);
-    }
+  if (!needStop) {
+    timer = requestAnimationFrame(loop)
+  }
 }
 
 function init(canvasElem, width = 220, height = 30, color = '#D94240') {
-    canvas        = canvasElem;
-    canvas.width  = width;
-    canvas.height = height;
-    ctx           = canvas.getContext('2d');
-    ctx.fillStyle = color;
-    ctx.translate(0, height / 2);
+  canvas = canvasElem
+  canvas.width = width
+  canvas.height = height
+  ctx = canvas.getContext('2d')
+  ctx.fillStyle = color
+  ctx.translate(0, height / 2)
 
-    for (let i = 0; i < 64; i++) {
-        var xSpace   = i == 0 ? 0 : 5 * i;
-        var tempItem = {
-            xSpace   : xSpace,
-            width    : 1,
-            getHeight: randHeightGenerator(randHeight())
-        };
-        specItems.push(tempItem);
+  for (let i = 0; i < 64; i++) {
+    var xSpace = i == 0 ? 0 : 5 * i
+    var tempItem = {
+      xSpace: xSpace,
+      width: 1,
+      getHeight: randHeightGenerator(randHeight())
     }
+    specItems.push(tempItem)
+  }
 }
 
 function draw() {
-    needStop = false;
-    loop();
+  needStop = false
+  loop()
 }
 
 function stop() {
-    needStop = true;
+  needStop = true
 }
 
-export {init, draw, stop};
+export { init, draw, stop }

+ 29 - 31
src/js/utils.js

@@ -1,48 +1,46 @@
 function toggleClass(el, className) {
-    if (el.classList) {
-        el.classList.toggle(className);
-    } else {
-        var classes       = el.className.split(' ');
-        var existingIndex = classes.indexOf(className);
+  if (el.classList) {
+    el.classList.toggle(className)
+  } else {
+    var classes = el.className.split(' ')
+    var existingIndex = classes.indexOf(className)
 
-        if (existingIndex >= 0)
-            classes.splice(existingIndex, 1);
-        else
-            classes.push(className);
+    if (existingIndex >= 0) classes.splice(existingIndex, 1)
+    else classes.push(className)
 
-        el.className = classes.join(' ');
-    }
+    el.className = classes.join(' ')
+  }
 }
 
 function addClass(el, className) {
-    if (el.classList)
-        el.classList.add(className);
-    else
-        el.className += ' ' + className;
+  if (el.classList) el.classList.add(className)
+  else el.className += ' ' + className
 }
 
 function removeClass(el, className) {
-    if (el.classList)
-        el.classList.remove(className);
-    else
-        el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
+  if (el.classList) el.classList.remove(className)
+  else
+    el.className = el.className.replace(
+      new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'),
+      ' '
+    )
 }
 
 function getAbsLeft(el) {
-    var left = el.offsetLeft;
-    while (el.offsetParent) {
-        el = el.offsetParent;
-        left += el.offsetLeft;
-    }
-    return left;
+  var left = el.offsetLeft
+  while (el.offsetParent) {
+    el = el.offsetParent
+    left += el.offsetLeft
+  }
+  return left
 }
 
 function parseSec(sec) {
-    var tempMin = (sec / 60) | 0;
-    var tempSec = (sec % 60) | 0;
-    var curMin  = tempMin < 10 ? ('0' + tempMin) : tempMin;
-    var curSec  = tempSec < 10 ? ('0' + tempSec) : tempSec;
-    return curMin + ':' + curSec;
+  var tempMin = (sec / 60) | 0
+  var tempSec = (sec % 60) | 0
+  var curMin = tempMin < 10 ? '0' + tempMin : tempMin
+  var curSec = tempSec < 10 ? '0' + tempSec : tempSec
+  return curMin + ':' + curSec
 }
 
-export {toggleClass, addClass, removeClass, getAbsLeft, parseSec};
+export { toggleClass, addClass, removeClass, getAbsLeft, parseSec }