0

I'm working on canvas here I want to use same canvas multiple times on the same page I tried using the class name getElementsByClassName and using query selector also. but it's not working. Can anyone point me in the right direction what might be the issue here how can I achieve? in both boxes box1, box2 I want to add same canvas.

const noise = () => {
    let canvas, ctx;
    let wWidth, wHeight;
    let noiseData = [];
    let frame = 0;
    let loopTimeout;

    // Create Noise
    const createNoise = () => {
        const idata = ctx.createImageData(wWidth, wHeight);
        const buffer32 = new Uint32Array(idata.data.buffer);
        const len = buffer32.length;

        for (let i = 0; i < len; i++) {
            if (Math.random() < 0.5) {
                buffer32[i] = 0xff000000;
            }
        }

        noiseData.push(idata);
    };

    // Play Noise
    const paintNoise = () => {
        if (frame === 9) {
            frame = 0;
        } else {
            frame++;
        }
        ctx.putImageData(noiseData[frame], 0, 0);
    };


    // Loop
    const loop = () => {
        paintNoise(frame);
        loopTimeout = window.setTimeout(() => {
            window.requestAnimationFrame(loop);
        }, (1000 / 25));
    };


    // Setup
    const setup = () => {
        wWidth = window.innerWidth;
        wHeight = window.innerHeight;

        canvas.width = wWidth;
        canvas.height = wHeight;

        for (let i = 0; i < 10; i++) {
            createNoise();
        }
        loop();
    };


    // Reset
    let resizeThrottle;
    const reset = () => {
        window.addEventListener('resize', () => {
            window.clearTimeout(resizeThrottle);

            resizeThrottle = window.setTimeout(() => {
                window.clearTimeout(loopTimeout);
                setup();
            }, 200);
        }, false);
    };


    // Init
    const init = (() => {
         canvas = document.getElementById('noise');
        //canvas = document.getElementsByClassName('noise');
        ctx = canvas.getContext('2d');
        setup();
    })();
};
noise();
.noise {
    z-index: 100;
    position: absolute;
    top: 0;
    left: 0;   
    width: 100%;
    height: 100%;
    pointer-events: none;
    opacity: .5;
}
.box1, .box2 {
    position: relative;
    width: 300px;
    height: 300px;
    margin: 20px;
    background: #eee;
}
<div class="box1">
    <canvas id="noise" class="noise"></canvas>
</div>

<div class="box2">
    <canvas id="noise" class="noise"></canvas>
</div>
Husna
  • 1,286
  • 4
  • 19
  • 48
  • You can't have two of the same ids on the page, it's going to give you weird side effects. Use the class instead. getElementById will only every select one element. – SpeedOfRound Mar 25 '19 at 13:43
  • @SpeedOfRound yeah that's the reason I tried using the class name. – Husna Mar 25 '19 at 13:44
  • 1
    Then _show us_ what you actually tried. Explain your reasoning for the changes you made. – 04FS Mar 25 '19 at 13:45
  • @04FS ` var canvases = Array.from(document.getElementsByClassName('noise')); for (let canvas of canvases) { ctx = canvas.getContext('2d'); }` or ` canvas = document.getElementsByClassName('noise'); ctx = canvas[0].getContext('2d');` – Husna Mar 25 '19 at 13:46
  • 1
    you're overwriting ctx, which createnoise uses as the canvas. Please update your question, it's too difficult so see how things go together like this. – SpeedOfRound Mar 25 '19 at 13:48
  • I'm pretty sure you can't add the same element to two locations at once. If you just want a copy of the element, you can use cloneNode (https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode) You can do something like `const myCanvas = document.querySelector("canvas.whateverClass"); document.body.appendChild(myCanvas.cloneNode(true));` – Cat Mar 25 '19 at 13:56
  • @Cat can you please add the snippet of your code. – Husna Mar 25 '19 at 14:07
  • I don't have any more code to put in a snippet. My comment was just showing how to duplicate an element (just select it, call cloneNode on it, and append it to a container element on the page.) This is the closest you can get to using the same html element twice on the same page (although an argument could be made that using a – Cat Mar 25 '19 at 22:48

1 Answers1

0

Use getElementsByClassName. You will get an array then. For instance for class box:

canvas = document.getElementsByClassName("box");

for (i = 0; i < canvas.length; i++) { //...do smth here...// }
Gilles Heinesch
  • 2,889
  • 1
  • 22
  • 43
Roman
  • 456
  • 3
  • 4
  • Actually it doesn't returns an array, it returns an [HTMLCollection](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection). Not *a lot* of differences, but for example, `document.getElementsByClassNames('some-class').forEach(() => {})` is invalid – Nino Filiu Mar 25 '19 at 14:28