Jump to content
Search Community

Animation Interruption

Mary.Me test
Moderator Tag

Go to solution Solved by GSAP Helper,

Recommended Posts

Hello everyone! I'm working with React+Three.js + GSAP. I'm trying to animate a 3D model to make it rotate infinitely around its Y axis. The animation itself is applied, but I encounter a bug. The issue is that the animation randomly stops (does not complete a full rotation), and to restart it, I have to either drag the model again or move it (change its coordinates); otherwise, the model just remains stationary. So, it does not seem like a loading issue since otherwise, it would continue rotating on its own.

I've tried animating using GSAP and useFrame. I've attempted importing the model as .jsx, as .glb, but I get the same effect everywhere.

 

I also made a rotation animation in Blender and imported it, but I have the same error.

 

I also used other models. But I'm getting the same error.

This is the first time I'm encountering such an issue. Please advise on what might be the problem. 

 

 

Here is a GIF demonstrating the operation: https://drive.google.com/file/d/14pjIwIL-RqjsGepeEYC2owZ97dopJgDC/view?usp=drive_link

 

This is the code of my component with a 3D model. I've shortened it for convenience. The comments indicate functions that I also tried. It didn't work. 

import React, { useRef, useEffect } from 'react'
import { useAnimations, useGLTF } from '@react-three/drei'
import * as THREE from 'three';
import { useGSAP } from '@gsap/react';
import gsap from 'gsap';
import { useFrame } from '@react-three/fiber';

export function Model(props) {
  const group = useRef()
  const { nodes, materials, animations } = useGLTF('models/bmw_m4_csl_2023.glb')
  const { actions, names } = useAnimations(animations, group)


  /*useEffect(()=>{
    actions[names[0]].reset().fadeIn(3).play()
  },[])
 */
  gsap.registerPlugin(useGSAP)

  /*useGSAP(()=>{
    let ctx = gsap.context(() => {
    gsap.to(group.current.rotation,{
      y: "+=1", repeat: -1, ease: 'none', repeatRefresh: true, duration: 4
    }),group})
    return () => ctx.revert();
  },[]);*/

/*
useFrame(() => {
        group.current.rotation.y += 0.01 
    })*/ 

 useEffect(() => {
    if (!group.current) return;
  
    gsap.to(group.current.rotation, {
      duration: 2, 
     repeat:-1,
     y:2*Math.PI
    });

  }, []);

  return (
    <group ref={group} {...props} dispose={null}>
      <group scale={0.01}>
        <group rotation={[-Math.PI / 2, 0, 0]} scale={100}>
          <mesh
            castShadow
            receiveShadow
            geometry={nodes.M4xNME_exhaust_M4xNME_mechanical_0.geometry}
            material={materials.M4xNME_mechanical}
          />
          <mesh
            castShadow
            receiveShadow
            geometry={nodes.M4xNME_exhaust_M4xNME_silver_0.geometry}
            material={materials.M4xNME_silver}
          />
        </group>
        <group rotation={[-Math.PI / 2, 0, 0]} scale={100}>
          <mesh
            castShadow
            receiveShadow
            geometry={nodes.M4xNME_radiator_M4xNME_Black_0.geometry}
            material={materials.M4xNME_Black}
          />
          <mesh
            castShadow
            receiveShadow
            geometry={nodes.M4xNME_radiator_M4xNME_Grille7_0.geometry}
            material={materials.M4xNME_Grille7}
          />
        </group>  
</group>

  )
}

useGLTF.preload('models/bmw_m4_csl_2023.glb')




export default Model;

Here is the component where the component with the 3D model is called.

import React, { useEffect, useRef } from 'react';
import Model from './Model';
import { OrbitControls } from '@react-three/drei';
import { Canvas } from '@react-three/fiber';



const ModelView = () => {

  return (

    <Canvas frameloop='demand' camera={{ position: [20, 10, 20], fov: 12 }}>

      <directionalLight position={[-19.772, 15.337, -0.439]} intensity={3.5} color="white"></directionalLight>
      <directionalLight position={[21.998, 14.051, -3.370]} intensity={2.46} color="white"></directionalLight>
      <directionalLight position={[-0.069, 13.752, -21.463]} intensity={5.08} color="white"></directionalLight>
      <directionalLight position={[4.116, 16.240, 20.387]} intensity={2.4} color="white"></directionalLight>
      <ambientLight intensity={2.12}></ambientLight>
      <directionalLight position={[0.009, 0.076, 7.499]} intensity={1.6} color="white"></directionalLight>
      <OrbitControls enableZoom={false} maxPolarAngle={Math.PI / 2} minPolarAngle={Math.PI / 2} />

      <Model />

    </Canvas>

  );
};

export default ModelView;

 

Link to comment
Share on other sites

  • Solution

Without a minimal demo, it's very difficult to troubleshoot; the issue could be caused by CSS, markup, a third party library, a 3rd party script, etc. Would you please provide a very simple CodePen or Stackblitz that illustrates the issue? 

 

Please don't include your whole project. Just some colored <div> elements and the GSAP code is best. See if you can recreate the issue with as few dependencies as possible. Start minimal and then incrementally add code bit by bit until it breaks. Usually people solve their own issues during this process! If not, at least we have a reduced test case which greatly increases your chances of getting a relevant answer.

 

See the Pen aYYOdN by GreenSock (@GreenSock) on CodePen

that loads all the plugins. Just click "fork" at the bottom right and make your minimal demo

 

Using a framework/library like React, Vue, Next, etc.? 

CodePen isn't always ideal for these tools, so here are some Stackblitz starter templates that you can fork and import the gsap-trial NPM package for using any of the bonus plugins: 

 

Please share the StackBlitz link directly to the file in question (where you've put the GSAP code) so we don't need to hunt through all the files. 

 

Once we see an isolated demo, we'll do our best to jump in and help with your GSAP-specific questions. 

Link to comment
Share on other sites

A minimal demo will be essential for troubleshooting, but I wanted to point out that I assume this is what you're looking for in terms of the GSAP code: 

useGSAP(()=>{
    gsap.to(group.current.rotation, {
      y: "+=1", 
      repeat: -1, 
      ease: 'none', 
      repeatRefresh: true, 
      duration: 4
    });
});

I'm not familiar with Three.js, but you might need to trigger a render in an onUpdate (if updating the .rotation doesn't automatically render that change)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...