Stackbits
Components > Icon Wheel

Icon Wheel

The IconWheel brings your favorite icons to life, spinning endlessly in a mesmerizing circular motion. Whether showcasing tech stacks, skills, or fun graphics, this component keeps things dynamic and engaging. Plus, with smooth hover effects and responsive resizing, it’s the perfect way to add some interactive flair to your UI. Let your icons orbit in style! βœ¨πŸŒ€

Preview

techstackwheel
techstackwheel
techstackwheel
techstackwheel
techstackwheel
techstackwheel
techstackwheel
techstackwheel

Follow below steps πŸ‘‡πŸ»

Install dependencies

1
npm i framer-motion

Component

Create a file icon-wheel.tsx in your components folder and paste this code

1
'use client';
2
3
import React, { useEffect, useState } from 'react';
4
import { motion } from 'framer-motion';
5
import Image from 'next/image';
6
7
type IconWheelProps = {
8
icons: Array<string>;
9
};
10
11
const IconWheel = ({ icons }: IconWheelProps) => {
12
const [radius, setRadius] = useState(200); // Adjust based on the container size
13
const centerX = 32; // Center of the wheel (half of the container width)
14
const centerY = 32; // Center of the wheel (half of the container height)
15
const angleStep = (2 * Math.PI) / icons.length; // Angle between each item
16
17
useEffect(() => {
18
window.addEventListener('resize', () => {
19
if (window.innerWidth < 500) setRadius(100);
20
else setRadius(200);
21
});
22
}, []);
23
24
return (
25
<motion.div
26
initial={{
27
opacity: 0
28
}}
29
whileInView={{
30
opacity: 1,
31
transition: {
32
delay: 0.5,
33
duration: 0.5
34
}
35
}}
36
viewport={{
37
once: true
38
}}
39
animate={{
40
rotateZ: 360,
41
transition: { duration: 10, ease: 'linear', repeat: Infinity }
42
}}
43
className="relative h-[250px] sm:h-[500px] w-[250px] sm:w-[500px] flex items-center justify-center my-10"
44
>
45
{icons.map((url, i) => {
46
const angle = i * angleStep; // Angle for the current icon
47
const x = centerX + radius * Math.cos(angle) - 32; // Subtract half of img width (64/2)
48
const y = centerY + radius * Math.sin(angle) - 32; // Subtract half of img height (64/2)
49
50
return (
51
<motion.div
52
animate={{
53
rotateZ: -360,
54
transition: { duration: 10, ease: 'linear', repeat: Infinity }
55
}}
56
whileHover={{
57
scale: 1.2
58
}}
59
key={`iconwheel${i}`}
60
initial={{ x, y }}
61
className="absolute rounded-full"
62
>
63
<Image src={url} height={64} width={64} alt="iconwheel" />
64
</motion.div>
65
);
66
})}
67
</motion.div>
68
);
69
};
70
71
export default IconWheel;

Usage

1
<IconWheel
2
icons={[
3
'/css.png',
4
'/framermotion.png',
5
'/javascript.png',
6
'/nextjs.png',
7
'/nodejs.png',
8
'/reactjs.png',
9
'/tailwindcss.png',
10
'/typescript.png'
11
]}
12
/>

⭐️ Got a question or feedback?
Feel free to reach out!