本文将使用原生JS一步步实现完整的图片预览和查看功能,无任何第三方依赖。
具备功能:
- 图片拖拽:图片放大后可以随意拖动图片。
- 滚轮缩放:支持鼠标滚轮对图片进行放大或缩小。
- 居中显示:自动计算图片位置和缩放比例,使图片适配窗口并居中。
- 关闭预览:点击关闭按钮关闭预览。
使用方法,直接将js放在程序中,在需要预览的图片上写一个点击事件,触发点击事件的时候将图片路径网络路径,base64都可以,没什么好说的,代码直接放下面。
示例如下
function openImagePreview(imgurl) {
// 接收图片路径
if (!imgurl) return;
const max = 20;
const scale = 0.08;
//
const box = document.createElement("div");
box.style.cssText = "position: fixed;top:0;left:0;z-index: 10000000000;background-color: rgba(0,0, 0, 0.3);width:" + (document.documentElement.clientWidth) + "px;height:" + (document.documentElement.clientHeight) + "px;border: 1px solid #000000;overflow: hidden;cursor: grab;";
const img = document.createElement("img");
img.style.cssText = "position: absolute;width:0;object-fit: contain;user-select: none;-webkit-user-drag: none;user-select: none;-moz-user-select: none;-webkit-user-select: none;-ms-user-select: none;";
img.src = imgurl;
img.title = "预览";
const close = document.createElement("img");
close.src = "/images/icon/gbpic.png"; //关闭图片 ,自己找一个
close.style.cssText = "position: absolute;top:20px;right:20px;width:20px;height:20px";
close.onclick = () => {
document.body.removeChild(box);
}
box.append(img);
box.append(close);
document.body.append(box);
img.onload = function () {
const imgRatio = img.naturalWidth / img.naturalHeight; //图片横纵比
const boxRatio = box.clientWidth / box.clientHeight; //容器横纵比
if (imgRatio > boxRatio) {
const scale = box.clientWidth / img.naturalWidth;
img.style.width = '800px'; //长度填充
img.style.height = img.naturalHeight * scale; //高度自适应
img.style.top = Math.ceil((box.clientHeight - img.clientHeight) / 2) + "px";//位置居中
img.style.left = Math.ceil((box.clientWidth - img.clientWidth) / 2) + "px";//位置居中
} else {
const scale = box.clientHeight / img.naturalHeight;
img.style.height = box.clientHeight;//高度填充
img.style.width = '800px';//长度自适应
img.style.top = Math.ceil((box.clientHeight - img.clientHeight) / 2) + "px";//位置居中
img.style.left = Math.ceil((box.clientWidth - img.clientWidth) / 2) + "px";//位置居中
}
};
// 缩放操作
box.onwheel = (event) => {
event.preventDefault(); //关闭默认事件
const center_x = event.clientX;
const center_y = event.clientY;
const wheelDelta = event.deltaY;
const top_d = center_y - img.offsetTop;
const left_d = center_x - img.offsetLeft;
if (wheelDelta > 0) {//缩小
let modifyHeight = img.clientHeight * (1 - scale);
let modifyWidth = img.clientWidth * (1 - scale);
if (modifyHeight * max > img.naturalHeight) { //只在比例范围内,放缩
img.style.height = modifyHeight + 'px';
img.style.width = modifyWidth + 'px';
img.style.top = center_y - top_d * (1 - scale);
img.style.left = center_x - left_d * (1 - scale);
} else {
}
} else {//放大
let modifyHeight = img.clientHeight * (1 + scale);
let modifyWidth = img.clientWidth * (1 + scale);
if (modifyHeight < img.naturalHeight * max) { //只在比例范围内,放缩
img.style.height = modifyHeight + 'px';
img.style.width = modifyWidth + 'px';
img.style.top = center_y - top_d * (1 + scale);
img.style.left = center_x - left_d * (1 + scale);
} else {
}
}
}
//拖拽操作
const drag = {
status: false,
lastX: null,
lastY: null
}
box.onmousedown = (event) => {
if (event.button === 0) {
document.onmousemove = (event) => {
if (drag.status) {
let mx = event.clientX - drag.lastX
let my = event.clientY - drag.lastY
drag.lastX = event.clientX
drag.lastY = event.clientY
let top = img.offsetTop + my
let left = img.offsetLeft + mx
img.style.left = getRange(left, img.clientWidth - 10, box.clientWidth - 10) + 'px';
img.style.top = getRange(top, img.clientHeight - 10, box.clientHeight - 10) + "px";
}
}
document.onmouseup = (event) => {
if (event.button === 0) {
drag.status = false
document.onmousemove = null
document.onmouseup = null
}
}
drag.status = true
drag.lastX = event.clientX
drag.lastY = event.clientY
}
}
const getRange = (actual, limita, limitb) => {
if (actual < -limita) {
return -limita;
} else if (actual > limitb) {
return limitb;
}
return actual;
}
}