0

The animation I'm playing with is reacting with delay. So on click the animation doesn't start right away.

My Parent component (positionsPlayer is the component of interest):


const positionsPlayer = [
      new THREE.Vector3(-4, -1.5, 0.1),
      new THREE.Vector3(-2, -1.5, 0.1),
      new THREE.Vector3(0, -1.5, 0.1),
      new THREE.Vector3(2, -1.5, 0.1),
      new THREE.Vector3(4, -1.5, 0.1),
];

<Canvas shadows camera={{ position: [0, -5, 10], fov: 40 }}>
        <OrbitControls />
        <ambientLight intensity={0.1} />
        <directionalLight color="white" position={[0, 5, 5]} intensity={1} castShadow />
        <color attach="background" args={['#409ECA']} />
        {opponentCards}
        <PlayingTable />
        {positionsPlayer.map((position, index) => {
          return <PlayerCard cardIndex={index} key={index} position={position}/>;
        })}
        {isBrowser && (
            <IsometricCamera position={[20, 20, 20]} near={0.1} far={100} aspect={window.innerWidth / window.innerHeight} />
        )}
</Canvas>

The PlayerCardComponents:

import { useEffect } from 'react';
import { Text } from '@react-three/drei';
import { useTexture } from '@react-three/drei';
import * as THREE from 'three';
import { RoundedBoxGeometry } from 'three/examples/jsm/geometries/RoundedBoxGeometry';
import { useSpring, animated, config } from '@react-spring/three';
import { useFrame, Vector3 } from '@react-three/fiber';
import { BufferGeometry, Mesh } from 'three';
import { useRecoilValue } from 'recoil';
import { playerCardAtom } from '@/recoil-state/player_card_state/player_card.atom';
import { usePlayerCardActions } from '@/recoil-state/player_card_state/player_card.actions';

interface PlayergCardProps {
  position: Vector3
  cardIndex: number;
}

export const PlayerCard = ({ position, cardIndex }: PlayergCardProps) => {
  const playerCardState = useRecoilValue(playerCardAtom);
  const playerCardActions = usePlayerCardActions();
  const myMesh: any = useRef()

  const [isThisCardPicked, setIsThisCardPicked] = useState(0)
  const [{ cardPick }]: any = useSpring(
    { cardPick: isThisCardPicked, config: { mass: 5, tension: 1000, friction: 50, precision: 0.0001 } }, [isThisCardPicked])
  
  const color = cardPick.to([0, 1], ["#51CF66", "#69D78A"])
  const pZ = cardPick.to([0, 1], [0.1, 0.5])

  useEffect(() => {
    if(playerCardState.isPicked === cardIndex) {
      setIsThisCardPicked(1)
    } else {
      setIsThisCardPicked(0)
    }
  },[playerCardState.isPicked])

  function handleClick() {
    playerCardActions.pickCard(cardIndex)
  }

  return (
    <animated.mesh ref={myMesh} position-z={pZ} castShadow scale={[0.5,0.5,0.5]} onClick={handleClick}>

      {/* Card body */}
      <mesh position={[0, 0, 0.1]} castShadow>
        <bufferGeometry attach="geometry" {...cardBodygeometry}/>
        <meshBasicMaterial attach="material" color={color.get()} />
        <meshPhongMaterial attach="material" color={color.get()} />
      </mesh>
    </animated.mesh>
  );
};

So when I click on a card the z position will change from 0.1 to 0.5 for a specific card player chooses. However the issue is that animation triggers after about a second of delay. I want animation to trigger instantly on click.

I tried to optimize it as much as I could so before I was using setState in Parent component, then I started using the react-recoil which optimizes rendering further, but the animation is still not reacting on click instantly. Is there any other way to optimize it further or approach it differently?

I tried also using useFrame hook:

useFrame(({ clock }) => {
    if(playerCardState.isPicked === cardIndex) {
      myMesh.current.position.z = 0.5
      myMesh.current.color = "#69D78A"
    } else {
      myMesh.current.position.x = position instanceof THREE.Vector3 ? position.x : 0;
      myMesh.current.position.y = position instanceof THREE.Vector3 ? position.y : 0;
      myMesh.current.position.z = position instanceof THREE.Vector3 ? position.z : 0;
      myMesh.current.color = "#51CF66"
    }
  })

But it would still be delayed.

0 Answers0