Created
August 18, 2019 19:56
-
-
Save steveruizok/6e293980318783e4fbf0abc7c43a83d8 to your computer and use it in GitHub Desktop.
Radial drag constraints in Framer X / Framer Motion.
This file contains hidden or 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 { Override, motionValue, useAnimation } from 'framer' | |
const x = motionValue(0) | |
const y = motionValue(0) | |
export function Knob(): Override { | |
const maxRadius = 32 | |
const overDrag = 0.25 | |
const animation = useAnimation() | |
// Constrain to radius (with overdrag) | |
const handleDrag = (event, info) => { | |
const { x: px, y: py } = info.point | |
const radius = Math.floor(Math.hypot(px, py)) | |
if (radius < maxRadius) return | |
const angle = Math.atan2(py, px) | |
const overdragRadius = maxRadius + (radius - maxRadius) * overDrag | |
animation.set({ | |
x: Math.cos(angle) * overdragRadius, | |
y: Math.sin(angle) * overdragRadius, | |
}) | |
} | |
// Spring back to radius, if overdragged | |
const handleDragEnd = (event, info) => { | |
const { x: px, y: py } = info.point | |
const radius = Math.floor(Math.hypot(px, py)) | |
if (radius < maxRadius) return | |
const angle = Math.atan2(py, px) | |
animation.start({ | |
x: Math.cos(angle) * maxRadius, | |
y: Math.sin(angle) * maxRadius, | |
transition: { | |
damping: 22, | |
velocity: 0, | |
mass: 1, | |
stiffness: 215, | |
restDelta: 0.01, | |
restSpeed: 0.01, | |
}, | |
}) | |
} | |
return { | |
x, | |
y, | |
drag: true, | |
dragMomentum: false, | |
onDrag: handleDrag, | |
onDragEnd: handleDragEnd, | |
animate: animation, | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment