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,
});
動画の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)",
});
ダサい!
気にせず続けます。
動画停止ボタンの実装
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",
});
完成です。
画面の右上にアニメーション停止ボタンを設置しました。
終わりに
videoタグの属性であるcontrols
を使えばこんな面倒なことをしなくても良いです。
ただ、デザイン的にプログレスバーを見せたくないけど、アクセシビリティの達成基準 2.2.2「一時停止、停止、非表示」を配慮しなければいけないとなった時に使えるネタかなと思います。
参考