簡體   English   中英

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

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM