React-Three-Fiber Animation Resets on Scroll

Viewed 1797

I created a low poly water animation using three.js and react-three-fiber. The animation begins to play when my webpage is loaded but as you start to scroll down to view the other content on my webpage, my animation resets and begins to start again.

PolyWater is just a component I created to make the low poly water using vertices.

The SeaScene is exported to a Home component that merges the rest of my components together.

My Home component is being Rendered in the App.js file in react using Router

SeaScene.js

import React, {useRef} from 'react'
import {Canvas, extend, useFrame, useThree} from "react-three-fiber"
import {OrbitControls} from "three/examples/jsm/controls/OrbitControls"
import PolyWater from "./PolyWater/PolyWater";
import './SeaScene.css'

extend({OrbitControls})

const Controls = () => {
    const orbitRef = useRef();
    const {camera, gl} = useThree();

    useFrame(() => {
        orbitRef.current.update()
        camera.position.set(25, 12.5, -20)
        camera.rotation.set(-1.5, 0, 0)
    })

    return (
        <orbitControls
            args={[camera, gl.domElement]}
            ref={orbitRef}
        />
    )
}

const SeaScene = () => {
    return (
        <section id="home" className="home-section">
            <Canvas>
                <ambientLight intensity={0.2}/>
                <directionalLight color={0xffffff} position={[0, 50, 30]}/>
                <Controls/>
                <PolyWater/>
            </Canvas>
        </section>
    )
}

Home.js

class Home extends Component {
    render() {
        return (
            <div>
                <SeaScene/>
                <About/>
                <Work/>
                <Footer/>
            </div>
        );
    }
}

App.js

class App extends Component {
    render() {
        return (
            <Router>
                <div>
                    <section>
                        <NavBar/>
                        <Switch>
                            <Route exact path='/' component={Home}/>
                        </Switch>
                    </section>
                </div>
            </Router>

        );
    };
}
2 Answers

I found the fix myself. It was on react-three-fibers github just didn't know that would be the fix. I changed my materials and geometry from the regular way you declare them to the way below.

const geom = useMemo(() => new BoxBufferGeometry(), [])
const mat = useMemo(() => new MeshBasicMaterial(), [])

A link to the page https://github.com/react-spring/react-three-fiber/blob/master/pitfalls.md

While the answer of @astronik is much better for overall performance. It only took me ages to replace every geometry and material.

So after some digging, I found a quick fix thanks to this comment by drcmda. Apparently, the canvas is always listening for scroll interactions in case of renderings. You can disable this behavior by simply setting scroll: false on the Canvas element.

   <Canvas resize={{ scroll: false }} >

⚠️ The only downside using this quick fix, is that you can not use hover/click/scroll elements in the canvas anymore.

Related