简体   繁体   中英

react-tsparticles, background darkmode

I'm working on background with react-tsparticles . I have a problem displaying this one, the whole code looks error free to me, but when displaying I have a flickering effect (particles appear and disappear). I want to particles switching color after selecting darkmode button

Here is my Background.js

import ParticlesConfig from "./ParticlesConfig";
import { useCallback } from 'react';
import { loadFull } from 'tsparticles';
import Particles from 'react-tsparticles';
import React, { useEffect, useState } from "react";


const Background = (props) => {
  const [theme, setTheme] = useState("light");
  const particlesInit = useCallback(async (engine) => {
    console.log(engine);
    // you can initiate the tsParticles instance (engine) here, adding custom shapes or presets
    // this loads the tsparticles package bundle, it's the easiest method for getting everything ready
    // starting from v2 you can add only the features you need reducing the bundle size
    await loadFull(engine);
  }, []);
  const [particlesContainer, setParticlesContainer] = useState();

  const particlesLoaded = (container) => {
    setParticlesContainer(container);
  };

  useEffect(() => {
    if (particlesContainer && particlesContainer.currentTheme !== props.theme) {
      particlesContainer.loadTheme(props.theme);
    }
  }, [props.theme, particlesContainer]);
  ;
  return (
    <div id='particle-background'>
     
    
    <div className="background">
    <button onClick={() => setTheme("light")}>Light</button>
  
    <button onClick={() => setTheme("dark")}>Dark</button>
    <Particles theme={theme}
     id='tsparticles'
     particlesLoaded='particlesLoaded'
     init={particlesInit}
     loaded={particlesLoaded}
     options={ParticlesConfig}
      />
    
  </div>
  </div>
  );
};

export default Background;

here is my ParticlesConfig.js

const ParticlesConfig = {
  autoplay: true,
  fullScreen: {
    enable: true,
    zIndex: 0,
  },
  background: {
    color: {
      value: "transparent"
    }
  },
  fpsLimit: 60,
  interactivity: {
    detect_on: 'window',
    events: {
      onClick: {
        enable: true,
        mode: "push"
      },
      onHover: {
        enable: true,
        mode: "repulse"
      },
      resize: true
    },
    modes: {
      bubble: {
        distance: 400,
        duration: 2,
        opacity: 0.8,
        size: 40
      },
      push: {
        quantity: 1
      },
      repulse: {
        distance: 200,
        duration: 0.4
      }
    }
  },
  particles: {
    color: {
      value: "#777"
    },
    links: {
      color: "#777777",
      distance: 150,
      enable: true,
      opacity: 0.5,
      width: 1
    },
    collisions: {
      enable: true
    },
    move: {
      direction: "none",
      enable: true,
      outMode: "bounce",
      random: false,
      speed: 1,
      straight: false
    },
    number: {
      density: {
        enable: true,
        area: 800
      },
      value: 90
    },
    opacity: {
      value: 0.5
    },
    shape: {
      type: "circle"
    },
    size: {
      random: true,
      value: 5
    }
  },
  themes: [
    {
      name: "light",
      default: {
        value: true,
        mode: "light"
      },
      options: {
        background: {
          color: "#0f0e17"
        },
        particles: {
          color: {
            value: "#ff8906"
          }
        }
      }
    },
    {
      name: "dark",
      default: {
        value: true,
        mode: "dark"
      },
      options: {
        background: {
          color: "transparent"
        },
        particles: {
          color: {
            value: "#ff8906"
          }
        }
      }
    }
  ],
  detectRetina: true


};
export default ParticlesConfig;

There are two issues in your code, you can see a working sample here: https://codesandbox.io/s/silly-artem-mbfryn?file=/src/Background.jsx

The two issues are:

  1. Using props.theme but you are setting it in the state, you can get rid of every props.theme using theme instead, if you want it as a property you can assign it to state instead of the default value you chose
  2. Not using the useCallback for the particlesLoaded function. That function is responsible of the flickering of the background. In the sample I've used a useCallback with empty dependencies array since they are not required, and it stopped flickering.

I've also changed the zIndex property in the fullScreen sections of your particles configuration for showing the theme buttons, and changed particles color just for seeing a difference other than the background.

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