Created
August 21, 2023 23:34
-
-
Save tcaraher/544c8f3f136e90a9bfff99812f6457f9 to your computer and use it in GitHub Desktop.
Animating SVGs with framer motion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
motion, | |
useAnimation, | |
useAnimationControls, | |
} from "framer-motion"; | |
import React, { useEffect, useState } from "react"; | |
function generateRandomInteger(min, max) { | |
return Math.floor(min + Math.random() * (max - min + 1)); | |
} | |
export const Ogham = () => { | |
const [clicked, setClicked] = useState(false); | |
const controls = useAnimationControls(); | |
const values = [-1000, 1000]; | |
const [yStart, setYStart] = useState(generateRandomInteger(values[0],values[1])); | |
const [xStart, setXStart] = useState(generateRandomInteger(values[0],values[1])); | |
const [xyStart, setXyStart] = useState(generateRandomInteger(values[0],values[1])); | |
const [yxStart, setYxStart] = useState(generateRandomInteger(values[0],values[1])); | |
const ypath = { | |
hidden: { | |
y: yStart, | |
opacity: 0, | |
rotate: 90, | |
}, | |
visible: { | |
rotate: 360, | |
y: 0, | |
opacity: 1, | |
transition: { | |
delay: 0.2, | |
duration: 1.5, | |
type: "spring", | |
stiffness: 100, | |
}, | |
}, | |
}; | |
const xpath = { | |
hidden: { | |
x: xStart, | |
opacity: 0, | |
rotate: 360, | |
}, | |
visible: { | |
rotate: 180, | |
x: 0, | |
opacity: 1, | |
transition: { | |
delay: 0.5, | |
duration: 2, | |
type: "spring", | |
stiffness: 60, | |
}, | |
}, | |
}; | |
const xypath = { | |
hidden: { | |
x: xyStart, | |
y: yxStart, | |
opacity: 0, | |
rotate: 180, | |
}, | |
visible: { | |
rotate: 360, | |
x: 0, | |
y: 0, | |
opacity: 1, | |
transition: { | |
delay: 0.9, | |
duration: 2.5, | |
type: "spring", | |
// damping: 20, | |
stiffness: 50, | |
}, | |
}, | |
}; | |
const yxpath = { | |
hidden: { | |
x: yxStart, | |
y: xyStart, | |
opacity: 0, | |
rotate: 90, | |
}, | |
visible: { | |
rotate: 180, | |
x: 0, | |
y: 0, | |
opacity: 1, | |
transition: { | |
delay: 1.2, | |
duration: 3, | |
type: "spring", | |
stiffness: 20, | |
}, | |
}, | |
}; | |
useEffect(() => { | |
if (clicked) { | |
setYStart(generateRandomInteger(values[0],values[1])); | |
setXStart(generateRandomInteger(values[0],values[1])); | |
setYxStart(generateRandomInteger(values[0],values[1])); | |
setXyStart(generateRandomInteger(values[0],values[1])); | |
controls.start("visible"); | |
} else { | |
controls.start("hidden"); | |
} | |
}, [clicked]); | |
return ( | |
<div> | |
<button | |
onClick={() => setClicked(!clicked)} | |
> | |
Toggle animation below: | |
</button> | |
<motion.svg | |
className="shadow-md" | |
initial="hidden" | |
viewBox="-350 -150 900 1200" | |
version="1.1" | |
xmlns="http://www.w3.org/2000/svg" | |
> | |
<motion.path | |
variants={ypath} | |
initial="hidden" | |
animate={controls} | |
d="M83.561,4.251l0.523,917.179" | |
/> | |
<motion.path | |
variants={xpath} | |
initial="hidden" | |
animate={controls} | |
d="M84.084,32.945l77.618,-0.125" | |
/> | |
<motion.path | |
variants={xpath} | |
initial="hidden" | |
animate={controls} | |
d="M84.084,67.606l77.618,-0" | |
/> | |
<motion.path | |
variants={xypath} | |
initial="hidden" | |
animate={controls} | |
d="M84.084,102.122l77.618,0.391" | |
/> | |
<motion.path | |
variants={yxpath} | |
initial="hidden" | |
animate={controls} | |
d="M84.084,136.942l77.618,0.106" | |
/> | |
<motion.path | |
variants={xpath} | |
initial="hidden" | |
animate={controls} | |
d="M84.084,172.095l77.618,-0.159" | |
/> | |
<motion.path | |
variants={xypath} | |
initial="hidden" | |
animate={controls} | |
d="M6.004,207.956l155.698,48.471" | |
/> | |
<motion.path | |
variants={xypath} | |
initial="hidden" | |
animate={controls} | |
d="M6.004,242.233l155.698,48.723" | |
/> | |
<motion.path | |
variants={yxpath} | |
initial="hidden" | |
animate={controls} | |
d="M50.403,327.633l68.33,-0.282" | |
/> | |
<motion.path | |
variants={xpath} | |
initial="hidden" | |
animate={controls} | |
d="M50.403,360.615l68.33,-0.063" | |
/> | |
<motion.path | |
variants={xypath} | |
initial="hidden" | |
animate={controls} | |
d="M50.403,431.32l68.33,0.645" | |
/> | |
<motion.path | |
variants={yxpath} | |
initial="hidden" | |
animate={controls} | |
d="M50.403,396.226l68.33,-0.148" | |
/> | |
<motion.path | |
variants={xypath} | |
initial="hidden" | |
animate={controls} | |
d="M50.403,465.635l68.33,0.811" | |
/> | |
<motion.path | |
variants={xypath} | |
initial="hidden" | |
animate={controls} | |
d="M84.568,529.085l79.075,0.327" | |
/> | |
<motion.path | |
variants={yxpath} | |
initial="hidden" | |
animate={controls} | |
d="M84.568,563.381l79.075,-0.214" | |
/> | |
<motion.path | |
variants={xpath} | |
initial="hidden" | |
animate={controls} | |
d="M84.568,596.662l79.075,0.13" | |
/> | |
<motion.path | |
variants={xypath} | |
initial="hidden" | |
animate={controls} | |
d="M84.568,631.55l79.075,-0.7" | |
/> | |
<motion.path | |
variants={yxpath} | |
initial="hidden" | |
animate={controls} | |
d="M50.403,691.646l68.33,1.044" | |
/> | |
<motion.path | |
variants={xypath} | |
initial="hidden" | |
animate={controls} | |
d="M50.403,726.38l65.593,0.806" | |
/> | |
<motion.path | |
variants={xpath} | |
initial="hidden" | |
animate={controls} | |
d="M50.403,762.116l68.33,0.13" | |
/> | |
<motion.path | |
variants={yxpath} | |
initial="hidden" | |
animate={controls} | |
d="M50.403,796.002l68.33,-0.261" | |
/> | |
<motion.path | |
variants={xypath} | |
initial="hidden" | |
animate={controls} | |
d="M83.2,856.566l-78.949,-0.047" | |
/> | |
<motion.path | |
variants={xpath} | |
initial="hidden" | |
animate={controls} | |
d="M83.2,891.798l-78.949,0" | |
/> | |
</motion.svg> | |
</div> | |
); | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment