最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

利用vue組件實現(xiàn)圖片的拖拽和縮放功能

 更新時間:2022年01月18日 15:39:51   作者:封號斗羅-逆天而行  
這篇文章主要給大家介紹了關(guān)于利用vue組件實現(xiàn)圖片的拖拽和縮放功能的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

前言

vue實現(xiàn)一個組件其實很簡單但是要寫出一個好的可復(fù)用的組件那就需要多學(xué)習(xí)和鉆研一下,一個好的組件必須有其必不可少的有優(yōu)點:一是能提高應(yīng)用開發(fā)效率、測試性、復(fù)用性等;二是組件應(yīng)該是高內(nèi)聚、低耦合的;三是組件應(yīng)遵循單向數(shù)據(jù)流的原則。

在實現(xiàn)我的圖片的拖拽組件我們的搞清其原理,在這里我使用的是mousedown,mousemove和mouseup來實現(xiàn)拖拽。

如圖所示:

方法如下:

1.新建ElementDrag.vue文件內(nèi)容如下:

<template>
    <div class="drag-outer" 
    ref="dragWrap"
    @mousemove="dragMousemove">
        <div class="drag-inner"
        ref="dragElement" 
        @mousedown="dragMousedown"
        @mouseup.stop="isMousedown = false">
            <slot></slot>
        </div>
    </div>
</template>

2. 定義moveStart用于記錄拖拽元素初始位置。定義isMousedown變量來判斷鼠標(biāo)是否按下, 如果isMousedown === true鼠標(biāo)移動就改變darg-inner位置。

<script>
export default {
    name: 'ElementDrag',
    data() {
        return {
            isMousedown: false, //鼠標(biāo)是否按下
            moveStart: {x: 0, y: 0}, //拖拽元素初始位置
            translate: {x: 0, y: 0}, //計算拖拽元素在下下x,y方向各移動了多少
            scale: 1, //拖拽元素縮放值
        }
    },
    methods: {
        dragMousedown() {
            this.moveStart.x = event.clientX
            this.moveStart.y = event.clientY
            this.isMousedown = true 
        },
        dragMousemove() {
            if(this.isMousedown) {
                this.translate.x += (event.clientX - this.moveStart.x) / this.scale
                this.translate.y += (event.clientY - this.moveStart.y) / this.scale
                this.$refs.dragElement.style.transform = `scale(${this.scale}) translate(${this.translate.x}px, ${this.translate.y}px)`
                this.moveStart.x = event.clientX
                this.moveStart.y = event.clientY
            }
        }
    }
}
</script>

3.樣式部分我們設(shè)置外層drag-outer用flex布局讓里面元素快速居中, user-drag: none;禁用圖片等元素的可拖拽屬性。

<style lang="scss" scoped>
.drag-outer {
    width: 100%;
    height: 100%;
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: center;
    .drag-inner {
        transform-origin: center center;
        display: flex;
        justify-content: center;
        align-items: center;
        cursor: move;
        user-select: none;
        >* {
            -webkit-user-drag: none;
            user-drag: none;
        }
    }
}
</style>

4.添加鼠標(biāo)滾輪事件縮放drag-inner元素, e.wheelDelta為正表示放大,為負(fù)縮小,值越大表示滾動越快。通過scale控制拖拽元素縮放。同過對組件傳值scaleZoom來控制其縮放最大最小程度值。

...
methods: {
    props: {
        type: Object,
        default(){ 
            return {
                min: 0.5,
                max: 5   
            }
        }
    },
    ...
    handleScroll(e) {
        let speed = e.wheelDelta/120
        if(e.wheelDelta > 0 && this.scale < this.scaleZoom.max) {
            this.scale+=0.04*speed
            this.$refs.dragElement.style.transform = `scale(${this.scale}) translate(${this.translate.x}px, ${this.translate.y}px)`
        }else if(e.wheelDelta < 0 && this.scale > this.scaleZoom.min){
            this.scale+=0.04*speed
            this.$refs.dragElement.style.transform = `scale(${this.scale}) translate(${this.translate.x}px, ${this.translate.y}px)`
        }
    }
},
mounted() {
    window.addEventListener('mousewheel',this.handleScroll,false) 
}

5.以上代碼已經(jīng)實現(xiàn)了功能我們預(yù)期的功能,但是為了更好的體驗,需要進(jìn)一步優(yōu)化組件。添加isHover來控制鼠標(biāo)是否移動到了drag-outer以外,如果isHover為false這時鼠標(biāo)滾輪滾動不會縮放元素,并且將isMousedown設(shè)置為false。再使用插槽slot預(yù)覽位置。

<template>
    <div class="drag-outer" 
    ref="dragWrap"
    @mouseenter="isHover = true" 
    @mouseleave="isHover = isMousedown = false"
    @mousemove="dragMousemove">
        <div class="drag-inner"
        ref="dragElement" 
        @mousedown="dragMousedown"
        @mouseup.stop="isMousedown = false">
            <slot></slot>
        </div>
    </div>
</template>
....
data() {
    return {
        ...,
        isHover: false,
    }
},
methods: {
    ...
    handleScroll(e) {
        if(this.isHover) {
            let speed = e.wheelDelta/120
            if(e.wheelDelta > 0 && this.scale < this.scaleZoom.max) {
                this.scale+=0.04*speed
                this.$refs.dragElement.style.transform = `scale(${this.scale}) translate(${this.translate.x}px, ${this.translate.y}px)`
            }else if(e.wheelDelta < 0 && this.scale > this.scaleZoom.min){
                this.scale+=0.04*speed
                this.$refs.dragElement.style.transform = `scale(${this.scale}) translate(${this.translate.x}px, ${this.translate.y}px)`
            }
        }
    }
}

貼上組件的最終代碼:

<template>
    <div class="drag-outer" 
    ref="dragWrap"
    :style="outerOptions"
    @mouseenter="isHover = true" 
    @mouseleave="isHover = isMousedown = false"
    @mousemove="dragMousemove">
        <div class="drag-inner"
        ref="dragElement" 
        :style="innerOptions"
        @mousedown="dragMousedown"
        @mouseup.stop="isMousedown = false">
            <slot></slot>
        </div>
    </div>
</template>

<script>
export default {
    name: 'ElementDrag',
    props: {
        outerOptions: {
            type: Object,
            default () {
                return {
                    background: 'rgba(0,0,0,0.9)'
                }
            }
        },
        innerOptions: {
            type: Object,
            default () {
                return {
                    background: 'rgba(0,0,0,0.1)',
                }
            }
        },
        scaleZoom: {
            type: Object,
            default () {
                return {
                    max: 5, 
                    min: 0.2
                }
            }
        }
    },
    data() {
        return {
            isMousedown: false,
            isHover: false,
            moveStart: {},
            translate: {x: 0, y: 0},
            scale: 1
        }
    },
    methods: {
        handleScroll(e) {
            if(this.isHover) {
                let speed = e.wheelDelta/120
                if(e.wheelDelta > 0 && this.scale < this.scaleZoom.max) {
                    this.scale+=0.04*speed
                    this.$refs.dragElement.style.transform = `scale(${this.scale}) translate(${this.translate.x}px, ${this.translate.y}px)`
                }else if(e.wheelDelta < 0 && this.scale > this.scaleZoom.min){
                    this.scale+=0.04*speed
                    this.$refs.dragElement.style.transform = `scale(${this.scale}) translate(${this.translate.x}px, ${this.translate.y}px)`
                }
            }
        },
        dragMousedown() {
            this.moveStart.x = event.clientX
            this.moveStart.y = event.clientY
            this.isMousedown = true 
        },
        dragMousemove() {
            if(this.isMousedown) {
                this.translate.x += (event.clientX - this.moveStart.x) / this.scale
                this.translate.y += (event.clientY - this.moveStart.y) / this.scale
                this.$refs.dragElement.style.transform = `scale(${this.scale}) translate(${this.translate.x}px, ${this.translate.y}px)`
                this.moveStart.x = event.clientX
                this.moveStart.y = event.clientY
            }
        }
    },
    mounted() {
        window.addEventListener('mousewheel',this.handleScroll,false) 
    }
}
</script>

<style lang="scss" scoped>
.drag-outer {
    width: 100%;
    height: 100%;
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: center;
    .drag-inner {
        transform-origin: center center;
        display: flex;
        justify-content: center;
        align-items: center;
        cursor: move;
        user-select: none;
        >* {
            -webkit-user-drag: none;
            user-drag: none;
        }
    }
}
</style>

在home.vue文件使用:點擊體驗

<template>
  <div class="home">
    <ElementDrag>
        <img src="https://img0.baidu.com/it/u=937276518,3474029246&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=750">
    </ElementDrag>
  </div>
</template>

<script>
import ElementDrag from '@/components/ElementDrag'
export default {
  name: 'Home',
  components: {
    ElementDrag
  }
}
</script>

<style scoped>
.home {
  width: 100vw;
  height: 100vh;
} 
</style>

總結(jié)

到此這篇關(guān)于利用vue組件實現(xiàn)圖片的拖拽和縮放功能的文章就介紹到這了,更多相關(guān)vue組件實現(xiàn)圖片拖拽縮放內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue中 process.env與process.VUE_CLI_SERVICE詳解

    vue中 process.env與process.VUE_CLI_SERVICE詳解

    這篇文章主要介紹了vue中process.env與process.VUE_CLI_SERVICE的相關(guān)資料,本文結(jié)合實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-05-05
  • vue v-viewer組件使用示例詳解(v-viewer輪播圖)

    vue v-viewer組件使用示例詳解(v-viewer輪播圖)

    這篇文章主要介紹了vue v-viewer組件使用示例詳解(v-viewer輪播圖),本文結(jié)合實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-02-02
  • Vue3響應(yīng)式方案及ref?reactive的區(qū)別詳解

    Vue3響應(yīng)式方案及ref?reactive的區(qū)別詳解

    眾所周知ref和reactive都是用來作響應(yīng)式數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于Vue3響應(yīng)式方案及ref?reactive區(qū)別的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • Vue組件之間的通信方式詳細(xì)講解

    Vue組件之間的通信方式詳細(xì)講解

    對于vue來說,組件之間的消息傳遞是非常重要的,用vue可以是要組件復(fù)用的,而組件實例的作用域是相互獨立,這意味著不同組件之間的數(shù)據(jù)無法互相引用,一般來說,組件之間可以有幾種關(guān)系,下面是我對組件之間消息傳遞的常用方式的總結(jié)
    2022-08-08
  • Vue Router 中meta 對象示例詳解

    Vue Router 中meta 對象示例詳解

    本文主要介紹了在VueRouter中,meta對象的使用和配置方式,meta對象可以包含任何你希望附加到路由的自定義信息,這些配置信息可以靈活的滿足你的應(yīng)用需求,使得路由配置更具靈活性和可擴(kuò)展性
    2024-10-10
  • vue項目引入遠(yuǎn)程jweixin-1.2.0.js文件并使用詳解

    vue項目引入遠(yuǎn)程jweixin-1.2.0.js文件并使用詳解

    這篇文章主要介紹了vue項目引入遠(yuǎn)程jweixin-1.2.0.js文件并使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • vue框架搭建之a(chǎn)xios使用教程

    vue框架搭建之a(chǎn)xios使用教程

    本文重點介紹axios如何配合vue搭建項目框架,文章給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友參考下吧
    2018-07-07
  • nuxt實現(xiàn)封裝axios并且獲取token

    nuxt實現(xiàn)封裝axios并且獲取token

    這篇文章主要介紹了nuxt實現(xiàn)封裝axios并且獲取token,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • 如何在寶塔面板部署vue項目

    如何在寶塔面板部署vue項目

    這篇文章主要給大家介紹了關(guān)于如何在寶塔面板部署vue項目的相關(guān)資料,寶塔面板可以通過Nginx來部署Vue項目,并解決跨域問題,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • vue項目引入本地bootstrap不生效問題及解決

    vue項目引入本地bootstrap不生效問題及解決

    這篇文章主要介紹了vue項目引入本地bootstrap不生效問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10

最新評論

夏津县| 大理市| 兰坪| 满城县| 石柱| 安丘市| 广水市| 如东县| 淳安县| 安康市| 乾安县| 怀仁县| 南涧| 西安市| 措美县| 乐至县| 抚宁县| 城市| 延长县| 沽源县| 万山特区| 汶川县| 佛山市| 进贤县| 平阴县| 故城县| 南溪县| 汉源县| 林西县| 九龙县| 永嘉县| 芦山县| 营口市| 荔浦县| 景德镇市| 宁蒗| 光山县| 铜陵市| 海晏县| 西林县| 望都县|