skip to Main Content

I’m trying to do a polygon mask on an svg with tsParticles.
However neither the particles or the svg show up, only the background color I define in my CSS.

Here is my particles component:

import { useCallback } from "react";
import Particles from "react-tsparticles";
import { loadFull } from "tsparticles";
import { loadPolygonMaskPlugin } from "@tsparticles/plugin-polygon-mask";
import { tsParticles } from "@tsparticles/engine";
import mysvg from "../assets/mysvg.svg";



const options = {
  polygon: {
    draw: {
      enable: true,
      stroke: {
        color: "#fff",
        width: 0.3,
        opacity: 0.2,
      },
    },
    move: {
      radius: 10,
    },
    inline: {
      arrangement: "equidistant",
    },
    scale: 0.5,
    type: "inline",
    url: "mysvg",
  },
  fpsLimit: 60,
  particles: {
    number: {
      value: 100,
    },
    color: {
      value: "#ff0000",
    },
    shape: {
      type: ["image", "circle"],
      image: {
        src: "cural",
        height: 500,
        width: 500,
      },
    },
    opacity: {
      value: 0.5,
      random: true,
    },
    size: {
      value: 5,
      random: true,
    },
    move: {
      enable: true,
      speed: 2,
      direction: "none",
      outModes: {
        default: "out",
      },
    },
  },
  interactivity: {
    events: {
      onHover: {
        enable: true,
        mode: "repulse",
      },
      onClick: {
        enable: true,
        mode: "push",
      },
    },
    modes: {
      repulse: {
        distance: 200,
        duration: 0.4,
      },
      push: {
        quantity: 4,
      },
    },
  },
  detectRetina: true,
};





const ParticleComponent = () => {
  const particlesInit = useCallback(async (engine) => {
    console.log("Initializing tsParticles");
    await loadFull(engine);
    console.log("tsParticles loaded");
    await loadPolygonMaskPlugin(engine);
  }, []);





> const particlesLoaded = useCallback(async (container) => {
>         console.log("Particles loaded", container);
>       }, []);



return (
    <Particles
      id="tsparticles"
      init={particlesInit}
      loaded={particlesLoaded}
      options={options}
    />
  );
};

CSS:

.particles-container {
  position: relative;
  width: 100vw;
  
  height: 100vh;
  
  overflow: hidden;
  
  z-index: 1100;

#tsparticles {
  position: relative;
  width: 100%;
  height: 100%;
  background-color: lightblue;
  top: 0;
  left: 0;
  z-index: 1200;
}

Where I render particles:

import ParticleComponent from "./Page2";

const Pricing = () => {
      return (
        <Section id="section2">
          <div className="particles-container">
            <div id="tsparticles">
              <ParticleComponent />
            </div>
          </div>
        </Section>
      );
    };

console log show the particles DO load:

Particles loaded beep beep

  1. Container {id: ‘tsparticles’, engine: Engine, fpsLimit: 120, intersectionManager: ƒ, _nextFrame: ƒ, …}
    1. actualOptions: Options {_engine: Engine, *container: Container, autoPlay: true, *findDefaultTheme: ƒ, _importPreset: ƒ, …}
    2. canvas: Canvas {container: Container, *applyPostDrawUpdaters: ƒ, *applyPreDrawUpdaters: ƒ, *applyResizePlugins: ƒ, *getPluginParticleColors: ƒ, …}
    3. destroyed: false
    4. drawers: Map(0) {size: 0}
    5. fpsLimit: 120
    6. id: "tsparticles"
    7. interactivity: {mouse: {…}, element: Window, status: ‘pointerleave’}
    8. lastFrameTime: 9867.8
    9. pageHidden: true
    10. particles: Particles {_engine: Engine, *applyDensity: ƒ, *initDensityFactor: ƒ, *pushParticle: ƒ, *removeParticle: ƒ, …}
    11. pathGenerators: Map(0) {size: 0}
    12. plugins: Map(0) {size: 0}
    13. retina: Retina {container: Container, pixelRatio: 1.3499999046325684, reduceFactor: 1, attractDistance: 269.9999809265137, maxSpeed: 67.49999523162842, …}
    14. smooth: false
    15. started: true
    16. zLayers: 100
    17. _delay: 0
    18. _delayTimeout: 13
    19. _duration: 0
    20. engine**: Engine {configs: Map(0), *domArray: Array(1), eventDispatcher: EventDispatcher, _initialized: true, plugins: Plugins}
    21. eventListeners: EventListeners {container: Container, *doMouseTouchClick: ƒ, *handleThemeChange: ƒ, *handleVisibilityChange: ƒ, _handleWindowResize: ƒ, …}
    22. _firstStart: true
    23. _initialSourceOptions: {background: {…}, fpsLimit: 120, interactivity: {…}, particles: {…}, detectRetina: true}
    24. _intersectionManager: (entries) => {…}
    25. _intersectionObserver: IntersectionObserver {root: null, rootMargin: ‘0px 0px 0px 0px’, thresholds: Array(1), delay: 0, trackVisibility: false, …}
    26. _lifeTime: 8407
    27. _nextFrame: async (timestamp) => {…}
    28. options: Options {engine: Engine, *container: Container, autoPlay: true, *findDefaultTheme: ƒ, _importPreset: ƒ, …}
    29. _paused: false
    30. _sourceOptions**: {background: {…}, fpsLimit: 120, interactivity: {…}, particles: {…}, detectRetina: true}
    31. options: (…)
    32. sourceOptions: (…)
    33. [[Prototype]]: Object

What am I doing wrong?

Made sure all packages are correctly installed. Tried a simpler page without svg but the result is always the same, I just see the background defined in CSS.

2

Answers


  1. Chosen as BEST ANSWER

    Ok, I managed to fix it by doing two things. I used loadSlim instead of loadFull as I was getting an "interactor.init is not a Function" error. I read up and found it might have to do with the current/newest version.

    The other thing I did was to restructure my code like so:

    import  { useEffect, useState, useMemo } from "react";
    import Particles, { initParticlesEngine } from "@tsparticles/react";
    import { loadSlim } from "@tsparticles/slim";
    import { loadPolygonMaskPlugin } from "@tsparticles/plugin-polygon-mask";
    import { images8 } from "../constants";
    
    
    const ParticleComponent = () => {
      const [init, setInit] = useState(false);
      useEffect(() => {
        initParticlesEngine(async (engine) => {
          await loadSlim(engine);
          await loadPolygonMaskPlugin(engine);
        }).then(() => {
          setInit(true);
        });
      }, []);
    
      const particlesLoaded = (container) => {
        
      };
    
      const options = useMemo(
        () => ({
          background: {
            color: {
              value: "transparent",
            },
          },
    
          fpsLimit: 60,
          interactivity: {
            events: {
              onHover: {
                enable: true,
                mode: "bubble",
              },
            },
            modes: {
              bubble: {
                distance: 40,
                duration: 2,
                opacity: 8,
                size: 6,
                speed: 3,
              },
            },
          },
          particles: {
            color: {
              value: "#ff0000",
              animation: {
                enable: true,
                speed: 20,
                sync: true,
              },
            },
            links: {
              blink: false,
              color: "random",
              consent: false,
              distance: 30,
              enable: true,
              opacity: 0.3,
              width: 0.5,
            },
            move: {
              enable: true,
              outModes: "bounce",
              speed: { min: 0.5, max: 1 },
            },
            number: {
              value: 200,
            },
            opacity: {
              animation: {
                enable: true,
                speed: 2,
                sync: false,
              },
              random: false,
              value: { min: 0.05, max: 1 },
            },
            shape: {
              type: "circle",
            },
            size: {
              animation: {
                enable: false,
                speed: 40,
                sync: false,
              },
              random: true,
              value: { min: 0.1, max: 1 },
            },
          },
          polygon: {
            draw: {
              enable: true,
              stroke: {
                color: "#fff",
                width: 0.3,
                opacity: 0.2,
              },
            },
    
            move: {
              radius: 10,
            },
            inline: {
              arrangement: "equidistant",
            },
    
            scale: 1,
    
            type: "inline",
            url: images8,
          },
    
          detectRetina: true,
        }),
        []
      );
    
      if (init) {
        return (
          <Particles
            id="tsparticles"
            particlesLoaded={particlesLoaded}
            options={options}
          />
        );
      }
    
      return <></>;
    };
    export default ParticleComponent;
    

  2. It seems like the issue is with how the SVG URL is specified in your tsParticles configuration. You’ve set the url property in the polygon mask options to "mysvg", which doesn’t link to the actual SVG file. Try to replace "mysvg" with the imported mysvg variable that contains the path to your SVG.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search