Search code examples
javascriptsettimeoutsetintervalvisual-glitch

Add pauses to a JavaScript glitch effect


I have an effect that causes a canvas element to "glitch". I would like to edit the effect so that there is more pause between each glitch – as of now, the glitch pause is too short and the glitch is too close to the one before. You can see it in action here: http://naratif.jvitasek.cz/

Also, the code for the glitch is as follows:

function glitchElement(sourceImg, idCanvas) {
    var canvas = document.getElementById(idCanvas)
      , context = canvas.getContext('2d')
      , img = new Image()
      , w
      , h
      , offset
      , glitchInterval;

    img.src = sourceImg;
    img.onload = function() {
      init();
        window.onresize = init;
    };

    var init = function() {
        clearInterval(glitchInterval);
        canvas.width = w = window.innerWidth;
        offset = w * .1;
        canvas.height = h = ~~(230 * ((w - (offset * 2)) / img.width));
        glitchInterval = setInterval(function() {
            clear();
            context.drawImage(img, 0, 0, img.width, 230, offset, 0, w - (offset * 2), h);
            setTimeout(glitchImg, randInt(250,1000));
        }, 500);
    };

    var clear = function() {
        context.rect(0, 0, w, h);
        context.fillStyle = "white";
        context.fill();
    };

    var glitchImg = function() {
        for (var i = 0; i < randInt(1, 13); i++) {
            var x = Math.random() * w;
            var y = Math.random() * h;
            var spliceWidth = w - x;
            var spliceHeight = randInt(5, h / 3);
            context.drawImage(canvas, 0, y, spliceWidth, spliceHeight, x, y, spliceWidth, spliceHeight);
            context.drawImage(canvas, spliceWidth, y, x, spliceHeight, 0, y, x, spliceHeight);
        }
    };

    var randInt = function(a, b) {
        return ~~(Math.random() * (b - a) + a);
    };
}

In this code, there has to be a way to make the pauses longer. That means keep everything as is now, but glitch ... wait longer with the image with no effect (static) .... and then glitch again after like 6 seconds (now it is somewhere between 1 and 1,5s I think).

I just need a name of the library function or something that could help me do that. I looked into setTimeout and setInterval but couldn't really figure it out. Any help appreciated.


Solution

  • To achieve the effect needed, I had to rewrite the init() function and also add a redraw() function like this:

    var init = function() {
        clearInterval(glitchInterval);
        canvas.width = w = window.innerWidth;
        offset = w * 0.1;
        canvas.height = h = ~~(230 * ((w - (offset * 2)) / img.width));
        glitchInterval = setInterval(function() {
            clear();
            console.log('glitching');
            context.drawImage(img, 0, 0, img.width, 230, offset, 0, w - (offset * 2), h);
            glitchImg();
            setTimeout(function() {
                clear();
                redraw();
                console.log('redrawing');
            }, randInt(100,1000)); // the time the image is glitched
        }, randInt(5000,10000)); // the interval between each glitch
    };
    

    The redraw function:

    function redraw() {
        context.drawImage(img, 0, 0, img.width, 230, offset, 0, w - (offset * 2), h);
    }