组件 · COMPONENT
视频播放键 VideoPlay
全站唯一允许为圆形的交互键。圆形不是装饰例外,而是「点按即开始播放」这个媒体语义的通用符号——导学封面与所有课时海报共用这一个原件。
export function PlayButton() {
return (
<button type="button" className="zzm-video-play" aria-label="播放">
<svg className="zzm-video-play__icon" viewBox="0 0 20 20" aria-hidden="true">
<path d="M7 4.5 L15.5 10 L7 15.5 Z" />
</svg>
</button>
)
}<button type="button" class="zzm-video-play" aria-label="播放">
<svg class="zzm-video-play__icon" viewBox="0 0 20 20" aria-hidden="true">
<path d="M7 4.5 L15.5 10 L7 15.5 Z"></path>
</svg>
</button>/* controls.css */
.zzm-v4 .zzm-video-play {
display: grid;
place-items: center;
width: 72px;
height: 72px;
padding: 0;
border: 1px solid rgba(0, 0, 0, .16);
border-radius: 50%;
cursor: pointer;
color: #1D1D1B;
background: linear-gradient(180deg, #FFFFFF 0%, #F2F2EF 100%);
box-shadow:
0 0 0 4px rgba(255, 255, 255, .24),
0 2px 4px rgba(0, 0, 0, .16),
0 6px 16px rgba(0, 0, 0, .22),
inset 0 1px 0 rgba(255, 255, 255, .96),
inset 0 -1px 0 rgba(0, 0, 0, .08);
transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
.zzm-v4 .zzm-video-play:hover {
border-color: rgba(0, 0, 0, .3);
box-shadow:
0 0 0 5px rgba(255, 255, 255, .3),
0 3px 6px rgba(0, 0, 0, .18),
0 9px 22px rgba(0, 0, 0, .28),
inset 0 1px 0 rgba(255, 255, 255, .98),
inset 0 -1px 0 rgba(0, 0, 0, .08);
}
.zzm-v4 .zzm-video-play:active {
transform: scale(.98);
background: linear-gradient(180deg, #E9E9E6 0%, #F4F4F1 100%);
box-shadow:
0 0 0 4px rgba(255, 255, 255, .24),
inset 0 2px 5px rgba(0, 0, 0, .16),
inset 0 1px 2px rgba(0, 0, 0, .10);
}
.zzm-v4 .zzm-video-play:focus-visible {
outline: none;
box-shadow:
0 0 0 4px rgba(166, 64, 47, .28),
0 2px 4px rgba(0, 0, 0, .16),
0 6px 16px rgba(0, 0, 0, .22),
inset 0 1px 0 rgba(255, 255, 255, .96);
}
.zzm-v4 .zzm-video-play__icon {
width: 24px;
height: 24px;
margin-left: 4px;
fill: currentColor;
}在海报上居中
加 --center 修饰:绝对定位到父容器正中,悬停 / 按压的缩放也由它接管。父容器需要 position: relative。
export function OnPoster() {
return (
<div style={{ position: 'relative', width: 480, maxWidth: '100%', aspectRatio: '16/9', borderRadius: 12, background: '#131316', overflow: 'hidden' }}>
<button type="button" className="zzm-video-play zzm-video-play--center" aria-label="播放本节">
<svg className="zzm-video-play__icon" viewBox="0 0 20 20" aria-hidden="true">
<path d="M7 4.5 L15.5 10 L7 15.5 Z" />
</svg>
</button>
</div>
)
}<div
style="
position: relative;
width: 480px;
max-width: 100%;
aspect-ratio: 16/9;
border-radius: 12px;
background: #131316;
overflow: hidden;
"
>
<button type="button" class="zzm-video-play zzm-video-play--center" aria-label="播放本节">
<svg class="zzm-video-play__icon" viewBox="0 0 20 20" aria-hidden="true">
<path d="M7 4.5 L15.5 10 L7 15.5 Z"></path>
</svg>
</button>
</div>/* controls.css */
.zzm-v4 .zzm-video-play {
display: grid;
place-items: center;
width: 72px;
height: 72px;
padding: 0;
border: 1px solid rgba(0, 0, 0, .16);
border-radius: 50%;
cursor: pointer;
color: #1D1D1B;
background: linear-gradient(180deg, #FFFFFF 0%, #F2F2EF 100%);
box-shadow:
0 0 0 4px rgba(255, 255, 255, .24),
0 2px 4px rgba(0, 0, 0, .16),
0 6px 16px rgba(0, 0, 0, .22),
inset 0 1px 0 rgba(255, 255, 255, .96),
inset 0 -1px 0 rgba(0, 0, 0, .08);
transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
.zzm-v4 .zzm-video-play--center {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.zzm-v4 .zzm-video-play:hover {
border-color: rgba(0, 0, 0, .3);
box-shadow:
0 0 0 5px rgba(255, 255, 255, .3),
0 3px 6px rgba(0, 0, 0, .18),
0 9px 22px rgba(0, 0, 0, .28),
inset 0 1px 0 rgba(255, 255, 255, .98),
inset 0 -1px 0 rgba(0, 0, 0, .08);
}
.zzm-v4 .zzm-video-play--center:hover { transform: translate(-50%, -50%) scale(1.06); }
.zzm-v4 .zzm-video-play:active {
transform: scale(.98);
background: linear-gradient(180deg, #E9E9E6 0%, #F4F4F1 100%);
box-shadow:
0 0 0 4px rgba(255, 255, 255, .24),
inset 0 2px 5px rgba(0, 0, 0, .16),
inset 0 1px 2px rgba(0, 0, 0, .10);
}
.zzm-v4 .zzm-video-play--center:active { transform: translate(-50%, -50%) scale(.98); }
.zzm-v4 .zzm-video-play:focus-visible {
outline: none;
box-shadow:
0 0 0 4px rgba(166, 64, 47, .28),
0 2px 4px rgba(0, 0, 0, .16),
0 6px 16px rgba(0, 0, 0, .22),
inset 0 1px 0 rgba(255, 255, 255, .96);
}
.zzm-v4 .zzm-video-play__icon {
width: 24px;
height: 24px;
margin-left: 4px;
fill: currentColor;
}export function GuideCover() {
return (
<div style={{ position: 'relative', width: 360, maxWidth: '100%', aspectRatio: '4/3', borderRadius: 12, background: '#0E0E10', overflow: 'hidden' }}>
<button type="button" className="zzm-video-play zzm-video-play--center" aria-label="播放导学">
<svg className="zzm-video-play__icon" viewBox="0 0 20 20" aria-hidden="true">
<path d="M7 4.5 L15.5 10 L7 15.5 Z" />
</svg>
</button>
</div>
)
}<div
style="
position: relative;
width: 360px;
max-width: 100%;
aspect-ratio: 4/3;
border-radius: 12px;
background: #0e0e10;
overflow: hidden;
"
>
<button type="button" class="zzm-video-play zzm-video-play--center" aria-label="播放导学">
<svg class="zzm-video-play__icon" viewBox="0 0 20 20" aria-hidden="true">
<path d="M7 4.5 L15.5 10 L7 15.5 Z"></path>
</svg>
</button>
</div>/* controls.css */
.zzm-v4 .zzm-video-play {
display: grid;
place-items: center;
width: 72px;
height: 72px;
padding: 0;
border: 1px solid rgba(0, 0, 0, .16);
border-radius: 50%;
cursor: pointer;
color: #1D1D1B;
background: linear-gradient(180deg, #FFFFFF 0%, #F2F2EF 100%);
box-shadow:
0 0 0 4px rgba(255, 255, 255, .24),
0 2px 4px rgba(0, 0, 0, .16),
0 6px 16px rgba(0, 0, 0, .22),
inset 0 1px 0 rgba(255, 255, 255, .96),
inset 0 -1px 0 rgba(0, 0, 0, .08);
transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
.zzm-v4 .zzm-video-play--center {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.zzm-v4 .zzm-video-play:hover {
border-color: rgba(0, 0, 0, .3);
box-shadow:
0 0 0 5px rgba(255, 255, 255, .3),
0 3px 6px rgba(0, 0, 0, .18),
0 9px 22px rgba(0, 0, 0, .28),
inset 0 1px 0 rgba(255, 255, 255, .98),
inset 0 -1px 0 rgba(0, 0, 0, .08);
}
.zzm-v4 .zzm-video-play--center:hover { transform: translate(-50%, -50%) scale(1.06); }
.zzm-v4 .zzm-video-play:active {
transform: scale(.98);
background: linear-gradient(180deg, #E9E9E6 0%, #F4F4F1 100%);
box-shadow:
0 0 0 4px rgba(255, 255, 255, .24),
inset 0 2px 5px rgba(0, 0, 0, .16),
inset 0 1px 2px rgba(0, 0, 0, .10);
}
.zzm-v4 .zzm-video-play--center:active { transform: translate(-50%, -50%) scale(.98); }
.zzm-v4 .zzm-video-play:focus-visible {
outline: none;
box-shadow:
0 0 0 4px rgba(166, 64, 47, .28),
0 2px 4px rgba(0, 0, 0, .16),
0 6px 16px rgba(0, 0, 0, .22),
inset 0 1px 0 rgba(255, 255, 255, .96);
}
.zzm-v4 .zzm-video-play__icon {
width: 24px;
height: 24px;
margin-left: 4px;
fill: currentColor;
}类名
| 类 | 作用 |
|---|---|
.zzm-video-play | 72×72 圆形纸面凸键,墨色三角,键盘焦点为朱色光晕 |
.zzm-video-play--center | 绝对居中于父容器(translate -50% -50%) |
.zzm-video-play__icon | 24px 三角图标,左移 4px 做视觉居中 |
铁律
✓ 要只用于「点按即开始播放」
✗ 不要借它的圆形去做别的按钮——文字按钮仍然是圆角矩形
✓ 要导学封面与课时海报用同一个原件
✗ 不要在不同页面给同一个动作画不同的播放键