Técnicas de Animación
Vue proporciona los componentes <Transition> y <TransitionGroup> para manejar transiciones de entrada/salida y de lista. Sin embargo, hay muchas otras formas de usar animaciones en la web, incluso en una aplicación Vue. Aquí discutiremos algunas técnicas adicionales.
Animaciones Basadas en Clases
Para elementos que no están entrando/saliendo del DOM, podemos activar animaciones añadiendo dinámicamente una clase CSS:
js
const disabled = ref(false)
function warnDisabled() {
disabled.value = true
setTimeout(() => {
disabled.value = false
}, 1500)
}template
<div :class="{ shake: disabled }">
<button @click="warnDisabled">Click me</button>
<span v-if="disabled">This feature is disabled!</span>
</div>css
.shake {
animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
transform: translate3d(0, 0, 0);
}
@keyframes shake {
10%,
90% {
transform: translate3d(-1px, 0, 0);
}
20%,
80% {
transform: translate3d(2px, 0, 0);
}
30%,
50%,
70% {
transform: translate3d(-4px, 0, 0);
}
40%,
60% {
transform: translate3d(4px, 0, 0);
}
}Animaciones Dirigidas por el Estado
Algunos efectos de transición pueden aplicarse interpolando valores, por ejemplo, vinculando un estilo a un elemento mientras ocurre una interacción. Tomemos este ejemplo:
js
const x = ref(0)
function onMousemove(e) {
x.value = e.clientX
}template
<div
@mousemove="onMousemove"
:style="{ backgroundColor: `hsl(${x}, 80%, 50%)` }"
class="movearea"
>
<p>Move your mouse across this div...</p>
<p>x: {{ x }}</p>
</div>css
.movearea {
transition: 0.3s background-color ease;
}Move your mouse across this div...
x: 0
Además del color, también puedes usar enlaces de estilo para animar transform, width o height. Incluso puedes animar rutas SVG usando física de resorte; después de todo, todos son enlaces de datos de atributos:
Drag Me
Animando con watchers
Con algo de creatividad, podemos usar watchers para animar cualquier cosa basada en algún estado numérico. Por ejemplo, podemos animar el número en sí:
js
import { ref, reactive, watch } from 'vue'
import gsap from 'gsap'
const number = ref(0)
const tweened = reactive({
number: 0
})
// Note: For inputs greater than Number.MAX_SAFE_INTEGER (9007199254740991),
// the result may be inaccurate due to limitations in JavaScript number precision.
watch(number, (n) => {
gsap.to(tweened, { duration: 0.5, number: Number(n) || 0 })
})template
Type a number: <input v-model.number="number" />
<p>{{ tweened.number.toFixed(0) }}</p> Type a number:
0