当前位置: 首页 > web >正文

『uniapp』自己实现手动图片列表滑动 + 图片手势缩放+ 图片点击缩放(详细图文注释)

目录

    • 预览效果
    • 思路分析
    • 完整代码
    • 总结


欢迎关注 『uniapp』 专栏,持续更新中
欢迎关注 『uniapp』 专栏,持续更新中

预览效果

在这里插入图片描述


思路分析

这个目前有点问题,就是因为监听触摸导致手机上有点卡顿,体验上不如uni-swiper

主要是为了双指缩放和点击缩放综合运用了movable-area和movable-view,抛砖引玉,仅供参考.

后续找机会优化,也期待评论区的朋友们提点建议.


完整代码

<template><view><!-- 通过定位来控制面板显示 --><view class="box" :style="widthStyle"><view class="bbox" :style="bboxStyle"><movable-area class="movable-area" v-for="(item, index) in localImageList" :style="widthStyle" :key="'key' + index"><movable-view @dblclick="dblclick(index)" @touchstart="handleTouchStart" @touchmove="handleTouchMove" @touchend="handleTouchEnd" @scale="scale" @change="handleMovableViewChange" animation="true" damping="200" friction="2" class="movable-view" direction="all" scale="true" scale-min="1" scale-max="4" :scale-value="scaleList[index]"><view style="padding: 12px; border-bottom: 1px solid #ccc"> 我是一个安装教程,假装我是pdf, </view><view style="height: 5px; background-color: beige"> </view><view>{{ imageListIndex + 1 }}</view><br /><image class="lookimg" :src="localImageList[index]" mode="widthFix"></image></movable-view></movable-area></view></view></view>
</template><script>export default {data() {return {// 开始和结束来记录左滑还是右滑,以及滑动距离touchStartX: 0,touchEndX: 0,changeText: '', // 操作moveX: 0, // 内部节点的x定位quickStartX: 0, // 快照scaleValue: 1, // 缩放倍数quickScale: 1, // 快照offset: 0, //偏移量isOffset: false, // 是否叠加偏移量//cscs: false,localImageList: [], //图片本地url列表imgNum: 1, //pdf页数picListIndex: '1/1', //当前图片索引pdfUrl: '', //文件urllanguage: '', //使用教程pdf语言isAndroid: true,imageListIndex: 0, //当前处于第几页isDisableTouch: false, //是否禁止滑动scaleList: new Array(16).fill(1),// scale: 1, // 图片放大倍数moveDirction: '', //移动方向changePageFlag: false, //minMoveLength: 50, //最小移动距离阈值xNow: 0, //当前x坐标 用于判断是否到边界startX: 0, //记录触摸开始时的screenWidth: 0,}},onLoad(option) {this.screenWidth = uni.getSystemInfoSync().screenWidththis.imgNum = 4this.picListIndex = '1/' + this.imgNumthis.localImageList = ['../../static/1.png','../../static/2.png','../../static/3.png','../../static/4.png','../../static/1.png','../../static/2.png','../../static/3.png','../../static/4.png','../../static/1.png','../../static/2.png','../../static/3.png','../../static/4.png','../../static/1.png','../../static/2.png','../../static/3.png','../../static/4.png','../../static/1.png','../../static/2.png','../../static/3.png','../../static/4.png','../../static/1.png','../../static/2.png','../../static/3.png','../../static/4.png','../../static/1.png','../../static/2.png','../../static/3.png','../../static/4.png']},computed: {},props: {isBack: {type: Boolean,default: true},titleSize: {type: String,default: '34'},titleColor: {type: String,default: '#D2D2D2'},background: {type: Object,default: () => {return {background: '#272729'}}}},methods: {//双击缩放dblclick(index) {if (this.scaleList[index] < 1.5) {this.$set(this.scaleList, index, 1.5);} else if (this.scaleList[index] < 2) {this.$set(this.scaleList, index, 2);} else if (this.scaleList[index] >= 2) {this.$set(this.scaleList, index, 1);}},reset() {// 切换面板重置数据this.moveX = 0this.quickStartX = 0this.quickScale = 1this.scaleValue = 1},scale(event) {// 缩放过程事件this.scaleValue = event.detail.scale},handleMovableViewChange(event) {// movable-view @change事件this.moveX = event.detail.x},// 触控开始handleTouchStart(event) {this.quickStartX = this.moveXthis.quickScale = this.scaleValuethis.touchStartX = event.touches[0].clientX},// 触控过程handleTouchMove(event) {// 是否叠加偏移量if (this.moveX == this.quickStartX && this.scaleValue == this.quickScale) {this.isOffset = true} else {this.isOffset = false}// 偏移量this.offset = event.touches[0].clientX - this.touchStartX},// 触控结束handleTouchEnd(event) {this.touchEndX = event.changedTouches[0].clientXthis.detectSwipeDirection()// 是否叠加偏移量this.isOffset = false},// 计算操作情况,判断是否要切换面板detectSwipeDirection() {let changeText = ''const touchDistance = this.touchEndX - this.touchStartX// 小于120像素的滑动不触发左右切换if (Math.abs(touchDistance) < 120) return// x快照和x定位不一致,证明非边界情况if (this.moveX != this.quickStartX) return// x快照和x定位不一致,证明是正在放大缩小if (this.scaleValue != this.quickScale) returnif (touchDistance > 0) {console.log('向右滑动')changeText = '向右滑动'// 到底了if (this.imageListIndex == 0) returnthis.imageListIndex--// 快照和数据重置this.reset()} else if (touchDistance < 0) {console.log('向左滑动')changeText = '向左滑动'// 到底了if (this.imageListIndex == this.localImageList.length - 1) returnthis.imageListIndex++// 快照和数据重置this.reset()}console.log('滑动距离:', Math.abs(touchDistance))this.changeText = changeText + '滑动距离:' + Math.abs(touchDistance)}},computed: {widthStyle() {const width = `${this.screenWidth}px`return {width}},bboxStyle() {// console.log(' uni.getSystemInfoSync().screenWidth', uni.getSystemInfoSync().screenWidth)const isOffset = this.isOffsetconst width = `${100 * this.localImageList.length}vw`let base = -1 * this.screenWidth * this.imageListIndexconst left = this.isOffset ? base + this.offset + 'px' : base + 'px'const transition = 'left 0.1s'// 返回一个对象,包含计算得到的样式return {width,left,transition}}}}
</script>
<style scoped>.box {height: 100vh;position: relative;overflow: hidden;}.bbox {display: flex;left: 0;position: relative;height: 100vh;/* background-color: bisque; */}.movable-view {display: flex;flex-direction: column;align-items: center;justify-content: center;height: 100%;width: 100%;position: relative;}.movable-area {height: 100%;/* background-color: blue; */}.lookimg {height: 100%;width: 100%;display: block;position: relative;top: 0px;left: 0px;border: 0rpx solid #d6d6d7;box-shadow: 0 -3rpx 5rpx 1rpx rgba(0, 0, 0, 0.1), 0 2rpx 5rpx 1rpx rgba(0, 0, 0, 0.1);/* margin-top: 15%; */}
</style>

总结

大家喜欢的话,给个👍,点个关注!给大家分享更多计算机专业学生的求学之路!

版权声明:

发现你走远了@mzh原创作品,转载必须标注原文链接

Copyright 2024 mzh

Crated:2024-4-1

欢迎关注 『uniapp』 专栏,持续更新中
欢迎关注 『uniapp』 专栏,持续更新中
『未完待续』


http://www.xdnf.cn/news/8912.html

相关文章:

  • 分布式消息中间件设计与实现
  • Android自定义View学习总结
  • 【机器人】复现 Embodied-Reasoner 具身推理 | 具身任务 深度推理模型 多模态场景 长远决策 多轮互动
  • Python Day33
  • GO 语言中变量的声明
  • Python中字典(dict)知识详解应用
  • 非接触式互连:当串扰是您的朋友时
  • NumPy 数组属性
  • 英语科研词汇现象及语言演变探讨
  • Rephrase and Respond :让大语言模型为自己提出更优的问题
  • Disruptor—3.核心源码实现分析二
  • 第十八章:数据治理之数据质量:“数据质量”不仅仅和“数据质量”有关
  • 数据库故障排查指南技术文章
  • 用 Python 构建自动驾驶的实时通信系统:让车辆“交流”起来!
  • 【Python 元祖】 Tuple 核心知识点
  • no cmake_c_compiler could be found.
  • SQL每日一练(7)
  • 动态规划-53.最大子数组和-力扣(LeetCode)
  • java 动态代理
  • 计算机系统简介(一)
  • 使用keil5实现RA4M2按键控制LED的状态
  • java学习记录——MyBatisPlus
  • 结合GIS谈谈Java面向对象(OOP,Object-Oriented Programming)的核心思想
  • redis集群配置
  • 20250525-更新 Anaconda 和 `pip` 中的库包
  • 嵌入式项目之QT页面制作
  • 英伟达破局1000 Token/秒!Llama 4以光速重塑AI推理边界
  • 为什么hash函数能减少哈希冲突
  • C++函数入门:void与int详解
  • 前端融球效果原理讲解+具体实现+模糊度,对比度基础教学