万圣节&圣诞节皮肤

This commit is contained in:
eafonyang
2026-09-30 17:48:27 +08:00
parent 65f9be4f64
commit db76456ee0
31 changed files with 1038 additions and 27 deletions
@@ -0,0 +1,94 @@
import { memo } from "react";
const LIGHT_POSITIONS = [4, 17, 30, 43, 56, 69, 82, 95];
/** 设备卡片的静态圣诞装饰:只占上沿,不接收点击或参与布局。 */
export default memo(function ChristmasCardDecoration() {
return (
<div className="christmas-card-decoration" aria-hidden="true">
<svg
className="christmas-card-snow christmas-card-snow-left"
viewBox="0 0 76 12"
focusable="false"
>
<path
d="M0 10Q3 0 15 1L65 1Q75 1 76 3Q70 7 60 5Q54 4 49 7Q43 9 36 6Q29 4 23 7Q18 10 13 7Q6 6 0 10Z"
fill="#e8eff1"
/>
<path d="M10 3Q30 1 49 3T69 3" fill="none" stroke="#fff" strokeWidth="1.5" />
</svg>
<svg
className="christmas-card-snow christmas-card-snow-right"
viewBox="0 0 60 10"
focusable="false"
>
<path
d="M0 2Q10 0 21 1L46 1Q56 0 60 8Q54 5 49 7Q42 9 36 6Q29 3 23 6Q17 8 12 5Q5 5 0 2Z"
fill="#e8eff1"
/>
</svg>
<div className="christmas-card-lights">
<svg
className="christmas-card-wire"
viewBox="0 0 100 18"
preserveAspectRatio="none"
focusable="false"
>
<path
d="M0 2Q50 15 100 2"
fill="none"
stroke="#77623c"
strokeWidth="1"
vectorEffect="non-scaling-stroke"
/>
</svg>
{LIGHT_POSITIONS.map((position) => {
const ratio = position / 100;
// 与灯线的二次曲线保持一致;灯泡固定尺寸,不随宽屏拉伸。
const top = 2 + 26 * ratio * (1 - ratio);
return (
<span
key={position}
className="christmas-card-light"
style={{ left: `${position}%`, top }}
>
<span className="christmas-card-bulb" />
</span>
);
})}
</div>
<svg
className="christmas-card-sprig"
viewBox="0 0 48 44"
fill="none"
focusable="false"
>
{/* 松枝与针叶保持小尺寸的辨识度,不覆盖下方旋钮。 */}
<g strokeLinecap="round" strokeLinejoin="round">
<path d="M27 13L6 34M28 13L44 32M28 14L29 39" stroke="#567b50" strokeWidth="1.8" />
<path
d="M23 17L13 15M23 17L25 26M18 22L7 21M18 22L21 32M13 27L4 28M13 27L14 36M9 31L3 33"
stroke="#356749"
strokeWidth="2.8"
/>
<path
d="M32 18L32 26M32 18L40 17M37 23L37 32M37 23L45 23M41 28L41 35M41 28L47 29M29 23L24 30M29 27L34 34M29 32L25 39"
stroke="#43805a"
strokeWidth="2.4"
/>
<path d="M20 19L14 19M15 24L9 25M34 21L39 21M29 30L30 36" stroke="#8da57a" strokeWidth="1" />
</g>
{/* 红丝带的两翼、飘带与结心均为静态。 */}
<path d="M25 14L18 29L18 23L13 24L22 12M28 14L37 26L31 24L30 30L25 16" fill="#a92f39" stroke="#71242b" strokeWidth="1" />
<path d="M24 13C17 3 9 3 11 11C12 18 19 18 24 13Z" fill="#d3484f" stroke="#8f2933" strokeWidth="1.2" />
<path d="M27 13C30 3 40 2 40 10C39 17 33 17 27 13Z" fill="#c73a46" stroke="#8f2933" strokeWidth="1.2" />
<path d="M14 8Q17 7 21 12M30 11Q35 6 37 8" stroke="#ef8b83" strokeWidth="1.4" strokeLinecap="round" />
<rect x="22" y="10" width="8" height="8" rx="3" fill="#e45b5b" stroke="#962b35" strokeWidth="1" />
<circle cx="23" cy="26" r="2.1" fill="#d95150" />
<circle cx="27" cy="29" r="1.7" fill="#b83240" />
</svg>
</div>
);
});