framer / motion

Open source, production-ready animation and gesture library for React
https://framer.com/motion
MIT License
23.71k stars 804 forks source link

[BUG] R3F: AmbientLight is not part of the THREE namespace! Did you forget to extend? #2074

Closed hi6724 closed 9 months ago

hi6724 commented 1 year ago

image

When I use MotionCanvas I face this Error here is my code

import { MotionCanvas } from 'framer-motion-3d';

function UserProfile() {
  return (
    <div>
      <MotionCanvas>
        <mesh>
          <boxGeometry />
        </mesh>
      </MotionCanvas>
    </div>
  );
}

export default UserProfile;

But, if I add Canvas with display none this error was deleted.

import { Canvas } from '@react-three/fiber';
import { MotionCanvas } from 'framer-motion-3d';

function UserProfile() {
  return (
    <div>
      <MotionCanvas>
        <mesh>
          <boxGeometry />
        </mesh>
      </MotionCanvas>
      <Canvas style={{ display: 'none' }}>
        <mesh></mesh>
      </Canvas>
    </div>
  );
}

export default UserProfile;
gonghaibo commented 1 year ago

I also encountered this issue and spent a lot of time troubleshooting. Later, I found out that the version number in the demo was 5.5.5, but the latest version number is already 10.X.

TheBigSasha commented 1 year ago

I also get this issue. Everything works if I use an R3F::Canvas, but I get the R3F: <elementname> is not part of the THREE namespace! Did you forget to extend? for any R3F or framer-motion-3d component inside the Canvas. I tried solving using extend({ MotionCanvas, motion3d }); to no avail. I haven't been able to track down anyone who's got a working project with a recent framer-motion-3d version using MotionCanvas. Does anyone have a link to a sandbox with it working?

syarif-studio commented 1 year ago

Add something like this

import { Mesh, BoxGeometry, MeshStandardMaterial, Group } from 'three'

extend({ Mesh, BoxGeometry, MeshStandardMaterial, Group })

check this link : canvas-tree-saking

syarif-studio commented 1 year ago

Add something like this

import { Mesh, BoxGeometry, MeshStandardMaterial, Group } from 'three'

extend({ Mesh, BoxGeometry, MeshStandardMaterial, Group })

check this link : canvas-tree-saking

gregnr commented 1 year ago

If you don't care about tree shaking and wish to have the same functionality as a regular <Canvas> the solution is:

import { extend } from '@react-three/fiber';
import { MotionCanvas } from 'framer-motion-3d';
import { useMemo } from 'react';
import * as THREE from 'three'

export default function MyComponent() {
  useMemo(() => extend(THREE), []);

  return (
    <MotionCanvas>
      ...
    </MotionCanvas>
  );
}

Which will extend the entire THREE catalog as is done in the real <Canvas> component.

As of R3F v8, the underlying reconciler no longer pulls in the THREE namespace automatically and instead moves this logic directly to the <Canvas> component (giving you the flexibility to tree shake if you implement your own <Canvas>). It appears <MotionCanvas> doesn't carry over the THREE extend logic, so you have to do it yourself now.

mattgperry commented 9 months ago

This is in the docs so closing but good to know there is a fix of sorts that I might look at if we get back to Three.js