/** * OmniMotion — 列表流动 / Marquee (React 18+ · 纯 CSS 版本) * 复刻来源: lusion.co — 列表上下缓动往返 * 用法: */ export default function Marquee({ rows = 3, speed = 6 }) { return ( {Array.from({ length: rows }).map((_, i) => ( ))} ); } /* 样式(可直接放入全局 CSS) .mk-marquee { position: relative; display: block; width: 172px; height: 108px; overflow: hidden; border-radius: 4px; border: 1px solid var(--mk-stage-line); background: var(--mk-stage-surface); -webkit-mask-image: linear-gradient(180deg, transparent, #000 16%, #000 84%, transparent); mask-image: linear-gradient(180deg, transparent, #000 16%, #000 84%, transparent); } .mk-marquee__track { position: absolute; left: 0; right: 0; top: 50%; display: flex; flex-direction: column; gap: 8px; animation: mk-marquee 6s cubic-bezier(0.2, 0.8, 0.2, 1) infinite; } .mk-marquee__row { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-radius: 4px; background: var(--mk-stage-raised); } .mk-marquee__dot { flex: none; width: 8px; height: 8px; border-radius: 999px; background: var(--mk-primary-quiet); } .mk-marquee__line { flex: 1 1 auto; height: 6px; border-radius: 999px; background: #3a423d; } .mk-marquee__line--short { flex: 0 0 auto; width: 34%; } @keyframes mk-marquee { 0% { transform: translateY(calc(-50% - 34px)); } 50% { transform: translateY(calc(-50% + 34px)); } 100% { transform: translateY(calc(-50% - 34px)); } } */