大屏---适配比例缩放--视频播放完路由自动切换

1. 比例缩放

1-1. 方法一: 全局引进

文件 flex.js ---- 代码如下:
((win, doc) => {
  const body = document.body

  const resizeEvt = 'orientationchange' in win ? 'orientationchange' : 'resize'

  const recalc = () => {
    const clientWidth = body.clientWidth
    const clientHeight = body.clientHeight
    const documentWidth = document.documentElement.clientWidth
    const documentHeight = document.documentElement.clientHeight
    if (!clientWidth) return
    body.style.WebkitTransform = `scale(${documentWidth /
        clientWidth},${documentHeight / clientHeight})`
  }

  if (!doc.addEventListener) return

  win.addEventListener(resizeEvt, recalc, false)
  doc.addEventListener('DOMContentLoaded', recalc, false)
})(window, document)
在 vue.config.js中配置入口文件
  configureWebpack: {
    entry: {
      app: './src/main.js',
      'lib-flex': './src/assets/js/flex.js',
    },
  }
    1. window.innerWidth/Height => 获取浏览器可视区域宽/高度
    1. document.documentElement.clientWidth/Height => 获取浏览器可视区域宽/高
      document.documentElement指的是html
    1. document.body.clientWidth/Height => 获取body的宽/高(除去margin)   
      document.body指的是body元素

①document.documentElement.clientHeight 和 window.innerHeight 是相等的,但是宽度差个滚动条宽度;
②document.documentElement.clientWidth/Height 和 window.innerWIdth/innerHeight 都是获取浏览器可视区域的宽高。其大小随浏览器缩放变化,不因body边距变化;
③document.body.clientWidth/Height 获取的是body实际宽高,不包括滚动条及工具栏宽高,其大小随body元素实际宽高变化而变化。

1-2. 方法二: 局部引进

监听浏览器窗口大的小,同时控制变化的比例
采用了css3的缩放transform: scale(X)属性

封装一个全局组件 – ScreenAdapter
<template>
  <div class="ScreenAdapter" :style="style">
    <slot />
  </div>
</template>
<script>
export default {
  name: '',
  props: {
    width: {
      type: String,
      default: '1920'
    },
    height: {
      type: String,
      default: '1080'
    }
  },
  data() {
    return {
      style: {
        width: this.width + 'px',
        height: this.height + 'px',
        transform: 'scale(1) translate(-50%, -50%)'
      }
    }
  },
  mounted() {
    this.setScale()
    window.onresize = this.Debounce(this.setScale, 10)
  },
  methods: {
    Debounce: (fn, t) => {
      const delay = t || 500
      let timer
      return function() {
        const args = arguments
        if (timer) {
          clearTimeout(timer)
        }
        const context = this
        timer = setTimeout(() => {
          timer = null
          fn.apply(context, args)
        }, delay)
      }
    },
    // 获取放大缩小比例
    getScale() {
      const w = window.innerWidth / this.width
      const h = window.innerHeight / this.height
      console.log('--------getScale-------', [w, h])
      // return w < h ? w : h
      return [w, h]
    },
    // 设置比例
    setScale() {
      this.style.transform = 'scale(' + this.getScale()[0] + ',' + this.getScale()[1] + ') translate(-50%, -50%)'
      // this.style.transform = 'scale(' + this.getScale() + ') translate(-50%, -50%)'
      console.log('任你千变万化,我都不会影响性能')
    }
  }
}
</script>
<style lang="scss" scoped>
.ScreenAdapter {
  transform-origin: 0 0;
  position: absolute;
  left: 50%;
  top: 50%;
  transition: 0.3s;
  background: red;
}
</style>

使用组件

<ScreenAdapter> <div>大家好,我是大屏展示页面</div> </ScreenAdapter>

2. 路由自动切换

需求

  1. 每个路由中的视频自动播放3遍或者5遍,,然后自动切换下一个路由,继续自动播放下一个路由的视频;
  2. 如果点击tab 导航,,则循环该路由中的视频3遍,然后跳转首页继续循环播放;

实现

app.vue 文件 <router-view @switchRouter="switchRouter"></router-view> , 这样子路由可以传参并执行父组件的方法!

每个子组件挂载时监听that.$refs.media的视频播放end状态,播放达到次数则that.$emit('switchRouter',that.$route.name)

export const waitingVideoNum = (that) => {
    let num = 0;
    let endFlag = false
    const ipv6RouterList = ['ipv6-first', 'ipv6-second', 'ipv6-third', 'ipv6-fourth', 'IPv6']
    const routerList = ['main', '5GtoB', 'cloudNet']

    that.$refs.media.addEventListener("ended", function () {
        num++
        endFlag = (num === 5 && that.$route.name === 'computer') || (num === 1 && ipv6RouterList.includes(that.$route.name)) || (num === 3 && routerList.includes(that.$route.name))
        if (endFlag) {
          that.$emit('switchRouter',that.$route.name)
        } else {
            this.play()
        }
    },false);
}

APP.vue 文件

        <div>
          <router-link to="/main" class="main-title" tag="div">
          </router-link>
          <div
            :class="['fiveGtoB-tab-svg', tabActive === '5GtoB' ? 'activeFiveGtoB' : '']"
            @click="goto('5GtoB',true)"
          ></div>
          <div
            :class="['IP-tab-svg', tabActive === 'IPv6' ? 'activeIP' : '']"
            @click="goto('IPv6',true)"
          > </div>
          <div
            :class="['cloudNet-tab-svg', tabActive === 'cloudNet' ? 'activeCloudNet' : '']"
            @click="goto('cloudNet',true)"
          > </div>
          <router-view @switchRouter="switchRouter"></router-view>
        </div>

  methods: {
    goto(activeTab,isClick) {
      isClick && this.setIsClick(isClick || false)
      this.tabActive = activeTab
      this.$router.push({
        name: activeTab
      });
    },
    switchRouter (name) {
      let routerList = ['main','5GtoB','ipv6-first','ipv6-second','ipv6-third','ipv6-fourth','cloudNet'];
      const index = routerList.indexOf(name || '')
      if (index !== -1) {
        const routerName = this.isClick || !routerList[index + 1] ?  routerList[0] : routerList[index + 1]
        this.goto(routerName)
        if (this.isClick) {
          this.setIsClick(false)
        }
      }
    },
    setIsClick (isClick) {
      this.isClick = isClick;
      localStorage.setItem('isClick',JSON.stringify(isClick))
    }
}

router.js

import Vue from 'vue';
import Router from 'vue-router';

Vue.use(Router);

export default new Router({
    scrollBehavior: () => ({y: 0}),
    routes: [
        {path: '/main', name: 'main', component: () => import('./views/mainContainer')},
        {path: '/5GtoB', name: '5GtoB', component: () => import('./views/5GtoB')},
        {path: '/IPv6', name: 'IPv6', component: () => import('./views/IPv6'), redirect:'/IPv6/first',
            children: [
                {path: 'first', name: 'ipv6-first', component: () => import('./components/ipv6/ipv6First.vue')},
                {path: 'second', name: 'ipv6-second', component: () => import('./components/ipv6/ipv6Second.vue')}
            ]
        },
        {path: '/cloudNet', name: 'cloudNet', component: () => import('./views/cloudNet')},
        {path: '*', redirect: '/main'}
    ]
})

waitingVideoNum.js

注意: 视频如果太大,会分段加载

export const waitingVideoNum = (that) => {
    let num = 0;
    let endFlag = false
    const ipv6RouterList = ['ipv6-first', 'ipv6-second', 'ipv6-third', 'ipv6-fourth', 'IPv6']
    const routerList = ['main', '5GtoB', 'cloudNet']

    that.$refs.media.addEventListener("ended", function () {
        num++
        endFlag = (num === 5 && that.$route.name === 'computer') || (num === 1 && ipv6RouterList.includes(that.$route.name)) || (num === 3 && routerList.includes(that.$route.name))
        if (endFlag) {
          that.$emit('switchRouter',that.$route.name)
        } else {
            this.play()
        }
    },false);
}

5GtoB.vue

在 vue文件里面引用 waitingVideoNum from ‘…/utils/waitingVideoNum.js’

<template>
  <div class="main-container">
    <video
      style="display:block;"
      width="100%"
      height="100%"
      ref="media"
      autoplay
      muted
      webkit-playsinline
      x5-playsinline
      playsinline
    >
      <source src="@/assets/video/5g.mp4" type="video/mp4" />
    </video>
  </div>
</template>

<script>
import { waitingVideoNum } from '../utils/waitingVideoNum.js'
export default {
  mounted() {
    this.init();
  },
  methods: {
    init() {
      waitingVideoNum(this)
    },
  },
};
</script>

<style lang="scss" scoped>
.main-container {
  position: absolute;
  top: 0px;
  left: 0px;
  video { object-fit: cover; }
  z-index: 0;
}
</style>
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值