Animar elemento transformar rotar


82

¿Cómo rotaría un elemento con un jQuery .animate()? Estoy usando la línea de abajo, que actualmente está animando la opacidad correctamente, pero ¿esto es compatible con las transformaciones CSS3?

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

1
Hay un complemento de jQuery que animará las transformaciones CSS. Funciona en Firefox, Chrome, Safari, Opera e Internet Explorer. github.com/puppybits/QTransform
puppybits

Terminé aquí en una búsqueda con el mismo tema y descargué el complemento; funciona bien, pero causó un conflicto con esta instrucción en otro complemento que hice: $ ("#" + self.id) .css ("transform", "scale (1)"); Cambié esta línea: elem.style [$. CssProps.transform] = val + '%'; a esto: if (isNaN (val)) elem.style [$. cssProps.transform] = val; más elem.style [$. cssProps.transform] = val + '%'; Piensa que no necesita más explicaciones.
sergio0983

Respuestas:


95

Hasta donde yo sé, las animaciones básicas no pueden animar propiedades CSS no numéricas.

Creo que podría hacer esto usando una función de paso y la transformación css3 apropiada para el navegador de los usuarios. La transformación CSS3 es un poco complicada para cubrir todos sus navegadores (IE6 necesita usar el filtro Matrix, por ejemplo).

EDITAR : aquí hay un ejemplo que funciona en navegadores webkit (Chrome, Safari): http://jsfiddle.net/ryleyb/ERRmd/

Si solo desea admitir IE9, puede usar en transformlugar de -webkit-transform, o -moz-transformsería compatible con FireFox.

El truco utilizado es animar una propiedad CSS que no nos importa ( text-indent) y luego usar su valor en una función de paso para hacer la rotación:

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

Esta es una solución dolorosa tanto en lo que respecta al mantenimiento del código como a la velocidad. Olvídese jQuerymientras transforming, compruebe mi solución.
Dyin

¿Qué pasa si tienes un valor que cambia todo el tiempo para rotar, no fijo?
edonbajrami

78

La respuesta de Ryley es excelente, pero tengo texto dentro del elemento. Para rotar el texto junto con todo lo demás, utilicé la propiedad border-spacing en lugar de text-indent.

Además, para aclarar un poco, en el estilo del elemento, establezca su valor inicial:

#foo {
    border-spacing: 0px;
}

Luego, en el fragmento animado, su valor final:

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

En mi caso, gira 90 grados en sentido antihorario.

Aquí está la demostración en vivo .


3
usar z-index también es una buena opción si no lo está usando en ningún otro lugar. pero no querrás ser negativo con eso.
Sherzod

4
Es posible que desee agregar las extensiones -ms- y -o- también (consulte css3please.com )
Joram van den Boezem

¿Cómo se pueden animar propiedades adicionales al mismo tiempo?
MadTurki

@MadTurki, escribí una respuesta a tu pregunta a continuación.
skagedal

5
jQuery es lo suficientemente inteligente como para agregar todos los prefijos -moz-, -webkit-, etc., para que pueda simplificar un poco este código. muy buena respuesta. +1
Octopus

48

En mi opinión, jQuery animateestá un poco sobreutilizado, en comparación con CSS3 transition, que realiza dicha animación en cualquier propiedad 2D o 3D. También me temo que dejarlo en manos del navegador y olvidar la capa llamada JavaScript podría llevar a un uso de CPU de repuesto , especialmente cuando desea explotar con las animaciones. Por lo tanto, me gusta tener animaciones donde están las definiciones de estilo, ya que tú defines la funcionalidad con JavaScript . Cuanta más presentación inyecte en JavaScript, más problemas enfrentará más adelante.

Todo lo que tienes que hacer es usar addClassel elemento que deseas animar, donde configuras una clase que tiene transitionpropiedades CSS . Usted acaba de "activar" la animación , que se mantiene a cabo sobre la capa de presentación pura .

.js

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

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

Se podría eliminar fácilmente una clase con jQuery o eliminar una clase sin biblioteca .

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

Esta es una solución rápida y conveniente para la mayoría de los casos de uso.

También uso esto cuando quiero implementar un estilo diferente (propiedades CSS alternativas) y deseo cambiar el estilo sobre la marcha con una animación global de .5s. Agrego una nueva clase a BODY, mientras tengo CSS alternativo en una forma como esta:

.js

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

.css

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

De esta manera, puede aplicar diferentes estilos con animaciones, sin cargar diferentes archivos CSS. Solo implica JavaScript para configurar un class.


1
Eso está bien, pero está limitado a navegadores que admiten transiciones CSS3 . Entonces, no IE8 o IE9. Es un segmento bastante grande al que renunciar.
Ryley

11
@Ryley Estás hablando de un 12% de porcentaje de usuarios. Los usuarios de IE8 o IE9 están por debajo del 5%. No es un segmento muy grande al que renunciar, ya que seguimos hablando de la capa de presentación y no de la funcionalidad. Aproximadamente el 5% de sus visitantes no verán sus animaciones 3D. Además, si un navegador (IE) no es compatible transition, ciertamente tampoco admitirá sus transformaciones.
Dyin

Eso no es del todo cierto, transformes compatible con IE9. Pero estoy de acuerdo en que no es el grupo de usuarios más grande al que renunciar (IE8).
Ryley

2
@Dyin No es un 12% fijo, depende de su grupo demográfico objetivo. El 50% de los usuarios de mi empresa están en IE8 según google-analytics. La clave es conocer a tu audiencia. Dicho esto: ¡bravo amigo! Esta respuesta es mucho mejor que las dos primeras. Manera de ser el "diamante en bruto".
Ziggy

2
Esto tampoco tiene en cuenta los valores de rotación dinámica.
Yuschick

19

Para agregar a las respuestas de Ryley y atonyc, en realidad no tiene que usar una propiedad CSS real, como text-indexo border-spacing, sino que puede especificar una propiedad CSS falsa, como rotationo my-awesome-property. Puede ser una buena idea usar algo que no corra el riesgo de convertirse en una propiedad CSS real en el futuro.

Además, alguien preguntó cómo animar otras cosas al mismo tiempo. Esto se puede hacer como de costumbre, pero recuerde que la stepfunción se llama para cada propiedad animada, por lo que tendrá que verificar su propiedad, así:

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

(Nota: no puedo encontrar la documentación para el objeto "Tween" en la documentación de jQuery; desde la página de documentación animada hay un enlace a http://api.jquery.com/Types#Tween, que es una sección que no parece existir. Puedes encontrar el código para el prototipo Tween en Github aquí ).


¿Qué es myRotationProperty ... es algo personalizado que definiste? y lo que es nowdepende de este.
Muhammad Umer

@MuhammadUmer - sí, myRotationPropertyes algo personalizado, una propiedad CSS "falsa" inventada. nowes el primer argumento de la función de devolución de llamada del paso, que especifica el cambio en el valor de la propiedad en este paso.
skagedal

entonces también inicializó esta propiedad en css. O simplemente puede ponerlo animado, lo toma cero.
Muhammad Umer

7

Solo usa transiciones CSS:

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

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

Como ejemplo, establecí la duración de la animación en 0,5 segundos.

Tenga en cuenta que setTimeoutpara eliminar la transitionpropiedad css después de que finalice la animación (500 ms)


Para facilitar la lectura, omití los prefijos de los proveedores.

Esta solución requiere el soporte de transición del navegador por supuesto.


Gracias, funcionó para mí. También olvidó un punto y coma detrás del paréntesis de cierre.
Devin Carpenter

@ Sorrow123444 Me alegro de que te haya funcionado. Arreglé el punto y coma que faltaba, gracias
Paolo

3

Me encontré con esta publicación, buscando usar la transformación CSS en jQuery para una animación de bucle infinito. Este funcionó bien para mí. Aunque no sé qué tan profesional es.

function progressAnim(e) {
    var ang = 0;

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

Ejemplo de uso:

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');
            } 
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.