基于touch.js手势库+zepto.js插件开发图片查看器(滑动、缩放、双击缩放)

首先讲一下所需工具:

  • touch.js:一款轻量级的移动端手势库,用于实现图片的缩放、滑动等手势操作;
  • Zepto.js:一款轻量级的JavaScript库,可用于DOM操作、事件绑定等常见操作。

如果你已经准备好了这些工具,接下来我们就可以开始制作基于touch.js和Zepto.js的图片查看器了。

步骤一、创建HTML结构

首先我们需要先创建出HTML结构,这个结构比较简单,主要就是一个包含图片的div容器。

<div class="image-viewer">
  <img src="example.jpg" alt="example image">
</div>

其中的class可以用于样式设置和JS操作。

步骤二、调用touch.js和Zepto.js库

我们需要在HTML文件中引入touch.js和zepto.js库,代码如下:

<script src="./path/to/touch.js"></script>
<script src="./path/to/zepto.js"></script>

引入之后我们就可以使用库中的方法和函数了。

步骤三、添加基本样式

若要使图片查看器显示正常,我们需要为其添加一些基本样式,主要是设置图片容器的宽度、高度等。

.image-viewer {
  width: 100%;
  height: 100%;
  overflow: hidden;
  position: relative;
}

.image-viewer img {
  max-width: 100%;
  max-height: 100%;
  display: block;
  margin: auto;
}

以上代码主要功能为设置图片容器为相对定位和隐藏溢出部分,同时设置图片为居中显示。

步骤四、编写js代码实现手势操作

接下来我们就开始编写JavaScript代码来实现手势操作。

首先,我们需要给图片容器添加touchstart、touchmove、touchend事件,用于在触摸时实现滑动、缩放等操作。代码如下:

const imgViewer = document.querySelector('.image-viewer');

let initScale = 1; // 初始缩放比例
let curScale = 1; // 当前缩放比例
let prevDistance = 0; // 前一时刻的两个手指的距离
let startX, startY, moveX, moveY, lastMoveX = 0, lastMoveY = 0; // 手指的初始位置和移动距离
let isSingleTap = false; // 是否为单击事件
let isDoubleTap = false; // 是否为双击事件
let lastTapTime = null; // 上一次触摸结束的时间

let isTouchStart = false; // 是否触摸开始

imgViewer.addEventListener('touchstart', function(e) {
  e.preventDefault();
  isTouchStart = true;

  // 判断是否为双击事件
  let currentTapTime = Date.now();
  if (lastTapTime !== null && currentTapTime - lastTapTime < 300) {
    isDoubleTap = true;
  } else {
    isSingleTap = true;
    lastTapTime = currentTapTime;
  }

  // 获取初始位置
  startX = e.touches[0].pageX;
  startY = e.touches[0].pageY;

  // 重置相关值
  lastMoveX = moveX;
  lastMoveY = moveY;
  prevDistance = 0;
});

imgViewer.addEventListener('touchmove', function(e) {
  e.preventDefault();

  // 获取移动距离
  moveX = e.touches[0].pageX - startX + lastMoveX;
  moveY = e.touches[0].pageY - startY + lastMoveY;

  if (e.touches.length > 1) { // 处理双指操作
    isSingleTap = false;

    let distance = Math.sqrt(
      (e.touches[1].pageX - e.touches[0].pageX) ** 2 +
      (e.touches[1].pageY - e.touches[0].pageY) ** 2);

    if (prevDistance !== 0) {
      curScale = curScale * (distance / prevDistance);
      imgViewer.style.transform = `scale(${curScale}) translate(${moveX}px, ${moveY}px)`;
    }
    prevDistance = distance;
  } else { // 处理单指操作
    isDoubleTap = false;
    curScale = initScale;
    imgViewer.style.transform = `scale(${curScale}) translate(${moveX}px, ${moveY}px)`;
  }
});

imgViewer.addEventListener('touchend', function(e) {
  e.preventDefault();
  if (isSingleTap) {
    // 处理单击事件
  } else if (isDoubleTap) {
    // 处理双击事件
  }

  // 重置相关值
  prevDistance = 0;
  isSingleTap = false;
  isDoubleTap = false;

  // 是否触摸结束
  isTouchStart = false;
});

以上代码主要处理了以下事件:

  • touchstart:获取触摸开始的位置,并判断是否为单击或双击事件;
  • touchmove:获取触摸滑动的距离,并实现图片的移动和缩放操作;
  • touchend:处理单击和双击事件,同时重置相关变量。

步骤五、实现双击操作和缩放操作

实现双击操作主要需要在touchstart、touchend事件中对isDoubleTap进行判断,并在touchstart事件中记录下当前时间,用于判断两次触摸间隔是否小于300ms。若是,则视为双击。

imgViewer.addEventListener('touchstart', function(e) {
  // 判断是否为双击事件
  let currentTapTime = Date.now();
  if (lastTapTime !== null && currentTapTime - lastTapTime < 300) {
    isDoubleTap = true;
  } else {
    isSingleTap = true;
    lastTapTime = currentTapTime;
  }

  // ...
});

imgViewer.addEventListener('touchend', function(e) {
  // 处理双击事件
  if (isDoubleTap) {
    if (curScale === initScale) {
      // 如果当前缩放比例为1,则双击放大
      curScale = 2;
      imgViewer.style.transform = `scale(${curScale}) translate(${moveX}px, ${moveY}px)`;
    } else {
      // 如果当前缩放比例大于1,则双击缩小至初始比例
      curScale = initScale;
      imgViewer.style.transform = `scale(${curScale}) translate(0, 0)`;
    }
  }

  // ...
});

实现缩放操作其实就是在touchmove事件中对curScale进行计算,并实时更新图片的缩放比例和位置。

imgViewer.addEventListener('touchmove', function(e) {
  // 获取移动距离
  moveX = e.touches[0].pageX - startX + lastMoveX;
  moveY = e.touches[0].pageY - startY + lastMoveY;

  if (e.touches.length > 1) { // 处理双指操作
    // ...

    if (prevDistance !== 0) {
      curScale = curScale * (distance / prevDistance);
      imgViewer.style.transform = `scale(${curScale}) translate(${moveX}px, ${moveY}px)`;
    }

    // ...
  } else { // 处理单指操作
    // ...

    curScale = initScale;
    imgViewer.style.transform = `scale(${curScale}) translate(${moveX}px, ${moveY}px)`;

    // ...
  }
});

步骤六、完善单击事件和完整代码

最后,我们需要完善单击事件,通过判断触摸开始和触摸结束的时间间隔来区分单击和长按事件。代码如下:

imgViewer.addEventListener('touchstart', function(e) {
  // 记录触摸开始的时间
  touchStartTime = Date.now();
  // ...
});

imgViewer.addEventListener('touchend', function(e) {
  // 记录触摸结束的时间
  touchEndTime = Date.now();
  // 判断是否为单击事件或长按事件
  if (isTouchStart && touchEndTime - touchStartTime <= 350) {
    // 处理单击事件
  } else if (isTouchStart && touchEndTime - touchStartTime > 350) {
    // 处理长按事件
  }
  // ...
});

完整代码如下:

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>图片查看器</title>
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
  <style type="text/css">
    .image-viewer {
      width: 100%;
      height: 100%;
      overflow: hidden;
      position: relative;
    }

    .image-viewer img {
      max-width: 100%;
      max-height: 100%;
      display: block;
      margin: auto;
    }
  </style>
</head>

<body>
  <div class="image-viewer">
    <img src="example.jpg" alt="example image">
  </div>
  <script src="./path/to/touch.js"></script>
  <script src="./path/to/zepto.js"></script>
  <script type="text/javascript">
    const imgViewer = document.querySelector('.image-viewer');

    let initScale = 1; // 初始缩放比例
    let curScale = 1; // 当前缩放比例
    let prevDistance = 0; // 前一时刻的两个手指的距离
    let startX, startY, moveX, moveY, lastMoveX = 0, lastMoveY = 0; // 手指的初始位置和移动距离
    let isSingleTap = false; // 是否为单击事件
    let isDoubleTap = false; // 是否为双击事件
    let lastTapTime = null; // 上一次触摸结束的时间

    let isTouchStart = false; // 是否触摸开始
    let touchStartTime, touchEndTime; // 触摸开始和结束的时间

    imgViewer.addEventListener('touchstart', function(e) {
      e.preventDefault();

      // 判断是否为双击事件
      let currentTapTime = Date.now();
      if (lastTapTime !== null && currentTapTime - lastTapTime < 300) {
        isDoubleTap = true;
      } else {
        isSingleTap = true;
        lastTapTime = currentTapTime;
      }

      // 记录触摸开始的位置
      startX = e.touches[0].pageX;
      startY = e.touches[0].pageY;

      // 重置相关值
      lastMoveX = moveX;
      lastMoveY = moveY;
      prevDistance = 0;

      // 记录触摸开始的事件
      touchStartTime = Date.now();

      isTouchStart = true;
    });

    imgViewer.addEventListener('touchmove', function(e) {
      e.preventDefault();

      // 获取移动距离
      moveX = e.touches[0].pageX - startX + lastMoveX;
      moveY = e.touches[0].pageY - startY + lastMoveY;

      if (e.touches.length > 1) { // 处理双指操作
        isSingleTap = false;

        let distance = Math.sqrt(
          (e.touches[1].pageX - e.touches[0].pageX) ** 2 +
          (e.touches[1].pageY - e.touches[0].pageY) ** 2);

        if (prevDistance !== 0) {
          curScale = curScale * (distance / prevDistance);
          imgViewer.style.transform = `scale(${curScale}) translate(${moveX}px, ${moveY}px)`;
        }
        prevDistance = distance;
      } else { // 处理单指操作
        isDoubleTap = false;
        curScale = initScale;
        imgViewer.style.transform = `scale(${curScale}) translate(${moveX}px, ${moveY}px)`;
      }
    });

    imgViewer.addEventListener('touchend', function(e) {
      e.preventDefault();

      // 记录触摸结束的时间
      touchEndTime = Date.now();

      if (isSingleTap) {
        // 处理单击事件
        if (isTouchStart && touchEndTime - touchStartTime <= 350) {
          // 处理单击事件
        }
      } else if (isDoubleTap) {
        // 处理双击事件
        if (curScale === initScale) {
          // 如果当前缩放比例为1,则双击放大
          curScale = 2;
          imgViewer.style.transform = `scale(${curScale}) translate(${moveX}px, ${moveY}px)`;
        } else {
          // 如果当前缩放比例大于1,则双击缩小至初始比例
          curScale = initScale;
          imgViewer.style.transform = `scale(${curScale}) translate(0, 0)`;
        }
      }

      // 重置相关值
      prevDistance = 0;
      isSingleTap = false;
      isDoubleTap = false;

      // 是否触摸结束
      isTouchStart = false;
    });
  </script>
</body>

</html>

以上就是基于touch.js和zepto.js的图片查看器的完整攻略,其中包含了双击、滑动、缩放等多个手势操作,可以应用于各类移动端H5网站和APP开发中。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:基于touch.js手势库+zepto.js插件开发图片查看器(滑动、缩放、双击缩放) - Python技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • Android webview与js交换JSON对象数据示例

    为了让大家更好地理解“Android webview与js交换JSON对象数据”的过程,我将详细讲解一下: 1. 什么是Android WebView Android WebView是一个使用Android内置WebKit引擎实现的组件,可以让开发者在Android应用程序中嵌入Web页面。 它提供了多种方法来加载HTML内容,包括从Web服务器加载内容,也…

    JavaScript 2023年5月27日
    00
  • 分享javascript计算时间差的示例代码

    为了分享 JavaScript 计算时间差的示例代码,我将会提供以下步骤: 1. 引入 moment.js 库 moment.js 是一个流行的 JavaScript 日期和时间处理库,提供方便的日期和时间格式化、计算和解析功能。可以通过在 HTML 头部添加以下代码,引入 moment.js 库: <script src="https://…

    JavaScript 2023年5月27日
    00
  • javascript引用类型之时间Date和数组Array

    接下来我会给你详细讲解JavaScript引用类型之时间Date和数组Array的完整攻略。 JavaScript引用类型之时间Date 在JavaScript中,时间是以Date对象的形式存在的。我们可以使用Date对象表示一个日期,也可以使用它来执行与日期相关的操作。 创建Date对象 创建一个Date对象的方式有以下三种: 使用new Date()构造…

    JavaScript 2023年5月27日
    00
  • 关于javascript模块加载技术的一些思考

    关于 JavaScript 模块加载技术的一些思考 什么是模块加载技术? JavaScript 作为一门基于对象的语言,可以使用函数和对象等抽象概念来组织代码。在应用程序越来越庞大的情况下,我们需要将代码分割成多个模块,这样既方便代码管理,也有利于代码的可重用性。模块加载技术就是将模块引入到应用程序中,以便让应用程序能够使用模块提供的功能。 JavaScri…

    JavaScript 2023年6月11日
    00
  • js运动事件函数详解

    JS运动事件函数详解 在JS中,事件函数是编写交互逻辑的重要部分。其中,运动事件函数可以实现对象的平移、缩放、旋转等效果。本文将详细讲解JS中的运动事件函数,包括常见的函数、使用注意事项和两个示例说明。 常见的运动事件函数 以下是JS常用的运动事件函数: setInterval():重复调用一个函数或执行一段代码,间隔一定的时间(以毫秒为单位)。 setTi…

    JavaScript 2023年5月27日
    00
  • javascript对HTML字符转义与反转义

    下面是关于JavaScript对HTML字符转义与反转义的完整攻略。 什么是HTML字符转义与反转义? HTML字符转义指的是将HTML代码中的特殊字符转换成它们对应的实体编码,这是为了避免这些字符被解析成HTML代码而产生错误。例如,把小于号 < 转换成 &lt;。 HTML字符反转义指的是将实体编码转换回原始的字符,以便正确地显示内容。 J…

    JavaScript 2023年5月20日
    00
  • Javascript 闭包详解及实例代码

    JavaScript 闭包详解及实例代码 什么是闭包? 在 JavaScript 中,闭包是一种特殊的函数,它可以访问在它创建时外部作用域的变量和参数,即使这些变量和参数在函数调用时已经不存在了。 简单来说,闭包就是“函数和函数所能够访问的外部变量的一个共同体”。 闭包的运作原理 在 JavaScript 中,每次创建一个函数,都会同时创建一个作用域链(sc…

    JavaScript 2023年6月10日
    00
  • js前端实现word excel pdf ppt mp4图片文本等文件预览

    实现Word、Excel、PDF、PPT、MP4、图片等文件预览,可以通过前端技术结合第三方库来实现。 使用第三方库Viewer.js实现文件预览 Viewer.js是一个基于JavaScript的图像和文档查看器,它可以让你轻松地查看各种文件类型,包括图片、PDF、SVG、Microsoft Word、Microsoft Excel、Microsoft P…

    JavaScript 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部