Vue2實(shí)現(xiàn)圖片的拖拽,縮放和旋轉(zhuǎn)效果的示例代碼
效果圖
分步驟實(shí)現(xiàn)
在這里看下 拖拽、旋轉(zhuǎn)、縮放的幾個方法
1.獲取圖片的實(shí)際寬高
getImgSize(url) { return new Promise((resolve, reject) => { let imgObj = new Image(); imgObj.src = url; imgObj.onload = () => { resolve({ width: imgObj.width, height: imgObj.height, }); }; }); },
2.根據(jù)盒子的大小、圖片的大小來計算 要顯示多大的圖片
async initImage() { if (!this.imageUrl) { return; } let { width, height } = await this.getImgSize(this.imageUrl); // 設(shè)置原始圖片的大小 let realWidth = width; let realHeight = height; // 獲取高寬比例 const whRatio = realWidth / realHeight; const hwRatio = realHeight / realWidth; //獲取盒子的大小 const boxW = this.$refs.maskBox.clientWidth; const boxH = this.$refs.maskBox.clientHeight; if (realWidth >= realHeight) { this.imgH = hwRatio * boxW; const nih = this.imgH; if (nih > boxH) { this.imgH = boxH; this.imgW = whRatio * boxH; } else { this.imgW = boxW; } this.top = (boxH - this.imgH) / 2; this.left = (boxW - this.imgW) / 2; } else { this.imgW = (boxH / realHeight) * realWidth; this.imgH = boxH; this.left = (boxW - this.imgW) / 2; } },
在這里主要是根據(jù)圖片的寬高 ,以及盒子的大小來計算 盒子中展示多大的圖片,將圖片按照比例縮放后展示到盒子中。
3.拖拽圖片
主要是監(jiān)聽@mousedown
事件
onmousedownHandle(e) { const that = this; this.$refs.maskBox.onmousemove = function (el) { const ev = el || window.event; // 阻止默認(rèn)事件 ev.preventDefault(); that.left += ev.movementX; that.top += ev.movementY; }; this.$refs.maskBox.onmouseup = function () { // 鼠標(biāo)抬起時將操作區(qū)域的鼠標(biāo)按下和抬起事件置為null 并初始化 that.$refs.maskBox.onmousemove = null; that.$refs.maskBox.onmouseup = null; }; if (e.preventDefault) { e.preventDefault(); } else { return false; } },
4. 旋轉(zhuǎn)圖片
handleRotate() { this.deg += 90; if (this.deg >= 360) { this.deg = 0; } this.size = 0; this.scale = `scale(1) rotateZ(${this.deg}deg)`; },
5.監(jiān)聽鼠標(biāo)的滾動,進(jìn)行縮放圖片
在 mounted() 中監(jiān)聽鼠標(biāo)的滾動事件
mounted() { // 兼容火狐瀏覽器 this.mousewheelevt = /Firefox/i.test(navigator.userAgent)? "DOMMouseScroll" : "mousewheel"; // 為空間區(qū)域綁定鼠標(biāo)滾輪事件 =》 處理函數(shù)是wheelHandle // 如果你監(jiān)聽了window的scroll或者touchmove事件,你應(yīng)該把passive設(shè)置為true,這樣滾動就會流暢很多 this.$refs.maskBox.addEventListener(this.mousewheelevt, this.wheelHandle, {passive:true}); },
處理鼠標(biāo)的滾動事件
wheelHandle(e) { // 兼容性處理 => 火狐瀏覽器判斷滾輪的方向是屬性 detail,谷歌和ie瀏覽器判斷滾輪滾動的方向是屬性 wheelDelta const ev = e || window.event; // dir = -dir; // dir > 0 => 表示的滾輪是向上滾動,否則是向下滾動 => 范圍 (-120 ~ 120) const dir = ev.detail ? ev.detail * -120 : ev.wheelDelta; //滾動的數(shù)值 / 2000 => 表示滾動的比例,用此比例作為圖片縮放的比例 this.imgScaleHandle(dir / 2000); },
放大縮小圖片
/** * 圖片的縮放 * zoom >0 放大 * zoom <0 縮小 */ imgScaleHandle(zoom) { this.size += zoom; if (this.size < -0.5) { this.size = -0.5; } this.scale = `scale(${1 + this.size}) rotateZ(${this.deg}deg)`; },
頁面銷毀的時候 注意要取消鼠標(biāo)的監(jiān)聽事件
beforeDestroy() { //取消監(jiān)聽 this.$refs.maskBox.removeEventListener(this.mousewheelevt,this.wheelHandle,{passive:true}); },
以上就是主要實(shí)現(xiàn)功能的方法
完整代碼
<template> <div class="home"> <div class="btn-area"> <button @click="switchImgHandle(1)">豎圖</button> <button @click="switchImgHandle(2)">橫圖</button> <button @click="handleRotate">旋轉(zhuǎn)</button> <button @click="imgScaleHandle(0.25)">放大</button> <button @click="imgScaleHandle(-0.25)">縮小</button> <button @click="handleReset">重置</button> </div> <div class="image-box" ref="maskBox" @mousedown="onmousedownHandle"> <img :src="imageUrl" alt="" :style="{width: imgW + 'px', height: imgH + 'px', top: top + 'px', left: left + 'px', transform: scale, }" /> </div> </div> </template> <script> export default { name: "HomeView", data() { return { imageUrl: "", imageUrl1: require("@/assets/img1.jpg"), imageUrl2: require("@/assets/img2.jpg"), imgW: 0, imgW: 0, imgH: 0, deg: 0, top: 0, left: 0, scale: "scale(1)", size: 0, mousewheelevt: null, }; }, mounted() { this.imageUrl = this.imageUrl1; //初始化圖片 this.initImage(); // 兼容火狐瀏覽器 this.mousewheelevt = /Firefox/i.test(navigator.userAgent) ? "DOMMouseScroll" :"mousewheel"; // 為空間區(qū)域綁定鼠標(biāo)滾輪事件 =》 處理函數(shù)是wheelHandle // 如果你監(jiān)聽了window的scroll或者touchmove事件,你應(yīng)該把passive設(shè)置為true,這樣滾動就會流暢很多 this.$refs.maskBox.addEventListener(this.mousewheelevt, this.wheelHandle, { passive:true}); }, beforeDestroy() { //取消監(jiān)聽 this.$refs.maskBox.removeEventListener(this.mousewheelevt,this.wheelHandle,{passive:true}); }, methods: { /** * 切換圖片 * flag: 1豎圖 2 橫圖 */ switchImgHandle(flag) { if (flag === 1) { this.imageUrl = this.imageUrl1; } else { this.imageUrl = this.imageUrl2; } this.handleReset(); }, /** * 獲取圖片的url * @param {string} url */ getImgSize(url) { return new Promise((resolve, reject) => { let imgObj = new Image(); imgObj.src = url; imgObj.onload = () => { resolve({ width: imgObj.width, height: imgObj.height, }); }; }); }, /** * 初始化圖片 */ async initImage() { if (!this.imageUrl) { return; } let { width, height } = await this.getImgSize(this.imageUrl); // 設(shè)置原始圖片的大小 let realWidth = width; let realHeight = height; // 獲取高寬比例 const whRatio = realWidth / realHeight; const hwRatio = realHeight / realWidth; //獲取盒子的大小 const boxW = this.$refs.maskBox.clientWidth; const boxH = this.$refs.maskBox.clientHeight; if (realWidth >= realHeight) { this.imgH = hwRatio * boxW; const nih = this.imgH; if (nih > boxH) { this.imgH = boxH; this.imgW = whRatio * boxH; } else { this.imgW = boxW; } this.top = (boxH - this.imgH) / 2; this.left = (boxW - this.imgW) / 2; } else { this.imgW = (boxH / realHeight) * realWidth; this.imgH = boxH; this.left = (boxW - this.imgW) / 2; } }, /** * 旋轉(zhuǎn) */ handleRotate() { this.deg += 90; if (this.deg >= 360) { this.deg = 0; } this.size = 0; this.scale = `scale(1) rotateZ(${this.deg}deg)`; }, /** * 圖片的縮放 * zoom >0 放大 * zoom <0 縮小 */ imgScaleHandle(zoom) { this.size += zoom; if (this.size < -0.5) { this.size = -0.5; } this.scale = `scale(${1 + this.size}) rotateZ(${this.deg}deg)`; }, /** * 重置 */ handleReset() { this.imgW = 0; this.imgH = 0; this.top = 0; this.left = 0; this.deg = 0; this.scale = "scale(1)"; this.size = 0; this.initImage(); }, /** * 鼠標(biāo)滾動 實(shí)現(xiàn)放大縮小 */ wheelHandle(e) { const ev = e || window.event; // 兼容性處理 => 火狐瀏覽器判斷滾輪的方向是屬性 detail,谷歌和ie瀏覽器判斷滾輪滾動的方向是屬性 wheelDelta // dir = -dir; // dir > 0 => 表示的滾輪是向上滾動,否則是向下滾動 => 范圍 (-120 ~ 120) const dir = ev.detail ? ev.detail * -120 : ev.wheelDelta; //滾動的數(shù)值 / 2000 => 表示滾動的比例,用此比例作為圖片縮放的比例 this.imgScaleHandle(dir / 2000); }, /** * 處理圖片拖動 */ onmousedownHandle(e) { const that = this; this.$refs.maskBox.onmousemove = function (el) { const ev = el || window.event; // 阻止默認(rèn)事件 ev.preventDefault(); that.left += ev.movementX; that.top += ev.movementY; }; this.$refs.maskBox.onmouseup = function () { // 鼠標(biāo)抬起時將操作區(qū)域的鼠標(biāo)按下和抬起事件置為null 并初始化 that.$refs.maskBox.onmousemove = null; that.$refs.maskBox.onmouseup = null; }; if (e.preventDefault) { e.preventDefault(); } else { return false; } }, }, }; </script> <style scoped> .home { width: 1000px; margin: 50px auto; } .btn-area { display: flex; justify-content: center; width: 100%; margin-bottom: 50px; } .btn-area button { width: 100px; height: 40px; font-size: 18px; margin-right: 10px; } .image-box { position: relative; margin: 0 auto; width: 1000px; height: 700px; border: 1px solid #333; overflow: hidden; } .image-box img { position: absolute; cursor: pointer; } </style>
以上就是Vue2實(shí)現(xiàn)圖片的拖拽,縮放和旋轉(zhuǎn)效果的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于Vue圖片拖拽 縮放 旋轉(zhuǎn)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
尤雨溪開發(fā)vue?dev?server理解vite原理
這篇文章主要為大家介紹了尤雨溪開發(fā)的玩具vite,vue-dev-server來理解vite原理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07vue vite之LogicFlow安裝核心依賴及項目初始化詳解
這篇文章主要為大家介紹了vue vite之LogicFlow安裝核心依賴及項目初始化詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01vue-draggable實(shí)現(xiàn)拖拽表單的示例代碼
本文主要介紹了vue-draggable實(shí)現(xiàn)拖拽表單的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05vue實(shí)現(xiàn)動態(tài)路由添加功能的簡單方法(無廢話版本)
ue動態(tài)路由(約定路由),聽起來好像很玄乎的樣子,但是你要是理解了實(shí)現(xiàn)思路,你會發(fā)現(xiàn)沒有想象中的那么難,下面這篇文章主要給大家介紹了關(guān)于vue實(shí)現(xiàn)動態(tài)路由添加功能的簡單方法,需要的朋友可以參考下2023-02-02vue前端實(shí)現(xiàn)表格數(shù)據(jù)增查改刪功能
增刪改查是我們寫項目百分之七十會遇到的代碼,下面這篇文章主要給大家介紹了關(guān)于vue前端實(shí)現(xiàn)表格數(shù)據(jù)增查改刪功能的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-05-05vue3+el-select實(shí)現(xiàn)觸底加載更多功能(ts版)
這篇文章主要給大家介紹了基于vue3和el-select實(shí)現(xiàn)觸底加載更多功能,文中有詳細(xì)的代碼示例,感興趣的同學(xué)可以借鑒參考下2023-07-07