0

我正在尝试在我的项目中创建惊人的动画效果。我正在使用 vue 3 和animejs 3.2.1。基本上,我像这样动态呈现了一个列表:

<div class="products-container">
    <transition-group class="flex-container" tag="ul" appear @before-enter="beforeEnterCans" @enter="enterCans">
      <li class="dynamic-flex-children" v-for="cokeImage in cokeImages" :key="cokeImage.id">
        <img :src="cokeImage.src" :alt="cokeImage.title" class="can-image">
        <p>{{cokeImage.title}}</p>
      </li>
    </transition-group>
  </div>

这会生成一个包含八个项目的列表,我在使用 flex 的网格布局中拥有这些项目。

.products-container{
  height: 90vh;
  width: 100vw;
  overflow-y: hidden;
}
.flex-container{
  height: 100%;
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  padding: 5% 10%;
}
.dynamic-flex-children{
  list-style-type: none;
  flex-basis: 25%;
}
.dynamic-flex-children img{
  width: 40%;
}
.dynamic-flex-children p{
  font-size: 0.7rem;
}

如您所见,<ul>将 vue 动画钩子附加到<transition-group>. 在组件实例中,我现在使用animejs来尝试为每个<li>列表进入屏幕时实现一个惊人的效果

<script>
import anime from 'animejs/lib/anime.es.js';
export default {
  name: 'Products',
  data(){
    return {
      cokeImages: [
        { title: 'Cocacola Life', src: require('@/assets/cocacola-cans/cocacola-life.png'), id: 1 },
        { title: 'Cocacola Zero', src: require('@/assets/cocacola-cans/cocacola-zero.png'), id: 2 },
        { title: 'Diet Coke', src: require('@/assets/cocacola-cans/diet-coke.png'), id: 3 },
        { title: 'Cocacola Classic', src: require('@/assets/cocacola-cans/classic-coke-two.png'), id: 4 },
        { title: 'New Cocacola', src: require('@/assets/cocacola-cans/classic-cocacola.png'), id: 5 },
        { title: 'Vanilla', src: require('@/assets/cocacola-cans/cocacola-vanilla.png'), id: 6 },
        { title: 'Cocacola Light', src: require('@/assets/cocacola-cans/cocacola-light.png'), id: 7 },
        { title: 'Cocacola Cherry', src: require('@/assets/cocacola-cans/cocacola-cherry.png'), id: 8 }
      ]
    }
  },
  methods: {
    beforeEnterCans(el){
      el.style.transform = "translateX(-100%)"
      el.style.opacity = 0
    },
    enterCans(el){
      anime({
        targets: el,
        opacity: 1,
        translateX: 0,
        delay: anime.stagger(200, {start: 100}),
        easing: 'easeInOutSine'
      })
    }
  }

}
</script>

无论出于何种原因,列表在他们过渡时都不会错开。

4

2 回答 2

0

el 是单个元素,因此由于您没有将元素列表传递给目标,因此交错不起作用。

我的解决方案是将索引作为数据属性传递:

<li class="dynamic-flex-children" v-for="(cokeImage, index) in cokeImages" :key="cokeImage.id" :data-index="index">
        <img :src="cokeImage.src" :alt="cokeImage.title" class="can-image">
        <p>{{cokeImage.title}}</p>
</li>

然后像这样设置延迟:

enterCans(el){

  let delay = el.dataset.index * 100;


  anime({
    targets: el,
    opacity: 1,
    translateX: 0,
    delay: delay,
    easing: 'easeInOutSine'
  })
}
于 2021-07-02T22:14:52.237 回答
0

经过多次尝试和错误,我发现了问题所在。

enter(el){
      anime({
        targets: ".dynamic-flex-children",
        duration: 700,
        opacity: 1,
        translateX: 0,
        delay: anime.stagger(100, {start: 100, direction: "reverse"}),
        easing: 'easeInOutSine'
      })
    }

Anime.js 使用类来定位元素。我传递给目标选项,而不是所有动态生成的标签el的共享类名。<li>我只是将目标选项从el共享类名更改为.dynamic-flex-children有效。

于 2021-09-04T00:40:09.967 回答