Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If it is possible to animate image pixelation without canvas, using only CSS

So you can get pixelation in CSS by doing the following:

  • Set background-image to a very small image (say 50px or 100px).
  • Set image-rendering: pixelated on the element.

That will give you the pixelated look.

Now I would like to animate this, by replacing the "very small image" with a large image after it finishes downloading by the browser:

let img = new Image()
img.src = largeVersion
img.onload = function(){
  // set css background-image to the new image perhaps, not sure...      
}

The problem is two-fold.

  1. I want to have the background-image using background-size: cover so it properly fills the container element. So you can't use background-size in any pixelation animation.
  2. transform: scale(0.1) (to get close to the original pixelation size) doesn't work because it scales the whole element.

I would like to do something like this: animate transform: scale(x) to go from 50px pixelated image to 2000px unpixelated image, over 0.3 or 0.5 seconds. But that doesn't work. I thought maybe using background-size, but that doesn't work either because of the constraint.

Wondering if there is any way to accomplish this.

I have seen this which does pixelation using canvas. Wondering if there is no other solution that works without using JS/canvas.

<style>
  div {
    background-size: cover;
    background-repeat: no-repeat;
    background-position: center center;
  }
</style>
<div style='background-image: url(/100px.jpg)'></div>
like image 533
Lance Avatar asked Jan 26 '26 15:01

Lance


1 Answers

You can do pixelation with an svg filter. You can then animate the filter. to use the filter on a div background you just do filter: url(#filterid)

put together it looks like this:

#myDiv::before{
content:"";
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
filter:url(#pixelate);
background-size:cover;
background-image:url(https://images.unsplash.com/photo-1475724017904-b712052c192a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2850&q=80)

}

#myDiv {
  position:relative;
  width:350px;
  height:250px;
}

.inside {
  position: relative;
}
<div id="myDiv"> <div class="inside"><h1>Hello</h1></div> </div>
<svg>
  <filter id="pixelate" x="0" y="0">
    <feFlood x="4" y="4" height="1" width="1" />
    <feComposite id="composite1" width="10" height="10" />
    <feTile result="a" />
    <feComposite in="SourceGraphic" in2="a" operator="in" />
    <feMorphology id="morphology" operator="dilate" radius="5" />
  </filter>

  <animate xlink:href="#composite1" id="anim-width" 
    attributeName="width" from="40" to="10" dur=".8s"
    fill="freeze" />  
  <animate xlink:href="#composite1" id="anim-height" 
    attributeName="height" from="40" to="10" dur=".8s"
    fill="freeze" />
  <animate xlink:href="#morphology" id="anim-radius" 
    attributeName="radius" from="20" to="5" dur=".8s"
    fill="freeze"/>
</svg>

Notice I had to create a inner div and apply the background on a pseudo-element ::before but "soon" this will become unnecessary, when the support of backdrop-filter improves.

references:

Pixelate svg effect: https://codesandbox.io/s/km3opvn6yv

Animate an svg filter: https://codepen.io/chriscoyier/pen/dPRVqL

backdrop-filter: https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter

like image 145
Tiago Coelho Avatar answered Jan 28 '26 06:01

Tiago Coelho



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!