# 结算过程金色旋转边框样式与动画 本文档保存当前 PC 端与移动端在开奖/结算过程里使用的金色边框、旋转描边和发光动画,便于后续下载、复用或对接设计标注。 ## 源码位置 - PC 端挂载位置:`src/features/game/components/desktop/desktop-animal.tsx` - 移动端挂载位置:`src/features/game/components/mobile/mobile-animal.tsx` - 样式定义位置:`src/style/index.css` PC 端在 `revealFrame` 存在时渲染: ```tsx
``` 移动端在 `revealFrame` 存在时渲染: ```tsx
``` ## 动画机制 - `--gold-angle`:注册为 CSS angle 自定义属性,用于驱动 `conic-gradient` 旋转。 - `rotating-gold-border`:把 `--gold-angle` 从 `0deg` 推到 `360deg`,形成边框旋转。 - `gold-border-pulse`:让外层金色光晕做轻微透明度和缩放呼吸。 - `::before`:主金色旋转边框,8 秒一圈。 - `::after`:高光扫光边框,2.1 秒一圈,并从反向角度偏移 `180deg` 开始。 - `static-border`:静态金色实体边框,保证边框厚度和底色稳定。 - `glow`:外部径向金色光晕,增强结算聚焦感。 ## PC 端样式 ```css @property --gold-angle { syntax: ""; inherits: false; initial-value: 0deg; } @keyframes rotating-gold-border { to { --gold-angle: 360deg; } } @keyframes gold-border-pulse { 0%, 100% { opacity: 0.34; transform: scale(0.992); } 50% { opacity: 0.54; transform: scale(1.008); } } .gold-reveal-shell { --gold-angle: 0deg; position: absolute; inset: calc(var(--design-unit) * 2.6); border-radius: calc(var(--design-unit) * 16); overflow: hidden; clip-path: inset(0 round calc(var(--design-unit) * 16)); pointer-events: none; } .gold-reveal-shell::before { content: ""; position: absolute; inset: 0; border-radius: calc(var(--design-unit) * 16); padding: calc(var(--design-unit) * 5.6); background: conic-gradient( from var(--gold-angle), #534217 10%, #534217 20%, #ffe226 45%, #534217 60%, #534217 85%, #ffe226 95%, #534217 100% ); -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude; animation: rotating-gold-border 8s linear infinite; } .gold-reveal-shell::after { content: ""; position: absolute; inset: calc(var(--design-unit) * 1); border-radius: calc(var(--design-unit) * 15); padding: calc(var(--design-unit) * 4); background: conic-gradient( from calc(var(--gold-angle) + 180deg), rgba(255, 247, 210, 0) 0%, rgba(255, 247, 210, 0) 66%, rgba(255, 252, 232, 0.14) 71%, rgba(255, 254, 244, 0.98) 75%, rgba(255, 230, 130, 0.96) 79%, rgba(255, 247, 210, 0.18) 84%, rgba(255, 247, 210, 0) 90%, rgba(255, 247, 210, 0) 100% ); -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude; animation: rotating-gold-border 2.1s linear infinite; } .gold-reveal-static-border { position: absolute; inset: calc(var(--design-unit) * 2.8); border-radius: calc(var(--design-unit) * 16); border: calc(var(--design-unit) * 7.4) solid rgba(181, 138, 40, 0.98); box-shadow: inset 0 0 calc(var(--design-unit) * 14) rgba(255, 241, 181, 0.38), 0 0 calc(var(--design-unit) * 18) rgba(255, 210, 102, 0.32); pointer-events: none; } .gold-reveal-glow { position: absolute; inset: calc(var(--design-unit) * 1.4); border-radius: calc(var(--design-unit) * 18); background: radial-gradient( circle at center, rgba(255, 226, 92, 0.18) 0%, rgba(219, 161, 42, 0.14) 42%, rgba(127, 86, 13, 0.08) 62%, transparent 82% ); filter: blur(calc(var(--design-unit) * 2.8)); opacity: 0.36; pointer-events: none; animation: gold-border-pulse 1.9s ease-in-out infinite; } ``` ## 移动端样式 ```css .mobile-gold-reveal-shell { --gold-angle: 0deg; position: absolute; inset: calc(var(--design-unit) * 2.2); border-radius: calc(var(--design-unit) * 7); overflow: hidden; clip-path: inset(0 round calc(var(--design-unit) * 7)); pointer-events: none; } .mobile-gold-reveal-shell::before { content: ""; position: absolute; inset: 0; border-radius: calc(var(--design-unit) * 7); padding: calc(var(--design-unit) * 2.5); background: conic-gradient( from var(--gold-angle), #534217 10%, #534217 20%, #ffe226 45%, #534217 60%, #534217 85%, #ffe226 95%, #534217 100% ); -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude; animation: rotating-gold-border 8s linear infinite; } .mobile-gold-reveal-shell::after { content: ""; position: absolute; inset: calc(var(--design-unit) * 0.5); border-radius: calc(var(--design-unit) * 6.5); padding: calc(var(--design-unit) * 1.7); background: conic-gradient( from calc(var(--gold-angle) + 180deg), rgba(255, 247, 210, 0) 0%, rgba(255, 247, 210, 0) 66%, rgba(255, 247, 210, 0.14) 71%, rgba(255, 254, 244, 0.98) 75%, rgba(255, 230, 130, 0.96) 79%, rgba(255, 247, 210, 0.18) 84%, rgba(255, 247, 210, 0) 90%, rgba(255, 247, 210, 0) 100% ); -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude; animation: rotating-gold-border 2.1s linear infinite; } .mobile-gold-reveal-static-border { position: absolute; inset: calc(var(--design-unit) * 2.7); border-radius: calc(var(--design-unit) * 7); border: calc(var(--design-unit) * 2.8) solid rgba(181, 138, 40, 0.98); box-shadow: inset 0 0 calc(var(--design-unit) * 7) rgba(255, 241, 181, 0.38), 0 0 calc(var(--design-unit) * 9) rgba(255, 210, 102, 0.32); pointer-events: none; } .mobile-gold-reveal-glow { position: absolute; inset: calc(var(--design-unit) * 1.4); border-radius: calc(var(--design-unit) * 8); background: radial-gradient( circle at center, rgba(255, 226, 92, 0.2) 0%, rgba(219, 161, 42, 0.16) 42%, rgba(127, 86, 13, 0.08) 62%, transparent 82% ); filter: blur(calc(var(--design-unit) * 1.4)); opacity: 0.42; pointer-events: none; animation: gold-border-pulse 1.9s ease-in-out infinite; } ``` ## 减少动画模式 组件中已经接入 `useReducedMotion()`。当用户系统设置减少动态效果时,PC 与移动端都会把旋转和呼吸动画关闭: ```tsx style={prefersReducedMotion ? { animation: 'none' } : undefined} ``` 光晕层在减少动画模式下固定为: ```tsx style={{ animation: 'none', opacity: 0.36, transform: 'scale(1)', }} ``` ## 复用注意事项 - 父容器必须是 `position: relative`,三层边框节点必须是绝对定位。 - 需要提供 `--design-unit`,当前项目用它控制 PC 与移动端等比缩放。 - `@property --gold-angle` 是旋转效果的关键;如果目标浏览器不支持 `@property`,可改用 `transform: rotate()` 方案,但需要额外包一层元素。 - 移动端额外叠加了 `animalBorderImage` 图片边框,CSS 金色旋转边框位于图片边框下方,增强结算选中效果。