简体   繁体   中英

How to use vanta with nextjs?

I am trying to use vanta with next.js, following this guide . It works completely fine with the Net Effect, however, when I try to use the Globe Effect, I get

[VANTA] Init error TypeError: r.Geometry is not a constructor
    at h.onInit (vanta.globe.min.js:1)
    at h.init (vanta.globe.min.js:1)
    at new r.VantaBase (vanta.globe.min.js:1)
    at new h (vanta.globe.min.js:1)
    at r.<computed> (vanta.globe.min.js:1)

I have isolated Vanta into an Background Component

//Background.js
import { useState, useRef, useEffect } from "react";
import NET from "vanta/dist/vanta.globe.min"
import * as THREE from "three";

export default function Background({ width, height, children }) {
    const [vantaEffect, setVantaEffect] = useState(0);

    const vantaRef = useRef(null);

    useEffect(() => {
        if (!vantaEffect) {
            setVantaEffect(
                NET({
                    THREE,
                    el: vantaRef.current,
                })
            );
        }
        return () => {
            if (vantaEffect) vantaEffect.destroy();
        };
    }, [vantaEffect]);

    return (
        <div ref={vantaRef}>{children}</div>
    )
}

And added the THREE script into my _app.js

import '../styles/globals.css'
import Head from "next/head";
import Navbar from "../components/Navbar";
import { useEffect } from "react";

export default function App({ Component, pageProps }) {
  useEffect(() => {
    const threeScript = document.createElement("script");
    threeScript.setAttribute("id", "threeScript");
    threeScript.setAttribute(
      "src",
      "https://cdnjs.cloudflare.com/ajax/libs/three.js/r121/three.min.js"
    );
    document.getElementsByTagName("head")[0].appendChild(threeScript);
    return () => {
      if (threeScript) {
        threeScript.remove();
      }
    };
  }, []);
  return (
    <>
      <Head>
        <title>BrainStorm Tutoring</title>
      </Head>
      <Navbar />
      <Component {...pageProps} />
    </>
  )
}

and used it like so

//index
import Background from "../components/Background";

export default function Home() {

  return (
    <Background height="400" width="400">
      <h1 className="text-white text-8xl text-left p-36">Fish Bowl</h1>
    </Background >
  )
}

Is it something wrong with THREE, or is it that next.js can't support vanta?

I have that issue with Halo, so i think the THREE object was not available or was not defined in the HALO.js file.

So i go to the official github repo of Vanta and take the source of Halo and Net (the tutorial effect) file, and i found constructor was missing in the Halo file. So i take the one of Net and put in the Halo file.

constructor(userOptions) {
  THREE = userOptions.THREE || THREE;
  super(userOptions);
}

Then i import my custom Halo file for the effect and it works.

I was playing around with this and found that, if I keep the Three.js version to 122. I don't get the error. Apparently any version after that has a breaking change.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM