Files
web_hghl_h5/src/components/common/ad-icon-marquee.tsx
T
谢宇宁andClaude Opus 5.5 61d0a11dfa Initial commit
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 17:51:31 +07:00

67 lines
2.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { useLayoutEffect, useRef, useState, type ReactNode } from "react";
/** 恒定线速度:px/s,图标多少只影响时长 */
const SCROLL_PX_PER_SEC = 36;
type AdIconMarqueeProps = {
children: ReactNode;
className?: string;
/** 段内间距,需与尾部 spacer 对齐以无缝衔接 */
gapClassName?: string;
/** 段尾 spacer 宽度,应等于 gap(gap-2→w-2,gap-3→w-3) */
spacerClassName?: string;
/** 内容签名:列表变化时重算时长 */
contentKey?: string;
};
/** Icon 广告从右向左无缝自动滚动(内容复制两段,translateX -50%) */
export function AdIconMarquee({
children,
className = "",
gapClassName = "gap-3",
spacerClassName = "w-3",
contentKey = "",
}: AdIconMarqueeProps) {
const segmentRef = useRef<HTMLDivElement>(null);
const [durationSec, setDurationSec] = useState(20);
useLayoutEffect(() => {
const el = segmentRef.current;
if (!el) return;
const update = () => {
const width = el.getBoundingClientRect().width;
if (width <= 0) return;
setDurationSec(Math.max(width / SCROLL_PX_PER_SEC, 8));
};
update();
const observer = new ResizeObserver(update);
observer.observe(el);
return () => observer.disconnect();
}, [contentKey]);
return (
<div
data-component="ad-icon-marquee"
className={`overflow-hidden [scrollbar-width:none] [&::-webkit-scrollbar]:hidden ${className}`}
>
<div
className="ad-icon-marquee-track flex w-max items-start"
style={{ animationDuration: `${durationSec}s` }}
>
<div ref={segmentRef} className={`flex shrink-0 items-start ${gapClassName}`}>
{children}
<span className={`${spacerClassName} shrink-0`} aria-hidden />
</div>
<div className={`flex shrink-0 items-start ${gapClassName}`} aria-hidden>
{children}
<span className={`${spacerClassName} shrink-0`} aria-hidden />
</div>
</div>
</div>
);
}