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)'
});
kalpaitch
źródło
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)'); 
}
...
Ryley
źródło
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 .

atonyc
źródło
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.

Umieram
źródło
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 ).

skagedal
źródło
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.

Paolo
źródło
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)
Faradin
źródło
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');
            } 
Colin Rickels
źródło