欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue實(shí)現(xiàn)鼠標(biāo)滑動(dòng)預(yù)覽視頻封面組件示例詳解

 更新時(shí)間:2022年07月25日 10:35:01   作者:JYeontu  
這篇文章主要為大家介紹了vue實(shí)現(xiàn)鼠標(biāo)滑動(dòng)預(yù)覽視頻封面組件示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

組件效果

http://www.dbjr.com.cn/Special/926.htm

組件設(shè)計(jì)

我們首先應(yīng)該要對組件進(jìn)行一個(gè)簡單的設(shè)計(jì)。

主要的邏輯如上圖??????,可以拆分成這么幾個(gè)步驟:

1、視頻截取關(guān)鍵幀

我們可以先將視頻各個(gè)時(shí)間的關(guān)鍵幀截圖保存,具體截取幀數(shù)可以使用傳入?yún)?shù)控制。

2、鼠標(biāo)移入封面時(shí)顯示對應(yīng)關(guān)鍵幀

在鼠標(biāo)移入的時(shí)候我們應(yīng)該要計(jì)算當(dāng)前鼠標(biāo)位置和視頻寬度的比例關(guān)系,然后從視頻幀列表中獲取到對應(yīng)的圖片作為當(dāng)前的視頻封面圖片。

3、視頻和封面的狀態(tài)切換

這里我們是將用兩個(gè)元素分別作為視頻和封面,所以我們狀態(tài)切換的時(shí)候需要控制兩個(gè)元素的顯示和隱藏。

  • 點(diǎn)擊封面

顯示并播放視頻,隱藏封面。

  • 暫停播放

顯示封面,隱藏視頻。

功能實(shí)現(xiàn)

分析完組件的關(guān)鍵步驟之后我們便可以開始動(dòng)手來實(shí)現(xiàn)相應(yīng)的功能了。

1、視頻截取關(guān)鍵幀圖片列表

1.1 截取指定幀

視頻關(guān)鍵幀的截取我們可以使用canvas來實(shí)現(xiàn),具體實(shí)現(xiàn)方法如下:

/** 
 * @param {element} video 
 * @param {number} currentTime
 * @return {void}
 */
cutCover(video, currentTime) {
    video.currentTime = currentTime;
    const canvas = document.createElement("canvas");
    let ctx = canvas.getContext("2d");
    canvas.width = parseInt(this.width);
    canvas.height = parseInt(this.height);
    ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
    const img = canvas.toDataURL("image/png");
    return img;
},

通過該函數(shù)我們可以獲取指定時(shí)間的視頻圖片幀。

  • 傳入?yún)?shù)
/** 
 * @param {element} video 
 * @param {number} currentTime
 */

video為需要截取視頻的dom元素,currentTime為要截取圖片幀的時(shí)間點(diǎn)。

  • 返回參數(shù)
/** 
 * @return {Base64} img
 */

返回參數(shù)為截取的指定幀的Base64格式的圖片。

1.2 截取stepNums張關(guān)鍵幀圖片

stepNums為我們傳入的組件參數(shù),及需要截取的封面關(guān)鍵幀圖片數(shù)量,數(shù)量越多,預(yù)覽的效果越連貫,可以根據(jù)視頻長度來調(diào)整截取的張數(shù)。

init(){
    const videoContentShow = document.getElementById(
        this.uid + "-video"
    );
    videoContentShow.style.height = this.height;
    videoContentShow.style.width = this.width;
    const videoContent = videoContentShow.cloneNode();
    videoContent.addEventListener("canplay", () => {
        if (this.currentTime < this.duration) this.cut(videoContent);
        else this.progressValue = 0;
    });
}
cut(video) {
    const duration = video.duration;
    this.duration = duration;
    this.currentTime += duration / this.stepNums;
    const img = this.cutCover(video, this.currentTime);
    this.imgList.push(img);
    if (this.imgList.length == 2) {
        this.coverSrc = img;
        const coverImg = document.getElementById(
            this.uid + "-coverImg"
        );
        coverImg.setAttribute("src", img);
    }
}

具體代碼如上,首先我們應(yīng)該先要獲取到視頻的dom元素,但是要注意:我們不在原始視頻元素上進(jìn)行截取操作,我們這里使用了cloneNode()來克隆一個(gè)dom元素進(jìn)行操作。因?yàn)樵谶M(jìn)行截取的時(shí)候我們需要對視頻的currentTime屬性進(jìn)行一個(gè)修改,也就是改變視頻的播放進(jìn)度,如果在原視頻上截取的話,在未截取完成前播放視頻會(huì)導(dǎo)致視頻播放進(jìn)度混亂,所以這里我們在克隆元素對象上進(jìn)行操作。

我們總共需要截取stepNums張圖片,所以每次截取的時(shí)間間隔應(yīng)該為:duration / this.stepNums,即視頻總時(shí)間長度/截取圖片張數(shù),循環(huán)截取即可。

2、鼠標(biāo)移入封面時(shí)顯示對應(yīng)關(guān)鍵幀

鼠標(biāo)移入封面的時(shí)候我們需要對封面圖片進(jìn)行切換。

2.1 鼠標(biāo)移動(dòng)事件監(jiān)聽

<img
    :id="uid + '-coverImg'"
    :src="coverSrc"
    class="j-coverImg"
    @mousemove="imgHover"
    @mouseleave="hoverOut"
    @click="coverClick"
/>

這里我們使用vue中的mousemove和mouseleave對鼠標(biāo)事件進(jìn)行監(jiān)聽。

imgHover(e) {
    const coverImg = document.getElementById(this.uid + "-coverImg");
    const w = coverImg.offsetWidth / this.stepNums;
    const x = e.offsetX - coverImg.offsetLeft;
    const index = Math.min(
        Math.max(Math.ceil(x / w), 1),
        this.stepNums
    );
    if (this.imgList.length < index) return;
    this.progressValue = index;
    coverImg.setAttribute(
        "src",
        this.imgList[Math.min(this.imgList.length - 1, index)]
    );
},

鼠標(biāo)移入的時(shí)候我們需要根據(jù)鼠標(biāo)的坐標(biāo)位置來計(jì)算展示的幀數(shù)下標(biāo),具體計(jì)算如下:

  • 每張圖片展示的區(qū)間大小
const w = coverImg.offsetWidth / this.stepNums;

每個(gè)區(qū)間的大小我們只需要將封面的寬度除于圖片幀列表的數(shù)量即可得到每張圖片展示的區(qū)間大小。

  • 當(dāng)前鼠標(biāo)所在區(qū)間
const x = e.offsetX - coverImg.offsetLeft;
const index = Math.min(
    Math.max(Math.ceil(x / w), 1),
    this.stepNums
);

首先我們應(yīng)該要計(jì)算當(dāng)前鼠標(biāo)在封面里的相對位置,這里我們只需要其橫坐標(biāo)x即可,然后將坐標(biāo)除于區(qū)間大小,我們即可得到當(dāng)前坐標(biāo)所對應(yīng)的區(qū)間下標(biāo)。這里的最大值應(yīng)該進(jìn)行限制為1和stepNums。

2.2 鼠標(biāo)移出事件監(jiān)聽

鼠標(biāo)移出的時(shí)候我們需要將封面恢復(fù)成當(dāng)前視頻的封面。

hoverOut(e) {
    const coverImg = document.getElementById(this.uid + "-coverImg");
    const step = this.duration / this.stepNums;
    const index = Math.ceil(this.pauseTime / step);
    this.progressValue = index;
    coverImg.setAttribute("src", this.pauseCover || this.coverSrc);
},

3、視頻和封面的狀態(tài)切換

封面和視頻的顯示隱藏需要根據(jù)播放狀態(tài)來進(jìn)行對應(yīng)的切換。

3.1 播放視頻

點(diǎn)擊封面的時(shí)候播放視頻,需要隱藏封面及相關(guān)的進(jìn)度條并顯示視頻

doHide(hide = false) {
    const videoContent = document.getElementById(this.uid + "-video");
    videoContent.style.display = hide ? "block" : "none";
    videoContent.currentTime = this.pauseTime;
    hide ? videoContent.play() : videoContent.pause();
    const img = document.getElementById(this.uid + "-coverImg");
    img.style.display = hide ? "none" : "block";
    const progress = document.getElementById(this.uid + "-progress");
    progress.style.display = hide ? "none" : "block";
    const progress1 = document.getElementById(this.uid + "-progress1");
    progress1.style.display = hide ? "none" : "block";
},
coverClick() {
    this.doHide(true);
},

3.2 視頻暫停

視頻暫停時(shí)我們需要隱藏視頻,截取當(dāng)前幀作為封面并顯示封面及相關(guān)的進(jìn)度條。

videoContentShow.addEventListener("pause", e => {
    this.pauseTime = videoContentShow.currentTime;
    this.pauseCover = this.cutCover(
        videoContentShow,
        videoContentShow.currentTime
    );
    coverImg.setAttribute("src", this.pauseCover);
    const step = this.duration / this.stepNums;
    const index = Math.ceil(this.pauseTime / step);
    this.progressValue = index;
    setTimeout(() => {
        if (videoContentShow.paused) this.doHide();
    }, 200);
});

這里我使用了一個(gè)setTimeout來進(jìn)行一個(gè)延時(shí)控制,大家知道為什么嗎?因?yàn)橐曨l有兩種操作會(huì)觸發(fā)視頻的pause事件:

  • 點(diǎn)擊暫停按鈕
  • 拉動(dòng)進(jìn)度條

這里拉動(dòng)進(jìn)度條的時(shí)候會(huì)觸發(fā)視頻的pause事件并且馬上繼續(xù)播放,所以我們應(yīng)該要過濾掉這一情況。

組件使用

<template>
    <div class="content">
        <div class="video-list">
            <j-video-cover
                class="video"
                :videoUrl="videoUrl"
                stepNums="40"
            ></j-video-cover>
        </div>
    </div>
</template>
<script>
    export default {
        data() {
            return {
                videoUrl: require("../../assets/video/202112250058.mp4"),
            }
        }
    }
</script>

組件庫引用

這里我將這個(gè)組件打包進(jìn)了自己的一個(gè)組件庫,并將其發(fā)布到了npm上,有需要的同學(xué)也可以直接引入該組件進(jìn)行使用。

引入組件代碼

 <j-code-height-light :code = "code" 
        :keyWords = "keyWords"       
        :color = "color">
    </j-code-height-light>
    <!-- 注釋 -->
    <div class = 'body'>
      <div class = 'title'>標(biāo)題</div>
      <div class = 'main'>
        <span >內(nèi)容</span>
      </div>
    </div>


        /**
         * 組件參數(shù)配置如下
         */
        props: {
            code: {
                type: String,
                default: ''
            },
            keyWords:{
                type:Array,
                default:[
                    {
                        value:'關(guān)鍵字1',
                        color:'顏色1'
                    },
                    {
                        value:'關(guān)鍵字2',
                        color:'顏色2'
                    }
                ]
            },
            color:{
                type: Object,
                default: {
                    keyWord:'orange',//js關(guān)鍵字
                    varWord:'purple',//js變量
                    tagWord:'#F9273F',//html標(biāo)簽
                    strWord:'green',//字符串變量值
                    attrWord:'green',//html屬性
                    attrValue:'yellow',//html屬性值
                    methodkeyWord:'#74759b',//js方法
                    functionkeyWord:'#2c9678',//自定義函數(shù)
                    note:'grey'//注釋
                }
            }
        },
        methods:{
            test(){
                console.log('test');
            },
            testP(p1,p2){
                console.log(p1,p2);
            }
        }

引入后即可直接使用。

源碼地址

組件庫已開源,想要查看完整源碼的可以到 gitee 查看,自己也整理了相關(guān)的文檔對其進(jìn)行了簡單介紹,具體如下:

組件文檔 http://shouce.jb51.net/vue/single-file-components.html

以上就是vue實(shí)現(xiàn)鼠標(biāo)滑動(dòng)預(yù)覽視頻封面組件示例詳解的詳細(xì)內(nèi)容,更多關(guān)于vue鼠標(biāo)滑動(dòng)視頻封面預(yù)覽的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解vue-router 初始化時(shí)做了什么

    詳解vue-router 初始化時(shí)做了什么

    這篇文章主要介紹了詳解vue-router 初始化時(shí)做了什么,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-06-06
  • vue+koa2搭建mock數(shù)據(jù)環(huán)境的詳細(xì)教程

    vue+koa2搭建mock數(shù)據(jù)環(huán)境的詳細(xì)教程

    這篇文章主要介紹了vue+koa2搭建mock數(shù)據(jù)環(huán)境的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05
  • 通過Element ui往頁面上加一個(gè)分頁導(dǎo)航條的方法

    通過Element ui往頁面上加一個(gè)分頁導(dǎo)航條的方法

    這篇文章主要介紹了通過Element ui往頁面上加一個(gè)分頁導(dǎo)航條的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • 前端vue?a鏈接下載文件失敗的問題(未發(fā)現(xiàn)文件)

    前端vue?a鏈接下載文件失敗的問題(未發(fā)現(xiàn)文件)

    這篇文章主要介紹了前端vue?a鏈接下載文件失敗的問題(未發(fā)現(xiàn)文件),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • 詳解本地Vue項(xiàng)目請求本地Node.js服務(wù)器的配置方法

    詳解本地Vue項(xiàng)目請求本地Node.js服務(wù)器的配置方法

    本文只針對自己需要本地模擬接口于是搭建一個(gè)本地node服務(wù)器供自己測試使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-03-03
  • vue實(shí)現(xiàn)瀏覽器全屏展示功能

    vue實(shí)現(xiàn)瀏覽器全屏展示功能

    這篇文章主要介紹了vue實(shí)現(xiàn)瀏覽器全屏展示功能,項(xiàng)目中使用的是sreenfull插件,執(zhí)行命令安裝,具體實(shí)現(xiàn)代碼跟隨小編一起看看吧
    2019-11-11
  • vue封裝form表單組件拒絕重復(fù)寫form表單

    vue封裝form表單組件拒絕重復(fù)寫form表單

    這篇文章主要為大家介紹了vue封裝form表單組件拒絕重復(fù)寫form表單的實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Vue中使用eslint和editorconfig方式

    Vue中使用eslint和editorconfig方式

    這篇文章主要介紹了Vue中使用eslint和editorconfig方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • webpack項(xiàng)目中使用vite加速的兼容模式詳解

    webpack項(xiàng)目中使用vite加速的兼容模式詳解

    這篇文章主要為大家介紹了webpack項(xiàng)目中使用vite加速的兼容模式示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Vue引用第三方datepicker插件無法監(jiān)聽datepicker輸入框的值的解決

    Vue引用第三方datepicker插件無法監(jiān)聽datepicker輸入框的值的解決

    這篇文章主要介紹了Vue引用第三方datepicker插件無法監(jiān)聽datepicker輸入框的值的解決,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01

最新評論