V-002 Media medium

How to create a mini player dock ミニプレーヤードックの作り方

A fixed mini video player dock with thumbnail, metadata, and progress bar. 画面下に固定したミニ動画プレーヤー。サムネイルと進捗バーを1列にまとめたUI。

ライブデモ Live Demo

Main Content Area

このエリアでは通常のコンテンツが表示され、下部のプレーヤーは常に見えています。

The mini player stays visible while users navigate other content.

概要・用途・特徴Overview, Usage & Features

何ができるかWhat it does

A fixed mini video player dock with thumbnail, metadata, and progress bar.

画面下に固定したミニ動画プレーヤー。サムネイルと進捗バーを1列にまとめたUI。

どこで使うかWhere to use

content gallery, video player, media library, portfolio showcase

動画講座、チュートリアルページ、ライブストリーム、長編動画コンテンツ

特徴Key features

Floating mini video player that docks to a corner on scroll. Smooth transition from inline to picture-in-picture dock position. Draggable within the viewport. Close button to dismiss. Preserves playback state during transition.

スクロール時にコーナーにドッキングするフローティングミニ動画プレイヤー。インラインからピクチャーインピクチャードック位置へのスムーズなトランジション。ビューポート内でドラッグ可能。閉じるボタンで非表示。トランジション中の再生状態を保持。

調整可能パラメータ Adjustable Parameters

Parameter Default Description
backdrop bluradjust background blur intensity
player heightplayer height and padding
thumbnail sizemodify thumbnail size
progress stylingprogress bar color and style

実装コード Implementation Code

// react/V-002.jsx
import { useState } from "react";
import "./V-002.css";

export default function MiniPlayerDock() {
  const [visible, setVisible] = useState(false);

  return (
    <>
      <button onClick={() => setVisible(!visible)}>
        {visible ? "Hide" : "Show"} Player
      </button>
      <div className={`mini-player ${visible ? "visible" : ""}`}>
        <div className="player-thumbnail" />
        <div className="player-info">
          <span className="player-title">Track Name</span>
          <span className="player-artist">Artist</span>
        </div>
        <div className="player-progress">
          <div className="progress-bar"><div className="progress-fill" /></div>
        </div>
        <button className="control-btn play">&#9654;</button>
        <button className="close-btn" onClick={() => setVisible(false)}>&#10005;</button>
      </div>
    </>
  );
}
/* react/V-002.css */
.mini-player {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(19, 24, 37, 0.95);
  backdrop-filter: blur(20px);
  padding: 16px 20px;
  display: flex;
  align-items: center;
  gap: 16px;
  transform: translateY(100%);
  transition: transform 0.3s ease;
}

.mini-player.visible {
  transform: translateY(0);
}
import { useState } from "react";
import "./V-002.css";

export default function MiniPlayerDock({
  title = "Flow State Documentary",
  duration = "05:20",
  initialProgress = 40,
  thumbnail = "https://images.unsplash.com/photo-1469474968028-56623f02e42e?auto=format&fit=crop&w=600&q=60",
}) {
  const [progress, setProgress] = useState(initialProgress);

  return (
    <div className="player-dock">
      <img src={thumbnail} alt={title} />
      <div className="player-info">
        <h3>{title}</h3>
        <small>{duration}</small>
        <div className="player-progress">
          <span style={{ width: `${progress}%` }} />
        </div>
      </div>
      <div className="player-controls">
        <button onClick={() => setProgress((value) => Math.max(0, value - 10))}>⏮</button>
        <button onClick={() => setProgress((value) => Math.min(100, value + 10))}>⏭</button>
      </div>
    </div>
  );
}
.player-dock {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  width: min(560px, calc(100% - 32px));
  display: flex;
  gap: 12px;
  align-items: center;
  padding: 12px 16px;
  border-radius: 16px;
  background: rgba(5, 7, 18, 0.85);
  border: 1px solid rgba(255, 255, 255, 0.08);
  color: #f5f6ff;
  box-shadow: 0 20px 50px rgba(3, 4, 12, 0.6);
}

.player-dock img {
  width: 56px;
  height: 56px;
  border-radius: 10px;
  object-fit: cover;
}

.player-info {
  flex: 1;
}

.player-info h3 {
  margin: 0;
  font-size: 16px;
}

.player-progress {
  height: 4px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 999px;
  overflow: hidden;
  margin-top: 8px;
}

.player-progress span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, #5c6ac4, #22d3ee);
}

.player-controls {
  display: flex;
  gap: 8px;
}

.player-controls button {
  border: none;
  width: 36px;
  height: 36px;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
  cursor: pointer;
}

仕組みとカスタマイズHow It Works & Customization

仕組みHow it works

An IntersectionObserver watches the main video container. When it leaves the viewport, the video element is cloned or moved to a fixed mini-player div with a CSS transition. The mini-player uses position: fixed and slides into a corner. Clicking close removes the fixed player and scrolls back to the original position.

IntersectionObserverがメイン動画コンテナを監視。ビューポートから出ると動画要素がCSSトランジションでfixed mini-player divにクローンまたは移動。mini-playerはposition:fixedを使用してコーナーにスライドイン。クリックで閉じるとfixedプレイヤーを削除して元の位置にスクロールバック。

カスタマイズ方法Customization

Allow users to choose which corner the mini player docks to. Add a drag handle so users can reposition the mini player freely. Integrate with the native Picture-in-Picture API for browsers that support it.

ユーザーがミニプレイヤーをドッキングするコーナーを選択できるようにする。ユーザーがミニプレイヤーを自由に移動できるドラッグハンドルを追加。サポートするブラウザ向けにネイティブのPicture-in-Picture APIと統合。

注意点Caveats

The native Picture-in-Picture API is more robust for video — consider it as a progressive enhancement. Ensure the mini player has sufficient contrast against page backgrounds when overlaid. Add an accessible close button with aria-label.

ネイティブPicture-in-Picture APIは動画に対してより堅牢です — プログレッシブエンハンスメントとして検討してください。オーバーレイ時にミニプレイヤーがページ背景に対して十分なコントラストを持つことを確認してください。aria-labelを持つアクセシブルな閉じるボタンを追加してください。

よくある質問 Frequently Asked Questions

How to customize the mini player dock? Mini Player Dockをカスタマイズするには?

Modify the CSS custom properties and class styles defined in the code section. Key adjustable values include colors, sizes, durations, and spacing. See the Adjustable Parameters section for specific variables.

コードセクションで定義されているCSSカスタムプロパティとクラススタイルを変更してください。色、サイズ、時間、間隔が主な調整可能値です。具体的な変数は調整可能パラメータセクションを参照してください。

How to use the mini player dock in React? ReactでMini Player Dockを使うには?

Import the provided React component and its CSS file. The component accepts props for customization. Check the React code section for the full implementation and available props.

提供されているReactコンポーネントとCSSファイルをインポートしてください。コンポーネントのpropsでカスタマイズできます。完全な実装と利用可能なpropsはReactコードセクションを参照してください。

What are the performance implications of mini player dock? Mini Player Dockのパフォーマンスへの影響は?

This implementation uses CSS transforms and opacity for animations, which are GPU-accelerated. It's lightweight and doesn't cause layout thrashing. Consider using prefers-reduced-motion for accessibility.

この実装はCSSのtransformとopacityを使用しており、GPUアクセラレーションされます。軽量でレイアウトスラッシングを引き起こしません。アクセシビリティのためにprefers-reduced-motionの使用を検討してください。

AIへの指示テンプレート AI Prompt Template

以下をAIに貼り付けると実装を依頼できます。 Paste the following into your AI assistant to request implementation.