Animacja przekształcania elementu, obracania


83

Jak obrócić element z jQuery .animate()? Używam poniższej linii, która obecnie prawidłowo animuje krycie, ale czy obsługuje ona transformacje CSS3?

$(element).animate({
   opacity: 0.25,
   MozTransform: 'rotate(-' + -amount + 'deg)',
   transform: 'rotate(' + -amount + 'deg)'
});

1
Istnieje wtyczka jQuery, która animuje transformacje CSS. Działa w przeglądarkach Firefox, Chrome, Safari, Opera i Internet Explorer. github.com/puppybits/QTransform
puppybits

Zakończyłem tutaj wyszukiwaniem z tym samym tematem i pobrałem wtyczkę; działa dobrze, ale spowodowało konflikt z tą instrukcją w innej wtyczce, którą stworzyłem: $ ("#" + self.id) .css ("transform", "scale (1)"); Zmieniłem tę linię: elem.style [$. CssProps.transform] = val + '%'; do tego: if (isNaN (val)) elem.style [$. cssProps.transform] = val; else elem.style [$. cssProps.transform] = val + '%'; Myślę, że nie potrzebuje dalszych wyjaśnień.
sergio0983

Odpowiedzi:


96

O ile wiem, podstawowe animacje nie mogą animować nienumerycznych właściwości CSS.

Uważam, że można to zrobić za pomocą funkcji step i odpowiedniej transformacji css3 dla przeglądarki użytkowników. Transformacja CSS3 jest nieco trudna do objęcia wszystkich przeglądarek (na przykład IE6 musisz użyć filtru Matrix).

EDYCJA : oto przykład, który działa w przeglądarkach webkit (Chrome, Safari): http://jsfiddle.net/ryleyb/ERRmd/

Jeśli chcesz obsługiwać tylko IE9, możesz użyć transformzamiast -webkit-transformlub -moz-transformobsługiwać FireFox.

Użyta sztuczka polega na animowaniu właściwości CSS, na której nie zależy nam ( text-indent), a następnie użyciu jej wartości w funkcji step do wykonania rotacji:

$('#foo').animate(
..
step: function(now,fx) {
  $(this).css('-webkit-transform','rotate('+now+'deg)'); 
}
...

Jest to bolesne rozwiązanie zarówno pod względem obsługi kodu, jak i szybkości. Zapomnij jQuerypodczas transformlogowania, sprawdź moje rozwiązanie.
Dyin

A co, jeśli masz wartość, która zmienia się cały czas, aby się obracać, a nie stałą?
edonbajrami

78

Odpowiedź Ryleya jest świetna, ale element zawiera tekst. Aby obrócić tekst wraz ze wszystkim innym, użyłem właściwości border-spacing zamiast text-indent.

Aby nieco wyjaśnić, w stylu elementu ustaw początkową wartość:

#foo {
    border-spacing: 0px;
}

Następnie w animowanym fragmencie ostateczna wartość:

$('#foo').animate({  borderSpacing: -90 }, {
    step: function(now,fx) {
      $(this).css('transform','rotate('+now+'deg)');  
    },
    duration:'slow'
},'linear');

W moim przypadku obraca się o 90 stopni w kierunku przeciwnym do ruchu wskazówek zegara.

Oto demo na żywo .


3
używanie indeksu z jest również dobrą opcją, jeśli nie używasz go nigdzie indziej. ale nie chciałbyś mieć negatywnego nastawienia do tego.
Sherzod

4
Możesz również dodać rozszerzenia -ms- i -o- (patrz css3please.com )
Joram van den Boezem

Jak możesz jednocześnie animować dodatkowe właściwości?
MadTurki

@MadTurki, poniżej napisałem odpowiedź na twoje pytanie!
skagedal

5
jQuery jest wystarczająco inteligentny, aby dodać wszystkie przedrostki -moz-, -webkit-, itp., więc możesz nieco uprościć ten kod. bardzo dobra odpowiedź. +1
Octopus

49

Moim zdaniem jQuery animatejest nieco nadużywany w porównaniu do CSS3 transition, który wykonuje taką animację na dowolnej właściwości 2D lub 3D. Obawiam się również, że pozostawienie tego przeglądarce i zapomnienie o warstwie o nazwie JavaScript może doprowadzić do zaoszczędzenia mocy procesora - szczególnie, gdy chcesz się bawić animacjami. Dlatego lubię mieć animacje, w których są definicje stylów, ponieważ definiuje się funkcjonalność za pomocą JavaScript . Im więcej prezentacji wprowadzisz do JavaScript, tym więcej problemów napotkasz później.

Wszystko, co musisz zrobić, to użyć addClasselementu, który chcesz animować, gdzie ustawiasz klasę, która ma transitionwłaściwości CSS . Po prostu „aktywujesz” animację , która pozostaje zaimplementowana na warstwie czystej prezentacji .

.js

// with jQuery
$("#element").addClass("Animate");

// without jQuery library
document.getElementById("element").className += "Animate";

Można łatwo usunąć klasę za pomocą jQuery lub usunąć klasę bez biblioteki .

.css

#element{
    color      : white;
}

#element.Animate{
    transition        : .4s linear;
    color             : red;
    /** 
     * Not that ugly as the JavaScript approach.
     * Easy to maintain, the most portable solution.
     */
    -webkit-transform : rotate(90deg);
}

.html

<span id="element">
    Text
</span>

Jest to szybkie i wygodne rozwiązanie w większości przypadków użycia.

Używam tego również, gdy chcę zaimplementować inny styl (alternatywne właściwości CSS) i chcę zmienić styl w locie za pomocą globalnej animacji .5s. Dodaję nową klasę do pliku BODY, mając alternatywny CSS w takiej postaci:

.js

$("BODY").addClass("Alternative");

.css

BODY.Alternative #element{
    color      : blue;
    transition : .5s linear;
}

W ten sposób możesz zastosować różne style z animacjami, bez ładowania różnych plików CSS. Używasz JavaScript tylko do ustawienia pliku class.


1
To dobrze, ale jest ograniczone do przeglądarek obsługujących przejścia CSS3 . Tak więc nie ma IE8 ani IE9. To dość duży segment, z którego można się poddać.
Ryley

11
@Ryley Mówisz o 12% procentu użytkowników. Użytkownicy IE8 lub IE9 mają poniżej 5%. Nie jest to dość duży segment do rezygnacji, ponieważ wciąż mówimy o warstwie prezentacji, a nie o funkcjonalności. Około 5% odwiedzających nie zobaczy Twoich animacji 3D. Również jeśli przeglądarka (IE) nie obsługuje transition, z pewnością nie będzie również obsługiwać twoich przekształceń.
Dyin

To nie do końca prawda - transformjest obsługiwane przez IE9. Ale zgadzam się, że nie jest to największa grupa użytkowników, z której można się poddać (IE8).
Ryley

2
@Dyin To nie jest płaskie 12%, zależy to od docelowej grupy demograficznej. Według Google Analytics 50% użytkowników mojej firmy korzysta z IE8. Kluczem do sukcesu jest poznanie swoich odbiorców. To powiedziawszy: brawo koleś! Ta odpowiedź jest znacznie lepsza niż dwie pierwsze. Sposób na bycie „nieoszlifowanym diamentem”.
Ziggy

2
Nie uwzględnia to również wartości dynamicznej rotacji.
Yuschick

19

Aby dodać do odpowiedzi Ryley i atonyc, w rzeczywistości nie musisz używać prawdziwej właściwości CSS, takiej jak text-indexlub border-spacing, ale zamiast tego możesz określić fałszywą właściwość CSS, taką jak rotationlub my-awesome-property. Dobrym pomysłem może być użycie czegoś, co nie grozi, że stanie się rzeczywistą właściwością CSS w przyszłości.

Ktoś również zapytał, jak animować inne rzeczy w tym samym czasie. Można to zrobić jak zwykle, ale pamiętaj, że stepfunkcja jest wywoływana dla każdej animowanej właściwości, więc będziesz musiał sprawdzić swoją właściwość, na przykład:

$('#foo').animate(
    {
        opacity: 0.5,
        width: "100px",
        height: "100px",
        myRotationProperty: 45
    },
    {
        step: function(now, tween) {
            if (tween.prop === "myRotationProperty") {
                $(this).css('-webkit-transform','rotate('+now+'deg)');
                $(this).css('-moz-transform','rotate('+now+'deg)'); 
                // add Opera, MS etc. variants
                $(this).css('transform','rotate('+now+'deg)');  
            }
        }
    });

(Uwaga: nie mogę znaleźć dokumentacji obiektu "Tween" w dokumentacji jQuery; na stronie z dokumentacją animacji jest link do http://api.jquery.com/Types#Tween, który jest sekcją, która nie Wygląda na to, że istnieje. Możesz znaleźć kod prototypu Tween na Github tutaj ).


co to jest myRotationProperty ... czy zdefiniowałeś coś niestandardowego; a co to nowzależy od tego.
Muhammad Umer

@MuhammadUmer - tak, myRotationPropertyto coś niestandardowego, wymyślona, ​​„fałszywa” właściwość CSS. nowjest pierwszym argumentem funkcji zwrotnej kroku, określającym zmianę wartości właściwości w tym kroku.
skagedal

czy też zainicjowałeś tę właściwość w css. Lub możesz po prostu ustawić animację, że zajmuje zero.
Muhammad Umer,

7

Po prostu użyj przejść CSS:

$(element).css( { transition: "transform 0.5s",
                  transform:  "rotate(" + amount + "deg)" } );

setTimeout( function() { $(element).css( { transition: "none" } ) }, 500 );

Jako przykład ustawiłem czas trwania animacji na 0,5 sekundy.

Zwróć uwagę, setTimeoutaby usunąć transitionwłaściwość css po zakończeniu animacji (500 ms)


Dla czytelności pominąłem prefiksy dostawców.

To rozwiązanie wymaga oczywiście obsługi przejścia przeglądarki.


Dzięki, pracował dla mnie. Zapomniałeś również o średniku za nawiasem zamykającym.
Devin Carpenter

@ Sorrow123444 Cieszę się, że to zadziałało. Naprawiłem brakujący średnik, dziękuję
Paolo

3

Natknąłem się na ten post, szukając użycia transformacji CSS w jQuery do nieskończonej animacji pętli. Ten działał dobrze dla mnie. Nie wiem jednak, jakie to profesjonalne.

function progressAnim(e) {
    var ang = 0;

    setInterval(function () {
        ang += 3;
        e.css({'transition': 'all 0.01s linear',
        'transform': 'rotate(' + ang + 'deg)'});
    }, 10);
}

Przykład użycia:

var animated = $('#elem');
progressAnim(animated)

1
//this should allow you to replica an animation effect for any css property, even //properties //that transform animation jQuery plugins do not allow

            function twistMyElem(){
                var ball = $('#form');
                document.getElementById('form').style.zIndex = 1;
                ball.animate({ zIndex : 360},{
                    step: function(now,fx){
                        ball.css("transform","rotateY(" + now + "deg)");
                    },duration:3000
                }, 'linear');
            } 
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.