Videoタグのcontrolsを使わずにアニメーションを一時停止させる

## Videoタグとは

サイトのコンテンツに動画再生を対応するメディアプレイヤーを埋め込める要素です。

https://developer.mozilla.org/ja/docs/Web/HTML/Element/video

## Videoタグを実装していく

背景要素をVideoタグにして、背景がアニメーションさせている様なページをReactを使用して作っていきます。

 ```App.tsx

 /** @jsxImportSource @emotion/react */
import { css } from "@emotion/react";

export default function App() {
  return (
    <div css={wrapStyle}>
      <video
        css={videoStyle}
        src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.webm"
        loop
        autoPlay
        muted
        playsInline
      />
    </div>
  );
}

const wrapStyle = css({
  position: "relative",
  padding: 0,
  margin: 0,
  width: "100%",
  height: "100vh",
});

const videoStyle = css({
  position: "fixed",
  top: 0,
  left: 0,
  width: "100%",
  height: "100vh",
  objectFit: "cover",
  zIndex: -1,
});
 ```
:::note warn
動画のURLはMdnのvideoタグのページから拝借しています。
:::


## テキストを書いていく
今回の趣旨は「背景画像に動画を使用したい」ので、背景に重なるようにテキストを書いていきます。

```App.tsx

import { css } from "@emotion/react";

export default function App() {
  return (
    <div css={wrapStyle}>
      <video
        css={videoStyle}
        src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.webm"
        loop
        autoPlay
        muted
        playsInline
      />
      <h1 css={titleStyle}>株式会社フラワーショップQiita</h1> {/* 追加 */}
    </div>
  );
}

const wrapStyle = css({
  position: "relative",
  padding: 0,
  margin: 0,
  width: "100%",
  height: "100vh",
});

const videoStyle = css({
  position: "fixed",
  top: 0,
  left: 0,
  width: "100%",
  height: "100vh",
  objectFit: "cover",
  zIndex: -1,
});

// 追加

const titleStyle = css({
  color: "#fff",
  fontSize: "5vw",
  position: "absolute",
  top: "50%",
  left: "50%",
  transform: "translate(-50%, -50%)",
  width: "max-content",
  textShadow: "2px 3px 3px rgba(0, 0, 0, 0.71)",
});
```

![スクリーンショット 2024-12-25 16.37.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3443/83a3d8b2-c13d-eb9b-8eb4-40d87ab53821.png)

**ダサい！**
気にせず続けます。

## 動画停止ボタンの実装

`useState`と`useRef`を使って停止ボタンを作ります。

```App.tsx

/** @jsxImportSource @emotion/react */
import { css } from "@emotion/react";
import { useState, useRef } from "react"; //追加

export default function App() {
  // アニメーションの一時停止のロジックを追加
  const [isAnimationStop, setIsAnimationStop] = useState(false);
  const videoRef = useRef<HTMLVideoElement>(null);

  const handlePlayPause = () => {
    if (videoRef.current) {
      if (isAnimationStop) {
        videoRef.current.play();
      } else {
        videoRef.current.pause();
      }
    }
    setIsAnimationStop((prevState) => !prevState);
  };
 // アニメーションの一時停止のロジックここまで
  return (
    <div css={wrapStyle}>
      <video
        css={videoStyle}
        ref={videoRef}
        src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.webm"
        loop
        autoPlay
        muted
        playsInline
      />
      <h1 css={titleStyle}>株式会社フラワーショップQiita</h1>
      {/* ボタンを追加 */}
      <button onClick={handlePlayPause} css={buttonStyle}>
        アニメーションを{isAnimationStop ? "再生する" : "停止する"}
      </button>
    </div>
  );
}

const wrapStyle = css({
  position: "relative",
  padding: 0,
  margin: 0,
  width: "100%",
  height: "100vh",
});

const videoStyle = css({
  position: "fixed",
  top: 0,
  left: 0,
  width: "100%",
  height: "100vh",
  objectFit: "cover",
  zIndex: -1,
});

const titleStyle = css({
  color: "#fff",
  fontSize: "5vw",
  position: "absolute",
  top: "50%",
  left: "50%",
  transform: "translate(-50%, -50%)",
  width: "max-content",
  textShadow: "2px 3px 3px rgba(0, 0, 0, 0.71)",
});

// ボタンのスタイルを追加
const buttonStyle = css({
  position: "absolute",
  right: "10px",
  top: "10px",
});

```
完成です。

https://zzps5m.csb.app/

![スクリーンショット 2024-12-25 17.19.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3443/db965374-e3aa-50e5-b317-266a52f0074d.png)

画面の右上にアニメーション停止ボタンを設置しました。

## 終わりに

videoタグの属性である`controls`を使えばこんな面倒なことをしなくても良いです。
ただ、デザイン的にプログレスバーを見せたくないけど、アクセシビリティの達成基準 2.2.2「一時停止、停止、非表示」を配慮しなければいけないとなった時に使えるネタかなと思います。


## 参考

https://waic.jp/translations/UNDERSTANDING-WCAG20/time-limits-pause.html