用vue3.x开发一个门户网站,动效有点多,浅谈一下其中走过的弯路吧;
用到的插件
-
框架用的 "vue": "^3.2.25",
-
构建工具 "vite": "^2.9.5",
-
轮播 "swiper": "^8.1.4",
-
动画组件 "wow.js": "^1.2.2"
wowjs 是一款配合Animatecss 出的 下载完成后自动带有 Animatecss ,所以就不用单独下载;
都是下载的最新的插件,
我先说说我的需求。
首页两个 板块需要动画。一个是banner 就是轮播图,第二个是三张图片分别从三个方向合成一个;
都完成后发现轮播的动画只执行一次,只有刷新后才回再次执行,然后需求是轮播滑动翻页都要触发动画,因为每张轮播图上都有不同的动画效果;
然后我说说我的骚操作,就是调用swiper的onSlideChange来监听翻页,一翻页就再次new 动画类
ps: wow.js 的用法随便都可以百度,这里不过多赘述!
const onSlideChange = () => {
new WOW().init();
};
每new 一次动画就执行一次;
然而下面的动画也会跟着执行,这就是比较蛋疼了;
然后看了swiper的文档 但适配上不兼容,放弃了;
找到网上的大佬们的方法就有了我现在的这种结合;
先找到
自己创建一个TS,swiper.animate.js 然后自己在写一下
//隐藏元素
export const swiperAnimateCache=()=> {
const allBoxes: any = window.document.documentElement.querySelectorAll(".animation")
for (var i = 0; i < allBoxes.length; i++) {
allBoxes[i].attributes["style"]
? allBoxes[i].setAttribute("swiper-animate-style-cache", allBoxes[i].attributes["style"].value)
: allBoxes[i].setAttribute("swiper-animate-style-cache", " ")
allBoxes[i].style.visibility = "hidden"
}
}
// 开始动画
export const swiperAnimate = (a: any) => {
//每次添加的时候先把样式清除一遍
clearSwiperAnimate()
var b = a.slides[a.activeIndex].querySelectorAll(".animation")
for (var i = 0; i < b.length; i++) {
b[i].style.visibility = "visible"
const effect = b[i].attributes["swiper-animate-effect"]
? b[i].attributes["swiper-animate-effect"].value
: ""
b[i].className = b[i].className + " " + effect + " " + "animated"
const duration = b[i].attributes["swiper-animate-duration"]
? b[i].attributes["swiper-animate-duration"].value
: ""
// duration && style
const delay = b[i].attributes["swiper-animate-delay"]
? b[i].attributes["swiper-animate-delay"].value
: ""
const style = b[i].attributes["style"].value + "animation-duration:" + duration + ";-webkit-animation-duration:" + duration + ";" + "animation-delay:" + delay + ";-webkit-animation-delay:" + delay + ";"
// delay && (style = style )
b[i].setAttribute("style", style)
}
}
// 清楚样式。 获取 .animation 类名, 注意这个所有的.animation 类名都会被获取,所以可以自己取
export const clearSwiperAnimate = () => {
const allBoxes: any = window.document.documentElement.querySelectorAll(".animation")
for (var i = 0; i < allBoxes.length; i++) {
allBoxes[i].attributes["swiper-animate-style-cache"] && allBoxes[i].setAttribute("style", allBoxes[i].attributes["swiper-animate-style-cache"].value)
allBoxes[i].style.visibility = "hidden"
allBoxes[i].className = allBoxes[i].className.replace("animated", " ")
const effectValue = allBoxes[i].attributes["swiper-animate-effect"].value
/* eslint-disable-next-line */
allBoxes[i].attributes['swiper-animate-effect'] && (allBoxes[i].className = allBoxes[i].className.replace(effectValue, ' '))
}
}
按照源码上的拿过来自己改改;
引入 组件
<script lang="ts" setup>
import { Swiper, SwiperSlide, } from 'swiper/vue';
import { Navigation, Pagination, A11y, Autoplay } from 'swiper';
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';
import 'swiper/css/autoplay';
import { swiperAnimate, swiperAnimateCache } from '../../utils/animate';
const init = (e: any) => {
swiperAnimateCache()
swiperAnimate(e)
}
const slideChangeTransitionEnd = (e: any) => {
swiperAnimate(e);
}
</script>
用法
<swiper class="h-full" @init="init" @slide-change-transition-end="slideChangeTransitionEnd"
:autoplay="{ delay: 5000 }" :pagination="{ clickable: true, }" :slides-per-view="1"
:modules="[Navigation, Pagination, A11y, Autoplay]" :loop="true" navigation :scrollbar="{ draggable: true }"
>
<swiper-slide>
<div class="animation" swiper-animate-effect="pulse"
swiper-animate-duration="14s">
<img class="object-cover w-full h-full "
src="https://imgs.blazor.zone/images/Pic120.jpg"
alt="">
</div>
</swiper-slide>
<swiper-slide>
<div class="animation" swiper-animate-effect="pulse"
swiper-animate-duration="14s">
<img class="object-cover w-full h-full "
src="https://imgs.blazor.zone/images/Pic110.jpg"
alt="">
</div>
</swiper-slide>
</swiper>
animation 自己定义 swiper-animate-effect 动画名称。Animatestyle动画库想要什么都有 60多种 swiper-animate-duration 动画时长
pps: 按照swiper的官网来有个问题 ,就是不显示轮播,原因出在。:slides-per-view="1" ,要把参数变成 1 ,它的例子是 3 ;