Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS Box Shadow-Animated Pixel Art Flickering

Partly for funsies, and partly for a design idea I had, I'm trying to convert an animated gif into pure animated CSS.

It's very nearly working but I've hit a snag and am unsure what is causing my issue, or how I could fix it. I have an unfortunate suspicion that I've simply hit a limitation of the technology.

The gif I've been using for testing is this: https://us.v-cdn.net/5018289/uploads/editor/yj/lcdjneh1yoxv.gif

As for the actual CSS, I've been trying to implement the method here (animated box-shadow properties), as it seemed like the most feasible: https://codepen.io/andrewarchi/pen/OXEEgL

#ash::after {
  animation: ash-frames 0.4s steps(1) infinite;
}

@keyframes ash-frames {
    0% {box-shadow: 32px 8px #181818, 40px 8px #181818,...}
    ...
}

The animation seems fairly seamless in the given example, so I figured it was worth a try. Obvious differences: the gif I'm using has more frames and more pixels.

And just as a quick overview, my CSS (I am using vendor tags etc, this is just an example):

.pixel-art-3940::after {
    animation: pixel-art-3940-frames 1s steps(5, end) infinite;
}

@keyframes pixel-art-3940-frames {
    0% {box-shadow: 112px 68px rgba(77, 69, 64, 1),...}
    16.666666666666668% {box-shadow:115px 65px rgba(77, 69, 64, 1),...}
    ...
}

The animation does seem to be actually working, however there's an intense 'flickering' effect on the animation. See below:

flickering animation

I've tried the usual solutions to 'flickering transitions' in Chrome - such as setting -webkit-backface-visibility to hidden - but so far nothing has solved the issue.

As I said, I fear I've simply hit a limitation of the technology itself. Any ideas what the problem might be, and whether I can solve it?

EDIT: The full source code of this particular animation can be found in these two Gists. I opted for Gists because of the size of the CSS file.

  • HTML: https://gist.githubusercontent.com/ChrGriffin/2f1f221143e24d3e39cad8e7369bc167/raw/16ea77d21aa79cf9da52fc3477a6773af41130f2/image.html
  • CSS: https://gist.githubusercontent.com/ChrGriffin/7dcff0f119532ff37f68c01a8a22ecb5/raw/3e49d3dd0b7fa93aef6708750770d2616c53f682/image.css
like image 766
CGriffin Avatar asked May 28 '18 04:05

CGriffin


1 Answers

Correct answer

In the end, it was all due to the animation-timing-function. First param in steps() function is not the number of keyframes (or number of steps in the loop) but the number of steps rendered in between keyframes.

So changing it to steps(1,end) fixes it, as the browser no longer has to calculate intermediary frames (where it obviously fails due to the large number of box-shadow values - there's basically 1 value for each pixel - wicked technique, btw).

See it working: https://jsfiddle.net/websiter/wnrxmapu/2/


Previous answer: (partially incorrect, led to the correct one above - i left it as it might prove helpful to others debugging similar animations):

Initially I thought your exporting tool was... simply wrong.

Why? Because increasing animation-duration from 1s to 100s produced this result.

The apparent conclusion is that your intermediary frames are bugged.

However, I tested each of them individually and, to my surprise, they rendered correctly.

Which leads to the conclusion that the number of box-shadow calculations per keyframe is limited and some sort of clustering algorithm is performed.

Which makes sense, since we're talking box-shadow here, which, in 99.999999999% of cases (basically all except yours) does not have to be accurate. It should be (and obviously is) approximated favoring rendering speed, for obvious reasons: we're talking user experience and "feel". Most users are non-technical and they simply expect smooth scrolling under any and all conditions.

I've come to the conclusion there must be a limit on the amount allowed calculations per keyframe after trying my best at optimizing your code, reducing it to less than half the initial size: https://jsfiddle.net/websiter/wnrxmapu/1/

I wasn't able to find any material on pixel clustering techniques for box-shadow and I don't think much is available online - this should be classified information.

However, IMHO, other than bragging rights, I don't think your technique stands a chance in terms of rendering performance when compared to a gif or svg. Emphasis on "IMHO". If you insist on getting this done, you might want to slice the image up and check if the limit on allowed calculation is per element or per page.

But I wouldn't keep my hopes too high. It is optimizations like the one your code has revealed that make CSS lightning fast. If it had to be accurate it wouldn't be so fast.

like image 63
tao Avatar answered Nov 15 '22 06:11

tao