美文网首页
4.qq音乐练习3 进度条

4.qq音乐练习3 进度条

作者: wudimingwo | 来源:发表于2018-12-02 16:13 被阅读0次

step1
更新alltime功能
pro.js

// 进度条模块

(function ($,root) {
    // 渲染总时间 根据 duration
    
    function renderalltime (time) {
        $body = $(document.body);
        time = format(time);
        $body.find('.all-time').html(time);
        
    }
    // 转换时间格式
    function format (time) {
        var m = parseInt(time/60);
        var s = time%60;
        m = ('0' + m).slice(-2); 
        s = ('0' + s).slice(-2); 
        return (m + ':' + s);
        
    }
    
    root.pro = {
      renderalltime,
    }
    
})(window.Zepto ,window.player || (window.player = {}));

step2
渲染 播放计时

// 进度条模块

(function ($,root) {
    // 渲染总时间 根据 duration
    var duration;
    var $body = $(document.body);
    var frameId;
    var lastper = 0;
    var starttime;
    function renderalltime (time) {
      duration = time;
        time = format(time);
        $body.find('.all-time').html(time);
    }
    // 转换时间格式
    function format (time) {
      time = Math.round(time);
        var m = Math.round(time/60);
        var s = time%60;
        m = ('0' + m).slice(-2); 
        s = ('0' + s).slice(-2); 
        return (m + ':' + s);
        
    }
    
    function start () {
        starttime = new Date().getTime();
        function frame () {
            var currentTime = new Date().getTime();
            var percent = lastper + (currentTime - starttime) / (duration * 1000);
//          console.log(lastper);
            update(percent);
            frameId = requestAnimationFrame(frame);
        }
        frame();
        
    }
    
    function stop () {
      cancelAnimationFrame(frameId);
      var stoptime = new Date().getTime();
      console.log(stoptime - starttime);
      lastper += (stoptime - starttime) / (duration * 1000);
    }
    
    function update (p) {
        var time = p * duration;
        time = format(time);
        $body.find('.current-time').html(time);
    }
    
    
    
    root.pro = {
      renderalltime,
      start,
      update,
      stop,
    }
    
})(window.Zepto ,window.player || (window.player = {}));

step3
控制条
样式部分
index.less

.pro-wrap{
                    flex: 1;
                    position: relative;
                    overflow: hidden;
                    >div{// 这是坑, 如果不加这个默认后代都会被设上.以前没注意.
                        position: absolute;
                        width: 100%;
                        height: 2px;
                        left: 0;
                        right: 0;
                        top: 0;
                        bottom: 0;
                        margin: auto;
                    }
                    .pro-bottom{
                        background-color: rgba(200,200,200,0.8);
                    }
                    .pro-top{
                        background-color: rgba(240,240,240,1);
                        height: 3px;
                        transform: translateX(-100%);
                        .slider{
                            position: absolute;
                            width: 15px;
                            height: 15px;
                            border-radius: 50%;
                            right: -15px;
                            top: 0;
                            bottom: 0;
                            margin: auto;
                            background-color: #fff;
                        }
                    }
                }

pro.js

    function update (p) {
        var time = p * duration;
        time = format(time);
        $body.find('.current-time').html(time);
        var pX = (p - 1) * 100 + "%";
        $body.find(".pro-top").css({
          'transform' : 'translateX(' + pX +')'
        })
    }

step4
pro.js
实现拖拽

// 进度条模块

(function ($,root) {
    // 渲染总时间 根据 duration
    var duration;
    var $body = $(document.body);
    var frameId;
    var lastper = 0;
    var starttime;
    function renderalltime (time) {
      duration = time;
        time = format(time);
        lastper = 0;
        starttime = 0;
        $body.find('.all-time').html(time);
    }
    // 转换时间格式
    function format (time) {
      time = Math.round(time);
        var m = Math.round(time/60);
        var s = time%60;
        m = ('0' + m).slice(-2); 
        s = ('0' + s).slice(-2); 
        return (m + ':' + s);
        
    }
    
    function start (per) {
        lastper = per == undefined ? lastper : per;
      cancelAnimationFrame(frameId);
      starttime = new Date().getTime();
        function frame () {
            var currentTime = new Date().getTime();
            var percent = lastper + (currentTime - starttime) / (duration * 1000);
//          console.log(lastper);
            update(percent);
            frameId = requestAnimationFrame(frame);
        }
        frame();
        
    }
    
    function stop () {
      cancelAnimationFrame(frameId);
      var stoptime = new Date().getTime();
      console.log(stoptime - starttime);
      lastper += (stoptime - starttime) / (duration * 1000);
    }
    
    function update (p) {
        var time = p * duration;
        time = format(time);
        $body.find('.current-time').html(time);
        var pX = (p - 1) * 100 + "%";
        $body.find(".pro-top").css({
          'transform' : 'translateX(' + pX +')'
        })
    }
    
    
    
    root.pro = {
      renderalltime,
      start,
      update,
      stop,
    }
    
})(window.Zepto ,window.player || (window.player = {}));

index.js

var root = window.player;
//var nowIndex = 0;
var dataLength = null;
var dataclone;
var url = '../mock/data.json';

var audio = root.audioManager;

var control;

var timer;
var duration = 0;

root.gaussBlur = gaussBlur;

function getData(url) {
  $.ajax({
    type: "GET",
    url: url,
    async: true,
    success: function(data) {
      console.log(data[2]);
      dataLength = data.length;
      dataclone = data;
      control = new root.controlIndex(dataLength);
      var i = control.index;
      root.render(data[i]);
      audio.getAudio(data[i].audio);
      duration = dataclone[i].duration;
      root.pro.renderalltime(duration);
      audio.audio.onloadedmetadata = function () {
        console.log(audio.audio.duration);
      }
      bindEvent();
    },
    error: function() {
      console.log("error");
    }
  });
}

function bindEvent() {

  $("body").on("play:change", function(e, index) {

    audio.getAudio(dataclone[index].audio);
    audio.play();
    $(".icon-PLAY").removeClass('icon-PLAY').addClass('icon-stop');
    root.render(dataclone[index]);
    rotate();
    root.pro.renderalltime(dataclone[index].duration);
    $(".img-box").css({
      'transform': 'rotateZ(0deg)',
      'transition': 'none'
    });
  })

  $(".pre").on('click', function() {
    var i = control.pre();
    $("body").trigger("play:change", i);
    root.pro.start();
  });
  $(".next").on('click', function() {
    var i = control.next();
    $("body").trigger("play:change", i);
    root.pro.start();
  });

  $(".play").on('click', function() {
    // 图案变成 暂停
    // 音乐停止播放
    // 图片停止旋转.

    if(audio.state == 'play') {
      $(".icon-stop").removeClass('icon-stop').addClass('icon-PLAY');
      audio.pause();
      //    var reg = /\d+/g;
      //    var deg = $(".img-box").css('transform').match(reg)[0];
      //    $(".img-box").attr('data-deg',deg);
      root.pro.stop();
      clearInterval(timer);
    } else if(audio.state == 'pause') {
      $(".icon-PLAY").removeClass('icon-PLAY').addClass('icon-stop');
      audio.play();
      root.pro.start();
      rotate();
    }

  })
}

function bindTouch() {
    var $body = $(document.body);
    var $slider = $body.find('.slider');
    var offset = $slider.offset();
    var left = offset.left;
    var width = $slider.parent().offset().width;
    $slider.on("touchstart",function (e) {
        root.pro.stop();
    }).on("touchmove",function (e) {
        var x = e.changedTouches[0].clientX;
        var per = (x - left) / width;
        // 需要存进去.
        console.log(per,duration,per*duration);
        if (per < 1 && per > 0) {
          root.pro.update(per);
        }
        
    }).on("touchend",function (e) {
        var x = e.changedTouches[0].clientX;
    var per = (x - left) / width;
    if (per < 1 && per > 0) {
      audio.playTo(duration * per);
      root.pro.start(per);
    }
    })
}

bindTouch();

function rotate() {
  clearInterval(timer);
  //  var deg = Number($(".img-box").attr('data-deg')) || 0;
  var deg = 0;
  timer = setInterval(function() {
    deg += 2;
    $(".img-box").css({
      'transform': 'rotateZ(' + deg + 'deg)',
      'transition': 'transform .2s ease-in-out'
    });
  }, 200);
}

getData("../mock/data.json");

拖拽 到达临界点的时候有问题.
而且会出现数值超过all-time的情况


image.png

这个问题出在
format 时间转换中

不能是    
var m = Math.round(time / 60);
    var m = Math.floor(time / 60);

还有一个问题是, 这个计算不准的原因,可能是我拖动所求的百分比有问题.
因为样式部分的设置,视频里没有交代,
所以这部分可能有所出入,
可以稍微改一下求百分比的方式.

pro.js

// 进度条模块

(function($, root) {
  // 渲染总时间 根据 duration
  var duration;
  var $body = $(document.body);
  var frameId;
  var lastper = 0;
  var starttime;

  function renderalltime(time) {
    duration = time;
    time = format(time);
    lastper = 0;
    starttime = 0;
    $body.find('.all-time').html(time);
  }
  // 转换时间格式
  function format(time) {
    time = Math.round(time);
    var m = Math.floor(time / 60);
    var s = time % 60;
    m = ('0' + m).slice(-2);
    s = ('0' + s).slice(-2);
    return(m + ':' + s);

  }

  function start(per) {
    lastper = per == undefined ? lastper : per;
    cancelAnimationFrame(frameId);
    starttime = new Date().getTime();

    function frame() {
      var currentTime = new Date().getTime();
      var percent = lastper + (currentTime - starttime) / (duration * 1000);
      update(percent);
      frameId = requestAnimationFrame(frame);
      if(percent >= 1) {
        percent = 0;
        lastper = 0;
        update(0);
      }
    }
    frame();

  }

  function stop() {
    cancelAnimationFrame(frameId);
    var stoptime = new Date().getTime();
    console.log(stoptime - starttime);
    lastper += (stoptime - starttime) / (duration * 1000);
  }

  function update(p) {
    var time = p * duration;
    time = format(time);
    $body.find('.current-time').html(time);
    var pX = (p - 1) * 100 + "%";
    $body.find(".pro-top").css({
      'transform': 'translateX(' + pX + ')'
    })
  }

  root.pro = {
    renderalltime,
    start,
    update,
    stop,
  }

})(window.Zepto, window.player || (window.player = {}));

index.js

var root = window.player;
//var nowIndex = 0;
var dataLength = null;
var dataclone;
var url = '../mock/data.json';

var audio = root.audioManager;

var control;

var timer;
var duration = 0;

root.gaussBlur = gaussBlur;

function getData(url) {
  $.ajax({
    type: "GET",
    url: url,
    async: true,
    success: function(data) {
      console.log(data[2]);
      dataLength = data.length;
      dataclone = data;
      control = new root.controlIndex(dataLength);
      var i = control.index;
      root.render(data[i]);
      audio.getAudio(data[i].audio);
      duration = dataclone[i].duration;
      root.pro.renderalltime(duration);
      audio.audio.onloadedmetadata = function() {
        console.log(audio.audio.duration);
      }
      bindEvent();
    },
    error: function() {
      console.log("error");
    }
  });
}

function bindEvent() {

  $("body").on("play:change", function(e, index) {

    audio.getAudio(dataclone[index].audio);
    audio.play();
    $(".icon-PLAY").removeClass('icon-PLAY').addClass('icon-stop');
    root.render(dataclone[index]);
    rotate();
    root.pro.renderalltime(dataclone[index].duration);
    $(".img-box").css({
      'transform': 'rotateZ(0deg)',
      'transition': 'none'
    });
  })

  $(".pre").on('click', function() {
    var i = control.pre();
    $("body").trigger("play:change", i);
    root.pro.start();
  });
  $(".next").on('click', function() {
    var i = control.next();
    $("body").trigger("play:change", i);
    root.pro.start();
  });

  $(".play").on('click', function() {
    // 图案变成 暂停
    // 音乐停止播放
    // 图片停止旋转.

    if(audio.state == 'play') {
      $(".icon-stop").removeClass('icon-stop').addClass('icon-PLAY');
      audio.pause();
      //    var reg = /\d+/g;
      //    var deg = $(".img-box").css('transform').match(reg)[0];
      //    $(".img-box").attr('data-deg',deg);
      root.pro.stop();
      clearInterval(timer);
    } else if(audio.state == 'pause') {
      $(".icon-PLAY").removeClass('icon-PLAY').addClass('icon-stop');
      audio.play();
      root.pro.start();
      rotate();
    }

  })
}

function bindTouch() {
  var $body = $(document.body);
  var $slider = $body.find('.slider');
  var offset = $slider.parent().offset();
  var left = $slider.offset().left;
  var width = offset.width;
  var length;
  $slider.on("touchstart", function(e) {
    root.pro.stop();
  }).on("touchmove", function(e) {
    length = e.changedTouches[0].clientX - left;
    var per = length / width;
    // 需要存进去.
    if(per < 1 && per > 0) {
      root.pro.update(per);
    }

  }).on("touchend", function(e) {
    length = e.changedTouches[0].clientX - left;
    var per = length / width;
    if(per < 1 && per > 0) {
      audio.playTo(duration * per);
      root.pro.start(per);
    }else if (per >= 1) {
        audio.playTo(duration);
      root.pro.start(per);
    }else if (per <= 0){
      audio.playTo(0);
      root.pro.start(0);
    }
  })
}

bindTouch();

function rotate() {
  clearInterval(timer);
  //  var deg = Number($(".img-box").attr('data-deg')) || 0;
  var deg = 0;
  timer = setInterval(function() {
    deg += 2;
    $(".img-box").css({
      'transform': 'rotateZ(' + deg + 'deg)',
      'transition': 'transform .2s ease-in-out'
    });
  }, 200);
}

getData("../mock/data.json");

开始跟着写这个之前,感觉会非常的简单.
可是写到越往后的时候,就觉得越复杂.
比如知道 写这个control之前都很简单,
单写这一个control也很简单,
但在之前的基础之上, 再写这个control的时候,
就感觉有点复杂.
为什么会复杂呢?

相关文章

  • 4.qq音乐练习3 进度条

    step1更新alltime功能pro.js step2渲染 播放计时 step3控制条样式部分index.les...

  • 2018-03-19 音乐播放器(一)

    笔记如下 进度条跟随音乐播放滑动 音乐暂停的方法

  • SeekBar的用法

    1)ProgressBar (一般进度条,例如:下载进度条)2)SeekBar(拖动条,适用于音乐,视频播放进度条...

  • 前端常用的正则 以及 input正则验证

    前端常用的正则 1.字母、数字、中文、小数 2.日期 3.手机号、座机 4.qq、微信、email 5.用户名、密...

  • js实现手机端音频进度条拖拽

    主要功能:1、支持点击进度条调整播放的位置2、显示音乐的播放时间3、暂停播放等~ js html css 未实现功...

  • 2019-04-30

    1.solo练习圆三角方形 2.grow move 先音乐再beat 73开 3.音乐风格了解 4.基本功练习,元...

  • 常用搜索引擎集合

    1.谷歌2.百度3.淘宝4.QQ群 设计SDC设计师网址导航 CCsearch 无版权素材图片搜索引擎Soogif...

  • IOS开发 UISlider和UIProgressView

    进度条和滑动动条控件 本节学习内容: 1.进度条和滑动条的概念 2.进度条和滑动条的属性 3.进度条和滑动条的使用...

  • 《第一行代码》学习笔记 第 3 章

    第 3 章 UI 开发的点点滴滴 一:ProgressBar 默认为旋转进度条 修改为水平进度条在布局中修改进度条...

  • 直播序目

    1.QQ 我得到的一次奖励 2.QQ 你想减肥吗 3.QQ 投诉电话可以这样打 4.QQ 小区停电《一段琐事》 5...

网友评论

      本文标题:4.qq音乐练习3 进度条

      本文链接:https://www.haomeiwen.com/subject/flzdcqtx.html