在React.js/路由器实现背景粒子动画的自断区间
Self-breaking interval in React.js / router implementation of background particles animation
已解决 - 问题是容器中使用“/about”和“/portfolio”路径呈现的 setInterval 方法 - 它使动画滞后
https://github.com/kaczmarekm/portfolio - 完整的应用程序代码
http://users.pja.edu.pl/~s17335/portfolio/ - 应用程序 - 观察粒子动画如何在单击导航按钮更改页面后开始滞后、减慢和停止 - 它在几秒钟后发生,它并没有完全停止 - 它改变颜色是由于SetParticleColor() 函数,但是有很大的延迟,就像间隔设置的时间比 10ms 长得多
问题是我不知道为什么会这样,所以希望有人能找到来源。
代码:
App.js
export default class App extends Component {
constructor(){
super();
this.state = {
particleInterval: null
}
}
componentWillMount() {
InitCanvas();
Paint();
}
componentDidMount(){
this.setState({
particleInterval: setInterval(() =>
requestAnimationFrame(Particles), 10)
})
}
render() {
return (
<Router>
<div>
<NavigationContainer/>
<Switch>
<Route path="/home" component={HomeContainer}/>
<Route path="/about" component={AboutContainer}/>
<Route path="/portfolio" component={PortfolioContainer}/>
<Route path="/contact" component={ContactContainer}/>
<Route path="*" component={EntryPageContainer}/>
</Switch>
</div>
</Router>
);
}
}
InitCanvas.js
export function InitCanvas() {
const rootWidth = window.innerWidth;
const rootHeight = window.innerHeight;
const canvas = document.createElement('canvas');
canvas.id = 'canvas';
canvas.width = rootWidth;
canvas.height = rootHeight;
canvas.style.zIndex = '-1';
canvas.style.position = 'absolute';
canvas.style.margin = '0';
canvas.style.padding = '0';
canvas.style.display = 'block';
const root = document.getElementById('root');
root.appendChild(canvas);
}
Particles.js
import { ParticleArray } from "../../Constants/ParticleArray";
import { SetParticleColor } from "./SetParticleColor";
const rootWidth = window.innerWidth;
const rootHeight = window.innerHeight;
for (let i = 0; i < 500; i++) {
let moveX = Math.random() - 0.5;
let moveY = Math.random() - 0.5;
ParticleArray[i] = Math.random()*rootWidth, Math.random()*rootWidth,
moveX,moveY];
}
export function Particles() {
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, rootWidth, rootHeight);
for (let i = 0; i < 500; i++) {
let centerX = ParticleArray[i][0];
let centerY = ParticleArray[i][1];
let moveX = ParticleArray[i][2];
let moveY = ParticleArray[i][3];
let radius = 2;
ctx.beginPath();
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = SetParticleColor();
ctx.fill();
centerX += moveX;
centerY += moveY;
if(centerX >= rootWidth || centerX <= 0 || centerY >= rootHeight ||
centerY <= 0){
centerX = Math.random() * rootWidth;
centerY = Math.random() * rootHeight;
}
ParticleArray[i] = [centerX, centerY, ParticleArray[i][2],
ParticleArray[i][3]];
}
}
考虑以下更改以最大程度地减少您可能对内存管理施加的负载 - 关键是要避免每次动画迭代重新创建约 500 个粒子对象,如下所示。
还要考虑颜色结果的重用,以提供一些额外的性能提升(取决于 SetParticleColor()
中发生的计算):
/* Avoid calling for each particle seeing the color is the same
*/
var currentColor = SetParticleColor();
for (let i = 0; i < 500; i++) {
/* Consider extracting the current particle, and working with it
as shown below
*/
let particle = ParticleArray[i]
let centerX = particle[0];
let centerY = particle[1];
let moveX = particle[2];
let moveY = particle[3];
let radius = 2;
ctx.beginPath();
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = currentColor;
ctx.fill();
centerX += moveX;
centerY += moveY;
if(centerX >= rootWidth || centerX <= 0 || centerY >= rootHeight ||
centerY <= 0){
centerX = Math.random() * rootWidth;
centerY = Math.random() * rootHeight;
}
/* Mutate the existing particle in your particles array rather
than recreating a new replacement particle for every iteration
*/
particle[0] = centerX
particle[1] = centerY
particle[2] = moveX
particle[3] = moveY
}
我还建议使用 setTimeout
而不是 setInterval
来更新动画,同时对动画循环进行以下修改。 setInterval
将在您设置的时间间隔内重新运行,即使间隔任务尚未完成,也会重新运行。这意味着如果先前的间隔任务尚未完成,则后续任务有可能在执行中重叠 - 在这样的动画中,这将是有问题的。考虑对 componentDidMount
的以下更改:
componentDidMount(){
// Render frame itteration
const renderFrame = () => {
// Request a re-render
requestAnimationFrame(Particles)
// Sechedule the next renderFrame when the
// browser is ready
setTimeout(() => renderFrame(), 10)
}
renderFrame();
}
希望对您有所帮助(以及不错的投资组合网站)! :-)
已解决 - 问题是容器中使用“/about”和“/portfolio”路径呈现的 setInterval 方法 - 它使动画滞后
https://github.com/kaczmarekm/portfolio - 完整的应用程序代码
http://users.pja.edu.pl/~s17335/portfolio/ - 应用程序 - 观察粒子动画如何在单击导航按钮更改页面后开始滞后、减慢和停止 - 它在几秒钟后发生,它并没有完全停止 - 它改变颜色是由于SetParticleColor() 函数,但是有很大的延迟,就像间隔设置的时间比 10ms 长得多
问题是我不知道为什么会这样,所以希望有人能找到来源。
代码:
App.js
export default class App extends Component {
constructor(){
super();
this.state = {
particleInterval: null
}
}
componentWillMount() {
InitCanvas();
Paint();
}
componentDidMount(){
this.setState({
particleInterval: setInterval(() =>
requestAnimationFrame(Particles), 10)
})
}
render() {
return (
<Router>
<div>
<NavigationContainer/>
<Switch>
<Route path="/home" component={HomeContainer}/>
<Route path="/about" component={AboutContainer}/>
<Route path="/portfolio" component={PortfolioContainer}/>
<Route path="/contact" component={ContactContainer}/>
<Route path="*" component={EntryPageContainer}/>
</Switch>
</div>
</Router>
);
}
}
InitCanvas.js
export function InitCanvas() {
const rootWidth = window.innerWidth;
const rootHeight = window.innerHeight;
const canvas = document.createElement('canvas');
canvas.id = 'canvas';
canvas.width = rootWidth;
canvas.height = rootHeight;
canvas.style.zIndex = '-1';
canvas.style.position = 'absolute';
canvas.style.margin = '0';
canvas.style.padding = '0';
canvas.style.display = 'block';
const root = document.getElementById('root');
root.appendChild(canvas);
}
Particles.js
import { ParticleArray } from "../../Constants/ParticleArray";
import { SetParticleColor } from "./SetParticleColor";
const rootWidth = window.innerWidth;
const rootHeight = window.innerHeight;
for (let i = 0; i < 500; i++) {
let moveX = Math.random() - 0.5;
let moveY = Math.random() - 0.5;
ParticleArray[i] = Math.random()*rootWidth, Math.random()*rootWidth,
moveX,moveY];
}
export function Particles() {
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, rootWidth, rootHeight);
for (let i = 0; i < 500; i++) {
let centerX = ParticleArray[i][0];
let centerY = ParticleArray[i][1];
let moveX = ParticleArray[i][2];
let moveY = ParticleArray[i][3];
let radius = 2;
ctx.beginPath();
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = SetParticleColor();
ctx.fill();
centerX += moveX;
centerY += moveY;
if(centerX >= rootWidth || centerX <= 0 || centerY >= rootHeight ||
centerY <= 0){
centerX = Math.random() * rootWidth;
centerY = Math.random() * rootHeight;
}
ParticleArray[i] = [centerX, centerY, ParticleArray[i][2],
ParticleArray[i][3]];
}
}
考虑以下更改以最大程度地减少您可能对内存管理施加的负载 - 关键是要避免每次动画迭代重新创建约 500 个粒子对象,如下所示。
还要考虑颜色结果的重用,以提供一些额外的性能提升(取决于 SetParticleColor()
中发生的计算):
/* Avoid calling for each particle seeing the color is the same
*/
var currentColor = SetParticleColor();
for (let i = 0; i < 500; i++) {
/* Consider extracting the current particle, and working with it
as shown below
*/
let particle = ParticleArray[i]
let centerX = particle[0];
let centerY = particle[1];
let moveX = particle[2];
let moveY = particle[3];
let radius = 2;
ctx.beginPath();
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = currentColor;
ctx.fill();
centerX += moveX;
centerY += moveY;
if(centerX >= rootWidth || centerX <= 0 || centerY >= rootHeight ||
centerY <= 0){
centerX = Math.random() * rootWidth;
centerY = Math.random() * rootHeight;
}
/* Mutate the existing particle in your particles array rather
than recreating a new replacement particle for every iteration
*/
particle[0] = centerX
particle[1] = centerY
particle[2] = moveX
particle[3] = moveY
}
我还建议使用 setTimeout
而不是 setInterval
来更新动画,同时对动画循环进行以下修改。 setInterval
将在您设置的时间间隔内重新运行,即使间隔任务尚未完成,也会重新运行。这意味着如果先前的间隔任务尚未完成,则后续任务有可能在执行中重叠 - 在这样的动画中,这将是有问题的。考虑对 componentDidMount
的以下更改:
componentDidMount(){
// Render frame itteration
const renderFrame = () => {
// Request a re-render
requestAnimationFrame(Particles)
// Sechedule the next renderFrame when the
// browser is ready
setTimeout(() => renderFrame(), 10)
}
renderFrame();
}
希望对您有所帮助(以及不错的投资组合网站)! :-)