feat(sponsor-list): implement green screen keying and themed layout

This commit overhauls the display page by replacing the luminance-based keying with a more robust chroma key (green
screen) algorithm for cleaner video cutouts.

A new visual theme has been implemented, featuring:
- Custom fonts for titles and poems.
- A main title, subtitle, and vertical poems styled with Tailwind CSS.
- Reorganization of assets into dedicated `assets` and `fonts` directories.
- Updated video source to a green screen version and adjusted canvas parameters accordingly.
This commit is contained in:
xiaomai
2025-10-12 14:00:01 +08:00
parent 02065d9c63
commit ea4ccec42d
3 changed files with 120 additions and 19 deletions

View File

@@ -35,9 +35,12 @@
// 默认参数
const defaults = {
threshold: 8,
threshold: 30,
softness: 10,
leftMargin: 0,
// leftMargin: 0,
// topOffset: -200,
// scalePercent: 125
leftMargin: 600,
topOffset: -200,
scalePercent: 125,
rotationDeg: 0,
@@ -151,7 +154,7 @@
// 载入背景图(使用背景图做最终合成;如果你希望使用 CSS 背景而不是图片文件,可改这里)
const bgImg = new Image();
bgImg.src = "background.png";
bgImg.src = "../assets/background.png";
bgImg.onload = () => {
// 等背景加载后设置主 canvas 大小
const w = bgImg.naturalWidth || 1080;
@@ -223,19 +226,38 @@
const threshold = THRESHOLD;
const softness = Math.max(1, SOFTNESS);
// 基于平均亮度的简单抠像:黑色 -> 透明
// // 基于平均亮度的简单抠像:黑色 -> 透明
// for (let i = 0; i < len; i += 4) {
// const r = data[i],
// g = data[i + 1],
// b = data[i + 2];
// const lum = (r + g + b) / 3;
// if (lum < threshold) {
// data[i + 3] = 0;
// } else if (lum < threshold + softness) {
// const t = (lum - threshold) / softness;
// data[i + 3] = Math.round(255 * t);
// } // else keep alpha
// }
// 基于绿色背景的抠像Green Screen / Chroma Key
for (let i = 0; i < len; i += 4) {
const r = data[i],
g = data[i + 1],
b = data[i + 2];
const lum = (r + g + b) / 3;
if (lum < threshold) {
data[i + 3] = 0;
} else if (lum < threshold + softness) {
const t = (lum - threshold) / softness;
const r = data[i];
const g = data[i + 1];
const b = data[i + 2];
// “绿色程度”与“非绿色程度”的差距
const greenDiff = g - Math.max(r, b);
// 以 threshold / softness 控制去除强度和平滑边缘
if (greenDiff > threshold) {
data[i + 3] = 0; // 透明
} else if (greenDiff > threshold - softness) {
const t = (threshold - greenDiff) / softness;
data[i + 3] = Math.round(255 * t);
} // else keep alpha
} // 其他保持原样
}
ctxTemp.putImageData(img, 0, 0);
processed = true;
} catch (err) {

View File

@@ -6,24 +6,100 @@
<title>Canvas 实时抠像(可控面板)</title>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<style type="text/tailwindcss">
@import "tailwindcss";
@theme {
/* 🎨 定义自定义字体族变量 */
--font-bai-ge: "BaiGeTianXing", sans-serif;
--font-gu-huang: "ShangShouGuHuang", sans-serif;
--font-tang-ying: "YeZiTangYingHei", sans-serif;
--color-default: #4f46e5;
--color-success: #10b981;
--color-warning: #f59e0b;
--color-danger: #ef4444;
}
@font-face {
font-family: "BaiGeTianXing";
src: url("../fonts/字魂白鸽天行体.ttf") format("truetype");
font-display: swap;
}
@font-face {
font-family: "ShangShouGuHuang";
src: url("../fonts/ShangShouGuHuangTi-2.ttf") format("truetype");
font-display: swap;
}
@font-face {
font-family: "YeZiTangYingHei";
src: url("../fonts/YeZiGongChangTangYingHei-2.ttf") format("truetype");
font-display: swap;
}
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">
<body class="min-h-screen flex items-center justify-center bg-black text-white">
<div class="stage relative w-full h-screen overflow-hidden">
<canvas id="mainCanvas" class="block w-full h-auto"></canvas>
<!-- 标题 -->
<h1 class="absolute top-4 text-center w-full font-bai-ge text-8xl text-yellow-300">
永平赵子龙庙
</h1>
<!-- 副标题描边层 -->
<h2
class="absolute top-28 w-full text-center font-bai-ge text-6xl text-transparent [-webkit-text-stroke:4px_yellow]"
>
庆祝赵子龙元帅暨众神圣诞千秋
</h2>
<!-- 副标题实色层 -->
<h2 class="absolute top-28 text-center w-full font-bai-ge text-6xl text-red-500">
庆祝赵子龙元帅暨众神圣诞千秋
</h2>
<!-- 四句诗边框容器 -->
<div
class="absolute inset-0 flex items-center justify-between px-32 pointer-events-none"
>
<p
class="font-gu-huang text-7xl leading-loose text-center text-transparent
[writing-mode:vertical-lr] [text-orientation:upright]
[-webkit-text-stroke:8px_black]"
>
血染征袍透甲红<br>当阳谁敢与争锋
</p>
<p
class="font-gu-huang text-7xl leading-loose text-center text-transparent
[writing-mode:vertical-rl] [text-orientation:upright]
[-webkit-text-stroke:8px_black]"
>
古来冲锋扶危主<br>唯有常山赵子龙
</p>
<!-- 四句诗容器 -->
<div
class="absolute inset-0 flex items-center justify-between px-32 pointer-events-none"
>
<p
class="font-gu-huang text-7xl leading-loose text-center text-white
[writing-mode:vertical-lr] [text-orientation:upright]"
>
血染征袍透甲红<br>当阳谁敢与争锋
</p>
<p
class="font-gu-huang text-7xl leading-loose text-center text-white
[writing-mode:vertical-rl] [text-orientation:upright]"
>
古来冲锋扶危主<br>唯有常山赵子龙
</p>
<!-- 来源资源:替换为你自己的文件,若跨域请加 crossorigin="anonymous" 并确保服务器允许 CORS -->
<video
id="video"
@@ -32,7 +108,7 @@
muted
loop
autoplay
src="赵子龙元帅-竖屏.mp4"
src="../assets/赵云绿幕.mp4"
></video>
<!-- Controls 面板(可关闭) -->

View File

@@ -0,0 +1,3 @@
@import "tailwindcss";