react-nativecanvasexpo2d-context-api

Why variable value inside of canvas function not incrementing?


Here is an open GitHub issue Github Issue

Here is a Expo Snack

For some reason, variables are not incrementing inside the canvas function while outside works just fine. Please have a look at my code:

function home ({ navigation }) {

const [counter, setCounter] = useState(330);

      useEffect(() => {
      const timeout = setTimeout(() => {
      setCounter(counter + 1);
      }, 1000);
  
      return () => {
      clearTimeout(timeout);
      };
  }, [counter]);

console.log('outside ', counter);

    const _onGLContextCreate = (gl) => {
        var ctx = new Expo2DContext(gl);

     //   setInterval(() => {
     //       console.log('set interval doesnt refresh too ', counter);
     //   }, 1000);

console.log('inside ', counter);
    
    let circle = {
        x: counter, 
        y: 100,
        radius: 30,
        color: 'black'
    }
    
    let circle2 = {
        x: 400,
        y: 100,
        radius: 30,
        color: 'blue'
    }
    
        function drawCircle() {
            ctx.beginPath();
            ctx.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2);
            ctx.fillStyle = circle.color;
            ctx.fill();
            ctx.closePath();
        }
    
        function drawCircle2() {
            ctx.beginPath();
            ctx.arc(circle2.x, circle2.y, circle2.radius, 0, Math.PI * 2);
            ctx.fillStyle = circle2.color;
            ctx.fill();
        }

        function update() {
            drawCircle();
            drawCircle2();
        }

        function animate() {
        ctx.clearRect(0, 0, ctx.width, ctx.height);
        requestAnimationFrame(animate);
    
        update();
    
        ctx.flush();
        }
    
        animate();
    
        ctx.stroke();
        ctx.flush();
    };

    
    return (
            <GLView style={{ flex: 1 }} onContextCreate={_onGLContextCreate} />
    );
}

export { home };

Here is what logs show:

outside  330
inside  330
outside  331
outside  332
outside  333
outside  334
outside  335
outside  336
outside  337

Does anybody know why is being read once in canvas and what could be the solution to increment it as in ouside in canvas function?


Solution

  • I don't know exactly what is the cause, but I found issues in the architecture, and when I fixed them it worked. TL;DR see result here https://snack.expo.dev/@dozsolti/expogl-ball

    1. You don't need to rerender the component because you update only the canvas so the useState will be swapped with useRef. Also, you probably meant to update the counter every second so for that I changed useTimeout with useInterval. (The useTimeout worked only because it was in a useEffect with the counter dependency which was updated, sort of like calling himself. The correct way was to use a useEffect when the component was loaded and a setInterval)
    2. After that you needed to swap counter with counter.current
    3. Keep in mind that the _onGLContextCreate is running only once so the circle and circle2 objects aren't changing. That's we I changed changed the x value in the update

    Besides those, everything looks fine, I guess you optimize the code a little bit, like create a single DrawCircle function that takes x,y as parameters, and so on.