web-dev-qa-db-fra.com

Animer le filtre de flou

Est-il possible d'animer le filtre de flou CSS3 à l'aide de jQuery?

Cela fonctionne comme un moyen statique d'appliquer les règles CSS: 

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

mais quand je remplace la méthode css par la méthode animate, rien ne se passe.

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

Y a-t-il un truc dont je ne suis pas au courant? Comment puis-je animer le flou d'un article?

15
Vincent Duprez

Vous pouvez utiliser la fonction .animate() sur une variable de valeur numérique et l'animer en conséquence - appelez une fonction à chaque étape et affectez cette nouvelle valeur numérique en tant que propriété de filtre de flou de rayon 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)"
            });
        }
    });
});

Mise à jour mineure: il est possible que la fonction .animate() de jQuery ne soit pas correctement interpolée, comme indiqué dans une autre réponse ci-dessous . Dans ce cas, il est toujours plus sûr de chaîner un rappel qui définit manuellement le rayon de flou sur la valeur finale souhaitée. J'ai modularisé les fonctions pour qu'il puisse être réutilisé sans trop de redondances:

$(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);
});

Vous pouvez voir ce code mis à jour en action dans l'extrait de code ci-dessous.


Il est important de noter que Firefox (FF ≥35 et supérieur prend en charge les filtres CSS non préfixés ), IE et Opera possède aucun support pour les filtres CSS3 , il n'est donc pas nécessaire d'utiliser -moz-, -ms- ou -o-. préfixes :) 

Voir le violon: http://jsfiddle.net/teddyrised/c72Eb/ (avant la mise à jour)

Voir l'extrait de code ci-dessous pour obtenir l'exemple le plus récent:

$(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>

20
Terry

Une requête de recherche Google m'a donné ce résultat vous voudrez peut-être jeter un coup d'oeil. Ce que je suggère de faire, c'est de basculer une classe dans votre JS et de gérer le reste dans votre CSS, par exemple:

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

Manipulez le reste dans votre CSS:

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

J'ai essayé la réponse de Terry, qui a bien fonctionné jusqu'à ce que j'essaie d'inverser le processus pour animer la suppression de l'effet de flou. Au lieu de se terminer par un flou de 0, le processus s'est terminé par un flou de 0,0815133px. La plupart des navigateurs semblaient arrondir à zéro, mais iOS ne le laissait pas et laissait un flou perceptible sur la page. Après le changement animé en réglant manuellement le flou à zéro, cela corrigeait ceci:

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