framer-motion#useMotionValue TypeScript Examples
The following examples show how to use
framer-motion#useMotionValue.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: useWrapperScroll.ts From tesla-homepage-ui-clone with MIT License | 6 votes |
useWrapperScroll = (): {
scrollY: MotionValue<number>;
scrollYProgress: MotionValue<number>;
} => {
const { wrapperRef } = useContext(ModelsContext);
const scrollY = useMotionValue(0);
const scrollYProgress = useMotionValue(0);
useEffect(() => {
if (wrapperRef.current) {
const updateScrollValue = () => {
if (wrapperRef.current) {
const { scrollTop, scrollHeight, offsetHeight } = wrapperRef.current;
const fullScroll = scrollHeight - offsetHeight;
scrollY.set(scrollTop);
scrollYProgress.set(scrollTop / fullScroll);
}
};
wrapperRef.current.addEventListener('scroll', updateScrollValue);
return () => wrapperRef?.current?.removeEventListener('scroll', updateScrollValue);
}
}, [wrapperRef, scrollY, scrollYProgress]);
return { scrollY, scrollYProgress };
}
Example #2
Source File: useInViewScroll.ts From framer-motion-hooks with MIT License | 6 votes |
useInViewScroll = (
el: RefObject<HTMLElement>,
options: IOptions = {}
): MotionValue<number> => {
const progress = useMotionValue(0)
const { scrollY } = useViewportScroll()
useEffect(() => {
const handleScrollProgress = () => {
const node = el.current
if (!node) return
const threshold = options.threshold || 0
const elPosY = node.getBoundingClientRect().top + scrollY.get()
const elHeight = node.scrollHeight
const viewIntersect = Math.max(elPosY - window.innerHeight, 0)
const current = scrollY.get() - viewIntersect - threshold
const total = Math.min(window.innerHeight, elPosY) + elHeight - threshold
const quotient = current / total
if (quotient > 0 && quotient < 1) {
progress.set(quotient)
}
}
handleScrollProgress()
const unsubscribeFromScroll = scrollY.onChange(handleScrollProgress)
return () => unsubscribeFromScroll()
}, [el, options])
return progress
}
Example #3
Source File: useStateAsMotion.tsx From framer-motion-hooks with MIT License | 6 votes |
useStateAsMotion = (state: any) => {
const motionValue = useMotionValue(state)
useEffect(() => {
motionValue.set(state)
}, [state])
return motionValue
}
Example #4
Source File: ActionCard.tsx From nosgestesclimat-site with MIT License | 4 votes |
Card = ({ children, style, onVote, id, ...props }) => {
// motion stuff
const cardElem = useRef(null)
const x = useMotionValue(0)
const controls = useAnimation()
const [constrained, setConstrained] = useState(true)
const [direction, setDirection] = useState()
const [velocity, setVelocity] = useState()
const getVote = (childNode, parentNode) => {
const childRect = childNode.getBoundingClientRect()
const parentRect = parentNode.getBoundingClientRect()
let result =
parentRect.left >= childRect.right
? false
: parentRect.right <= childRect.left
? true
: undefined
return result
}
// determine direction of swipe based on velocity
const getDirection = () => {
return velocity >= 1 ? 'right' : velocity <= -1 ? 'left' : undefined
}
const getTrajectory = () => {
setVelocity(x.getVelocity())
setDirection(getDirection())
}
const flyAway = (min) => {
const flyAwayDistance = (direction) => {
const parentWidth = cardElem.current.parentNode.getBoundingClientRect()
.width
const childWidth = cardElem.current.getBoundingClientRect().width
return direction === 'left'
? -parentWidth / 2 - childWidth / 2
: parentWidth / 2 + childWidth / 2
}
if (direction && Math.abs(velocity) > min) {
setConstrained(false)
controls.start({
x: flyAwayDistance(direction),
})
}
}
useEffect(() => {
const unsubscribeX = x.onChange(() => {
const childNode = cardElem.current
const parentNode = cardElem.current.parentNode
const result = getVote(childNode, parentNode)
result !== undefined && onVote(result)
})
return () => unsubscribeX()
})
const xInput = [-100, 0, 100]
const background = useTransform(x, xInput, [
'linear-gradient(180deg, #f2a4f4 0%, #f49494 100%)',
'linear-gradient(180deg, #fff 0%, #fff 100%)',
'linear-gradient(180deg, rgb(230, 255, 0) 0%, rgb(3, 209, 0) 100%)',
])
return (
<StyledCard
animate={controls}
dragConstraints={constrained && { left: 0, right: 0, top: 0, bottom: 0 }}
dragElastic={1}
ref={cardElem}
style={{ x }}
onDrag={getTrajectory}
myBackground={background}
onDragEnd={() => flyAway(500)}
whileTap={{ scale: 1.1 }}
{...props}
>
{children}
</StyledCard>
)
}
Example #5
Source File: Checkbox.tsx From chroma-react with MIT License | 4 votes |
Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
(
{
['aria-label']: ariaLabel,
checked,
className,
classes: additionalClasses,
color = 'default',
disabled = false,
errorMessage,
hasError,
helpMessage,
indeterminate = false,
id,
label,
name,
...rootProps
},
ref
) => {
const classes = useStyles({ classes: additionalClasses });
const [uniqueId] = React.useState<string>(
() => id || name || generateUniqueId('checkbox-')
);
const pathLength = useMotionValue(0);
const opacity = useTransform(pathLength, [0.05, 0.15], [0, 1]);
if (!label && !ariaLabel && process.env.NODE_ENV === 'development') {
throw new Error(
'If a "label" is not provided to Checkbox, please provide "aria-label".'
);
}
const variant = [
checked ? 'checked' : 'unchecked',
disabled ? 'disabled' : 'enabled',
];
return (
<motion.div
className={clsx(classes.root, className)}
animate={variant}
initial={false}
whileHover="hover"
whileTap="pressed"
>
<input
aria-describedby={buildDescribedBy({
hasError,
hasHelpMessage: !!helpMessage,
uniqueId,
})}
aria-checked={
checked && !indeterminate
? 'true'
: !checked && !indeterminate
? 'false'
: !checked && indeterminate
? 'mixed'
: 'false'
}
className={clsx(classes.input, {
[classes.inputInverse]: color === 'inverse',
})}
ref={ref}
type="checkbox"
id={uniqueId}
name={name}
checked={checked}
disabled={disabled}
tabIndex={0}
{...rootProps}
/>
<div className={classes.labelContainer}>
<motion.label
className={classes.label}
htmlFor={uniqueId}
animate={variant}
whileHover="hover"
whileTap="pressed"
>
<motion.svg
className={classes.svg}
width="21"
height="21"
viewBox="0 0 21 21"
>
<motion.path
className={classes.box}
d="M1,5.524A4.523,4.523,0,0,1,5.524,1h9.952A4.523,4.523,0,0,1,20,5.524v9.952A4.523,4.523,0,0,1,15.476,20H5.524A4.523,4.523,0,0,1,1,15.476Z"
fill="transparent"
stroke="var(--checkbox-secondary-emphasis)"
strokeOpacity="0"
strokeMiterlimit="10"
strokeWidth="2"
variants={getBoxVariants({
disabled,
hasError,
color,
})}
/>
{indeterminate && disabled ? (
<motion.path
d="M6.5,10.458h8"
fill="transparent"
strokeWidth="2.25"
stroke="#FFFFFF"
strokeLinecap="round"
strokeLinejoin="round"
style={{ pathLength, opacity }}
custom={checked}
variants={getTickVariants({
disabled,
indeterminate,
color,
})}
/>
) : indeterminate ? (
<>
<motion.path
d="M10.5,10.458h-4"
fill="transparent"
strokeWidth="2.25"
stroke="#FFFFFF"
strokeLinecap="round"
strokeLinejoin="round"
style={{ pathLength, opacity }}
custom={checked}
variants={getTickVariants({
disabled,
indeterminate,
color,
})}
/>
<motion.path
d="M10.5,10.458h4"
fill="transparent"
strokeWidth="2.25"
stroke="#FFFFFF"
strokeLinecap="round"
strokeLinejoin="round"
style={{ pathLength, opacity }}
custom={checked}
variants={getTickVariants({
disabled,
indeterminate,
color,
})}
/>
</>
) : (
<motion.path
d="M5.761,11.962l2.187,2.187,7.291-7.3"
fill="transparent"
strokeWidth="2.25"
stroke="#FFFFFF"
strokeOpacity="1"
strokeLinecap="round"
strokeLinejoin="round"
style={{ pathLength, opacity }}
custom={checked}
variants={getTickVariants({ disabled, indeterminate, color })}
/>
)}
</motion.svg>
<Text
size="subbody"
className={clsx(
color === 'inverse' ? classes.labelInverse : undefined,
!label && ariaLabel && classes.srOnly
)}
>
{label || ariaLabel}
</Text>
</motion.label>
</div>
{helpMessage && (
<FormHelpMessage
color={color}
rootElementId={uniqueId}
describedById={helpFor(uniqueId)}
>
{helpMessage}
</FormHelpMessage>
)}
{hasError && (
<FormErrorMessage
color={color}
rootElementId={uniqueId}
describedById={errorFor(uniqueId)}
>
{errorMessage}
</FormErrorMessage>
)}
</motion.div>
);
}
)