实现预览图片上下滑动关闭效果


今天的项目任务中实现一个瀑布流,点击图片可以实现图片预览、左右切换效果。说干就干,下班时,提交完代码准备溜时,提出一个新需求,在预览图片时添加一个上下滑动取消预览的效果,唉,加吧,我爱加班。
这里主要记录一下实现该功能的关键步骤,如下:

一、页面结构

以下是页面结构内容,css样式及组件内容不在此赘述

<template>
  <div>
    <halo-dialog class="preview-image" :visible="visible" @cancel="close">
      <swiper zoom lazy class="swiper-outer" :current="swiperIndex" @swiper="onSwiper" @slideChange="changeIndex">
        <swiper-slide v-for="(item, key) in computedList" :key="item.key || key">
          <div
            class="swiper-zoom-container"
            @touchstart="getTouchstartY"
            @touchmove="getTouchmove"
            @touchend="touchEnd"
            :style="transformStyle"
          >
            <img :data-src="`${item.path}-w1242.jpg`" class="swiper-lazy" />
            <div class="swiper-lazy-preloader swiper-lazy-preloader-white"></div>
          </div>
        </swiper-slide>
      </swiper>
      <div class="close-outer" @click.stop="close">
        <img src="./images/close_icon.png" class="close" />
      </div>
    </halo-dialog>
  </div>
</template>

二、触摸事件概述

预览图片时,移动端界面通过触摸事件来判断是否滑动

事件名称描述是否包含 touches 数组
touchstart触摸开始,多点触控,后面的手指同样会触发
touchmove接触点改变,滑动时
touchend触摸结束,手指离开屏幕时

每个触摸事件都包括了三个触摸列表,每个列表里包含了对应的一系列触摸点(用来实现多点触控):

  1. touches:当前位于屏幕上的所有手指的列表。
  2. targetTouches:位于当前DOM元素上手指的列表。
  3. changedTouches:涉及当前事件手指的列表。

每个 Touch 对象包含的属性如下:

  1. clientX:触摸目标在视口中的x坐标。
  2. clientY:触摸目标在视口中的y坐标。
  3. identifier:标识触摸的唯一ID。
  4. pageX:触摸目标在页面中的x坐标。
  5. pageY:触摸目标在页面中的y坐标。
  6. screenX:触摸目标在屏幕中的x坐标。
  7. screenY:触摸目标在屏幕中的y坐标。
  8. target:触摸的DOM节点目标。

三、功能实现

<script>
export default {
	data() {
		return {
			startY: 0,	
		    startX: 0,
		    imgScale: 1,
		    touchAngle: 0,
		    moveY: 0,
		    moveX: 0,
		    transformStyle: {}
		}
	},
	methods: {
		getTouchstartY(e) {
	      if (e.targetTouches.length === 1) {
	       // 初始style
	        this.transformStyle = {
	          transition: ""
	        };
	        // 获取触摸目标在视口中的位置
	        this.startY = e.targetTouches[0].clientY;  
	        this.startX = e.targetTouches[0].clientX;
	      }
	    },
	    getTouchmove(e) {
	      if (this.prevent) {
	        e.preventDefault();
	      }
	      if (e.targetTouches.length === 1) {
	      	// 获取滑动的距离
	        this.moveY = e.targetTouches[0].clientY - this.startY;
	        this.moveX = e.targetTouches[0].clientX - this.startX;
	        // 设置图片缩放的大小
	        this.imgScale = 1 - Math.abs(this.moveY) / 500;
	
	        // 触摸滑动角度
	        this.touchAngle = Math.abs(this.moveY / this.moveX);
	
	        if (this.touchAngle > 1) {
	          this.transformStyle = {
	            transform: `translate(${this.moveX}px,${this.moveY}px) scale(${this.imgScale})`
	          };
	        }
	      }
	    },
	    touchEnd() {
		   if (this.touchAngle > 1) {
		   		// 如果触摸滑动的距离大于130px,就关闭图片,关闭弹窗
		        if (Math.abs(this.moveY) > 130) {
		          this.transformStyle = {
		            transform: "scale(0)",
		            transition: "all .5s"
		          };
		          setTimeout(() => {
		            this.close();
		          }, 200);
		        } else {
		          // 如果触摸滑动的距离未超过130px,实现图片还原
		          this.transformStyle = {
		            transform: "translateY(0) scale(1)",
		            transition: "all 0.2s"
		          };
		        }
		      }
		 }
	}
}
</script>

四、实现效果

动态效果图可以参照https://live.photoplus.cn/live/65097362?nw=live#/live
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E7iOGxtN-1630051019776)(图片地址)]

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值