前端利用js做一个图片预览功能

本文将使用原生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;
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木子“

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值