14

I need to dynamically blur an image on my page, but only along one axis (Y specifically). So here are my requirements:

  • Has to be done "live" (I can't pre-render a blurred version of the image)
  • Like I said, only on the Y axis (like a motion blur, but vertical)
  • Needs to animate in
  • Should work in IE9+

My first thought was to use a simple CSS filter:

img {
    filter: blur(20px);
}

I can animate that by adding a transition (transition: filter 0.2s linear), but it only creates Gaussian blurs, which isn't the effect I want. The syntax doesn't support something like filter: blur(0 10px); to restrict the blur only to one axis.

Then I read that the blur filter (amongst others) is really just a shorthand for an SVG filter, which you can write manually if you want. So I created an SVG called filter.svg that specifies a 20px blur only along the Y axis (0 20):

<?xml version="1.0" standalone="no"?>
<svg width="1" height="1" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <defs>
        <filter id="blur">
            <feGaussianBlur in="SourceGraphic" stdDeviation="0 20" />
        </filter>
    </defs>
</svg>

And applied it like this:

img {
    filter: url("filter.svg#blur");
}

And that works perfectly...but only in Firefox. Safari/Chrome don't support url() as a value for filter. Plus, I can't animate it because the value is a URL rather than a number, so transition doesn't work.

On top of all that, I don't think either of these approaches work in IE9.

So: is there any way to do what I'm trying to do? I've looked into using canvas as an alternative, but can't find any examples of a blur that only goes in one direction.

daGUY
  • 27,055
  • 29
  • 75
  • 119
  • 1
    It will be much simpler to do this in a cross-browser way using JS rather than CSS and SVG. IIRC [EaselJS](http://www.createjs.com/#!/EaselJS) allows for single-axis blur animation. – Ennui Jun 04 '14 at 19:50
  • If you use -webkit-filter: url(etc.) then you will get support in Safari/Chrome (filters are not unprefixed yet there). You can also define an SVG animation using within your filter to get a transition. – Michael Mullany Jun 09 '14 at 18:09
  • @MichaelMullany: hm...I tried that, but it doesn't seem to do anything: `-webkit-filter: url(filter.svg#blur);`. The Web Inspector shows that the property is being applied, so it recognizes it, but it has no effect on my image. In Firefox, the exact same thing without the prefix works fine (`filter: url(filter.svg#blur);`). Do you have an example that shows this working in WebKit? – daGUY Jun 10 '14 at 14:59
  • Oh that's interesting – it works if the SVG is defined inline in the HTML. I guess I can do that, but I wonder why it doesn't work if it's in an external file? – daGUY Jun 10 '14 at 19:13
  • Ah ha! With the standard `filter` property, the URL is relative, but with `-webkit-filter`, it's absolute. So it does work in both Firefox and Safari/Chrome, but I have to write the path differently: `filter: url(filter.svg#blur);` and `-webkit-filter: url(css/filter.svg#blur);`. Now I'm getting somewhere... – daGUY Jun 10 '14 at 19:21
  • Can you update your example with an animation? I'm not clear on the syntax. – daGUY Jun 10 '14 at 19:27
  • Very hard to do it in a performant way with IE support. If IE is not required, you can try [imagemagick wasm port](https://www.npmjs.com/package/wasm-imagemagick). Motion blur in imagemagick, https://legacy.imagemagick.org/Usage/blur/#motion-blur – Pankaj Phartiyal Jun 08 '23 at 16:46

1 Answers1

-2

If I'm understanding the question right it can be donewith JQuery.

CSS3 does have it's limits and it's very limited in interactive values.

Jquery also adds cross-platform stability.

JQuery

$(document).ready(function() {
  var $img = $('.image')
  $img.hide();
  $img.show().animate({
      opacity: 100,
      paddingTop: '+=80'
  }, 500)
});

Here is an example of how it could work with javacript with a little fooling around on opacity.

function myMove() {
  var elem = document.getElementById("animate");
  var pos = 0;
  var id = setInterval(frame, 5);

  function frame() {
    if (pos == 150) {
      clearInterval(id);
    } else {
      pos++;
      elem.style.left = pos + 'px';
    }
  }
}
#container {
  width: 400px;
  height: 400px;
  position: relative;
  background: yellow;
}

#animate {
  width: 50px;
  height: 50px;
  position: absolute;
  background-color: red;
}
<p>
  <button onclick="myMove()">Click Me</button>
</p>

<div id="container">
  <div id="animate"></div>
</div>
Chris Barr
  • 29,851
  • 23
  • 95
  • 135
Jeff Klein
  • 23
  • 4
  • This answer would be more helpful if it provided a brief example of how you think this could be achieved using javascript. – fildred13 Jun 27 '17 at 17:17
  • Was this answer posted to the wrong question? The question asks how to apply an animated vertical blur to an image. The answer shows an example of a box moving from left to right...? – daGUY Apr 18 '19 at 23:40