<!-- * 变形动画 --> <script setup lang="ts"> import { ref, onMounted } from 'vue'; import anime from 'animejs/lib/anime.es.js'; const containerRef = ref<any>(null); onMounted(() => { for (let i = 1; i <= 100; i++) { const dot = document.createElement('div'); dot.classList.add('element'); containerRef.value.appendChild(dot); } const dotAll = document.querySelectorAll('.element'); const animation = anime.timeline({ targets: dotAll, easing: 'easeInOutExpo', delay: anime.stagger(100, { grid: [10, 10], from: 'center' }), loop: true, }); animation .add({ rotateZ: 180, translateY: anime.stagger(-20, { grid: [10, 10], from: 'center', axis: 'y', }), translateX: anime.stagger(-20, { grid: [10, 10], from: 'center', axis: 'x', }), opacity: 1, }) .add({ borderRadius: 50, }) .add({ scale: 0.2, opacity: 0.2, }) .add({ rotateZ: 180, translateY: anime.stagger(0, { grid: [10, 10], from: 'center', axis: 'y', }), translateX: anime.stagger(0, { grid: [10, 10], from: 'center', axis: 'x', }), opacity: 1, }) .add({ scale: 1, borderRadius: 0, }) .add({ rotateZ: -90, }); }); </script> <template> <div class="box"> <div class="container" ref="containerRef"></div> </div> </template> <style lang="scss" scoped> * { margin: 0; padding: 0; box-sizing: border-box; } :deep(.container .element) { position: relative; width: 40px; height: 40px; background-color: #fff; scale: 0.75; } .box { width: 100%; height: 100%; background-color: #222; display: flex; justify-content: center; align-items: center; } .container { position: relative; min-width: 400px; width: 400px; height: 400px; display: flex; justify-content: center; align-items: center; flex-wrap: wrap; } </style>