原生JS使用类实现图片拖拽,缩放等功能

该代码定义了一个Viewer类,用于在DOM元素内创建一个图片查看器。它包含构造函数,处理窗口resize事件,鼠标drag和wheel事件来实现图片移动和缩放。Viewer类还提供了设置图片URL、更新渲染和清理图片的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在需要展示图片的dom元素内生效

   const viewer = new Viewer(Htmlelement);

export class Viewer {
  dom;
  container;
  image;

  scale = 0.5;

  width = 0;
  height = 0;
  scaleWidth = 100;
  sacleHeight = 100;
  top = 0;
  left = 0;

  mouseX = 0;
  mouseY = 0;
  startX = 0;
  startY = 0;

  imageX = 0;
  imageY = 0;

  drag = false;

  constructor(dom) {
    console.log(dom);
    const width = dom.offsetWidth;
    const height = dom.offsetHeight;
    console.log({ width, height });
    const container = document.createElement("div");

    container.style.width = "100%";
    container.style.height = "100%";
    container.style.background = "gainsboro";
    container.style.position = "relative";
    container.style.overflow = "hidden";

    dom.appendChild(container);
    this.width = width;
    this.height = height;
    this.container = container;
    this.dom = dom;

    // resize
    window.addEventListener("resize", () => {
      this.resize();
    });

    // addevemt
    container.addEventListener("mousedown", (e) => {
      this.startX = e.clientX;
      this.startY = e.clientY;
      this.drag = true;
    });
    container.addEventListener("mousemove", (e) => {
      this.mouseX = e.clientX;
      this.mouseY = e.clientY;
    });
    container.addEventListener("mouseup", () => {
      this.drag = false;
      if (this.image) {
        console.log(this.image.style.left);
        this.imageY += this.top;
        this.imageX += this.left;
      }
    });

    container.addEventListener("mouseleave", () => {
      this.drag = false;
      if (this.image) {
        this.imageY += this.top;
        this.imageX += this.left;
      }
    });

    // 滚轮缩放
    container.addEventListener("wheel", (e) => {
      e.preventDefault(); // 阻止事件冒泡

      // 通过event.deltaY判断滚动方向
      if (e.deltaY < 0) {
        if (this.scale < 3) this.setScale(this.scale + 0.1);
      } else if (e.deltaY > 0) {
        if (this.scale > 0.3) this.setScale(this.scale - 0.1);
      }
    });
    const tick = () => {
      this.render();
      requestAnimationFrame(tick);
    };
    tick();

    this.setUrl(
      "https://img.js.design/assets/img/6235db02441fff2959ff0525.jpg"
    );
  }

  // 更新图片位置
  render() {
    if (this.drag) {
      this.left = this.mouseX - this.startX;
      this.top = this.mouseY - this.startY;

      this.image.style.top = this.imageY + this.top + "px";
      this.image.style.left = this.imageX + this.left + "px";
    }
  }

  // window resize
  resize() {
    this.width = this.dom.offsetWidth;
    this.height = this.dom.offsetHeight;
  }

  // 更换图片
  setUrl(url) {
    if (this.image) {
      this.claenImage();
    }
    const image = document.createElement("img");
    image.src = url;
    let top = this.top;
    let left = this.left;
    console.log(this);
    image.style.display = "block";
    image.style.width = this.scaleWidth + "%";
    image.style.height = this.sacleHeight + "%";
    image.style.position = "absolute";
    image.style.top = top + "px";
    image.style.left = left + "px";
    image.style.scale = this.scale;

    image.addEventListener("dragstart", function (event) {
      event.preventDefault();
      // 可以在此添加其他逻辑
    });

    this.image = image;
    this.container.appendChild(image);
  }

  // 重置所有属性
  claenImage() {
    this.container.removeChild(this.image);
    this.image = null;
    this.scale = 0.5;

    this.width = 0;
    this.height = 0;
    this.scaleWidth = 100;
    this.sacleHeight = 100;
    this.top = 0;
    this.left = 0;

    this.mouseX = 0;
    this.mouseY = 0;
    this.startX = 0;
    this.startY = 0;

    this.imageX = 0;
    this.imageY = 0;

    this.drag = false;
  }
  setScale(n) {
    this.scale = n;
    if (this.image) {
      this.image.style.scale = this.scale;
    }
  }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

鸢_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值