fix: 票券挖空补全三件套——阴影改 wrapper drop-shadow 跟随挖空轮廓(mask 默认 border-box 裁切会整体吃掉 box-shadow),孔缘补 .pk-arc ink 半圆弧线;E2E 统一契约改双机制同配方断言
This commit is contained in:
1 parent
b528b5396a
commit
e59db8c199
7 files changed
+83
-21
No files matched your search
@@ -1,13 +1,14 @@
|
||||
/** 票券 —— 只表达完成状态:完成=沿撕线打孔(半圆缺口),未开始=实线无孔。
|
||||
* 裁切式实现:头部色块无独立描边,由票体 overflow-hidden 裁出单一描边圆角。 */
|
||||
* 外层 wrapper 出阴影(drop-shadow 跟随挖空后的轮廓,box-shadow 会被 mask 裁掉);
|
||||
* 内层票体裁切式:头部色块无独立描边,由票体 overflow-hidden 裁出单一描边圆角。 */
|
||||
import type { Chapter } from '../lib/types'
|
||||
|
||||
export function Ticket({ chapter, done }: { chapter: Chapter; done: boolean }) {
|
||||
return (
|
||||
<div
|
||||
data-comp="ticket"
|
||||
className={`relative flex w-[216px] items-stretch overflow-hidden rounded-xl border-2 border-ink bg-paper shadow-hard ${done ? 'ticket-pk' : ''}`}
|
||||
>
|
||||
<div data-comp="ticket" className={`w-fit drop-shadow-hard ${done ? 'tk-pk' : ''}`}>
|
||||
<div
|
||||
className={`relative flex w-[216px] items-stretch overflow-hidden rounded-xl border-2 border-ink bg-paper ${done ? 'ticket-pk' : ''}`}
|
||||
>
|
||||
{/* 头部媒体块:章节色纯填充,无独立边框(由票体裁切) */}
|
||||
<div className="flex w-14 shrink-0 items-center justify-center text-[22px]" style={{ background: chapter.color }}>{chapter.emoji}</div>
|
||||
<div className="flex-1 py-2 pl-2.5 pr-2">
|
||||
@@ -21,6 +22,14 @@ export function Ticket({ chapter, done }: { chapter: Chapter; done: boolean }) {
|
||||
>
|
||||
№{String(chapter.id).padStart(2, '0')}
|
||||
</div>
|
||||
</div>
|
||||
{/* 孔缘弧线:mask 只减形不补线,弧线补上挖空边缘的 ink 描边 */}
|
||||
{done && (
|
||||
<>
|
||||
<i className="pk-arc pk-arc-t" aria-hidden />
|
||||
<i className="pk-arc pk-arc-b" aria-hidden />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
/* 统一硬投影——唯一投影配方,所有基础组件复用(rest / 拿起) */
|
||||
--shadow-hard: 5px 5px 0 var(--color-ink);
|
||||
--shadow-hard-lift: 8px 8px 0 var(--color-ink);
|
||||
/* 同配方的 drop-shadow 形态:给挖空轮廓用(票券)——box-shadow 会被 mask 裁掉 */
|
||||
--drop-shadow-hard: 5px 5px 0 var(--color-ink);
|
||||
|
||||
/* 章节色别名 */
|
||||
--color-ch1: #ff6b6b;
|
||||
@@ -29,17 +31,39 @@
|
||||
--color-ch6: #a78bfa;
|
||||
}
|
||||
|
||||
/* 票券打孔:两端各以 1/4 圆做差集(完成票专用)。
|
||||
* mask 硬停只做形状剪切(非色彩渐变):孔真正穿透票体——露出页面底色,
|
||||
* 描边与硬投影在孔处真实断开,无需伪元素盖色近似。 */
|
||||
.ticket-pk {
|
||||
/* 票券打孔(完成票专用),三件分工:
|
||||
* 挖空 = 票体 mask 差集(两端 1/4 圆硬停剪切,孔穿透露出页面底色);
|
||||
* 阴影 = 外层 wrapper drop-shadow-hard——drop-shadow 跟随 alpha 轮廓,
|
||||
* 孔挖到哪阴影咬到哪(box-shadow 会被 mask 的 border-box 裁切整体吃掉,不可用);
|
||||
* 孔缘 = .pk-arc 半圆环补 ink 边线(mask 只减形不补线),圆心骑撕线两端。 */
|
||||
.tk-pk {
|
||||
--hole-x: 172.75px; /* 撕线中心:216 − 右描边 2 − stub 42 + 撕线半宽 */
|
||||
}
|
||||
.ticket-pk {
|
||||
-webkit-mask-image:
|
||||
radial-gradient(circle 7px at var(--hole-x) 0, transparent 6.5px, #000 7px),
|
||||
radial-gradient(circle 7px at var(--hole-x) 100%, transparent 6.5px, #000 7px);
|
||||
radial-gradient(circle 7px at var(--hole-x) 0, transparent 6px, #000 6.5px),
|
||||
radial-gradient(circle 7px at var(--hole-x) 100%, transparent 6px, #000 6.5px);
|
||||
-webkit-mask-composite: source-in;
|
||||
mask-image:
|
||||
radial-gradient(circle 7px at var(--hole-x) 0, transparent 6.5px, #000 7px),
|
||||
radial-gradient(circle 7px at var(--hole-x) 100%, transparent 6.5px, #000 7px);
|
||||
radial-gradient(circle 7px at var(--hole-x) 0, transparent 6px, #000 6.5px),
|
||||
radial-gradient(circle 7px at var(--hole-x) 100%, transparent 6px, #000 6.5px);
|
||||
mask-composite: intersect;
|
||||
}
|
||||
/* 孔缘弧线:16px 圆环(描边带 r6–8),clip-path 只留票内一半,不进阴影轮廓 */
|
||||
.pk-arc {
|
||||
position: absolute;
|
||||
left: calc(var(--hole-x) - 8px);
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border: 2px solid var(--color-ink);
|
||||
border-radius: 9999px;
|
||||
pointer-events: none;
|
||||
}
|
||||
.pk-arc-t {
|
||||
top: -8px;
|
||||
clip-path: inset(50% 0 0 0);
|
||||
}
|
||||
.pk-arc-b {
|
||||
bottom: -8px;
|
||||
clip-path: inset(0 0 50% 0);
|
||||
}
|
||||
Reference in new issue
Block a user