nyawach
4/26/2017 - 11:22 AM

YouTube APIを用いた動画再生モーダル

YouTube APIを用いた動画再生モーダル

import $ from "jquery";
import FixedOverlay from "./FixedOverlay";

/**
  MovieModal.js
  .js-modal-link[data-videoId="YouTubeのビデオID"]クリック時にモーダルが表示される
*/
export default class MovieModal extends FixedOverlay {

  constructor(opts = {}) {
    super(opts.$root.find(".js-overlay"));
    this.$root = opts.$root;
    this.$container = this.$root.find(".js-container");
    this.$frame = this.$root.find(".js-frame");
    this.$closeBtn = this.$root.find(".js-close-button");

    this.$movieLink = $(".js-modal-link");

    this.EVENT = {
      OPEN: "open-modal",
      CLOSE: "close-modal",
    }

    this.CLASS = {
      OPEN: "is-open",
      CLOSE: "is-close",
    };

    this.player = null;
    this.videoId = null;

  }


  init() {
    this.insertYouTubeIframeAPI();
    this.initListener();
  }


  insertYouTubeIframeAPI() {
    const tag = document.createElement('script');
    const firstScriptTag = document.getElementsByTagName('script')[0];
    tag.src = "https://www.youtube.com/iframe_api";
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
  }

  initListener() {
    this.animationendEvent = "webkitAnimationEnd  msAnimationEnd animationend";
    this.$ov.on("click", () => this.close());
    this.$container.on("click", (evt) => evt.stopPropagation());
    this.$closeBtn.on("click", () => this.close());
    this.$movieLink.on("click", (evt) => this.open(evt.currentTarget.getAttribute("data-videoId")));
    this.$ov.on(this.animationendEvent, (evt) => {
      if(evt.target === this.$ov[0] && this.$root.hasClass(this.CLASS.CLOSE)) this.$root.removeClass(this.CLASS.CLOSE);
    });
  }


  open(videoId) {
    this.pinBackground();
    this.setYTPlayer(videoId);
    this.$root.addClass(this.CLASS.OPEN);
    this.$root.trigger(this.EVENT.OPEN);
  }


  close() {
    this.$root.addClass(this.CLASS.CLOSE).removeClass(this.CLASS.OPEN);
    this.unpinBackground();
    if(this.player && this.player.getPlayerState() !== 2) this.player.pauseVideo();
    this.$root.trigger(this.EVENT.CLOSE);
  }


  setYTPlayer(videoId) {
    if(this.videoId === videoId) return false;
    this.videoId = videoId;
    if(this.player) {
      this.player.cueVideoById({
        videoId: this.videoId
      });
    }
    else {
      this.player = new YT.Player(this.$frame.attr("id"), {
        videoId: this.videoId,
        events: {
          // 自動再生
          // onReady: (evt) => this.onPlayerReady(evt),
          // 読み込み完了時に閉じる
          // onStateChange: (evt) => this.onPlayerStateChange(evt),
        },
        playerVars: {
          rel: 0
        }
      });
    }
  }


  onPlayerReady(evt) {
    if(MS.UA.isDesktop) this.player.playVideo();
  }


  onPlayerStateChange(evt) {
    if(evt.target.getPlayerState() === 0) {
      this.close();
    }
  }

}