Animating canvas to look like tv noise

前端 未结 7 2134
野趣味
野趣味 2020-12-22 17:22

I have a function named generateNoise() which creates a canvas element and paints random RGBA values to it; which, gives the appearance of noise.


<
7条回答
  •  情歌与酒
    2020-12-22 18:03

    I re-wrote your code so each step is separate so you can re-use things without having to create and re-create each time, reduced in-loop calls and hopefully made it clear enough to be able to follow by reading it.

    function generateNoise(opacity, h, w) {
        function makeCanvas(h, w) {
             var canvas = document.createElement('canvas');
             canvas.height = h;
             canvas.width = w;
             return canvas;
        }
    
        function randomise(data, opacity) { // see prev. revision for 8-bit
            var i, x;
            for (i = 0; i < data.length; ++i) {
                x = Math.floor(Math.random() * 0xffffff); // random RGB
                data[i] =  x | opacity; // set all of RGBA for pixel in one go
            }
        }
    
        function initialise(opacity, h, w) {
            var canvas = makeCanvas(h, w),
                context = canvas.getContext('2d'),
                image = context.createImageData(h, w),
                data = new Uint32Array(image.data.buffer);
            opacity = Math.floor(opacity * 0x255) << 24; // make bitwise OR-able
            return function () {
                randomise(data, opacity); // could be in-place for less overhead
                context.putImageData(image, 0, 0);
                // you may want to consider other ways of setting the canvas
                // as the background so you can take this out of the loop, too
                document.body.style.backgroundImage = "url(" + canvas.toDataURL("image/png") + ")";
            };
        }
    
        return initialise(opacity || 0.2, h || 55, w || 55);
    }
    

    Now you can create some interval or timeout loop which keeps re-invoking the generated function.

    window.setInterval(
        generateNoise(.8, 200, 200),
        100
    );
    

    Or with requestAnimationFrame as in Ken's answer

    var noise = generateNoise(.8, 200, 200);
    
    (function loop() {
        noise();
        requestAnimationFrame(loop);
    })();
    

    DEMO

提交回复
热议问题