使用wowjs支持页面首次加载模块动画载以及原理解析

6 篇文章 0 订阅

安装

cnpm install wowjs -S
  • 根组件加入animate.css 的CDN
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css" />

使用

  1. 封装util注册方法
import { onMounted } from 'vue'
import { WOW } from 'wowjs'

// wow swing
export default () => {
  onMounted(() => {
    var wow = new WOW({
      boxClass: 'wow', // animated element css class (default is wow)
      animateClass: 'animated', // animation css class (default is animated)
      offset: 0, // distance to the element when triggering the animation (default is 0)
      mobile: true, // trigger animations on mobile devices (default is true)
      live: true, // act on asynchronously loaded content (default is true)
      callback: function (box) {
      },
      scrollContainer: null, // optional scroll container selector, otherwise use window,
      resetAnimation: true // reset animation on end (default is true)
    })
    wow.init()
  })
}

  1. 组件中使用
    1. data-wow-duration 设置动画时间
    1. data-wow-delay 设置延迟时间
    1. wow 类名必须加上,bounceInLeft为animate.css的动画类名
<template>
  <div class="wow bounceInLeft" data-wow-duration="3s" data-wow-delay="0s"></div>
  <div class="wow bounceInLeft" data-wow-duration="3s" data-wow-delay="0s"></div>
</template>
<script setup>
	import wow from '@/utils/wow.js'
	wow()
</script>

原理解析

提出问题 :

  1. 如何做到滚动到元素位置,触发事件?
  2. 触发事件后如何做到配合animate.css来使用?
问题1 如何做到滚动到元素位置,触发事件?

要知道当前元素是否在可是区域, 其实和 图片懒加载这个原理是一模一样的。

方式1, 使用 IntersectionObserver API

简单来说就是,当绑定的元素达到可以区域内能执行事件。

 const io = new IntersectionObserver(entries => {
    if(entries[0].isIntersecting){
		// 代表到了可视区域
     }
  });
  // 绑定对应监听的元素
  io.observe(el);

方式2,原生方法

通过 el.getBoundingClientRect(),clientHeight, scrollTop 等等自己去算当前是否在可视区域内。 注意要使用节流哦!!

问题2 触发事件后如何做到配合animate.css来使用?

问题1中已经解决了触发时机, 那么方法该如何写呢?

  • 我们先来讲解一下animate.css 基本设计原理。看如下代码:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>animate learn</title>
    <style lang="less">
        @keyframes bounce {
          from,
          20%,
          53%,
          to {
            animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
          }
        
          40%,
          43% {
            animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
            transform: translate3d(0, -30px, 0) scaleY(1.1);
          }
        
          70% {
            animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
            transform: translate3d(0, -15px, 0) scaleY(1.05);
          }
        
          80% {
            transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
            transform: translate3d(0, 0, 0) scaleY(0.95);
          }
        
          90% {
            transform: translate3d(0, -4px, 0) scaleY(1.02);
          }
        }
        .animate
        {
            animation: bounce 2s;
            /* transform-origin: center bottom; */
        }
        #main{
            width: 100px;
            height: 100px;
            position: absolute;
            top: 10%;
            font-size: 40px;
        }
        </style>
</head>
<body>
    <div id="main">animate.css</div>
    <button id="active">test</button>
</body>
<script>
    const animateCSS=(element,animationName)=>{
        new Promise((resolve,reject)=>{
            const node=document.querySelector(element);
            console.dir(node)
            node.classList.add(animationName);
            // When the animation ends, we clean the classes and resolve the Promise
            function handleAnimationEnd(event)
            {
                event.stopPropagation();
                node.classList.remove(animationName);
                resolve('animation end');
            }
            node.addEventListener('animationend', handleAnimationEnd, {once: true});
        })
        
    }
    const acticeButton=document.querySelector("#active");
    acticeButton.addEventListener('click',()=>{
        animateCSS('#main','animate')
    })
</script>
</html>

总结: 触发机制就是, 手动给元素绑定类名, 当动画执行完成以后把类名取消掉即可。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值