使用js实现类似微信图片查看器的功能,可以切换图片,实现图片的放大、缩小、旋转、平移和下载功能。直接上页面效果图。因为项目需求,使用react框架+electron封装成了桌面应用,作为单独的弹窗功能,在页面右上角添加窗口操作按钮。
1. 放大/缩小功能,可通过滚轮或点击底部按钮来实现
_large(num) {
let { scaling } = this.state;
scaling = Math.trunc(scaling) >= 10 ? 10 : scaling + num; // 缩放最大10倍
this.setState({
scaling
});
this._mouseEnterImg(scaling);
}
_small(num) {
let { scaling, moveX, moveY } = this.state;
scaling = scaling - num <= 0.1 ? 0.1 : scaling - num; // 缩放最小0.1倍
if (this.pointType === 'move') {
let n = Math.round((scaling - 1) / num);
if (moveX !== 0) {
moveX -= moveX / n;
}
if (moveY !== 0) {
moveY -= moveY / n;
}
} else {
moveX = 0;
moveY = 0;
}
this.setState({
scaling,
moveX,
moveY
});
this._mouseEnterImg(scaling);
}
2. 放大图片长宽超出最大值时,可以点击鼠标实现拖拽图片显示
_mouseDown = e => {
e.preventDefault();
const { scaling } = this.state;
if (this.pointType === 'default') return;
// 获取img-box img的宽度和高度
const boxW = document.body.clientWidth;
const boxH = document.body.clientHeight - 26 - 60;
const imgW = this.refImg.width * scaling;
const imgH = this.refImg.height * scaling;
let startX = e.clientX; // 鼠标按下的位置
let startY = e.clientY;
this.refImg.onmousemove = e => {
e.preventDefault();
let { moveX, moveY } = this.state;
const currentX = e.clientX;
const currentY = e.clientY;
let disX = currentX - startX; // 鼠标移动的像素 往右 往上是正数
let disY = currentY - startY;
if (imgW > boxW) {
if (disX > 0 && (imgW - boxW) / 2 - moveX * scaling > 0) {
// 往右走
moveX += disX / scaling;
if ((imgW - boxW) / 2 - moveX * scaling < 0) {
moveX = (imgW - boxW) / 2 / scaling;
}
} else if (disX < 0 && (imgW - boxW) / 2 + moveX * scaling > 0) {
// 往左走
moveX += disX / scaling;
if ((imgW - boxW) / 2 + moveX * scaling < 0) {
moveX = ((imgW - boxW) / 2 / scaling) * -1;
}
}
}
if (imgH > boxH) {
if (disY > 0 && (imgH - boxH) / 2 - moveY * scaling > 0) {
// 往下走
moveY += disY / scaling;
if ((imgH - boxH) / 2 - moveY * scaling < 0) {
moveY = (imgH - boxH) / 2 / scaling;
}
} else if (disY < 0 && (imgH - boxH) / 2 + moveY * scaling > 0) {
// 往上走
moveY += disY / scaling;
if ((imgH - boxH) / 2 + moveY * scaling < 0) {
moveY = ((imgH - boxH) / 2 / scaling) * -1;
}
}
}
startX = currentX;
startY = currentY;
this.setState({
moveX,
moveY
});
};
// 鼠标弹起停止移动
this.refImg.onmouseleave = () => {
this.refImg.onmousemove = null;
this.refImg.onmouseup = null;
};
this.refImg.onmouseup = () => {
this.refImg.onmousemove = null;
this.refImg.onmouseup = null;
};
};
3. 图片下载功能通过a标签download属性来实现
_download = () => {
let aD = document.createElement('a');
aD.href = this.refImg.src;
aD.download = `图片_${new Date().getTime() * Math.floor(Math.random() * 10000)}`;
aD.click();
};
4. 最后主要的render函数,其中Header组件为窗口操作按钮,添加css样式 -webkit-app-region: drag;让窗口可以拖动,如果不用electron封装,可以不用设置这个样式;Footer为底部操作按钮组件。