LoginSignup
0
0

More than 1 year has passed since last update.

Video.jsでスキップボタンを実装する

Last updated at Posted at 2023-03-19

YouTubeでやってるやつをVideo.jsでもやりたい。要するにこういうやつ。

Screenshot from 2023-03-19 21-48-02.png

で、それっぽいものができた。

デモはここ(JSBin)。このデモの元は公式のこれ(JSBin)になる。

解説

Video.jsのComponentを使うことで、プレイヤー内に操作できる要素を追加できる。

// Get the Component base class from Video.js
var Component = videojs.getComponent('Component');

// add skip button
var skipFwd = videojs.extend(Component, {
  constructor: function(player, options) {
    Component.apply(this, arguments)
  },
  createEl: function() {
    return videojs.createEl('div', {
      className: 'vjs-skip vjs-skip-fwd'
    })
  }
})
var skipBwd = videojs.extend(Component, {
  constructor: function(player, options) {
    Component.apply(this, arguments)
  },
  createEl: function() {
    return videojs.createEl('div', {
      className: 'vjs-skip vjs-skip-bwd'
    })
  }
})
// register skip button to videojs
videojs.registerComponent('skipFwd', skipFwd)
videojs.registerComponent('skipBwd', skipBwd)

上のコードはプレイヤーのComponentを取得して、追加要素skipFwd, skipBwdを定義し、Componentとして追加登録している。createElのAPI referenseを見るとこの定義内でイベントハンドラも定義できるようであるが、試したところイベントの要素をうまく渡す方法がわからなかったので、ここではdivの追加だけにとどめ、イベントハンドラは別のところで定義している。

// Create a player.
var player = videojs('my-player');
// add chile node to player
player.addChild('skipFwd')
player.addChild('skipBwd')

実際にプレイヤーのインスタンスを作成して、子要素として先程登録したComponentであるskipFwd, skipBwdを登録する。

document.getElementsByClassName('vjs-skip-fwd')[0].addEventListener('click', function(e) {
  videojs('my-player').currentTime(videojs('my-player').currentTime() + 5)
  setRipple(e.target, e.layerX, e.layerY)
})
document.getElementsByClassName('vjs-skip-bwd')[0].addEventListener('click', function(e) {
  videojs('my-player').currentTime(videojs('my-player').currentTime() - 5)
  setRipple(e.target, e.layerX, e.layerY)
})

追加したdivを取得して、イベントハンドラを追加する。リップルエフェクトをつけるための関数をここから呼び出している。

// add ripple effect
function setRipple(parentDom, x, y) {
  var rippledom = document.createElement('span')
  rippledom.style.setProperty('left', x-75+'px')
  rippledom.style.setProperty('top', y-75+'px')
  rippledom.setAttribute('class', 'vja-skip ripple')
  parentDom.appendChild(rippledom)
  setTimeout(() => {
    var rip = document.getElementByClassName('ripple')
    for (var i = 0; i < rip.length; i++) {
      rip[i].remove()
    }
  }, 400)
}

リップルエフェクトを追加するための関数。span要素で実装している。アニメーションはCSSで行っている(後述)。

.video-js .vjs-skip-fwd {
  background: rgba(0, 0, 0, 0);
  display: block;
  color: white;
  position: absolute;
  top: 0px;
  right: 0px;
  width: 40%;
  height: calc(100% - 30px);
  overflow: hidden;
}
.video-js .vjs-skip-bwd {
  background: rgba(0, 0, 0, 0);
  display: block;
  color: white;
  position: absolute;
  top: 0px;
  left: 0px;
  width: 40%;
  height: calc(100% - 30px);
  overflow: hidden;
}

これがスキップボタンのCSS定義。プレイヤーの両端から幅40%で透明なdivをかぶせるようにしている。

.vjs-skip .ripple {
  width: 150px;
  height: 150px;
  position: absolute;
  border-radius: 100%;
  pointer-events: none;
  transform: scale(0);
  opacity: 0;
  background: black;
  animation: rippleanm 0.4s ease-out;
}
@keyframes rippleanm {
  from {
    opacity: 0.5;
  }
  to {
    transform: scale(8);
    opacity: 0;
  }
}

これがリップルエフェクトのCSS。半透明の円が0.4秒で消えるようにしている。

player.play()

最後に再生を開始。ただブラウザによっては自動で開始しない。

以上です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0