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ù)盒子的大小、圖片的大小來計(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ù)圖片的寬高 ,以及盒子的大小來計(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-07
vue vite之LogicFlow安裝核心依賴及項(xiàng)目初始化詳解
這篇文章主要為大家介紹了vue vite之LogicFlow安裝核心依賴及項(xiàng)目初始化詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
vue-draggable實(shí)現(xiàn)拖拽表單的示例代碼
本文主要介紹了vue-draggable實(shí)現(xiàn)拖拽表單的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05
vue實(shí)現(xiàn)動態(tài)路由添加功能的簡單方法(無廢話版本)
ue動態(tài)路由(約定路由),聽起來好像很玄乎的樣子,但是你要是理解了實(shí)現(xiàn)思路,你會發(fā)現(xiàn)沒有想象中的那么難,下面這篇文章主要給大家介紹了關(guān)于vue實(shí)現(xiàn)動態(tài)路由添加功能的簡單方法,需要的朋友可以參考下2023-02-02
vue前端實(shí)現(xiàn)表格數(shù)據(jù)增查改刪功能
增刪改查是我們寫項(xiàng)目百分之七十會遇到的代碼,下面這篇文章主要給大家介紹了關(guān)于vue前端實(shí)現(xiàn)表格數(shù)據(jù)增查改刪功能的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-05-05
vue3+el-select實(shí)現(xiàn)觸底加載更多功能(ts版)
這篇文章主要給大家介紹了基于vue3和el-select實(shí)現(xiàn)觸底加載更多功能,文中有詳細(xì)的代碼示例,感興趣的同學(xué)可以借鑒參考下2023-07-07

