[英]How to add external javascript in react app
我制作了一个 JavaScript 粒子动画,它在普通的 html 网站上运行良好。 我尝试使用反应头盔/useEffect 将它实现到我的反应应用程序中,但两者都不起作用,我不知道发生了什么。
这是我的脚本:
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.style.position = 'absolute';
canvas.style.width = '100%';
canvas.style.height = '100%';
const container = document.querySelector('.particles');
container.appendChild(canvas);
let particleArray;
class Particle {
constructor(x, y, dirX, dirY, size, color) {
this.x = x;
this.y = y;
this.dirX = dirX;
this.dirY = dirY;
this.size = size;
this.color = color;
this.scale = .1;
this.counter = 0;
}
draw() {
var gradient = ctx.createRadialGradient(this.x, this.y, this.size / 8, this.x, this.y, this.size);
gradient.addColorStop(0, 'white');
gradient.addColorStop(1, 'white');
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2, false);
ctx.shadowColor = this.color;
ctx.shadowBlur = 10;
ctx.fillStyle = this.color;
ctx.fill();
}
update() {
if (this.x + this.size > canvas.width || this.x - this.size < 0) {
this.dirX = -this.dirX;
}
if (this.y + this.size > canvas.height || this.y - this.size < 0) {
this.dirY = -this.dirY;
}
this.size += this.scale;
this.counter += .1;
if (this.counter > 3) {
this.scale = -this.scale;
this.counter = 0;
}
this.x += this.dirX;
this.y += this.dirY;
this.draw();
}
}
function init() {
particleArray = [];
for (let i = 0; i < 25; i++) {
let size = Math.random() * 3;
let x = Math.random() * (innerWidth - size * 2);
let y = Math.random() * (innerHeight - size * 2);
let dirX = (Math.random() * .4) - .2;
let dirY = (Math.random() * .4) - .2;
let colors = ['#721240']
let color = colors[Math.floor(Math.random() * colors.length)];
particleArray.push(new Particle(x, y, dirX, dirY, size, color));
}
}
function animate() {
requestAnimationFrame(animate);
ctx.clearRect(0, 0, innerWidth, innerHeight);
for (let i = 0; i < particleArray.length; i++) {
particleArray[i].update();
}
}
init();
animate();
window.addEventListener('resize', () => {
canvas.width = innerWidth;
canvas.height = innerHeight;
init()
})
这是我尝试将它添加到 App.js 中的 React 应用程序的方法:
<div className="particles">
{useScript("./assets/particles.js")}
</div>
useScript 是一个使用 useEffect 的 react 函数:
import { useEffect } from "react";
function useScript(url) {
useEffect(() => {
const script = document.createElement("script");
script.src = url;
script.async = false;
document.body.appendChild(script);
return () => {
document.body.removeChild(script);
};
}, [url]);
}
export default useScript;
请帮助我被卡住了...
与其注入脚本,不如直接在useEffect
注入代码本身。 这在多个场合对我有用
这是我建议的代码。 console.log()
在多个地方使用 canvas 和particleArray 之类的东西来让它正确
import { useEffect } from "react";
function useScript(url) {
useEffect(() => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.style.position = 'absolute';
canvas.style.width = '100%';
canvas.style.height = '100%';
const container = document.querySelector('.particles');
container.appendChild(canvas);
let particleArray;
class Particle {
constructor(x, y, dirX, dirY, size, color) {
this.x = x;
this.y = y;
this.dirX = dirX;
this.dirY = dirY;
this.size = size;
this.color = color;
this.scale = .1;
this.counter = 0;
}
draw() {
var gradient = ctx.createRadialGradient(this.x, this.y, this.size / 8, this.x, this.y, this.size);
gradient.addColorStop(0, 'white');
gradient.addColorStop(1, 'white');
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2, false);
ctx.shadowColor = this.color;
ctx.shadowBlur = 10;
ctx.fillStyle = this.color;
ctx.fill();
}
update() {
if (this.x + this.size > canvas.width || this.x - this.size < 0) {
this.dirX = -this.dirX;
}
if (this.y + this.size > canvas.height || this.y - this.size < 0) {
this.dirY = -this.dirY;
}
this.size += this.scale;
this.counter += .1;
if (this.counter > 3) {
this.scale = -this.scale;
this.counter = 0;
}
this.x += this.dirX;
this.y += this.dirY;
this.draw();
}
}
function init() {
particleArray = [];
for (let i = 0; i < 25; i++) {
let size = Math.random() * 3;
let x = Math.random() * (innerWidth - size * 2);
let y = Math.random() * (innerHeight - size * 2);
let dirX = (Math.random() * .4) - .2;
let dirY = (Math.random() * .4) - .2;
let colors = ['#721240']
let color = colors[Math.floor(Math.random() * colors.length)];
particleArray.push(new Particle(x, y, dirX, dirY, size, color));
}
}
function animate() {
requestAnimationFrame(animate);
ctx.clearRect(0, 0, innerWidth, innerHeight);
for (let i = 0; i < particleArray.length; i++) {
particleArray[i].update();
}
}
init();
animate();
window.addEventListener('resize', () => {
canvas.width = innerWidth;
canvas.height = innerHeight;
init()
})
return ()=>{
window.removeEventListener('resize', () => {
canvas.width = innerWidth;
canvas.height = innerHeight;
init()
})
}
}, [url]);
}
export default useScript;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.