feat(demo): add real-time canvas video keying demo

This commit introduces a new interactive demo that performs real-time video keying using HTML5 Canvas.

The implementation processes video frames pixel by pixel to make dark areas transparent, simulating a chroma key effect.
The keyed video is then composited over a background image.

Features:
- An interactive control panel to adjust keying (threshold, softness) and transformation (position, scale, rotation,
opacity) parameters in real-time.
- Keyboard shortcuts for resetting parameters ('R') and toggling the control panel ('C').
- Graceful handling of potential cross-origin errors when processing video frames.
This commit is contained in:
xiaomai
2025-10-12 11:23:34 +08:00
parent bcbae992a3
commit 02065d9c63
2 changed files with 402 additions and 0 deletions

View File

@@ -0,0 +1,97 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Canvas 实时抠像(可控面板)</title>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<style type="text/tailwindcss">
@import "tailwindcss";
@theme {
--color-default: #4f46e5;
--color-success: #10b981;
--color-warning: #f59e0b;
--color-danger: #ef4444;
}
canvas#mainCanvas {
image-rendering: optimizeQuality;
}
</style>
</head>
<body class="min-h-screen flex items-center content-center">
<div class="stage" id="stage" class="relative w-full overflow-hidden">
<canvas id="mainCanvas" class="block w-full h-auto"></canvas>
<!-- 来源资源:替换为你自己的文件,若跨域请加 crossorigin="anonymous" 并确保服务器允许 CORS -->
<video
id="video"
class="hidden"
playsinline
muted
loop
autoplay
src="赵子龙元帅-竖屏.mp4"
></video>
<!-- Controls 面板(可关闭) -->
<div
class="absolute right-2 top-2 w-[320px] bg-white p-2 rounded-md hidden"
id="controlsPanel"
role="region"
aria-label="视频抠像控制面板"
>
<h4>
控制面板
<button class="close-btn" id="closePanel" title="关闭面板"></button>
</h4>
<div class="grid grid-cols-2 grid-rows-7">
<label>黑色阈值: <span id="thVal">30</span></label>
<input type="range" id="threshold" min="0" max="120" value="30" />
<label>羽化softness: <span id="sfVal">30</span></label>
<input type="range" id="softness" min="0" max="120" value="30" />
<label>左侧偏移 X (px): <span id="marginVal">40</span></label>
<input type="range" id="leftMargin" min="0" max="800" value="40" />
<label>顶部偏移 Y (px): <span id="topVal">0</span></label>
<input type="range" id="topOffset" min="-400" max="400" value="0" />
<label>缩放(%: <span id="scaleVal">90</span></label>
<input type="range" id="scale" min="20" max="200" value="90" />
<label>旋转deg: <span id="rotVal">0</span></label>
<input type="range" id="rotation" min="-45" max="45" value="0" />
<label>不透明度: <span id="opaVal">100</span>%</label>
<input type="range" id="opacity" min="0" max="100" value="100" />
</div>
<div style="display: flex; gap: 6px; margin-top: 8px">
<button
id="resetBtn"
class="flex-1 bg-danger rounded-md cursor-pointer"
>
重置 (R)
</button>
<button
id="applyHint"
class="flex-1 bg-warning rounded-md cursor-pointer"
>
帮助
</button>
</div>
</div>
<!-- 当面板关闭时显示的打开按钮 -->
<button id="openBtn" class="open-controls" style="display: none">
打开控制面板
</button>
</div>
<script src="background.js"></script>
</body>
</html>