Skip to content

Commit 46f2f86

Browse files
committed
feat: Maraquee animation
1 parent 44d1be2 commit 46f2f86

File tree

3 files changed

+71
-8
lines changed

3 files changed

+71
-8
lines changed

.vscode/cspell.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"ignorePaths": [],
44
"dictionaryDefinitions": [],
55
"dictionaries": [],
6-
"words": ["kars"],
6+
"words": ["kars", "maraquee"],
77
"ignoreWords": [],
88
"import": []
99
}

src/components/ui/maraquee.tsx

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { cn } from "@/utils/cn";
2+
3+
/*
4+
Copyright © 2024 Kars (github.com/kars1996)
5+
6+
Not to be shared, replicated or used without prior consent.
7+
Contact Kars for any enquiries
8+
*/
9+
10+
interface MarqueeProps {
11+
className?: string;
12+
reverse?: boolean;
13+
pauseOnHover?: boolean;
14+
children?: React.ReactNode;
15+
vertical?: boolean;
16+
repeat?: number;
17+
[key: string]: any;
18+
}
19+
20+
export default function Marquee({
21+
className,
22+
reverse,
23+
pauseOnHover = true,
24+
children,
25+
vertical = false,
26+
repeat = 4,
27+
...props
28+
}: MarqueeProps) {
29+
return (
30+
<div
31+
{...props}
32+
className={cn(
33+
"group flex overflow-hidden p-2 [--duration:40s] [--gap:1rem] [gap:var(--gap)]",
34+
{
35+
"flex-row": !vertical,
36+
"flex-col": vertical,
37+
},
38+
className,
39+
)}
40+
>
41+
{Array(repeat)
42+
.fill(0)
43+
.map((_, i) => (
44+
<div
45+
key={i}
46+
className={cn(
47+
"flex shrink-0 justify-around [gap:var(--gap)]",
48+
{
49+
"animate-marquee flex-row": !vertical,
50+
"animate-marquee-vertical flex-col": vertical,
51+
"group-hover:[animation-play-state:paused]":
52+
pauseOnHover,
53+
"[animation-direction:reverse]": reverse,
54+
},
55+
)}
56+
>
57+
{children}
58+
</div>
59+
))}
60+
</div>
61+
);
62+
}

tailwind.config.ts

+8-7
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,18 @@ const config: Config = {
3030
},
3131
},
3232
animation: {
33-
marquee: "marquee 25s linear infinite",
34-
marquee2: "marquee2 25s linear infinite",
33+
marquee: "marquee var(--duration) linear infinite",
34+
"marquee-vertical":
35+
"marquee-vertical var(--duration) linear infinite",
3536
},
3637
keyframes: {
3738
marquee: {
38-
"0%": { transform: "translateX(0%)" },
39-
"100%": { transform: "translateX(-100%)" },
39+
from: { transform: "translateX(0)" },
40+
to: { transform: "translateX(calc(-100% - var(--gap)))" },
4041
},
41-
marquee2: {
42-
"0%": { transform: "translateX(100%)" },
43-
"100%": { transform: "translateX(0%)" },
42+
"marquee-vertical": {
43+
from: { transform: "translateY(0)" },
44+
to: { transform: "translateY(calc(-100% - var(--gap)))" },
4445
},
4546
},
4647
},

0 commit comments

Comments
 (0)