I read Josh’s articles about SVGs and wanted to try something of my own.
I built a checkbox button using Motion. It is a great animation library, simple and effective.
I won’t go into details about it here.
This is the custom checkbox:
Using motion’s motion component, I can animate anything, including SVG paths.
Controlling the pathLength property of the SVG path, I can create a drawing effect as you saw when you clicked the checkbox.
Here is the code:
import { motion } from "motion/react"
import { useState } from "react"
const Checkbox = () => {
const [checked, setChecked] = useState(false);
return (
<div className="flex items-center gap-4">
<input type="checkbox" className="hidden" checked={checked} />
<motion.div whileTap={{ scale: 0.85 }}
onClick={() => { setChecked(!checked) }}
className="flex items-center justify-center border-2 border-black rounded w-6 h-6 cursor-pointer"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<rect width="256" height="256" fill="none" />
<motion.path
initial={{ pathLength: 0 }}
animate={{ pathLength: checked ? 1 : 0 }}
color={"black"}
strokeWidth={16}
transition={{
duration: 0.75,
ease: 'easeInOut',
}}
d="M104,147.43l98.34-97.09a8,8,..."
fill="none" stroke="currentColor" /></svg>
</motion.div>
<span>Click Me!</span>
</div>
)
}
export default Checkbox;
So I used whileTap to add a tap effect where the checkbox scales down a bit when clicked,
for the path element, I set the initial pathLength to 0 and used animate attribute to let motion know this is what
I intend to animate where it becomes 1 when checked and 0 when unchecked.Lastly a transition to control the duration and easing of the animation.
I love how the animation is interruptible, click as fast as you can and see how it behaves!
You may notice the lines aren’t joined at the ends, this is because I didn’t set the strokeLinecap property to round, you can try it out yourself. It will become like this:
It will have a dot in the checkbox since it is not parth of pathLength. There are couple ways to handle this but this is not my concern here.
I’m thinking of building a component library using motion and svgs, nothing for use just for fun.
I have this radio button too:
That’s it! This is nothing much, but imagine what you can build onwards using svgs and motion!