| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- "use client";
- import { useEffect, useState } from "react";
- const ITEM_HEIGHT = 40; // h-10 = 40px
- const INTERVAL = 3000;
- const TRANSITION_DURATION = 500;
- const messages = [
- "Tax Refund Season, Straight to The Lowest Price! As Low As $99!",
- "Free Shipping On Orders Over $99",
- "30 Days Easy Return & Exchange",
- ];
- export default function AnnouncementBar() {
- const [index, setIndex] = useState(0);
- const [enableTransition, setEnableTransition] = useState(true);
- // 最后复制第一条,实现无缝循环
- const loopMessages = [...messages, messages[0]];
- // 每隔 3 秒向上滚动一条
- useEffect(() => {
- if (messages.length <= 1) return;
- const timer = window.setInterval(() => {
- setIndex((prev) => prev + 1);
- }, INTERVAL);
- return () => {
- window.clearInterval(timer);
- };
- }, []);
- // 滚动到复制出来的第一条后,瞬间重置到真正第一条
- useEffect(() => {
- if (index !== messages.length) return;
- const timer = window.setTimeout(() => {
- // 先关闭 transition
- setEnableTransition(false);
- // 瞬间回到第一条
- setIndex(0);
- // 下一帧重新开启 transition
- requestAnimationFrame(() => {
- requestAnimationFrame(() => {
- setEnableTransition(true);
- });
- });
- }, TRANSITION_DURATION);
- return () => {
- window.clearTimeout(timer);
- };
- }, [index]);
- return (
- <div className="h-10 w-full overflow-hidden bg-[#036141]">
- <div
- className={
- enableTransition
- ? "transition-transform duration-500 ease-in-out"
- : ""
- }
- style={{
- transform: `translateY(-${index * ITEM_HEIGHT}px)`,
- }}
- >
- {loopMessages.map((message, messageIndex) => (
- <div
- key={messageIndex}
- className="
- flex
- h-10
- items-center
- justify-center
- px-4
- text-center
- text-[14px]
- font-medium
- text-white
- "
- >
- {message}
- </div>
- ))}
- </div>
- </div>
- );
- }
|