Анимировать преобразование элемента, поворот


83

Как мне повернуть элемент с помощью jQuery .animate()? Я использую строку ниже, которая в настоящее время правильно анимирует непрозрачность, но поддерживает ли она преобразования CSS3?

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

1
Есть плагин jQuery, который будет анимировать преобразования CSS. Работает в Firefox, Chrome, Safari, Opera и Internet Explorer. github.com/puppybits/QTransform
puppybits

Завершил здесь поиск по той же теме и загрузил плагин; работает нормально, но это вызвало конфликт с этой инструкцией в другом созданном мной плагине: $ ("#" + self.id) .css ("transform", "scale (1)"); Я изменил эту строку: elem.style [$. CssProps.transform] = val + '%'; на это: if (isNaN (val)) elem.style [$. cssProps.transform] = val; иначе elem.style [$. cssProps.transform] = val + '%'; Думаю, в дальнейших объяснениях это не нуждается.
sergio0983

Ответы:


96

Насколько мне известно, базовые анимации не могут анимировать нечисловые свойства CSS.

Я считаю, что вы могли бы сделать это, используя пошаговую функцию и соответствующее преобразование css3 для браузера пользователя. Преобразование CSS3 немного сложно охватить все ваши браузеры (например, в IE6 вам нужно использовать фильтр Matrix).

EDIT : вот пример, который работает в браузерах webkit (Chrome, Safari): http://jsfiddle.net/ryleyb/ERRmd/

Если вы хотите поддерживать только IE9, вы можете использовать transformвместо него -webkit-transformили -moz-transformподдерживать FireFox.

Используемый трюк состоит в том, чтобы анимировать свойство CSS, которое нам не важно ( text-indent), а затем использовать его значение в функции step для вращения:

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

Это болезненное решение как с точки зрения обслуживания кода, так и с точки зрения скорости. Забудьте об jQueryэтом transform, проверьте мое решение.
Dyin

А что если у вас есть значение, которое постоянно меняется для вращения, а не фиксированное?
edonbajrami

78

Ответ Райли отличный, но у меня есть текст внутри элемента. Чтобы повернуть текст вместе со всем остальным, я использовал свойство border-spacing вместо text-indent.

Также, чтобы немного уточнить, в стиле элемента установите начальное значение:

#foo {
    border-spacing: 0px;
}

Затем в анимированном фрагменте ваше окончательное значение:

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

В моем случае он вращается на 90 градусов против часовой стрелки.

Вот живая демонстрация .


3
использование z-index также является хорошим вариантом, если вы его больше нигде не используете. но вы не хотели бы отрицать это.
Шерзод

4
Возможно, вы захотите также добавить расширения -ms- и -o- (см. Css3please.com )
Joram van den Boezem

Как можно одновременно анимировать дополнительные свойства?
MadTurki

@MadTurki, ниже я написал ответ на ваш вопрос!
skagedal

5
jQuery на самом деле достаточно умен, чтобы добавить за вас все префиксы -moz-, -webkit- и т.д., так что вы можете немного упростить этот код. очень хороший ответ. +1
Octopus

49

На мой взгляд, jQuery animateиспользуется слишком часто по сравнению с CSS3 transition, который выполняет такую ​​анимацию для любого 2D или 3D свойства. Также я боюсь, что если оставить это браузеру и забыть о слое под названием JavaScript, это может привести к экономии ресурсов процессора - особенно, когда вы хотите взорвать анимацию. Таким образом, мне нравится иметь анимацию там, где есть определения стилей, поскольку вы определяете функциональность с помощью JavaScript. . Чем больше презентаций вы внедрите в JavaScript, тем с большим количеством проблем вы столкнетесь позже.

Все, что вам нужно сделать, это использовать addClassдля элемента, который вы хотите анимировать, где вы устанавливаете класс, имеющий transitionсвойства CSS . Вы просто «активируете» анимацию , которая остается реализованной на чистом уровне представления .

.js

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

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

Можно легко удалить класс с помощью jQuery или удалить класс без библиотеки .

.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>

Это быстрое и удобное решение для большинства случаев использования.

Я также использую это, когда хочу реализовать другой стиль (альтернативные свойства CSS) и хочу изменить стиль на лету с помощью глобальной анимации .5s. Я добавляю новый класс в класс BODY, имея альтернативный CSS в такой форме:

.js

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

.css

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

Таким образом, вы можете применять различные стили с анимацией, не загружая разные файлы CSS. Вы используете только JavaScript для установки файла class.


1
Это нормально, но доступно только для браузеров, поддерживающих переходы CSS3 . Итак, ни IE8, ни IE9. Это довольно большой сегмент, от которого стоит отказаться.
Ryley

11
@Ryley Вы говорите о 12% процентах пользователей. Пользователи IE8 или IE9 составляют менее 5%. Это не очень большой сегмент, от которого стоит отказываться, поскольку мы все еще говорим об уровне представления, а не о функциональности. Около 5% посетителей не увидят ваши 3D-анимации. Кроме того, если браузер (IE) не поддерживает transition, он определенно не будет поддерживать ваши преобразования.
Dyin

Это не совсем так - transformподдерживается IE9. Но я согласен, что это не самая большая группа пользователей, от которой следует отказаться (IE8).
Ryley

2
@Dyin Это не плоские 12%, это зависит от вашей целевой демографии. Согласно Google-Analytics, 50% пользователей моей фирмы используют IE8. Главное - знать свою аудиторию. При этом: браво, чувак! Этот ответ намного лучше, чем два первых. Способ быть «необработанным алмазом».
Зигги

2
Это также не учитывает значения динамического вращения.
Ющик

19

Чтобы добавить к ответам Ryley и atonyc, вам на самом деле не нужно использовать настоящее свойство CSS, например text-indexили border-spacing, вместо этого вы можете указать поддельное свойство CSS, например rotationили my-awesome-property. Было бы неплохо использовать что-то, что не рискует стать фактическим свойством CSS в будущем.

Также кто-то спросил, как анимировать одновременно другие вещи. Это можно сделать как обычно, но помните, что stepфункция вызывается для каждого анимированного свойства, поэтому вам нужно будет проверить свое свойство, например:

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

(Примечание: я не могу найти документацию по объекту "Tween" в документации jQuery; на странице документации по анимации есть ссылка на http://api.jquery.com/Types#Tween, в которой нет Кажется, не существует. Вы можете найти код для прототипа Tween на Github здесь ).


что такое myRotationProperty ... это что-то определенное вами; а что nowзависит от этого.
Мухаммад Умер

@MuhammadUmer - да, myRotationPropertyэто что-то нестандартное, выдуманное, "фальшивое" свойство CSS. now- это первый аргумент функции обратного вызова шага, определяющий изменение значения свойства на этом шаге.
skagedal

затем вы также инициализировали это свойство в css. Или вы можете просто поставить анимацию, это займет ноль.
Мухаммад Умер

7

Просто используйте переходы CSS:

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

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

В качестве примера я установил продолжительность анимации 0,5 секунды.

Обратите внимание на setTimeoutудаление transitionсвойства css после завершения анимации (500 мс)


Для удобства чтения я опустил префиксы производителей.

Это решение, конечно же, требует поддержки перехода в браузере.


Спасибо, у меня сработало. Вы также забыли точку с запятой после закрывающей круглой скобки.
Девин Карпентер

@ Sorrow123444 Я рад, что это сработало для вас. Я исправил пропущенную точку с запятой, спасибо
Паоло

3

Я наткнулся на этот пост, пытаясь использовать преобразование CSS в jQuery для анимации бесконечного цикла. Этот сработал для меня. Я не знаю, насколько это профессионально.

function progressAnim(e) {
    var ang = 0;

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

Пример использования:

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');
            } 
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.