PureScript bindings for Motion (formerly Framer Motion) - a production-ready animation library for React.
# Install PureScript package
spago install react-motion
# Install npm dependencies
npm install motion@^12.29.2 react@^18.2.0 react-dom@^18.2.0module Main where
import Prelude
import Framer.Motion.MotionComponent as Motion
import Framer.Motion.Types (animate, initial, whileHover, whileInView)
import React.Basic.DOM as R
import React.Basic.Hooks (element)
myComponent = element Motion.div
{ initial: initial { opacity: 0.0, y: 50.0 }
, animate: animate { opacity: 1.0, y: 0.0 }
, whileHover: whileHover { scale: 1.05 }
, whileInView: whileInView { opacity: 1.0 }
, children: [ R.text "Animated content!" ]
}- Scroll animations:
whileInViewprop anduseInViewhook - Focus animations:
whileFocusprop - Manual controls:
useAnimatehook with automatic scoping - Enhanced scroll tracking:
useScrollwith container and target options - React 18: Updated to latest React and Motion
- Better performance: Motion's hybrid animation engine
- 🎨 Declarative animations - Animate with simple props
- 🎯 Gesture support - Hover, tap, drag, pan out of the box
- 📜 Scroll animations - Both scroll-triggered and scroll-linked
- 🔄 Layout animations - Smooth layout transitions
- 🚪 Exit animations - AnimatePresence component
- 🎭 Variants - Orchestrate complex animations
- 🪝 Hooks - useAnimation, useScroll, useInView, useAnimate
- 🎮 MotionValues - Composable animation values
import Framer.Motion.MotionComponent as Motion
import Framer.Motion.Types (animate, initial, transition)
fadeIn = element Motion.div
{ initial: initial { opacity: 0.0 }
, animate: animate { opacity: 1.0 }
, transition: transition { duration: 0.5 }
, children: [ R.text "Fades in" ]
}scrollAnimation = element Motion.div
{ initial: initial { opacity: 0.0, y: 100.0 }
, whileInView: whileInView { opacity: 1.0, y: 0.0 }
, children: [ R.text "Animates when scrolled into view" ]
}interactive = element Motion.button
{ whileHover: whileHover { scale: 1.1 }
, whileTap: whileTap { scale: 0.95 }
, drag: drag true
, dragConstraints: dragConstraintsBoundingBox
{ left: -100.0, right: 100.0, top: -100.0, bottom: 100.0 }
, children: [ R.text "Drag me!" ]
}import Framer.Motion.Hook (useInView)
myComponent = React.component "MyComponent" \props -> React.do
ref <- React.useRef null
isInView <- useInView ref Nothing
pure $ element Motion.div
{ ref: ref
, style: { opacity: if isInView then 1.0 else 0.0 }
, children: [ R.text "Visible when in view" ]
}motion.div,motion.button,motion.span, etc. - Motion-enhanced DOM elementsmotion.svg,motion.path,motion.g, etc. - Motion-enhanced SVG elementsanimatePresence- Wrapper for exit animations
animate- Target animation stateinitial- Initial animation stateexit- Exit animation statetransition- Animation timingvariants- Named animation stateswhileHover- Hover statewhileTap- Tap statewhileDrag- Drag statewhileInView- NEW: Scroll into view statewhileFocus- NEW: Focus statelayout- Enable layout animationsdrag- Enable dragging- Various event handlers (
onHoverStart,onDragEnd, etc.)
useAnimation- Animation controlsuseViewportScroll- Page scroll valuesuseScroll- NEW: Enhanced scroll tracking with optionsuseInView- NEW: Viewport intersection detectionuseAnimate- NEW: Manual animation controlsuseTransform- Transform motion valuesuseSpring- Spring physicsuseMotionValue- Create motion values
If you're upgrading from the old framer-motion bindings:
-
Update npm packages:
npm uninstall framer-motion npm install motion@^12.29.2 react@^18.2.0 react-dom@^18.2.0
-
No PureScript code changes required! All your existing code will continue to work.
-
Start using new features like
whileInViewfor scroll animations.
See CHANGELOG.md for complete migration details.
MIT
Issues and PRs welcome!