Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS/JS scrolling glitch effect (performance)

I am trying to achieve a "crt-like" scrolling glitch effect using Javascript and CSS. I have come up with the following code which clones the content and applies clip to make it look like it scrolls while adding random horizontal offset.

function scanglitch() {
    var e = $('#wrapper').clone().appendTo('#glitchcontainer');
    var i = 0;
    e.css({"clip": "rect(" + i + "px,3830px," + (i + 15) + "px,0px)"});
    e.css("z-index",200);
    var interval = setInterval(function () {
        e.css({"clip": "rect(" + i + "px,3830px," + (i + 15) + "px,0px)"});
        e.css({"left": Math.round(Math.random() * 10) + "px"});
        i+=4;
        if (i > window.innerHeight) {
            e.remove();
            window.clearInterval(interval);
        }
    }, 40);
}

Fiddle (Click on the text to see the effect)

I am actually quite pleased with the effect, but the implementation is obviously a hack. As a result the performance is unacceptably low (chrome cpu usage spikes from 5% to 50% when the effect is triggered).

Could someone help me figure out a way to achieve this effect in a more elegant and less performance-heavy way?

UPDATE: I have implemented your suggestions: Using translate instead of left, scrolling with translate instead of a js loop, calculations outside of the css tag and using requestAnimationFrame(). The code is nicer and more predictable now, but the animations are still very taxing. New fiddle

like image 702
Hartger Avatar asked Feb 15 '26 11:02

Hartger


2 Answers

You can try using requestAnimationFrame (it is available in almost all browsers). Seems to make a big difference in Chrome.

JSFiddle

EDIT

Here's a transition-only version, and while it doesn't even implement the jitter, it's useful for comparison. Surprisingly(?) it shows about the same, if not more, CPU usage. (You can check the Profile and Timeline tabs in Chrome)

CSS3 Transition-Only JSFiddle

Here's some information about why that should be expected. Essentially, CSS transitions and requestAnimationFrame work very similarly under the hood.

like image 92
Jeff Meatball Yang Avatar answered Feb 18 '26 00:02

Jeff Meatball Yang


I would delegate as much as possible to css transitions. So instead of moving the clip with js in the interval callback, transition it from top to bottom (example of transitioning).

You could try something similar with the left property, there's no random easing function but maybe you could achieve something similar with one of the bounce functions. Maybe change the easing function with an interval that's less frequent than your current one.

Also, just by slowing the interval of your current solution you'd get visually ok results with less CPU usage.

Side-note: for a completely different route you can replicate your html in a canvas and apply some effects to that. Google has plenty of results for "canvas glitch".

Update: here's my version of your latest fiddle

I get about 10 % less cpu usage with it when comparing to yours. Key differences are:

  • uses a timeout instead of requestAnimationFrame. requestAnimationFrame is meant to keep framerate high and the animation smooth but we don't need that for the random offsetting. Timeout is also better than an interval since the loop function is quaranteed to finish before next iteration starts.

  • removed the transparent background, since transparency has a rendering cost

like image 42
ekuusela Avatar answered Feb 17 '26 23:02

ekuusela



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!