如何为YouTube嵌入动画制作自定义进度条?

时间:2016-06-02 03:52:54

标签: javascript youtube

有关YouTube视频不断发展的信息,很难制作出流畅的动画制作进度条。即使是YouTube内置的进度条也不顺畅。但我认为必须有办法做到这一点。

我使用自定义控件进行YouTube嵌入,我的进度条正在以一种跳跃的方式而不是顺利进行。这是代码:

vidClock = setInterval(function() {
    if (state == 1) {
        var time = player.getCurrentTime();
        var percent = (time / duration) * 100;
        $seekSlider.css({
            'width' : percent + '%'
        });
    }
}, 100);

这个变量起源并未全部显示,但它们代表的内容应该是显而易见的。如何让酒吧顺利移动?

我尝试在元素中添加CSS过渡效果,并尝试设置较小的间隔,例如10,20和30(在建议之后,尝试使用JQuery动画)。

示例,根据以下答案建议使用$.animate并不顺利:http://jsfiddle.net/e11oy0eu/290/

4 个答案:

答案 0 :(得分:2)

您可以使用.animate()函数:

vidClock = setInterval(function() {
    if (state == 1) {
        var time = player.getCurrentTime();
        var percent = (time / duration) * 100;
        $seekSlider.animate({
            'width' : percent + '%'
        },500);
    }
}, 500);

或者使用CSS动画:

CSS:

.progress {
    width: 0%;
    height: 100%;
    background-color: green;
    transition: all 0.5s linear;
}

JS:

vidClock = setInterval(function() {
    if (state == 1) {
        var time = player.getCurrentTime();
        var percent = (time / duration) * 100;
        $seekSlider.css({
            'width' : percent + '%'
        });
    }
}, 500);

答案 1 :(得分:2)

我选择了一种不同的方法来解决您的问题,首先我将Velocity.js添加到项目中,因为Alon在他的回答中说,它为您提供了更好的动画,然后而不是设置计时器并根据播放器的当前时间更改进度条大小,我创建了一个进度条,始终动画为100%,然后使用一些事件来停止视频播放停止时(由用户或停止缓冲时)的进度条。虽然这种策略有其缺点,但它可以让您获得更流畅的动画。

另外,对于更平滑的动画,我将.progress div的位置更改为absolute而不是更改div宽度,并使用transform:translateX属性移动它。我不确定这种变化有多大效果,也许根本没有效果。)

.progress-container {
  width: 640px;
  height: 30px;
  background-color: #efefef;
  position: relative;
  overflow: hidden;
}

.progress {
  width: 100%;
  height: 100%;
  background-color: green;
  position: absolute;
  left: -100%;
  top: 0;
}

在这些更改之后,handleState函数如下所示:

function handleState(state) {
  var $seekSlider = $('.progress');
  var $seekContainer = $('.progress-container');

  if (state == 1) { // when player starts playing
    duration = player.getDuration();
    currentTime = player.getCurrentTime();
    currentLocation = ((currentTime/duration) * 100).toFixed(4);

    $seekSlider
      .velocity('stop')
      .velocity({
        'translateX': currentLocation + '%'
      }, {duration: 0})
      .velocity({
        'translateX': '100%'
      }, {
        duration: Math.floor((duration-currentTime) * 1000),
        easing: 'linear'
      });
  }

  if (state == 2 || state == 3 || state == 0) {
    $seekSlider.velocity('stop');

    if (state == 3) {
      duration = player.getDuration();
      currentTime = player.getCurrentTime();
      currentLocation = ((currentTime/duration) * 100).toFixed(4);

      $seekSlider.velocity({
        'translateX': currentLocation + '%'
      }, {duration: 0});
    }

    if (state == 0) {
        $seekSlider.velocity({
        'translateX': '100%'
      }, {duration: 0});
    }
  }
}

您可以在this JSFiddle中查看工作结果和完整代码以及一些评论,另外我创建了一个gist,其中显示了您的脚本与我的脚本之间的差异。

答案 2 :(得分:2)

粗略的进展不仅是由getCurrentTime函数引起的,还是由您调整进度条的方式引起的。即使您以百分比设置CSS width,它也将始终呈现为整像素。您可以使用transform代替,这也会渲染“半”像素。

接下来,为了克服getCurrentTime每次调用不更新的限制,您可以将其值保存在变量中,并使用定时器间隔手动增加它:

function handleState(state) {
  var $seekSlider = $('.progress');
  var $seekContainer = $('.progress-container');
  if (state == 1) {
    duration = player.getDuration();
    var prevTime = 0;
    var elapsed = 0;
    vidClock = setInterval(function() {
      elapsed += 0.05; // Increase with timer interval
      if ((state == 1) && (seeking == false)) {
        var time = player.getCurrentTime();
        if (time != prevTime) {
          elapsed = time; // Update if getCurrentTime was changed
          prevTime = time;
        }
        var percent = (elapsed / duration);
        $seekSlider.css({
          'transform': 'scaleX(' + percent + ')'
        });
      }
    }, 50);
  } else {
    clearInterval(vidClock);
  }
}

请参阅updated fiddle

答案 3 :(得分:1)

您可以使用Velocity.js。它的动画比jQuery更顺畅,配置就像jQuery一样简单。

看看这个比较:http://webdesign.tutsplus.com/tutorials/silky-smooth-web-animation-with-velocityjs--cms-24266