Communitygithub.com

LP ヒーロービデオスキル

ランディングページにプロダクトデモを組み込むスキル。CSSアニメーションによるプロダクトUIモックや、ヒーロー動画、カード内動画など、Webサイトへのデモ演出パターンを実装します。

LP ヒーロービデオスキル とは?

このスキルは、ランディングページやWebサイトにプロダクトデモ動画を効果的に組み込むための包括的なガイドです。Hero Background VideoやProduct Card Video、Device Mockup Video、Lightbox Modal Videoの4つの実装パターンに加えて、動画ファイルを使わずにCSSアニメーションでプロダクトUIを再現するPattern 5も提供します。各パターンに対してReactコンポーネントの完全なコード例、使用例、パフォーマンスやアクセシビリティのチェックリストが含まれています。特に、自動再生動画に必要な属性(autoPlay, muted, loop, playsInline)、iOS対応、WebPフォーマット変換のffmpegコマンド、レスポンシブ対応、prefers-reduced-motionへの配慮など、実運用で必要なノウハウを網羅しています。このスキルは主にReact/Next.js環境を想定しており、framer-motionやTailwind CSSと組み合わせて使用します。また、動画素材の作成方法やホスティング戦略、ファイル配置規約についても具体的に説明しているため、プロダクトデモを導入したいあらゆる開発者やデザイナーに役立ちます。

対応~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/yuidvg/skills/tree/HEAD/skills/lp-hero-video

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

LP ヒーロービデオスキル は何をしますか?

ランディングページやWebサイトにプロダクトデモ動画を効果的に組み込むためのガイド。

対応パターン

  1. Hero Background Video — ページ上部の全面背景動画
  2. Product Demo Section — プロダクト紹介セクションにインライン動画
  3. Floating Device Mockup — デバイスフレーム内に動画を表示
  4. Lightbox / Modal Video — クリックで拡大再生
  5. CSS アニメーションによる UI モック — 動画ファイル不要のアニメーション描画

Step 0: 事前確認チェックリスト

動画を組み込む前に、以下を確認する:

動画素材の確認

  • 動画ファイルは用意済みか?(まだなら先にプレースホルダーUIを作成)
  • フォーマット: .mp4(H.264)+ .webm(VP9)の2形式が理想
  • 解像度: Hero用は 1920x1080 推奨、カード内は 1280x720 で十分
  • ファイルサイズ: Hero用は 5-15MB 目安、カード内は 2-5MB
  • 長さ: 自動再生は 10-30秒のループが最適

動画素材の作り方(Screen Studioなどで録画する場合)

  1. プロダクトの最も印象的な操作フローを 15-30秒で録画
  2. 解像度は 1920x1080 以上で録画
  3. エクスポート時に以下を設定:
    • MP4 (H.264): 品質 Medium-High、ビットレート 4-8 Mbps
    • WebM (VP9): 同等品質で追加エクスポート(対応ツールの場合)
  4. ffmpeg での変換コマンド:
# MP4 最適化(Web向け、faststart付き)
ffmpeg -i input.mov -c:v libx264 -crf 23 -preset slow \
  -movflags +faststart -an -vf scale=1920:-2 output.mp4

# WebM 変換
ffmpeg -i input.mov -c:v libvpx-vp9 -crf 30 -b:v 0 \
  -an -vf scale=1920:-2 output.webm

# カード用(小さめ)
ffmpeg -i input.mov -c:v libx264 -crf 26 -preset slow \
  -movflags +faststart -an -vf scale=1280:-2 output-card.mp4

ホスティング

  • ローカル(/public/videos/): 小規模サイト、Vercel / Netlify デプロイ向け
  • CDN / Object Storage: 大規模、複数動画の場合(Cloudflare R2、AWS S3 + CloudFront)
  • YouTube / Vimeo embed: SEO重視、外部共有したい場合

Pattern 1: Hero Background Video

ページ最上部に全面でプロダクトデモ動画を表示。テキストオーバーレイ付き。

React コンポーネント

interface HeroVideoProps {
  /** MP4 動画のパス */
  videoSrc: string;
  /** WebM 動画のパス(省略可) */
  videoSrcWebm?: string;
  /** 動画ロード前に表示するポスター画像 */
  posterSrc?: string;
  /** オーバーレイの子要素(見出しなど) */
  children?: React.ReactNode;
  /** オーバーレイの暗さ (0-1, デフォルト 0.4) */
  overlayOpacity?: number;
}

function HeroVideo({
  videoSrc,
  videoSrcWebm,
  posterSrc,
  children,
  overlayOpacity = 0.4,
}: HeroVideoProps) {
  const videoRef = useRef<HTMLVideoElement>(null);

  return (
    <div className="relative h-screen w-full overflow-hidden bg-black">
      {/* 背景動画 */}
      <video
        ref={videoRef}
        autoPlay
        muted
        loop
        playsInline
        poster={posterSrc}
        className="absolute inset-0 w-full h-full object-cover"
      >
        {videoSrcWebm && <source src={videoSrcWebm} type="video/webm" />}
        <source src={videoSrc} type="video/mp4" />
      </video>

      {/* 暗いオーバーレイ */}
      <div
        className="absolute inset-0"
        style={{ backgroundColor: `rgba(0, 0, 0, ${overlayOpacity})` }}
      />

      {/* ページ背景へのグラデーション */}
      <div className="absolute inset-x-0 bottom-0 h-32 bg-gradient-to-t from-background to-transparent" />

      {/* コンテンツ */}
      {children && (
        <div className="absolute inset-0 z-10 flex items-end">
          <div className="container pb-16 md:pb-24">{children}</div>
        </div>
      )}
    </div>
  );
}

使用例

<HeroVideo
  videoSrc="/videos/product-demo.mp4"
  videoSrcWebm="/videos/product-demo.webm"
  posterSrc="/images/hero-poster.jpg"
  overlayOpacity={0.35}
>
  <h1 className="text-4xl md:text-6xl font-normal text-white tracking-tight">
    テクノロジーで、対話を再発明する。
  </h1>
</HeroVideo>

Pattern 2: Product Card Video

プロダクト一覧の各カードで、静止画の代わりにデモ動画をホバーで再生。

React コンポーネント

interface ProductCardVideoProps {
  videoSrc: string;
  posterSrc: string;
  alt: string;
  className?: string;
}

function ProductCardVideo({
  videoSrc,
  posterSrc,
  alt,
  className,
}: ProductCardVideoProps) {
  const videoRef = useRef<HTMLVideoElement>(null);

  const handleMouseEnter = () => {
    videoRef.current?.play();
  };

  const handleMouseLeave = () => {
    const video = videoRef.current;
    if (video) {
      video.pause();
      video.currentTime = 0;
    }
  };

  return (
    <div
      className={cn("relative aspect-video bg-muted overflow-hidden", className)}
      onMouseEnter={handleMouseEnter}
      onMouseLeave={handleMouseLeave}
    >
      <video
        ref={videoRef}
        muted
        loop
        playsInline
        poster={posterSrc}
        preload="metadata"
        className="w-full h-full object-cover"
      >
        <source src={videoSrc} type="video/mp4" />
      </video>
    </div>
  );
}

使用例(既存カードの画像を置換)

// Before:
<ParallaxImage src="/images/kouchoai.png" alt={t.products.kouchouAI} />

// After:
<ProductCardVideo
  videoSrc="/videos/kouchou-ai-demo.mp4"
  posterSrc="/images/kouchoai.png"
  alt={t.products.kouchouAI}
/>

Pattern 3: Device Mockup Video

ブラウザやスマホのフレーム内にデモ動画を表示(信頼感 UP)。

function BrowserMockupVideo({
  videoSrc,
  posterSrc,
  title,
}: {
  videoSrc: string;
  posterSrc?: string;
  title?: string;
}) {
  return (
    <div className="border border-border bg-background overflow-hidden">
      {/* ブラウザのクローム */}
      <div className="flex items-center gap-2 px-4 py-3 bg-secondary/30 border-b border-border">
        <div className="flex gap-1.5">
          <div className="w-3 h-3 rounded-full bg-muted-foreground/20" />
          <div className="w-3 h-3 rounded-full bg-muted-foreground/20" />
          <div className="w-3 h-3 rounded-full bg-muted-foreground/20" />
        </div>
        {title && (
          <div className="flex-1 text-center">
            <span className="text-xs text-muted-foreground font-mono">{title}</span>
          </div>
        )}
      </div>
      {/* 動画コンテンツ */}
      <div className="aspect-video">
        <video
          autoPlay
          muted
          loop
          playsInline
          poster={posterSrc}
          className="w-full h-full object-cover"
        >
          <source src={videoSrc} type="video/mp4" />
        </video>
      </div>
    </div>
  );
}

Pattern 4: Lightbox Modal Video

サムネイルクリックで動画をモーダル表示。YouTube embed にも対応。

function VideoLightbox({
  thumbnailSrc,
  videoSrc,
  youtubeId,
  alt,
}: {
  thumbnailSrc: string;
  videoSrc?: string;
  youtubeId?: string;
  alt: string;
}) {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <>
      <button
        onClick={() => setIsOpen(true)}
        className="relative group cursor-pointer aspect-video w-full overflow-hidden"
      >
        <img src={thumbnailSrc} alt={alt} className="w-full h-full object-cover" />
        {/* 再生ボタンのオーバーレイ */}
        <div className="absolute inset-0 flex items-center justify-center bg-black/20 group-hover:bg-black/30 transition-colors">
          <div className="w-16 h-16 flex items-center justify-center bg-white/90 group-hover:bg-white transition-colors">
            <svg className="w-6 h-6 text-foreground ml-1" fill="currentColor" viewBox="0 0 24 24">
              <path d="M8 5v14l11-7z" />
            </svg>
          </div>
        </div>
      </button>

      {/* モーダル */}
      {isOpen && (
        <div
          className="fixed inset-0 z-50 flex items-center justify-center bg-black/80"
          onClick={() => setIsOpen(false)}
        >
          <div className="w-full max-w-5xl aspect-video" onClick={(e) => e.stopPropagation()}>
            {youtubeId ? (
              <iframe
                src={`https://www.youtube.com/embed/${youtubeId}?autoplay=1`}
                className="w-full h-full"
                allow="autoplay; encrypted-media"
                allowFullScreen
              />
            ) : (
              <video
                src={videoSrc}
                autoPlay
                controls
                className="w-full h-full object-contain bg-black"
              />
            )}
          </div>
        </div>
      )}
    </>
  );
}

Pattern 5: CSS アニメーションによるプロダクトUIモック(推奨)

動画ファイルなしで、プロダクトの操作感をCSSアニメーション / SVG / Canvasで直接描画する。 Stripe、Linear、Vercel が採用しているアプローチ。

メリット

  • 動画ファイル不要(ゼロバイト追加)
  • 完全レスポンシブ(どの画面サイズでも崩れない)
  • ネイティブ描画でシャープ(圧縮アーティファクトなし)
  • インタラクティブ対応可能(ホバー、クリックで変化)
  • ダークモード/ライトモード自動対応

共通デザイン原則

- 背景: 黒(#000000)、白要素で描画
- モノクロマティック(カラーは使わない or Brand Teal のみアクセント)
- フォント: var(--font-mono) でテックラベル、var(--font-sans) でUI要素
- 角丸なし: rx={0} / border-radius: 0px
- アニメーション: framer-motion の useInView + motion.* で scroll-triggered
- グリッド背景: 薄い白線グリッドパターン(GridBg ユーティリティ)
- グロー: feDropShadow で控えめな発光(GlowDef ユーティリティ)

Pattern 5A: ブラウザ枠 + アニメーションUI

ブラウザのクロム(タイトルバー + ドット)の中に、アニメーションで動くモックUIを表示。

function ProductDemoMock({
  title,
  children,
  className,
}: {
  title: string;
  children: React.ReactNode;
  className?: string;
}) {
  return (
    <div className={cn("border border-border bg-black overflow-hidden", className)}>
      {/* ブラウザのクローム */}
      <div className="flex items-center gap-2 px-4 py-3 bg-[#1c1c1e] border-b border-border">
        <div className="flex gap-1.5">
          <div className="w-2.5 h-2.5 rounded-full bg-white/10" />
          <div className="w-2.5 h-2.5 rounded-full bg-white/10" />
          <div className="w-2.5 h-2.5 rounded-full bg-white/10" />
        </div>
        <div className="flex-1 text-center">
          <span className="text-[10px] text-white/40 font-mono">{title}</span>
        </div>
      </div>
      {/* アニメーションコンテンツ */}
      <div className="aspect-video relative overflow-hidden">
        {children}
      </div>
    </div>
  );
}

実装チェックリスト

動画を追加する際は以下を確認:

パフォーマンス

  • autoPlay muted loop playsInline の4属性をセット(iOS対応必須)
  • poster 属性で初期フレーム画像を指定(ロード中の体験向上)
  • preload="metadata" でカード内動画の初期ロードを軽く
  • 動画ファイルに -movflags +faststart を適用済み(プログレッシブ再生)
  • MP4 + WebM の2形式を <source> で提供(ブラウザ互換性)

レスポンシブ

  • object-cover / object-contain で適切にフィット
  • モバイルでは動画の代わりに静止画を表示する選択肢も検討
    const isMobile = window.innerWidth < 768;
    // モバイルでは poster 画像のみ、動画はロードしない
    

アクセシビリティ

  • 自動再生動画は必ず muted(ユーザー操作なしの音声再生はブロックされる)
  • prefers-reduced-motion に対応し、アニメーション無効時は静止画にフォールバック
    @media (prefers-reduced-motion: reduce) {
      video { display: none; }
      .video-poster-fallback { display: block; }
    }
    

ファイル配置規約

client/
  public/
    videos/
      hero-demo.mp4           # ヒーロー動画(MP4)
      hero-demo.webm          # ヒーロー動画(WebM)
      hero-poster.jpg          # ヒーロー動画のポスター画像
      kouchou-ai-demo.mp4      # 広聴AI デモ動画
      baisoku-survey-demo.mp4  # 倍速サーベイ デモ動画
      baisoku-kaigi-demo.mp4   # 倍速会議 デモ動画
  src/
    components/
      HeroVideo.tsx             # ヒーロー全面動画コンポーネント
      ProductCardVideo.tsx      # カード内ホバー再生コンポーネント
      BrowserMockupVideo.tsx    # ブラウザフレーム付き動画
      VideoLightbox.tsx         # モーダル動画コンポーネント

よくある構成例

SaaS / プロダクトLP(推奨構成)

Hero全面動画(15-30秒ループ、ミュート自動再生)
  ↓
テキストセクション(ミッション・バリュー)
  ↓
ブラウザモックアップ動画(メインプロダクトのデモ)
  ↓
プロダクトカード(ホバーで個別デモ動画再生)
  ↓
ケーススタディ / 実績
  ↓
CTA

コーポレートサイト(控えめ構成)

ヒーロー画像 + 再生ボタン(クリックでLightbox動画)
  ↓
テキストセクション
  ↓
プロダクトカード(静止画、詳細ページに動画)

関連スキル