美文网首页
vue2.0开发H5页面+动画 + swiper 模板框架

vue2.0开发H5页面+动画 + swiper 模板框架

作者: 黎明的叶子 | 来源:发表于2024-01-14 11:53 被阅读0次

    1.引入swiper。

    npm i swiper@5.3.6
    npm i vue-awesome-swiper@4.0.4
    

    2.下载动画css。

    https://3.swiper.com.cn/download/index.html
    下载 animate.min.css 或 animate.css
    在入口文件中(多数为main)引入 import '@/utils/animate.min.css'(具体路径看下自己下载的路径)
    也可以在当前组件页面引入。

    //main.js
    // 访问swiper-H5
    import App from '@/views/swiperH5/swiperH5.vue' 
    
    //swiperH5.vue  
    import "./assets/css/animate.css" 
    

    3.由于Swiper动画js不适用VUE ,在utils下新增文件animate.js,重写Swiper动画js

      /*
     * @Descripttion: 在Swiper实例中的幻灯片中添加动画效果
     * @version: 0.0.1
     * @Author: PengShuai
     * @Date: 2023-08-31 11:03:10
     * @LastEditors: PengShuai
     * @LastEditTime: 2023-08-31 14:03:10
     */
    // 将所有具有  .ani  类的元素隐藏,并将它们的样式缓存起来。
    export function swiperAnimateCache() {
      const allBoxes = document.querySelectorAll('.ani')
      allBoxes.forEach((element) => {
        const styleValue = element.getAttribute('style') || ''
        element.setAttribute('swiper-animate-style-cache', styleValue)
        element.style.visibility = 'hidden'
      })
    }
     
    // 根据传入的 Swiper 实例  a ,为当前活动幻灯片中的所有具有  .ani  类的元素添加动画效果。
    // 它会根据元素的属性设置动画的持续时间、延迟和效果,并将元素的样式设置为可见。
    export function swiperAnimate(a) {
      clearSwiperAnimate()
      const activeSlide = a.slides[a.activeIndex]
      const animatedElements = activeSlide.querySelectorAll('.ani')
      animatedElements.forEach((element) => {
        element.style.visibility = 'visible'
        const effect = element.getAttribute('swiper-animate-effect') || ''
        element.classList.add('animated', effect)
        const duration = element.getAttribute('swiper-animate-duration') || ''
        const delay = element.getAttribute('swiper-animate-delay') || ''
        const style = `${
          element.getAttribute('style') || ''
        } animation-duration: ${duration}; -webkit-animation-duration: ${duration}; animation-delay: ${delay}; -webkit-animation-delay: ${delay};`
        element.setAttribute('style', style)
      })
    }
    // 清除所有具有  .ani  类的元素的动画效果。它会恢复元素的初始样式,并将元素隐藏起来。
    export function clearSwiperAnimate() {
      const allBoxes = document.querySelectorAll('.ani')
      allBoxes.forEach((element) => {
        const styleCache = element.getAttribute('swiper-animate-style-cache')
        if (styleCache) {
          element.setAttribute('style', styleCache)
        }
        element.style.visibility = 'hidden'
        element.classList.remove('animated')
        const effectValue = element.getAttribute('swiper-animate-effect')
        if (effectValue) {
          element.classList.remove(effectValue)
        }
      })
    }
    

    4.引入flexible.js 用rem自适应页面

    (function flexible (window, document) {
      var docEl = document.documentElement
      var dpr = window.devicePixelRatio || 1
    
      // adjust body font size
      function setBodyFontSize () {
        if (document.body) {
          document.body.style.fontSize = (12 * dpr) + 'px'
        }
        else {
          document.addEventListener('DOMContentLoaded', setBodyFontSize)
        }
      }
      setBodyFontSize();
    
      // 将页面分为10份
      // set 1rem = viewWidth / 10
      function setRemUnit () {
        var rem = docEl.clientWidth / 10 
        docEl.style.fontSize = rem + 'px'
      }
    
      setRemUnit()
    
      // reset rem unit on page resize
      window.addEventListener('resize', setRemUnit)
      window.addEventListener('pageshow', function (e) {
        if (e.persisted) {
          setRemUnit()
        }
      })
    
      // detect 0.5px supports
      if (dpr >= 2) {
        var fakeBody = document.createElement('body')
        var testElement = document.createElement('div')
        testElement.style.border = '.5px solid transparent'
        fakeBody.appendChild(testElement)
        docEl.appendChild(fakeBody)
        if (testElement.offsetHeight === 1) {
          docEl.classList.add('hairlines')
        }
        docEl.removeChild(fakeBody)
      }
    }(window, document))
    

    自动计算可以借助vscode的插件 px to rem & rpx & vw (cssrem)

    5.创建swiperH5.vue 页面,并引入相关文件

    //swiperH5.vue 
    import { Swiper, SwiperSlide } from 'vue-awesome-swiper'
    import 'swiper/css/swiper.css'
    import "./utils/flexible.js"
    import "./assets/css/animate.css"
    import "./assets/css/reset.css"
    import { swiperAnimateCache, swiperAnimate } from './utils/animate.js'
    import  musicAudio  from './musicAudio.vue'  // 音乐组件
    

    6.开发页面,加入底部箭头。此箭头也可以用组件,本文就写在当前页面了。swiperH5.vue

    完整代码

    
    <template>
      <div id="app" class="summary">
        <swiper ref="mySwiper" :slides-per-view="3" :space-between="50" :options="swiperOptions" @swiper="onSwiper"
          @slideChange="onSlideChange">
          <swiper-slide class="swiper1">
            <div class="page" :style="{
              'background-image': `url(${require('@/views/swiperH5/assets/images/bg/page1.jpeg')})`,
            }">
              <p style="text-align: center;" class="ani" swiper-animate-effect="fadeIn" swiper-animate-duration="2s"
                swiper-animate-delay="1s">
                第一句话:哈哈哈
              </p>
              <p style="text-align: center;" class="ani" swiper-animate-effect="bounceInUp" swiper-animate-duration="2s"
                swiper-animate-delay="2s">
                第二句话:啦啦啦
              </p>
            </div>
          </swiper-slide>
        </swiper>
        <div class="scrolltips">
          <div class="sc" :style="{
            'background-image': `url(${require('@/views/swiperH5/assets/images/arrow.png')})`,
          }"></div>
        </div>
        <musicAudio ref="musicAudio"></musicAudio>
      </div>
    </template>
        
    <script>
    import { Swiper, SwiperSlide } from 'vue-awesome-swiper'
    import 'swiper/css/swiper.css'
    import { swiperAnimateCache, swiperAnimate } from './utils/animate.js'
    import "./utils/flexible.js"
    import "./assets/css/animate.css"
    import "./assets/css/reset.css"
    import  musicAudio  from './musicAudio.vue'
    
    
    export default {
      data() {
        return {
          swiperOptions: {
            direction: "vertical",
            initialSlide: 0,
            on: {
              init: function () {
                swiperAnimateCache(); //隐藏动画元素
                swiperAnimate(this); //初始化完成开始动画
              },
              slideChange: function () {
                swiperAnimate(this); //每个slide切换结束时也运行当前slide动画 
              },
            },
          }
        };
      },
      components: {
        Swiper,
        SwiperSlide,
        musicAudio,
    
      },
      computed: {
    
      },
      mounted() {
    
      },
      methods: {
    
        onSwiper() {
    
        },
        onSlideChange() {
          this.$refs.musicAudio.handlePlay()
        }
      },
    }
    
    </script>
    <style lang="scss">
    /* 如果屏幕超过了750px,那么我们就就按照750px设计稿来走,不会让页面超过750px ,使用媒体查询来设置*/
    @media screen and (min-width: 750px) {
      html {
        font-size: 75px !important;
      }
    }
    
    .height100 {
      height: 100%;
    }
    
    .textCenter {
      text-align: center;
    }
    
    .summary {
      width: 100%;
      height: 100%;
      background-color: #fff;
    }
    
    .swiper-container {
      width: 100%;
      height: 100%;
    }
    
    .page {
      width: 100%;
      height: 100%;
      background-repeat: no-repeat;
      background-size: 100% 100%;
      position: relative;
    
      .item {
        position: absolute;
        font-size: 0.45rem;
        top: 3.5rem;
        left: 1.6rem;
    
        p {
          margin-bottom: 0.55rem;
        }
      }
    
      .strongText {
        color: #f86073;
        font-size: 0.6rem;
        font-family: 'alihya4';
        letter-spacing: 0.02rem;
      }
    }
    </style>
    <style lang='scss' scoped>
    .page5{
    
    }
    .scrolltips {
      position: absolute;
      bottom: 0;
      left: 50%;
      z-index: 50;
      width: 36px;
      margin-left: -18px;
    }
    
    .sc {
      width: 36px;
      height: 32px;
      position: absolute;
      bottom: 0;
      right: 0;
      opacity: 0;
      background-size: 100% 100%;
      -webkit-transform: translateY(-20px);
      -ms-transform: translateY(-20px);
      transform: translateY(-20px);
      -webkit-animation: sc 2s 0.3s infinite;
      animation: sc 2s 0.3s infinite;
    }
    
    @-webkit-keyframes sc {
      0% {
        -webkit-transform: translateY(-20px);
        transform: translateY(-20px);
        opacity: 0;
      }
    
      30%,
      70% {
        -webkit-transform: translateY(-40px);
        transform: translateY(-40px);
        opacity: 1;
      }
    
      100% {
        -webkit-transform: translateY(-40px);
        transform: translateY(-40px);
        opacity: 0;
      }
    }
    
    @keyframes sc {
      0% {
        -webkit-transform: translateY(-20px);
        transform: translateY(-20px);
        opacity: 0;
      }
    
      30%,
      70% {
        -webkit-transform: translateY(-40px);
        transform: translateY(-40px);
        opacity: 1;
      }
    
      100% {
        -webkit-transform: translateY(-40px);
        transform: translateY(-40px);
        opacity: 0;
      }
    }
    </style>
    

    7.musicAudio完整代码

    
    <template>
        <div class="switch-music">
            <audio :src="audioUrl" ref="backMusicRef" loop preload autoplay></audio>
            <div class="music" @click="toggleAudio">
                <img class="music-img " :class="{ ro: isPlay }" :src="musicIcon">
            </div>
        </div>
    </template>
        
    <script>
    
    
    export default {
        data() {
            return {
                audioUrl: require('@/views/swiperH5/assets/images/bgmAudio.mp3'),
                musicIcon: require('@/views/swiperH5/assets/images/yinyue.png'),
                audio: null,
                // 打开、关闭
                isPlay: false,
            };
        },
        components: {
    
        },
        computed: {
    
        },
        mounted() {
            this.init()
        },
        methods: {
            init() {
                this.audio = this.$refs.backMusicRef
                this.audio.addEventListener('play', this.handlePlay)
                this.audio.addEventListener('pause', this.handlePause)
            },
            handlePlay() {
                if (!this.isPlay) {
                    this.isPlay = true
                    this.audio.play()
                }
            },
            handlePause() {
                if (this.isPlay) {
                    this.isPlay = false
                    this.audio.pause()
                }
            },
            toggleAudio() {
                if (this.isPlay) {
                    this.audio.pause()
                } else {
                    this.audio.play()
                }
                this.isPlay = !this.isPlay
            },
    
    
        },
    }
    
    </script>
    <style lang='scss' scoped>
    .ro {
        animation:rotate 5s linear 0s infinite;
         -webkit-animation: rotate 5s linear 0s infinite;
     }
    @-webkit-keyframes rotate {
        0% {
            -webkit-transform: rotateZ(0deg)
        }
    
        100% {
            -webkit-transform: rotateZ(360deg)
        }
    }
     .music {
         width: 8%;
         height: auto;
         position: fixed;
         top: 15px;
         right: 15px;
         z-index: 9999;
         cursor: pointer;
     }
    
     .music-p {
         width: 140%;
         height: auto;
         position: absolute;
         top: -30%;
         right: -30%;
     }
    
     .music img,
     .music-p img {
         width: 100%;
         height: auto;
     }
    </style>
    

    8.参考地址

    https://www.cnblogs.com/psmart/p/17669716.html

    相关文章

      网友评论

          本文标题:vue2.0开发H5页面+动画 + swiper 模板框架

          本文链接:https://www.haomeiwen.com/subject/lvptodtx.html