Vue2 实现图片的拖拽缩放旋转
Posted Web_boom
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue2 实现图片的拖拽缩放旋转相关的知识,希望对你有一定的参考价值。
本文是基于vue2 实现图片的拖拽、旋转、鼠标滚动放大缩小等功能。
效果图
分步骤实现
在这里看下 拖拽、旋转、缩放的几个方法
1.获取图片的实际宽高
getImgSize(url) return new Promise((resolve, reject) => let imgObj = new Image();imgObj.src = url;imgObj.onload = () => resolve(width: imgObj.width,height: imgObj.height,);;);
,
2.根据盒子的大小、图片的大小来计算 要显示多大的图片
async initImage() if (!this.imageUrl) return;let width, height = await this.getImgSize(this.imageUrl);// 设置原始图片的大小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;,
在这里主要是根据图片的宽高 ,以及盒子的大小来计算 盒子中展示多大的图片,将图片按照比例缩放后展示到盒子中。
3.拖拽图片
主要是监听@mousedown
事件
onmousedownHandle(e) const that = this;this.$refs.maskBox.onmousemove = function (el) const ev = el || window.event; // 阻止默认事件ev.preventDefault();that.left += ev.movementX;that.top += ev.movementY;;this.$refs.maskBox.onmouseup = function () // 鼠标抬起时将操作区域的鼠标按下和抬起事件置为null 并初始化that.$refs.maskBox.onmousemove = null;that.$refs.maskBox.onmouseup = null;;if (e.preventDefault) e.preventDefault(); else return false;
,
4. 旋转图片
handleRotate() this.deg += 90;if (this.deg >= 360) this.deg = 0;this.size = 0;this.scale = `scale(1) rotateZ($this.degdeg)`;
,
5.监听鼠标的滚动,进行缩放图片
在 mounted() 中监听鼠标的滚动事件
mounted() // 兼容火狐浏览器this.mousewheelevt = /Firefox/i.test(navigator.userAgent)? "DOMMouseScroll" : "mousewheel";// 为空间区域绑定鼠标滚轮事件 =》 处理函数是wheelHandle// 如果你监听了window的scroll或者touchmove事件,你应该把passive设置为true,这样滚动就会流畅很多this.$refs.maskBox.addEventListener(this.mousewheelevt, this.wheelHandle, passive:true);
,
处理鼠标的滚动事件
wheelHandle(e) // 兼容性处理 => 火狐浏览器判断滚轮的方向是属性 detail,谷歌和ie浏览器判断滚轮滚动的方向是属性 wheelDeltaconst ev = e || window.event;// dir = -dir; // dir > 0 => 表示的滚轮是向上滚动,否则是向下滚动 => 范围 (-120 ~ 120)const dir = ev.detail ? ev.detail * -120 : ev.wheelDelta;//滚动的数值 / 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.degdeg)`;
,
页面销毁的时候 注意要取消鼠标的监听事件
beforeDestroy() //取消监听this.$refs.maskBox.removeEventListener(this.mousewheelevt,this.wheelHandle,passive:true);
,
以上就是主要实现功能的方法
完整代码
<template><div class="home"><div class="btn-area"><button @click="switchImgHandle(1)">竖图</button><button @click="switchImgHandle(2)">横图</button><button @click="handleRotate">旋转</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";// 为空间区域绑定鼠标滚轮事件 =》 处理函数是wheelHandle// 如果你监听了window的scroll或者touchmove事件,你应该把passive设置为true,这样滚动就会流畅很多this.$refs.maskBox.addEventListener(this.mousewheelevt, this.wheelHandle, passive:true);,beforeDestroy() //取消监听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);// 设置原始图片的大小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;,/** * 旋转 */handleRotate() this.deg += 90;if (this.deg >= 360) this.deg = 0;this.size = 0;this.scale = `scale(1) rotateZ($this.degdeg)`;,/** * 图片的缩放 *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.degdeg)`;,/** * 重置 */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();,/** * 鼠标滚动 实现放大缩小 */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;//滚动的数值 / 2000 => 表示滚动的比例,用此比例作为图片缩放的比例this.imgScaleHandle(dir / 2000);,/** * 处理图片拖动 */onmousedownHandle(e) const that = this;this.$refs.maskBox.onmousemove = function (el) const ev = el || window.event; // 阻止默认事件ev.preventDefault();that.left += ev.movementX;that.top += ev.movementY;;this.$refs.maskBox.onmouseup = function () // 鼠标抬起时将操作区域的鼠标按下和抬起事件置为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>
最后
整理了一套《前端大厂面试宝典》,包含了html、CSS、javascript、HTTP、TCP协议、浏览器、VUE、React、数据结构和算法,一共201道面试题,并对每个问题作出了回答和解析。
有需要的小伙伴,可以点击文末卡片领取这份文档,无偿分享
部分文档展示:
文章篇幅有限,后面的内容就不一一展示了
有需要的小伙伴,可以点下方卡片免费领取
微信小程序的拖拽缩放和旋转手势
在开发中,有时会遇到像App中的手势那样的效果,下面就仿照App实现了一下。
wxml部分:
<view class="touch-container">
<view class="msg">{{msg}}</view>
<image
class="img"
src="{{src}}"
style="width: {{width}}rpx; height: {{height}}rpx; left: {{left}}rpx; top: {{top}}rpx; transform: translate(-50%, -50%) scale({{ scale }}) rotate({{ rotate }}deg);"
bindload="bindload"
catchtouchstart="touchstart"
catchtouchmove="touchmove"
catchtouchend="touchend"
></image>
</view>
wxss:
page {
width: 100%;
height: 100%;
background: #ffffff;
}
.touch-container {
width: 100%;
height: 100%;
padding-top: 0.1px;
}
.msg {
width: 100%;
height: 60rpx;
line-height: 60rpx;
text-align: center;
font-size: 30rpx;
color: #666666;
}
.img {
position: absolute;
width: 690rpx;
height: 300rpx;
transform-origin: center center;
}
js部分:
var canOnePointMove = false
var onePoint = {
x: 0,
y: 0
}
var twoPoint = {
x1: 0,
y1: 0,
x2: 0,
y2: 0
}
Page({
data: {
msg: '',
src: 'http://img01.taopic.com/150508/318763-15050PU9398.jpg',
width: 0,
height: 0,
left: 375,
top: 600,
scale: 1,
rotate: 0
},
// 关闭上拉加载
onReachBottom: function() {
return
},
bindload: function(e) {
var that = this
var width = e.detail.width
var height = e.detail.height
if (width > 750) {
height = 750 * height / width
width = 750
}
if (height > 1200) {
width = 1200 * width / height
height = 1200
}
that.setData({
width: width,
height: height
})
},
touchstart: function(e) {
var that = this
if (e.touches.length < 2) {
canOnePointMove = true
onePoint.x = e.touches[0].pageX * 2
onePoint.y = e.touches[0].pageY * 2
}else {
twoPoint.x1 = e.touches[0].pageX * 2
twoPoint.y1 = e.touches[0].pageY * 2
twoPoint.x2 = e.touches[1].pageX * 2
twoPoint.y2 = e.touches[1].pageY * 2
}
},
touchmove: function(e){
var that = this
if (e.touches.length < 2 && canOnePointMove) {
var onePointDiffX = e.touches[0].pageX * 2 - onePoint.x
var onePointDiffY = e.touches[0].pageY * 2 - onePoint.y
that.setData({
msg: '单点移动',
left: that.data.left + onePointDiffX,
top: that.data.top + onePointDiffY
})
onePoint.x = e.touches[0].pageX * 2
onePoint.y = e.touches[0].pageY * 2
}else if (e.touches.length > 1) {
var preTwoPoint = JSON.parse(JSON.stringify(twoPoint))
twoPoint.x1 = e.touches[0].pageX * 2
twoPoint.y1 = e.touches[0].pageY * 2
twoPoint.x2 = e.touches[1].pageX * 2
twoPoint.y2 = e.touches[1].pageY * 2
// 计算角度,旋转(优先)
var perAngle = Math.atan((preTwoPoint.y1 - preTwoPoint.y2)/(preTwoPoint.x1 - preTwoPoint.x2))*180/Math.PI
var curAngle = Math.atan((twoPoint.y1 - twoPoint.y2)/(twoPoint.x1 - twoPoint.x2))*180/Math.PI
if (Math.abs(perAngle - curAngle) > 1) {
that.setData({
msg: '旋转',
rotate: that.data.rotate + (curAngle - perAngle)
})
}else {
// 计算距离,缩放
var preDistance = Math.sqrt(Math.pow((preTwoPoint.x1 - preTwoPoint.x2), 2) + Math.pow((preTwoPoint.y1 - preTwoPoint.y2), 2))
var curDistance = Math.sqrt(Math.pow((twoPoint.x1 - twoPoint.x2), 2) + Math.pow((twoPoint.y1 - twoPoint.y2), 2))
that.setData({
msg: '缩放',
scale: that.data.scale + (curDistance - preDistance) * 0.005
})
}
}
},
touchend: function(e) {
var that = this
canOnePointMove = false
}
})
json部分:
"navigationBarTitleText": "识别手势",
"navigationBarTextStyle":"black",
"navigationBarBackgroundColor": "#FFF",
"disableScroll": true
以上是关于Vue2 实现图片的拖拽缩放旋转的主要内容,如果未能解决你的问题,请参考以下文章