uniapp 做一个查看图片的组件,图片可缩放移动

news2024/9/20 15:38:36

因为是手机端,所以需要触摸可移动,双指放大缩小。

首先在components里建个组件

查看图片使用 uni-popup 弹窗

要注意 transform的translate和scale属性在同一标签上不会一起生效

移动就根据触摸效果进行偏移图片

缩放就根据双指距离的变大变小进行缩放

<template>
	<view>
		<uni-popup style="z-index: 99998;" ref="showImage" type="center">
			<view :style="{'transform':'translate('+x+'px,'+y+'px)'}">
				<img
					:style="{'transform':'scale(' + scale +')','height': height + 'px'}"
					@touchstart="touchstart"
					@touchmove="touchmove"
					@touchend="touchend"
					@touchcancel="touchcancel"
					mode="aspectFit"
					:src="src"></img>
			</view>
			<view class="closePopup" @click="close">
				<uni-icons type="closeempty" size="32" color="#fff"></uni-icons>
			</view>
		</uni-popup>
	</view>
</template>

<script>
	export default {
		name:"selectImage",
		data() {
			return {
				height: 0,
				src: '',
				x: 0,
				y:0,
				clientX: 0,
				clientY: 0,
				moveX: 0,
				moveY: 0,
				touchType: 0, // 0为单指触摸  1为双指
				// 初始双指距离
				distance: 0,
				// 初始缩放比例
				scale: 1
			};
		},
		created() {
			const me = this
			uni.getSystemInfo({
				success(res) {
					// 默认图片高度占屏幕一半展示
					me.height = res.windowHeight / 2
				}
			})
		},
		methods: {
			// 获取两点距离
			getDistance (point1, point2) {
				const x = point1.clientX - point2.clientX
				const y = point1.clientY - point2.clientY
				return Math.sqrt(x*x + y*y)
			},
			// 触摸开始
			touchstart (e) {
				// 当触摸事件为一个时
				if (e.touches.length === 1) {
					// 记录开始触摸位置
					this.clientX = e.changedTouches[0].clientX
					this.clientY = e.changedTouches[0].clientY
					this.touchType = 0
				} else if (e.touches.length === 2) {
					// 双指进行放大缩小操作
					this.touchType = 1
					// 获取双指距离
					this.distance = this.getDistance(e.touches[0], e.touches[1])
				}
			},
			// 触摸移动中
			touchmove (e) {
				// 当触摸事件为一个时
				if (this.touchType === 0) {
					// 记录移动的距离 
					const moveX = e.changedTouches[0].clientX - this.clientX
					const moveY = e.changedTouches[0].clientY - this.clientY
					// 最终偏移距离为初始偏移距离+当前偏移距离
					this.x = this.moveX + moveX
					this.y = this.moveY + moveY
				} else if (this.touchType === 1) {
					// 双指进行放大缩小操作
					if (e.touches.length === 2) {
						// 获取移动后的双指距离
						const le = this.getDistance(e.touches[0], e.touches[1])
						// 最终放大 缩小效果为 初始放大缩小比例 * 当前放大缩小比例
						const bl = le / this.distance
						const scale = this.scale * bl
						this.scale = scale > 0.1 ? scale : 0.1
						// 随着移动将开始的位置重置 不然会一次性放很大 或者缩很小,不好控制
						this.distance = le
					}
				}
			},
			// 触摸结束
			touchend (e) {
				// 当触摸事件为一个时
				if (this.touchType === 0) {
					// 记录最终移动距离
					const moveX = e.changedTouches[0].clientX - this.clientX
					const moveY = e.changedTouches[0].clientY - this.clientY
					// 最终偏移距离为初始偏移距离+当前偏移距离
					this.x = this.moveX + moveX
					this.y = this.moveY + moveY
					// 当前偏移距离设置为当前位置
					this.moveX = this.x
					this.moveY = this.y
				} else if (this.touchType === 1) {
					// 当双指松开后
					console.log(e)
				}
			},
			// 因电话等打断时触发
			touchcancel (e) {
				if (this.touchType === 0) {
					this.x = 0
					this.y = 0
				} else {
					this.clientX = 0
					this.clientY = 0
					this.moveX = 0
					this.moveY = 0
					this.touchType = 0 // 0为单指触摸  1为双指
					// 初始双指距离
					this.distance = 0
					// 初始缩放比例
					this.scale = 1
				}
			},
			open () {
				this.$refs.showImage.open()
			},
			close () {
				this.x = 0
				this.src = ''
				this.y = 0
				this.clientX = 0
				this.clientY = 0
				this.moveX = 0
				this.moveY = 0
				this.touchType = 0 // 0为单指触摸  1为双指
				// 初始双指距离
				this.distance = 0
				// 初始缩放比例
				this.scale = 1
				this.$refs.showImage.close()
			}
		}
	}
</script>

<style>
	.closePopup {
		position: fixed;
		top: 40px;
		right: 40px;
		width: 50px;
		height: 50px;
		text-align: center;
		line-height: 50px;
		z-index: 99999;
	}
</style>

外面组件调用时引用或者全局注册后使用

外面图片上加个点击事件

 @click="look(url)"

方法直接调用组件open方法就OK了。

look (url) {
				this.$refs.showImg.src = url
				this.$refs.showImg.open()
			},

效果图:

---------------查看-------------------------------移动------------------------------缩放

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2130828.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端练习小项目 —— 养一只电子蜘蛛

前言&#xff1a;在学习完JavaScript之后&#xff0c;我们就可以使用JavaScript来实现一下好玩的效果了&#xff0c;本篇文章讲解的是如何纯使用JavaScript来实现一个网页中的电子蜘蛛。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-C…

2.3.1 协程设计原理与汇编实现coroutine

LINUX 精通 7 day23 20240908 晚19&#xff1a;25 - 21:30 课程链接地址 2.3.1 协程设计原理与汇编实现coroutine 目的 协程不是某种语言特有的&#xff0c;lua&#xff0c;go都有 ntyco 是king老师自己写的 原语操作&#xff1a;“原语操作”通常指的是在编程或计算机科学中…

Android 12系统源码_窗口管理(八)WindowConfiguration的作用

前言 在Android系统中WindowConfiguration这个类用于管理与窗口相关的设置&#xff0c;该类存储了当前窗口的显示区域、屏幕的旋转方向、窗口模式等参数&#xff0c;应用程序通过该类提供的信息可以更好的适配不同的屏幕布局和窗口环境&#xff0c;以提高用户体验。 一、类定…

性能测试的复习2-jmeter的搭建、使用、参数化

通过网盘分享的文件&#xff1a;性能测试共享文件 链接: https://pan.baidu.com/s/1A4Nc8C5Xp6qxQ5QFtecK8g?pwds73c 提取码: s73c 1、性能测试工具 2、jmeter环境搭建 3、jmeter的基本使用 4、jmeter的参数化

strncpy函数的使用和模拟实现

目录 1.头文件 2.strncpy函数功能 2.1情况二&#xff1a; 3.strncpy函数&#xff08;模拟实现&#xff09; 方源一把抓住VS2022&#xff0c;催动春秋产的气息&#xff0c;顷刻炼化&#xff01; 1.头文件 strncpy函数的使用需要包括头文件<string.h> #include<string…

Windows系统好用软件推荐

uTools uTools官网&#xff1a;https://u.tools/download/ 功能介绍&#xff1a; 内置许多有用的插件、快速打开应用、复制图片保存等

4457E/4457F/4457G/4457K数字示波器

KEYSIGHT是德 4457E/4457F/4457G/4457K数字示波器 4457系列数字示波器共4个产品型号&#xff0c;产品带宽从1GHz到4GHz&#xff0c;采样率10GSa/s、20GSa/s&#xff0c;垂直分辨率8bit&#xff0c;存储深度2Gpts&#xff0c;最快波形捕获率120万个波形/秒&#xff0c;独创的An…

LIN帧显隐性电平和字节传输顺序理解

&#x1f345; 我是蚂蚁小兵&#xff0c;专注于车载诊断领域&#xff0c;尤其擅长于对CANoe工具的使用&#x1f345; 寻找组织 &#xff0c;答疑解惑&#xff0c;摸鱼聊天&#xff0c;博客源码&#xff0c;点击加入&#x1f449;【相亲相爱一家人】&#x1f345; 玩转CANoe&…

干耳屎硬掏不出来怎么办?质量最好的可视挖耳勺推荐

干耳朵的朋友都会有这样子的困扰&#xff0c;耳朵中的耳屎太硬挖不出来。用铁耳勺去挖会疼&#xff0c;还容易因为操作不当弄伤耳膜。而用棉签掏耳&#xff0c;只有越推越进去。所以当耳屎弄不出来是可以用专业的工具来挖取。市面上的可视挖耳勺通过内窥镜观察耳道中的情况。但…

电脑文件被删如何找回?选它,文件恢复又快又全面!

在我们的日常工作和生活中&#xff0c;文件是无比重要的存在。它可能是您精心撰写的报告&#xff0c;可能是珍贵的照片回忆&#xff0c;也可能是多年积累的工作资料。然而&#xff0c;有时一个不小心&#xff0c;文件可能就被我们删除了&#xff0c;那种焦急和无奈想必您也曾体…

解锁阿尔茨海默病(AD)靶点密码,开启靶向治疗新篇章

前 言&#xff1a; 阿尔茨海默病&#xff08;AD&#xff09;是一种严重的神经退行性疾病&#xff0c;多发于高龄人群&#xff0c;主要表现为记忆、思维、分析判断、视空间辨认、情绪等障碍。从实验室到临床应用的过程充满挑战。阿尔茨海默症新型疗法的开发主要聚焦于靶向Aβ、…

Percona Toolkit 神器全攻略(性能类)

Percona Toolkit 神器全攻略&#xff08;性能类&#xff09; Percona Toolkit 神器全攻略系列共八篇&#xff0c;前文回顾&#xff1a; 前文回顾Percona Toolkit 神器全攻略Percona Toolkit 神器全攻略&#xff08;实用类&#xff09;Percona Toolkit 神器全攻略&#xff08;配…

STM32+FATFS+SD卡+RTC(生成.CSV格式文件)

一、简介 实验目的&#xff1a;在SD卡上挂载文件系统&#xff0c;实时记录压力传感器采集到的数据&#xff1b;且在表格第一排记录采集时间&#xff1b; 因为前面文章包含了除RTC之外的所有的代码&#xff0c;此文章只放RTC代码。 二、工程源码 RTC.c #include "sys.h…

人工智能|集成学习——混合专家模型 (MoE)

随着 Mixtral 8x7B (announcement, model card) 的推出&#xff0c;一种称为混合专家模型 (Mixed Expert Models&#xff0c;简称 MoEs) 的 Transformer 模型在开源人工智能社区引起了广泛关注。在本篇博文中&#xff0c;我们将深入探讨 MoEs 的核心组件、训练方法&#xff0c;…

arcgisPro绘制平行线、垂直线段

1、绘制一条线 2、点击【创建要素】按钮&#xff0c;选择线&#xff0c;点一个点后&#xff0c;将鼠标移至需要对其的线上&#xff0c;并右击&#xff0c;选择【平行】 3、移动一段距离后&#xff0c;完成绘制&#xff0c;可得到一条平行线 4、得到平行线 5、绘制垂直线&#x…

一文读懂:区块链的原理、技术、应用领域

引言 在当今数字化时代&#xff0c;区块链技术已经成为全球范围内备受瞩目的话题。从金融到供应链&#xff0c;从物联网到数字身份&#xff0c;区块链正在以惊人的速度渗透到各个行业&#xff0c;并在重塑着我们的社会和经济格局。 区块链最初因其作为比特币背后技术的而引起…

OrionX vGPU研发测试场景下最佳实践之SSH模式

开发机场景概述 目前很多企业在做AI开发的场景时&#xff0c;对GPU资源的管理都是非常简单粗暴的。他们大多都是以开发小组为管理单位、由运维以台为单位分配给开发工程师使用。而在AI开发中涉及开发的场景和测试的场景&#xff0c;很多是将开发测试甚至训练任务都放在一起来使…

<<编码>> 第 11 章 逻辑门电路--门电路 示例电路

作为门电路的继电器开关电路 info::操作说明 鼠标单击开关切换开合状态 primary::在线交互操作链接 https://cc.xiaogd.net/?startCircuitLinkhttps://book.xiaogd.net/code-hlchs-examples/assets/circuit/code-hlchs-ch11-06-relay-as-gate.txt 作为反相器的继电器开关电路 …

EPON光模块介绍

EPON光模块在依靠光纤网络实现快速可靠的数据传输、增强带宽能力和提高网络效率的过程中发挥着至关重要的作用。在这篇文章中&#xff0c;我们将深入研究EPON光模块的基本概念、各种类型、优点和局限性&#xff0c;全面了解它们在现代电信中的重要性。 EPON光模块的定义 EPON…

ZYNQ 入门笔记(二):动态时钟

文章目录 1 概述1.1 DRP1.2 AXI4-Lite 2 示例2.1 单时钟输出2.2 多时钟输出 3 参考文档 1 概述 Clocking Wizard 可通过配置内部寄存器动态调整输出频率&#xff0c;配置接口可选 DRP 或 AXI4-Lite&#xff0c;其中 AXI4-Lite 实际上是对 DRP 接口的封装 1.1 DRP 通过 DRP 接…