How to integrate tsParticles in React

100 Views Asked by At

I'm trying to implement this https://codepen.io/idofugh/pen/KKrXJGE into a React website but I cannot seem to make it work.

First I've tried to create a TsParticles.jsx component like so:

import React, { useEffect } from 'react';
import Particles from 'react-tsparticles';
import noise from 'noisejs';


const TsParticles = () => {
  let noiseZ;
  let size;
  let columns;
  let rows;
  let w;
  let h;
  let field;

  const options = {
    background: {
      color: {
        value: '#161616',
      },
    },
    fpsLimit: 120,
    particles: {
      number: {
        value: 0,
      },
    },
    detectRetina: true,
    pauseOnBlur: true,
  };

  useEffect(() => {
    const setup = (container, options) => {
      size = 20;
      noiseZ = 0;
      reset(container);
      window.addEventListener('resize', reset);
    };

    const initField = () => {
      field = new Array(columns);
      for (let x = 0; x < columns; x++) {
        field[x] = new Array(columns);
        for (let y = 0; y < rows; y++) {
          field[x][y] = [0, 0];
        }
      }
    };

    const calculateField = () => {
      for (let x = 0; x < columns; x++) {
        for (let y = 0; y < rows; y++) {
          let angle = noise.perlin3(x / 50, y / 50, noiseZ) * Math.PI * 2;
          let length = noise.perlin3(x / 100 + 40000, y / 100 + 40000, noiseZ);
          field[x][y][0] = angle;
          field[x][y][1] = length;
        }
      }
    };

    const reset = (container) => {
      w = container.canvas.size.width;
      h = container.canvas.size.height;
      noise.seed(Math.random());
      columns = Math.floor(w / size) + 1;
      rows = Math.floor(h / size) + 1;
      initField();
    };

    const drawField = (ctx) => {
      for (let x = 0; x < columns; x++) {
        for (let y = 0; y < rows; y++) {
          let angle = field[x][y][0];
          let length = field[x][y][1];
          ctx.save();
          ctx.translate(x * size, y * size);
          ctx.rotate(angle);
          ctx.strokeStyle = 'white';
          ctx.beginPath();
          ctx.moveTo(0, 0);
          ctx.lineTo(0, size * length);
          ctx.stroke();
          ctx.restore();
        }
      }
    };

    return () => {
      window.removeEventListener('resize', reset);
    };
  }, []);

  const handleInit = (particles) => {
    // You can leave this empty since the setup logic is already defined in the useEffect hook
  };

  const handleLoaded = (particles) => {
    // You can leave this empty since the loaded logic is already defined in the useEffect hook
  };

  return (
    <Particles
      id="tsparticles"
      init={(particles) => handleInit(particles, options)}
      loaded={(particles) => handleLoaded(particles, options)}
      options={options}
    />
  );
};

export default TsParticles;

but I had no luck making it work, so I though I'll just pop it in a JS file and import the file inside the app.js. Managed to get rid of all the errors and I've ended up with this:

import { tsParticles } from "tsparticles-engine";
import noise from "noisejs";

let noiseZ;
let size;
let columns;
let rows;
let w;
let h;
let field;

let container;
const noiseInstance = new noise.Noise();

function setup(container) {
  size = 20;
  noiseZ = 0;
  reset(container);
  window.addEventListener("resize", reset);
}

function initField() {
  field = new Array(columns);
  for (let x = 0; x < columns; x++) {
    field[x] = new Array(columns);
    for (let y = 0; y < rows; y++) {
      field[x][y] = [0, 0];
    }
  }
}

function calculateField() {
  for (let x = 0; x < columns; x++) {
    for (let y = 0; y < rows; y++) {
      let angle = noiseInstance.simplex2(x / 50, y / 50) * Math.PI * 2;
      let length = noiseInstance.simplex2(x / 100 + 40000, y / 100 + 40000);
      field[x][y][0] = angle;
      field[x][y][1] = length;
    }
  }
}

function reset(container) {
  w = container.canvas.size.width;
  h = container.canvas.size.height;
  noiseInstance.seed(Math.random());
  columns = Math.floor(w / size) + 1;
  rows = Math.floor(h / size) + 1;
  initField();
}

function drawField(ctx) {
  for (let x = 0; x < columns; x++) {
    for (let y = 0; y < rows; y++) {
      let angle = field[x][y][0];
      let length = field[x][y][1];
      ctx.save();
      ctx.translate(x * size, y * size);
      ctx.rotate(angle);
      ctx.strokeStyle = "lightgrey"; // color.
      ctx.beginPath();
      ctx.moveTo(0, 0);
      ctx.lineTo(0, size * length);
      ctx.stroke();
      ctx.restore();
    }
  }
}

tsParticles
  .load("tsparticles", {
    background: {
      color: {
        value: "#161616"
      }
    },
    fpsLimit: 120,
    particles: {
      number: {
        value: 0
      }
    },
    detectRetina: true,
    pauseOnBlur: true
  })
  .then((container) => {
    container.setNoise({
      init: function () {
        setup(container);
      },
      update: function () {
        calculateField();

        const mousePos = container.interactivity.mouse.position;

        let sumZ;

        if (mousePos) {
          sumZ =
            (mousePos.x * mousePos.y) /
            (25 * container.canvas.size.width * container.canvas.size.height);
        } else {
          sumZ = 0.004;
        }

        noiseZ += sumZ;

        drawField(container.canvas.context);
      }
    });

    container.refresh();
  });

The problem is, there are no particles visible. The gets displayed but there are no particles.

I apologise if this is not the place to ask this question.

0

There are 0 best solutions below