aboutsummaryrefslogtreecommitdiff
path: root/files/es/web/css/css_animations/tips/index.html
blob: 1053ef24accfad56df0b72f7df066bad6ebb6a6c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
---
title: Animaciones CSS tips y trucos
slug: Web/CSS/CSS_Animations/Tips
translation_of: Web/CSS/CSS_Animations/Tips
---
<div>{{cssref}}</div>

<div>Las Animaciones con CSS hacen posible crear cosas increíbles con los elementos que forman parte de tus documentos y apps . Sin embargo, hay cosas que deseas hacer que no son evidentes, o soluciones inteligentes que quizás no encuentres de inmediato. Este artículo es una colección de tips y trucos que hemos encontrado que podrían hacer más fácil el trabajo, incluido cómo volver a ejecutar una animación detenida.</div>

<h2 id="Corriendo_una_animación_de_nuevo">Corriendo una animación de nuevo</h2>

<p>La especificación de CSS Animations no ofrece una forma de ejecutar una animación nuevamente. No hay un método mágico de <code>resetAnimation()</code> en los elementos, y tu no puedes solo configurar el elemento {{cssxref("animation-play-state")}} para <code>"correr"</code> de nuevo. En su lugar debes usar trucos inteligentes para que una animación detenida se reproduzca.</p>

<p>Aquí te mostramos una forma de hacerlo que sentimos es lo suficientemente estable y confiable para sugerirte</p>

<h3 id="Contenido_HTML">Contenido HTML </h3>

<p>Primero, definamos el HTML para un {{HTMLElement("div")}}  que deseamos animar y un botón que ejecurara (o repetira) la animación.</p>

<pre class="brush: html notranslate">&lt;div class="box"&gt;
&lt;/div&gt;

&lt;div class="runButton"&gt;Click me to run the animation&lt;/div&gt;</pre>

<h3 id="Contenido_CSS">Contenido CSS</h3>

<p>Ahora definiremos la animación en si usando CSS. Algún CSS que no es importante (el estilo del botón "Run" en sí)  no se muestran aquí, por brevedad.</p>

<div class="hidden">
<pre class="brush: css notranslate">.runButton {
  cursor: pointer;
  width: 300px;
  border: 1px solid black;
  font-size: 16px;
  text-align: center;
  margin-top: 12px;
  padding-top: 2px;
  padding-bottom: 4px;
  color: white;
  background-color: darkgreen;
  font: 14px "Open Sans", "Arial", sans-serif;
}</pre>
</div>

<pre class="brush: css notranslate">@keyframes colorchange {
  0% { background: yellow }
  100% { background: blue }
}

.box {
  width: 100px;
  height: 100px;
  border: 1px solid black;
}

.changing {
  animation: colorchange 2s;
}</pre>

<p>Aquí hay dos clases. La clase <code>"box"</code> es un descripción básica de la apariencia de la caja, sin ninguna información de la animación incluida. Los detalles de la animación son incluidos en la clase <code>"changing"</code> class, que dice que {{cssxref("@keyframes")}} llamado <code>"colorchange"</code> debe usarse en el transcurso de dos segundo para animar la caja.</p>

<p>Note que debido a esto, la caja no comienza con ningún efecto de animación en su lugar, por lo que no se animará</p>

<h3 id="Contenido_JavaScript">Contenido JavaScript</h3>

<p>Ahora veremos el JavaScript que jace el trabajo. La escencia de la técnica esta en la función <code>play()</code>, que se llama cuando el usuario hace clic en  el botón "Run".</p>

<pre class="brush: js notranslate">function play() {
  document.querySelector(".box").className = "box";
  window.requestAnimationFrame(function(time) {
    window.requestAnimationFrame(function(time) {
      document.querySelector(".box").className = "box changing";
    });
  });
}</pre>

<p>Esto se ve raro, ¿cierto? Esto se debe a que la única forma de volver a reproducir una animación es eleminar el efecto de animación, dejar que el documento vuelva a calcular los estilos para que sepa que lo ha hecho y luego volver a agregar el efecto de animación al elemento. Para que eso suceda, tenemos que ser creativos.</p>

<p>Esto es lo que sucede cuando la función <code>play()</code> es llamada:</p>

<ol>
 <li> La lista de clases CSS de caja se restablece a <code>"box"</code>. Esto tiene el efecto de remover   cualquier otra clase recurrente aplicada a la caja, incluida la clase <code>"changing"</code> que       controla la animación. En otras palabras eliminaremos el efecto de animación de la caja. Sin embargo, los cambios en la lista de clases no tienen efecto hasta que se recalcula completamente el estilo  y se ha producido una actualización para reflejar el cambio.</li>
 <li>Para estar seguros que los estilos son recalculados, nosotros usamos {{domxref("window.requestAnimationFrame()")}}, especifinado un callback. Nuestro callback se ejecuta justo antes del 'repaint' del documento. El problema para nosotros es que debido a que es antes del repaint, ¡El recalculo del estilo aún no ha suciedo! Por lo tanto...</li>
 <li>Nuestro callback habilmente llama a <code>requestAnimationFrame()</code> ¡por segunda vez!. En este momento el callback se compila antes del siguiente repaint, después de que se haya producido el recalculo del estilo. El callback añade la clase <code>"changing"</code>  de nuevo en la caja, para que el repaint inicie la animación una vez más.</li>
</ol>

<p>Por supuesto, también necesitamos agregar un controlador de eventos a nuestro botón  "Run" para que en verdad haga algo</p>

<pre class="brush: js notranslate">document.querySelector(".runButton").addEventListener("click", play, false);</pre>

<h3 id="Resultado">Resultado</h3>

<p>{{ EmbedLiveSample('Run_an_animation_again', 320, 160) }}</p>

<h2 id="Detener_la_animación">Detener la animación</h2>

<p>Simplemente removemos {{cssxref("animation-name")}} aplicado al elemento que hace que eso salte o corte a su siguiente estado.Si, en cambio, desea que la animación se complete y luego se detenga, debe probar un enfoque diferente. Los principales trucos son:</p>

<ol>
 <li>Haga que su animación sea lo más autónoma posible. Esto significa que no se debe confiar en<code>animation-direction: alternate</code>. En su lugar, debe escribir explícitamente una animación de fotogramas clave que pase por la animación completa en una repetición hacia adelante.</li>
 <li>Use JavaScript y borre la animación  que se esta utilizando cuando se activa el evento <code>animationiteration</code>.</li>
</ol>

<p>El siguiente demo muestra como puedes lograr las técnicas JavaScript mencionandas anteriormente:</p>

<pre class="brush: css notranslate">.slidein {
  animation-duration: 5s;
  animation-name: slidein;
  animation-iteration-count: infinite;
}

.stopped {
  animation-name: none;
}

@keyframes slidein {
  0% {
    margin-left: 0%;
  }
  50% {
    margin-left: 50%;
  }
  100% {
    margin-left: 0%;
  }
}
</pre>

<pre class="brush: html notranslate">&lt;h1 id="watchme"&gt;Click me to stop&lt;/h1&gt;
</pre>

<pre class="brush: js notranslate">let watchme = document.getElementById('watchme')

watchme.className = 'slidein'
const listener = (e) =&gt; {
  watchme.className = 'slidein stopped'
}
watchme.addEventListener('click', () =&gt;
  watchme.addEventListener('animationiteration', listener, false)
)
</pre>

<p>Demo <a href="https://jsfiddle.net/morenoh149/5ty5a4oy/">https://jsfiddle.net/morenoh149/5ty5a4oy/</a></p>

<h2 id="Mira_también">Mira también</h2>

<ul>
 <li><a href="/en-US/docs/Web/Guide/CSS/Using_CSS_transitions">Using CSS transitions</a></li>
 <li>{{domxref("Window.requestAnimationFrame()")}}</li>
</ul>