Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3D #1377

Merged
merged 37 commits into from
Dec 6, 2021
Merged

3D #1377

merged 37 commits into from
Dec 6, 2021

Conversation

mattgperry
Copy link
Collaborator

@mattgperry mattgperry commented Dec 2, 2021

Framer Motion 3D

This PR adds 3D support to Framer Motion via react-three-fiber. It supports most of the same features as Framer Motion for the DOM, such as animations, variants, exit animations and whileHover/whileTap.

Install

npm install three @react-three/fiber framer-motion

Use

Framer Motion 3D supports all the same components as r3f, but as special motion versions.

import { motion } from "framer-motion/three"

function App() {
  return (
    <Canvas>
      <motion.mesh initial={{ scale: 0 }} animate={{ scale: 1 }} />
    </Canvas>
  )
}

Variants can be passed from the DOM through to 3D by replacing Canvas with MotionCanvas:

import { motion } from "framer-motion"
import { motion as motion3d, MotionCanvas } from "framer-motion/three"

function App() {
  return (
    <motion.div initial="hidden" animate="visible">
      <MotionCanvas>
        <motion3d.mesh variants={{ hidden: {scale: 0}, visible: {scale: 1} }} />
      </MotionCanvas>
    </motion.div>
  )
}

TODO:

  • Set default spring settings to something more appropriate to the small values often used in 3D

Sorry, something went wrong.

@codesandbox-ci
Copy link

codesandbox-ci bot commented Dec 2, 2021

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 5b5bd54:

Sandbox Source
Framer Motion: Simple animation Configuration
App Store UI using React and Framer Motion Configuration
Framer Motion: Reorder animation Configuration
Framer Motion: growing item positionTransition issue Configuration
Framer Motion: Image lightbox Configuration

Copy link
Contributor

@huntercaron huntercaron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a ton of feedback as I'm not an expect on the core motion apis, but the overally gist and my early testing is 💯 very close to a shippable first concept

render(
<Canvas>
<motion.mesh animate={{ scale: 2 }} scale={[1, 1, 1]} />
<motion.meshStandardMaterial color="#000" variants={{}} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be inside the mesh yeah?

onAnimationComplete={() => resolve(output)}
transition={{
duration: 0.1,
ease: (t) => (t < 0.5 ? t : 0),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does this do / why?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add a comment, but this basically ensures onUpdate fires (because we animate changes) but that the final frame is the exact value we read the motion values as (returning 0 from the easing function)

import { AnimationType } from "../../utils/types"
import { ThreeMotionProps } from "../types"

export function useHover(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are mostly copied over for now yeah?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah they're quite similar although return props for r3f rather than binding events directly

const setVector =
(name: string, defaultValue: number) =>
(i: number) =>
(instance: Object3DNode<any, any>, value: number) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder how to expand this stuff into other nodes like material nodes and geometry nodes?

To animate color at least we'd want MaterialNode for motion.meshBasicMaterial and whatnot

another concept R3F has is "piercing" so you can do like <mesh material-color="pink" /> maybe we can do something there?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will already animate color, its just typed this way, and supports piercing for transforms. But I think we'd have to do something extra for material-color

@mergetron mergetron bot merged commit 4c1f073 into main Dec 6, 2021
@mergetron mergetron bot deleted the feature/three branch December 6, 2021 13:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants