自定义指令 下拉平滑过度

2024-03-14  本文已影响0人  抽疯的稻草绳
<template>
  <div class="container">
    <div class="item" v-slideIn v-for="(item, index) of 10" :key="index">
      {{ index + 1 }}
    </div>
  </div>
</template>
 
<script>
export default {};
</script>
 
<style lang="scss">
.container {
  width: 88%;
  margin: 1rem auto;
  .item {
    width: 100%;
    height: 300px;
    margin-bottom: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-size: 3rem;
    &:nth-child(3n-2) {
      background-color: #fd524c;
    }
    &:nth-child(3n-1) {
      background-color: #ffb527;
    }
    &:nth-child(3n) {
      background-color: #23c039;
    }
  }
}
</style>

自定义指令

const DISTANCE = 150;
const DURATION = 1000;
const animationMap = new WeakMap();
 
const ob = new IntersectionObserver(entries => {
    for (const entry of entries) {
        if (entry.isIntersecting) {    // isIntersecting这个属性判断元素是否与视口(或根元素)交叉
            const animation = animationMap.get(entry.target);
            animation.play();
            ob.unobserve(entry.target);
        }
    }
})
 
// 判断元素是不是在视口之下
function isBelowViewport(el) {
    const rect = el.getBoundingClientRect();
    return rect.top > window.innerHeight;
}
 
export default {
    inserted(el) {
        if (!isBelowViewport(el)) {
            return;
        }
        const animation = el.animate([
            {
                transform: `translateY(${DISTANCE}px)`,
                opacity: 0.5
            },
            {
                transform: 'translateY(0)',
                opacity: 1
            },
        ],
            {
                duration: DURATION,
                easing: 'ease'
            })
        animation.pause();  // 暂停动画
        animationMap.set(el, animation);
        ob.observe(el);
    },
    unbind() {
        ob.unobserve(el);
    }
}
上一篇下一篇

猜你喜欢

热点阅读