> Faqs > Cómo rotar un elemento de manera programática con Javascript y CSS con una animación suavizada

Cómo rotar un elemento de manera programática con Javascript y CSS con una animación suavizada

Buenas, quiero hacer que un elemento de la página, que es un SVG haga una rotación cuando se realiza una interacción con la página. Pero quiero que la rotación se haga de manera suavizada, mediante una animación.

Tengo este HTML:

<svg id="elementoFlecha" class="flecha" xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M504-480 320-664l56-56 240 240-240 240-56-56 184-184Z"/></svg>
<button id="botonRotar">Rotar</button>

Es un HTML con una imagen SVG que tiene una flecha. Además un botón de rotar. El botón solo lo quiero para desencadenar la rotación con Javascript. Eso va con una interfaz diferente, pero es por simplificar las cosas.

Mi pregunta es similar a la Cómo animar un elemento con CSS para que gire de manera constante pero en este caso la rotación solamente se realiza cuando se hace clic en el botón. Al hacer clic de nuevo quiero que vuelva a la posición original.

El CSS para rotar el elemento es este:

transform: rotate(90deg);

Respuestas

Lo que necesitas hacer es crearte una clase.

.rotar-izquierda {
  transform: rotate(90deg);
}

Luego, tu problema se reduce a poner y quitar las clases CSS de manera programática con Javascript, usando classList.add() o classList.remove().

Te paso el código Javascript para conseguirlo.

// Seleccionas el elemento
var elemento = document.getElementById('elementoRotar');

// Añades clases así
elemento.classList.add('rotar-izquierda');

// luego las quitas así
elemento.classList.remove('rotar-izquierda');

Ya luego, el tema de hacer que la animación sea suavizada lo puedes hacer usando la clase CSS "flecha" que tiene tu svg. Esa clase debe estar siempre presente:

.flecha {
  transition: transform 0.5s ease;
}

La propiedad tansition de css sirve para que los cambios sean graduales y parezcan animados. Puedes ajustar la duración y el tipo de transición según necesites.

Creo que con eso lo tienes, ya solament te queda asociar el código como manejador de evento al botón, o a tu interfaz personalizada en Javascript.

Te paso un código con todo montado por si te sirve de aclaración.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Rotar flecha con el botón con CSS y Javascript</title>
  <style>
  .flecha {
    transition: transform 0.5s ease; 
  }

  .rotar-izquierda {
    transform: rotate(90deg);
  }
  </style>
</head>
<body>
  <svg id="elementoFlecha" class="flecha" xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M504-480 320-664l56-56 240 240-240 240-56-56 184-184Z"/></svg>
  <button id="botonRotar">Rotar</button>

  <script>
    var elemento = document.getElementById('elementoFlecha');
    var boton = document.getElementById('botonRotar');

    // Aki asociamos el manejador de evento de click
    boton.addEventListener('click', function() {
      // Voy a usar contains() para saber si está o no aplicada la clase, lo que me dirá si está rotado o no
      // Pero en tu ejemplo puedes usar una variable de estado que te diga esa misma info, según la interfaz que tengas
      if (elemento.classList.contains('rotar-izquierda')) {
        elemento.classList.remove('rotar-izquierda');
      } else {
        elemento.classList.add('rotar-izquierda');
      }
    });
  </script>
</body>
</html>
Borja
325 6 27 17