0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Vue.jsで動画サイトによくある動画のプログレスバーを作る

Last updated at Posted at 2021-08-04

はじめに

YouTubeなどの動画サイトによくある再生時間のプログレスバー(サムネイル画像の下に表示される赤色のバーなど)を作ってみます。

TL;DRな方へ

結果

image.png
サムネイル画像の下に赤色のバーとグレーの背景が表示されています。
現在の再生時間が500秒で全体が1000秒で設定しているので、赤色のバーがちょうど真ん中の位置まで達していることがわかります。

コード

movie.vue
<template>
  <div class="movie">
    <!-- サムネイル画像 -->
    <v-img class="movie__thumbnail" src="https://picsum.photos/id/11/500/300" :aspect-ratio="16/9">
      <!-- プログレスバーの背景 -->
      <div class="movie__thumbnail__progress">
        <!-- プログレスバー -->
        <div class="movie__thumbnail__progress__bar" :style="'width: ' + durationPercentage" />
      </div>
    </v-img>
  </div>
</template>

<script>
export default {
  computed: {
    /**
     * @return {Number} 動画の尺(秒)
     * @todo 動的に取得しましょう
     */
    duration () {
      return 1000
    },
    /**
     * @return {Number} 現在の再生時間(秒)
     * @todo 動的に取得しましょう
     */
    currentTime () {
      return 500
    },
    /**
     * @return {String} 動画の尺に対する現在の再生時間のパーセンテージ
     */
    durationPercentage () {
      return String(this.currentTime / this.duration * 100) + '%'
    }
  }
}
</script>

<style lang="scss" scoped>
.movie {
  &__thumbnail {
    position: relative;
    width: 480px;
    height: 270px;
    background-color: #808080;
    &__progress {
      position: absolute;
      bottom: 0;
      left: 0;
      width: 100%;
      height: 4px;
      background-color: #808080;
      &__bar {
        height: 100%;
        background-color: #dc143c;
      }
    }
  }
}
</style>

詳細

HTML

movie.vue(HTML)
<template>
  <div class="movie">
    <!-- サムネイル画像 -->
    <v-img class="movie__thumbnail" src="https://picsum.photos/id/11/500/300" :aspect-ratio="16/9">
      <!-- プログレスバーの背景 -->
      <div class="movie__thumbnail__progress">
        <!-- プログレスバー -->
        <div class="movie__thumbnail__progress__bar" :style="'width: ' + durationPercentage" />
      </div>
    </v-img>
  </div>
</template>
...

全体に大きなdivがあって、その中にサムネイル画像、そしてプログレスバーの背景色がネストされて、更にプログレスバー(現在の再生時間)がネストされています。
movie__thumbnail__progress__barは幅が可変にしたいので、v-bindでstyleを指定することで実現しています。

Script

movie.vue(Script)
...
<script>
export default {
  computed: {
    /**
     * @return {Number} 動画の尺(秒)
     * @todo 動的に取得しましょう
     */
    duration () {
      return 1000
    },
    /**
     * @return {Number} 現在の再生時間(秒)
     * @todo 動的に取得しましょう
     */
    currentTime () {
      return 500
    },
    /**
     * @return {String} 動画の尺に対する現在の再生時間のパーセンテージ
     */
    durationPercentage () {
      return String(this.currentTime / this.duration * 100) + '%'
    }
  }
}
</script>
...

Script部分は大したことはしていません。

duration(), currentTime()

恐らく、サーバーにストアされた値を動的に取得する方式になると思います。
今は決め打ちで定数を返すようにしています。

durationPercentage()

動画全体の尺に対する再生時間の割合を計算しています。styleStringで記述する必要があるので、計算結果をStringにして%を付与して返しています。

CSS

movie.vue(Script)
...
<style lang="scss" scoped>
.movie {
  &__thumbnail {
    position: relative;
    width: 480px;
    height: 270px;
    background-color: #808080;
    &__progress {
      position: absolute;
      bottom: 0;
      left: 0;
      width: 100%;
      height: 4px;
      background-color: #808080;
      &__bar {
        height: 100%;
        background-color: #dc143c;
      }
    }
  }
}
</style>

__thumbnail

プログレスバー全体を画像の上にかかるように表示したいので、positionrelativeが指定されています。また、サムネイル画像が指定されていない場合はグレーの背景が表示されるように、backgroundを指定しています。

__progress

プログレスバーが画像全体に対する指定された位置に置かれるようにpositionabsoluteにしています。
画像の真下かつ左隅に合わせて置きたいのでbottomleftを0にしています。
色はお好みで選びましょう。

__bar

ここが現在の再生時間に合わせてwidthが変わります。
高さは__progressと同じにしたいので、100%を指定しています。
こちらも色はお好みで指定しましょう。

以上で完成です。
動画だけじゃなくフォームやアンケートの入力状況などにも応用できると思います。
ぜひ活用してみてください。

0
2
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
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?