简体   繁体   English

如何在反应应用程序中添加外部 javascript

[英]How to add external javascript in react app

I made a JavaScript particle animation and it works fine on a normal html website.我制作了一个 JavaScript 粒子动画,它在普通的 html 网站上运行良好。 I tried implementing it into my react app using react helmet/useEffect but both didn't work and I don't know what's going on.我尝试使用反应头盔/useEffect 将它实现到我的反应应用程序中,但两者都不起作用,我不知道发生了什么。

Here is my script:这是我的脚本:

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()
})

And here is how I tried to add it to my react app in App.js:这是我尝试将它添加到 App.js 中的 React 应用程序的方法:

<div className="particles">
    {useScript("./assets/particles.js")}
</div>

useScript is a react function using useEffect: 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;

Please help I'm stuck...请帮助我被卡住了...

Instead of injecting the script, why don't you directly inject the code itself in useEffect .与其注入脚本,不如直接在useEffect注入代码本身。 That's worked for me on multiple occassions这在多个场合对我有用

This is my proposed code.这是我建议的代码。 console.log() things like canvas and particleArray at multiple places to get it right 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM