threed-ai
Version:
'threed-ai' supporting Vite, Next, Nuxt, as a functioning, low-dependency app, a package supporting monorepos of workspaces that utilize 'ThreeJS, WebGL, React, TypeScript <r3Fiber>, GraphQL'.
56 lines (48 loc) • 1.94 kB
JSX
import React, { useState, useCallback } from "react";
import { useSpring } from "react-spring";
import { usePrefersReducedMotion } from "./prefers-reduced-motion";
// Heavily inspired by Josh Comeau: https://www.joshwcomeau.com/react/boop/ 💖
// Wiggle function accepts various parameters specifying properties for the animation
export function useWiggle({
x = 0,
y = 0,
rotation = 0,
scale = 1,
timing = 150,
springConfig = {
tension: 300,
friction: 10
}
}) {
// Accessibility setting from the user system indicating that they prefer to minimize motion
const prefersReducedMotion = usePrefersReducedMotion();
// Declare state variable isActive, set initially to false
const [isActive, setIsActive] = useState(false);
// We offload the actual animation to spring: https://www.react-spring.io/docs/hooks/use-spring
const style = useSpring({
transform: isActive
? `translate(${x}px, ${y}px) rotate(${rotation}deg) scale(${scale})`
: `translate(0px, 0px) rotate(0deg) scale(1)`,
config: springConfig
});
// Timing parameter determines how long the wiggle lasts using browser setTimeout function
// React useEffect function https://reactjs.org/docs/hooks-effect.html
React.useEffect(() => {
if (!isActive) {
return;
}
const timeoutId = window.setTimeout(() => {
setIsActive(false);
}, timing);
return () => {
window.clearTimeout(timeoutId);
};
}, [isActive]); // Continue wiggle until isActive is set false when timeout elapses
// Set wiggle to active when the triggering event occurs - will be set false when effect completes above
const trigger = useCallback(() => {
setIsActive(true);
}, []);
let appliedStyle = prefersReducedMotion ? {} : style;
// Return animation style effect and function to apply on trigger in page
return [appliedStyle, trigger];
}