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