动画模糊滤镜

17

能否使用jQuery来动态地实现CSS3模糊滤镜的动画效果?

以下是一种静态应用CSS规则的方法:

item.css({'filter': 'blur('+blur+')','-webkit-filter': 'blur('+blur+')','-moz-filter': 'blur('+blur+')','-o-filter': 'blur('+blur+')','-ms-filter': 'blur('+blur+')'});

但是当我将CSS方法替换为动画方法时,没有任何反应。

item.animate({'filter': 'blur('+blur+')','-webkit-filter': 'blur('+blur+')','-moz-filter': 'blur('+blur+')','-o-filter': 'blur('+blur+')','-ms-filter': 'blur('+blur+')'},500);

有什么诀窍我不知道吗?如何使一个项目的模糊效果动态化?


不值得,即使使用CSS过渡,模糊仍然太慢了。 - thelolcat
可能会慢一些,但我不需要它之后进行动画处理,它只需要保持原样即可。 - Vincent Duprez
4个回答

22

您可以在数值类型的变量上使用.animate()函数,并相应地进行动画处理 - 在每个步骤中调用一个函数并将该新数值作为CSS过滤器模糊半径属性来赋值 :)

$(function() {
    $({blurRadius: 0}).animate({blurRadius: 10}, {
        duration: 500,
        easing: 'swing', // or "linear"
                         // use jQuery UI or Easing plugin for more options
        step: function() {
            console.log(this.blurRadius);
            $('.item').css({
                "-webkit-filter": "blur("+this.blurRadius+"px)",
                "filter": "blur("+this.blurRadius+"px)"
            });
        }
    });
});

小更新: 注意到在下面的另一个答案中,jQuery的.animate()可能无法正确地缓动到最终值。在这种情况下,最保险的方法是链接一个回调函数,手动设置模糊半径到预期的最终值。我已经对这些函数进行了模块化处理,以便可以重复使用而不会出现太多的冗余:

$(function() {
        // Generic function to set blur radius of $ele
    var setBlur = function(ele, radius) {
            $(ele).css({
               "-webkit-filter": "blur("+radius+"px)",
                "filter": "blur("+radius+"px)"
           });
       },

       // Generic function to tween blur radius
       tweenBlur = function(ele, startRadius, endRadius) {
            $({blurRadius: startRadius}).animate({blurRadius: endRadius}, {
                duration: 500,
                easing: 'swing', // or "linear"
                                 // use jQuery UI or Easing plugin for more options
                step: function() {
                    setBlur(ele, this.blurRadius);
                },
                callback: function() {
                    // Final callback to set the target blur radius
                     // jQuery might not reach the end value
                     setBlur(ele, endRadius);
                }
            });
        };

    // Start tweening
    tweenBlur('.item', 0, 10);
});

您可以在下面的代码片段中看到这个更新后的代码的效果。


需要注意的是,Firefox(FF≥35及以上版本支持未加前缀的CSS滤镜),IE和Opera不支持CSS3滤镜无需使用 CSS3滤镜前缀:)

请参见fiddle:http://jsfiddle.net/teddyrised/c72Eb/(更新之前)

最新示例请参见以下代码片段:

$(function() {
        // Generic function to set blur radius of $ele
    var setBlur = function(ele, radius) {
            $(ele).css({
               "-webkit-filter": "blur("+radius+"px)",
                "filter": "blur("+radius+"px)"
           });
       },
       
       // Generic function to tween blur radius
       tweenBlur = function(ele, startRadius, endRadius) {
            $({blurRadius: startRadius}).animate({blurRadius: endRadius}, {
                duration: 500,
                easing: 'swing', // or "linear"
                                 // use jQuery UI or Easing plugin for more options
                step: function() {
                    setBlur(ele, this.blurRadius);
                },
                complete: function() {
                    // Final callback to set the target blur radius
                    // jQuery might not reach the end value
                    setBlur(ele, endRadius);
               }
           });
        };
    
    // Start tweening towards blurred image
    window.setTimeout(function() {
        tweenBlur('.item', 0, 10);
    }, 1000);
    
    // Reverse tweening after 3 seconds
    window.setTimeout(function() {
        tweenBlur('.item', 10, 0);
    }, 3000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="item">
    <p>Sample text that will be blurred.</p>
    <img src="http://placehold.it/500x500" />
</div>


1
截至今天,FF 35应用了没有前缀的过滤器,现在这应该适用于所有东西。 - Aamir Mahmood
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Terry

13

一个谷歌搜索查询给了我这个结果,你可能想要看一下。我的建议是在JS中只切换一个类并在CSS中处理其余部分,例如:

var $item = $('.item'); // or any selector you want to use
$item.addClass('item--blur');

在CSS中处理其余部分:

.item {
    transition: all 0.25s ease-out;
}
.item--blur {
    // all your filters
}

这个方法是可行的,但不适用于我的情况,因为我已经在另一个范围内使用了CSS动画。不过还是谢谢! - Vincent Duprez

2

我尝试了 Terry 的答案,一开始效果很好,但是当我尝试反转过程以动画方式移除模糊效果时,出现了问题。该过程结束时,模糊度不是 0,而是 0.0815133 像素。大多数浏览器似乎会将其四舍五入为零,但 iOS 没有这样做,在页面上留下了明显的模糊。通过手动将模糊度设置为零来跟随动画变化,解决了这个问题:

$('.item').css({
  "-webkit-filter": "blur(0)",
  "filter": "blur(0)"
});

是的,有时候 jQuery 的动画并不能完全精确地达到最终值。你可以设置回调函数以确保模糊半径被设置为最终预期的值 :) 我也更新了我的回答,感谢提醒! - Terry

0

尝试这个简单的解决方案:

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}
async function applyBlurFilter() {
    for (var i = 1 ; i <= 100; i++) {
        $('h1').css({ "filter": "blur(" + i/10 + "px)" });
        await sleep(40); //4 seconds (40 * 100 / 10)
    }
}

$(document).ready(function(){
  applyBlurFilter();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>
  This Text is going to be blured. 
</h1>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接