lamp heading
An elegant section heading with a customizable gradient underline and a subtle lamp-like glow effect and nice little animation.
Image Generation
AI Solutions
Data Analysis
Installation Guide
1
Install Dependencies
Utility Functions
npm install clsx tailwind-merge
2
Setup Configuration
Create file:
/lib/utils.ts
/lib/utils.ts
Configuration1import { clsx, type ClassValue } from "clsx";
2import { twMerge } from "tailwind-merge";
3
4export function cn(...inputs: ClassValue[]) {
5 return twMerge(clsx(inputs));
6}
3
Copy Component Code
lamp heading.tsx
TypeScript1"use client";
2import { useRef, useEffect } from "react";
3import { motion } from "framer-motion";
4import { cn } from "@/lib/utils";
5
6interface LampHeadingProps {
7 text: string;
8 className?: string;
9 gradientColors?: {
10 from: string;
11 to: string;
12 };
13 lineHeight?: number;
14 glowIntensity?: number;
15 glowSize?: number;
16 animationSpeed?: number;
17}
18
19export const LampHeading = ({
20 text,
21 className,
22 gradientColors = { from: "#ff3366", to: "#338ef7" },
23 lineHeight = 2,
24 glowIntensity = 0.7,
25 glowSize = 20,
26 animationSpeed = 3,
27}: LampHeadingProps) => {
28 const mainLineRef = useRef<HTMLDivElement>(null);
29 const flowAnimation = {
30 animate: {
31 backgroundPosition: ["0% 50%", "100% 50%", "0% 50%"],
32 transition: {
33 duration: animationSpeed,
34 ease: "easeInOut",
35 repeat: Infinity,
36 },
37 },
38 };
39
40 useEffect(() => {
41 if (mainLineRef.current) {
42 mainLineRef.current.style.backgroundSize = "200% 200%";
43 }
44 }, []);
45
46 return (
47 <div className={cn("flex flex-col items-start", className)}>
48 <h2 className="font-medium tracking-wide">{text}</h2>
49 <div className="w-full relative mt-1">
50 <motion.div
51 variants={flowAnimation}
52 animate="animate"
53 style={{
54 position: "absolute",
55 width: "100%",
56 height: `${Math.max(8, lineHeight * 3)}px`,
57 background: `linear-gradient(to right, ${gradientColors.from}, ${gradientColors.to}, ${gradientColors.from})`,
58 filter: `blur(${glowSize / 2}px)`,
59 opacity: glowIntensity * 0.7,
60 bottom: 0,
61 left: 0,
62 transformOrigin: "center bottom",
63 transform: "scaleY(1.2) translateY(0)",
64 backgroundSize: "200% 200%",
65 }}
66 className="rounded-full"
67 />
68 <motion.div
69 variants={flowAnimation}
70 animate="animate"
71 style={{
72 position: "absolute",
73 width: "100%",
74 height: `${Math.max(4, lineHeight * 2)}px`,
75 background: `linear-gradient(to right, ${gradientColors.from}, ${gradientColors.to}, ${gradientColors.from})`,
76 filter: `blur(${glowSize / 4}px)`,
77 opacity: glowIntensity,
78 bottom: 0,
79 left: 0,
80 transformOrigin: "center bottom",
81 transform: "scaleY(0.8) translateY(0)",
82 backgroundSize: "200% 200%",
83 }}
84 className="rounded-full"
85 transition={{
86 duration: animationSpeed * 0.8,
87 }}
88 />
89 <motion.div
90 ref={mainLineRef}
91 variants={flowAnimation}
92 animate="animate"
93 style={{
94 height: `${lineHeight}px`,
95 background: `linear-gradient(to right, ${gradientColors.from}, ${gradientColors.to}, ${gradientColors.from})`,
96 position: "relative",
97 zIndex: 10,
98 backgroundSize: "200% 200%",
99 }}
100 className="w-full rounded-full"
101 />
102 </div>
103 </div>
104 );
105};
106
107export default LampHeading;
108
4
Final Steps
Update Import Paths
Make sure to update the import paths in the component code to match your project structure. For example, change @/components/ui/button
to match your UI components location.
Props
Name | Type | Default | Description |
---|---|---|---|
text | string | "" | The text content of the heading. |
className | string | "" | Additional CSS classes to apply for styling the heading, including text color, font size, and weight. |
gradientColors | object | { from: "#ff3366", to: "#338ef7" } | The gradient colors used for the underline. Object should include 'from' and 'to' color hex values. |
lineHeight | number | 2 | The height of the underline in pixels. |
glowIntensity | number | 0.7 | The intensity of the glow effect (0-1). |
glowSize | number | 20 | The size of the glow effect in pixels. |