95 lines
3.5 KiB
TypeScript
95 lines
3.5 KiB
TypeScript
|
|
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>
|
||
|
|
);
|
||
|
|
});
|