react实现粒子圆圈波动动画效果代码

代码语言:html

所属分类:粒子

代码描述:react实现粒子圆圈波动动画效果代码

代码标签: 圆圈 波动 动画 效果

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >

<head>

  <meta charset="UTF-8">
<link type="text/css" rel="stylesheet" href="//repo.bfw.wiki/bfwrepo/css/material-icons.min.css">
<style>
/* Page Style */
a {
  color: white;
}

button {
  outline: none;
}

/* Control Panel */
.ps5-cpanel {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  padding: 1rem;
  width: 320px;
  max-width: 100%;
  box-sizing: border-box;
  overflow-y: auto;
  color: white;
  background: linear-gradient(45deg, #2d2e33, #191a22);
  box-shadow: -5px 0 15px black;
  transform: translateX(100%);
  transition: transform 300ms ease-in-out;
  will-change: transform;
}
@media (min-width: 576px) {
  .ps5-cpanel {
    padding: 2rem;
    width: 360px;
  }
}
.ps5-cpanel.active {
  transform: translateX(0);
}
.ps5-cpanel h3 {
  margin-top: 0;
}
.ps5-cpanel div {
  margin-bottom: 3rem;
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}
.ps5-cpanel label {
  display: inline-flex;
  width: 45%;
  align-items: center;
  justify-content: space-between;
}
.ps5-cpanel label button {
  width: 40px;
}
.ps5-cpanel input[type="color"] {
  padding: 0;
  background: none;
  border: none;
  width: 40px;
  height: 44px;
}
.ps5-cpanel input[type="number"] {
  width: 50px;
  padding: 0.5rem;
}
.ps5-cpanel button {
  width: 100%;
}

.ps5-cpanel-btn {
  position: absolute;
  z-index: 2;
  top: 1rem;
  right: 1rem;
  width: 40px;
}

.ps5-btn, .ps5-cpanel button, .ps5-cpanel-btn {
  display: flex;
  justify-content: center;
  align-items: center;
  color: black;
  background-color: white;
  border: none;
  border-radius: 20px;
  height: 40px;
  transition: color 300ms ease-in-out, background-color 300ms ease-in-out;
  will-change: color, background-color;
  cursor: pointer;
}
.ps5-btn:focus, .ps5-cpanel button:focus, .ps5-cpanel-btn:focus, .ps5-btn:hover, .ps5-cpanel button:hover, .ps5-cpanel-btn:hover {
  color: white;
  background-color: black;
}
</style>



</head>

<body>
  <div id="root"></div>

  
      <script type="module">
import React, { Component } from "https://cdn.skypack.dev/react@17.0.1";
import ReactDOM from "https://cdn.skypack.dev/react-dom@17.0.1";

const defaultConfig = {
  cpanel: true, // you can remove it if you don't need the CP
  particles: [],
  bgColorLeft: "#57484c",
  bgColorRight: "#10101c",
  particleColors: ["#FEFFAC", "#372627", "#FFFFFF"],
  particleSpeed: 1,
  particleMax: 200,
  particleDelay: 50,
  particleSize: 7 };


class Canvas extends Component {
  constructor(props) {
    super(props);
    this.state = defaultConfig;
    this.updateAnimationState = this.updateAnimationState.bind(this);
    this.timeLast = Date.now();
    this.colorVariation = 0;
  }

  componentDidMount() {
    this.rAF = requestAnimationFrame(this.updateAnimationState);
  }

  componentWillUnmount() {
    cancelAnimationFrame(this.rAF);
  }

  particleColor(color) {
    function hexToRgb(hex) {
      var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
      return result ?
      {
        r: parseInt(result[1], 16),
        g: parseInt(result[2], 16),
        b: parseInt(result[3], 16) } :

      null;
    }

    const rgbColor = hexToRgb(color);

    return {
      r: Math.round(
      Math.random() * this.colorVariation - this.colorVariation / 2 + rgbColor.r),

      g: Math.round(
      Math.random() * this.colorVariation - this.colorVariation / 2 + rgbColor.g),

      b: Math.round(
      Math.random() * this.colorVariation - this.colorVariation / 2 + rgbColor.b),

      a: 0,
      m: 1,
      s: Math.random() };

  }

  updateAnimationState() {
    let particlesCurrent = this.state.particles;

    if (particlesCurrent.length > 0) {
      particlesCurrent = particlesCurrent.filter(p => {
        return (
          p.x > -10 &&
          p.x < window.innerWidth + 10 &&
          p.y > -10 &&
          p.y < window.innerHeight + 10);

      });
    }

    if (particlesCurrent.length < this.state.particleMax) {
      const timeCurrent = Date.now();
      if (timeCurrent - this.timeLast > this.state.particleDelay) {
        particlesCurrent.push({
          x: Math.round(Math.random() * window.innerWidth),
          y: Math.round(
          Math.random() * window.innerHeight / 2 + window.innerHeight / 4),

          r: Math.ceil(Math.random() * this.state.particleSize),
          c: this.particleColor(
          this.state.particleColors[
          Math.floor(Math.random() * this.state.particleColors.length)]),


          s: Math.random() * 2,
          d: Math.round(Math.random() * 360) });

        this.timeLast = timeCurrent;
      }
    }

    if (particlesCurrent.length > 0) {
      particlesCurrent.map(p => {
        const n = 180 - (p.d + 90);
        if (p.c.a > 0.9) {
          p.c.m = -1;
        } else if (p.c.a < 0.1) {
          p.c.m = 1;
        }
        p.c.a += 0.05 * p.c.m * p.c.s;

        if (p.d > 0 && p.d < 180) {
          p.x +=
          Math.sin(p.d) / Math.sin(1) * (this.state.particleSpeed * p.s) * 0.1;
        } else {
          p.x -=
          Math.sin(p.d) / Math.sin(1) * (this.state.particleSpeed * p.s) * 0.1;
        }
        if (p.d > 90 && p.d < 270) {
          p.y +=
          Math.sin(n) / Math.sin(1) * (this.state.particleSpeed * p.s) * 0.1;
        } else {
          p.y -=
          Math.sin(n) / Math.sin(1) * (this.state.particleSpeed * p.s) * 0.1;
        }
        return p;
      });
    }

    this.setState({ particles: particlesCurrent });
    this.rAF = requestAnimationFrame(this.updateAnimationState);
  }

  handleChange(i, value) {
    let particleColors = [...this.state.particleColors];
    particleColors[i] = value;
    this.setState({ particleColors });
  }

  handleAdd() {
    let particleColors = [...this.state.particleColors];
    particleColors.push("#000000");
    this.setState({ particleColors });
  }

  handleRemove(i) {
    let p.........完整代码请登录后点击上方下载按钮下载查看

网友评论0