在项目开发中遇到一个需求:
1:用鼠标滚轮可对图片进行缩放处理
2:点击按钮可对图片进行缩放处理
3:可对图片进行拖拽处理
我在开发中通过自己实现与百度查看优秀的铁子进行了两种类型的使用
1:个人进行实现:
源码:文章来源:https://www.toymoban.com/news/detail-519207.html
<template>
<div class="pictureDetails">
<div class="pictureDetails-box">
<!-- 图片区 -->
<div class="box-img">
<div style="width: 100%" class="left" @mousewheel.prevent="rollImg">
<img :src="imgSrc" class="img" ref="imgDiv" :style="{ transform: 'scale(' + zoomD + ')' }"
@mousedown="move" />
</div>
<!-- 按钮 -->
<div class="Button-area">
<ol>
<li @click="zoomMax">
大
</li>
<li @click="zoomMin">
小
</li>
<li v-if="love" @click="btnLoveFlage">
未赞
</li>
<li v-else @click="btnLoveFlage">
已赞
<!-- <img src="@/assets/images/pictureDetails/Collection.png" alt="点赞icon"> -->
</li>
<li @click="downloadImg(imgSrc, '哇哈哈')
">
下载
</li>
</ol>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
zoomD: 1,
love: false,
imgSrc: 'https://img2.baidu.com/it/u=1395980100,2999837177&fm=253&fmt=auto&app=120&f=JPEG?w=1200&h=675', //横图
// imgSrc: 'https://img1.baidu.com/it/u=1518057857,2376515959&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1675530000&t=d847d2430e87d04936f7d07f38cf60c5', //竖图
}
},
created() {
//根据接口判断当前详情是否已经收藏
this.love = true;
},
mounted() {
},
methods: {
//移动demo
move(e) {
e.preventDefault();
// 获取元素
var personBox = document.querySelector(".left");
var img = document.querySelector(".img");
var x = e.pageX - img.offsetLeft;
var y = e.pageY - img.offsetTop;
// 添加鼠标移动事件
personBox.addEventListener("mousemove", move);
function move(e) {
img.style.left = e.pageX - x + "px";
img.style.top = e.pageY - y + "px";
}
// 添加鼠标抬起事件,鼠标抬起,将事件移除
img.addEventListener("mouseup", function () {
personBox.removeEventListener("mousemove", move);
});
// 鼠标离开父级元素,把事件移除
personBox.addEventListener("mouseout", function () {
personBox.removeEventListener("mousemove", move);
});
},
// 缩放图片
rollImg(e) {
let direction = e.deltaY > 0 ? 'down' : 'up'
if (direction === 'up') {
// 滑轮向上滚动
this.large();
} else {
// 滑轮向下滚动
this.Small();
}
},
//缩小按钮方法
zoomMin() {
this.Small();
},
//放大按钮方法
zoomMax() {
this.large();
},
//大
large() {
this.$nextTick(() => {
if (this.zoomD < 6) {
this.zoomD += 0.10
}
document.querySelector('.img').style.transform = `matrix(${this.zoomD}, 0, 0,${this.zoomD}, 0, 0)`
})
},
// 小
Small() {
this.$nextTick(() => {
if (this.zoomD > 0.3) {
this.zoomD -= 0.10
}
document.querySelector('.img').style.transform = `matrix(${this.zoomD}, 0, 0, ${this.zoomD}, 0, 0)`
})
},
//点击下载图片
downloadImg(url, name) {
let image = new Image();
image.setAttribute("crossOrigin", "anonymous");
image.src = url;
image.onload = () => {
let canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
let ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0, image.width, image.height);
canvas.toBlob((blob) => {
let url = URL.createObjectURL(blob);
this.download(url, name);
// 用完释放URL对象
URL.revokeObjectURL(url);
});
};
},
download(href, name) {
let eleLink = document.createElement("a");
eleLink.download = name;
eleLink.href = href;
eleLink.click();
eleLink.remove();
},
//点赞收藏
btnLoveFlage() {
this.love = this.love == true ? false : true;
console.log(this.love);
}
}
}
</script>
<style lang="scss" scoped>
.pictureDetails {
width: 100%;
height: auto;
background-color: #F3F1EE;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
.pictureDetails-box {
width: 1200px;
// height: 800px;
display: flex;
flex-direction: column;
.box-img {
width: 1200px;
height: 662px;
margin-bottom: 20px;
background: #DFDAD3;
position: relative;
.left {
position: absolute;
width: 660px;
height: 100%;
float: left;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
.img {
position: absolute;
/* top: 5px; */
/* left: 7px; */
// max-width: 923px;
// max-height: 460px;
cursor: move;
}
.Button-area {
width: 42px;
height: 200px;
// background-color: pink;
position: absolute;
right: -50px;
top: 0px;
ol {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
li {
width: 43px;
height: 42px;
background: #A58773;
cursor: pointer;
// padding: 8px 8px;
box-sizing: border-box;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
}
li:hover {
background: #634d3f;
}
}
}
}
}
}
</style>
效果:
2:通过借鉴他人优秀帖子所修改实现
源码:
<template>
<!-- 舆图库详情页 -->
<div class="mainPage">
<div class="watchMap">
<div class="imgBox" 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 class="Tools">
<div class="Tools-item" @click="imgScaleHandle(0.25)">
大
</div>
<div class="Tools-item" @click="imgScaleHandle(-0.25)">
小
</div>
<div class="Tools-item">
藏
</div>
<div class="Tools-item" @click="
downloadByBlob(
'https://img2.baidu.com/it/u=1395980100,2999837177&fm=253&fmt=auto&app=120&f=JPEG?w=1200&h=675',
'name'
)
">
下载
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
imageUrl:
"https://img2.baidu.com/it/u=1395980100,2999837177&fm=253&fmt=auto&app=120&f=JPEG?w=1200&h=675",
imgW: 0,
imgH: 0,
deg: 0,
top: 0,
left: 0,
scale: "scale(1)",
size: 0,
mousewheelevt: null,
};
},
mounted() {
//初始化图片
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);
},
beforeDestroy() {
//取消监听
this.$refs.maskBox.removeEventListener(
this.mousewheelevt,
this.wheelHandle
);
},
created() {
this.handleReset();
},
methods: {
/**
*
* 下載圖片
* **/
downloadByBlob(url, name) {
let image = new Image();
image.setAttribute("crossOrigin", "anonymous");
image.src = url;
image.onload = () => {
let canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
let ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0, image.width, image.height);
canvas.toBlob((blob) => {
let url = URL.createObjectURL(blob);
this.download(url, name);
// 用完释放URL对象
URL.revokeObjectURL(url);
});
};
},
download(href, name) {
let eleLink = document.createElement("a");
eleLink.download = name;
eleLink.href = href;
eleLink.click();
eleLink.remove();
},
/**
* 重置
*/
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();
},
/**
* 获取图片的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;
}
},
imgScaleHandle(zoom) {
this.size += zoom;
if (this.size < -0.5) {
this.size = -0.5;
}
this.scale = `scale(${1 + this.size}) rotateZ(${this.deg}deg)`;
},
/**
* 鼠标滚动 实现放大缩小
*/
wheelHandle(e) {
e.preventDefault();
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 lang="scss" scoped>
.world_map {
width: 1200px;
margin: 41px auto;
.name {
width: 95px;
margin: 0 auto;
font-size: 22px;
font-family: "st";
font-weight: bold;
color: pink;
line-height: 30px;
letter-spacing: 1px;
}
}
.watchMap {
width: 1200px;
height: 662px;
background: pink;
position: relative;
// overflow: hidden;
margin-left: 360px;
.imgBox {
width: 100%;
height: 100%;
overflow: hidden;
position: relative;
img {
cursor: move;
position: absolute;
}
}
.Tools {
width: 43px;
min-height: 100px;
position: absolute;
right: -50px;
top: 0;
user-select: none;
.Tools-item {
width: 100%;
height: 44px;
background: pink;
margin-bottom: 5px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
.Tools-item:hover{
background-color: red;
color: #fff;
}
}
}
</style>
效果:@韩桑文章来源地址https://www.toymoban.com/news/detail-519207.html
到了这里,关于vue项目实现图片缩放与拖拽功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!