vue3使用插件封装指令实现页面滚动动画

效果展示:

vue封装插件需要使用到install函数

export default ScrollAnimationPlugin = {
    install(app: App, options = {}) {
        // 需要实现的内容
    }
}

vue指令语法:

    app.directive('scroll-animation', {
      mounted(el: HTMLDivElement, binding: any) {
        // 需要实现的内容

      }
    })

监听页面滚动的web-api: IntersectionObserver

创建一个新的 IntersectionObserver 对象,当其监听到目标元素的可见部分(的比例)超过了一个或多个阈值(threshold)时,会执行指定的回调函数。

它接受2个参数,第一个是callback:回调函数,第二个是options:配置项

语法:

var observer = new IntersectionObserver(callback[, options]);

参考:IntersectionObserver文档

结合以上内容实现如下:

// scrollAnimation.ts
import { type App, nextTick } from 'vue'

const ScrollAnimationPlugin = {
  install(app: App, options = {}) {
    // 合并默认配置
    const defaultConfig = {
      defaultDistance: '100px',
      defaultDuration: 0.6,
      defaultDelay: 0,
      defaultClass: 'animate-from-bottom'
    }

    const config = { ...defaultConfig, ...options }

    app.directive('scroll-animation', {
      mounted(el: HTMLDivElement, binding: any) {
        const customConfig = binding.value || {}
        const delay = customConfig.delay ?? config.defaultDelay
        const distance = customConfig.distance ?? config.defaultDistance
        const duration = customConfig.duration ?? config.defaultDuration
        const animationClass = customConfig.class ?? config.defaultClass

        // 设置初始样式
        el.style.opacity = '0'
        el.style.transform = `translateY(${distance})`
        el.style.transition = `all ${duration}s ease-out ${delay}ms`

        const observer = new IntersectionObserver(
          entries => {
            entries.forEach(entry => {
              if (entry.isIntersecting) {
                nextTick(() => {
                  el.classList.add(animationClass, 'active')
                  observer.unobserve(el)
                }).then()
              }
            })
          },
          { threshold: 0.1 }
        )

        observer.observe(el)
      }
    })
  }
}

export { ScrollAnimationPlugin }

CSS样式文件:

/* animations.css */

/* 基础动画样式 */

.animate-from-bottom.active {
  opacity: 1 !important;
  transform: translateY(0) !important;
}

.animate-from-left.active {
  opacity: 1 !important;
  transform: translateX(0) !important;
}

.animate-fade.active {
  opacity: 1 !important;
  transform: none !important;
}

/* 性能优化 */
[data-scroll-animation] {
  will-change: transform, opacity;
}

main.ts 引入使用:

// main.ts

import { ScrollAnimationPlugin } form './scrollAnimation.ts'

import App from './App.vue'

const app = createApp(App)

app.use(ScrollAnimationPlugin)

app.mount('#app')
// useComponent.vue

你可能感兴趣的:(vue,前端,animation,vue.js,前端,javascript,css3,动画)