barbajs/barba

THREEJS meshes disappearing after barba transition

Serotoninene opened this issue · 1 comments

I can't reinitialize my threejs scene and meshes when i'm heading back to the home from my inside page. Does any one can see where the problem is ? I've been console logging the meshes, they appear in the console but not on the screen. Why ? Does anyone with more experience on mixing barba and threejs know ?

I've made a codeSandbox for more insight on the code : https://codesandbox.io/p/github/Serotoninene/webglCarousel/draft/pedantic-bohr?file=/src/inside.html:44,48&workspaceId=920cf671-f4e1-42cb-92f2-5c4639d15ed2

here is my barba function

 barba() {
    let that = this;

    barba.init({
      debug: true,
      transitions: [
        {
          name: "from-home-page-transition",
          from: {
            namespace: ["home"],
          },
          beforeLeave(data) {},
          leave(data) {
            // LEAVING HOME
            const tl = gsap.timeline();
            return tl.to(that.settings, {
              progress: 1,
              duration: 0.8,
              ease: Power3.easeInOut,
            });
          },
          afterLeave(data) {
            that.cleanUp();
          },
          beforeEnter(data) {
            const img = data.next.container.querySelector(".image img");
          },
          enter(data) {
            insideAnim();
          },
        },
        {
          name: "from-page-to-home",
          from: {
            namespace: ["inside"],
          },
          leave(data) {
            // LEAVING PROJECT PAGE
            const tl = gsap.timeline();
            return tl.to(data.current.container, {
              x: "-100%",
            });
          },
          async enter(data) {
            that.handleSettings();
            that.addObjects();
          },
        },
      ],
    });
  }

here is my addObjects function :

 async addObjects() {
    const textureLoader = new THREE.TextureLoader();

    for (let i = 0; i < this.n; i++) {
      const texture = await textureLoader.loadAsync(content[i].image);
      this.material[i] = new THREE.ShaderMaterial({
        uniforms: {
          uScrollY: { value: 0.0 },
          uProgress: { value: 0.0 },
          uResolution: {
            value: new THREE.Vector2(this.ndcWidth, this.ndcHeight),
          },
          uQuadSize: {
            value: new THREE.Vector2(
              this.settings.meshWidth,
              this.settings.meshHeight
            ),
          },
          uTexture: { value: texture },
          uTextureSize: {
            value: new THREE.Vector2(texture.image.width, texture.image.height),
          },
          uValue: { value: 0 },
        },
        vertexShader: vertexShader,
        fragmentShader: fragmentShader,
      });

      const mesh = new THREE.Mesh(
        new THREE.PlaneGeometry(1, 1, 32, 32),
        this.material[i]
      );

      if (this.sizes.width < 768) {
        mesh.position.y = 0.2;
      } else {
        mesh.position.y = 0.1;
      }
      mesh.position.x = i * this.margin;

      mesh.scale.set(this.settings.meshWidth, this.settings.meshHeight, 1);
      this.meshes.push(mesh);
      this.scene.add(mesh);
    }
  }

In order to have a better understanding of the problem, I made a more simple example using a very basic threejs scene and simple barbajs transitions : https://codesandbox.io/p/github/Serotoninene/webglCarousel/draft/pedantic-bohr?file=/src/script.js:56,44&workspaceId=920cf671-f4e1-42cb-92f2-5c4639d15ed2

Here is what I've found :

the "leave" function of barbajs must return something but the "enter" must not.
the cleanup must be thorough, you should remove the scene and dispose the render but also remove all eventsListeners;
I had to reset the scene, render and reselect the dom element I wanted to use as canvasContainer
and of course recreate the meshes and reset the requestAnimationFrame :)
I also learned that making the most simplified version is a great way to find the answer !

Hope this will help, Cheers