Unity3d C# 实现一个基于UGUI的自适应尺寸图片查看器(含源码)

前言

Unity3d实现的数字沙盘系统中,总有一些图片或者图片列表需要点击后弹窗显示大图,这个弹窗在不同尺寸分辨率的图片查看处理起来比较麻烦,所以,需要图片能够根据容器的大小自适应地进行缩放,兼容不太尺寸下的横竖图的展示,这个背景下,考虑写一个公共的图片查看器,能通过接口调起展示图片,自动适配尺寸能自动判定高度或者宽度自适应。加入图片的平移和缩放功能,以鼠标为中心点缩放,查看图片细节。

效果

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实现

基于Unity3d自带的UGUI系统来实现,使用了DOTweenPro插件作为移动动画的实现,核心思路就是将图片根据显示区域和尺寸做高度和宽度的自适应,动态的计算高度和宽度进行设置。

单图查看器

根据之前的需求,就是对单张图片的预览,缩放、平移功能是基本操作,核心是自适应高宽的实现。
缩放使用了之前博客实现的“Unity3d UGUI以鼠标位置点为中心缩放图片”,其核心思路就是根据鼠标位置计算图片的轴心点和对应于轴心点保持图片不移动的位置信息,让后将这些数值动态的赋值给图片,最后根据滚轮前后赋值缩放值。
窗体和图片的拖拽平移使用了之前博客实现的“Unity3d C#实现UGUI的界面可拖拽移动和选中置顶等功能”,其核心思路是依托于EventTrigger组件,根据拖拽的事件(StartDrag,Draging等)和鼠标点击事件进行相关的界面的位置同步处理即可实现该功能。详情可以移步对应博客查看。

UI搭建

UI的搭建相对简单,主要是使用了Image和mask组件,用于图片显示和超出范围隐藏,同时新增了图片重置和关闭按钮,详情如下:
在这里插入图片描述

动画

构想的动画是通过移动、缩放和透明度动画,移动是通过点击图片或者按钮后,窗口从触发位置移动到屏幕中间,实现代码如下:

    /// <summary>/// 设置移入移出位置/// </summary>/// <param name="Sender">目标对象</param>private void SetMovePos(Transform Sender){ResetImage();if (Sender == null){WindTran.localPosition = MovePos = Vector3.zero;}else{WindTran.position = Sender.position;MovePos = WindTran.localPosition;}WindTran.DOLocalMove(Vector3.zero, scaleDura);}

而缩放的动画使用了DOScale来实现:

WindTran.DOScale(Vector3.one * initScale, scaleDura); //修改默认缩放

透明度动画是使用CanvasGroup组件来整体控制窗口:

cg.DOFade(1, 0.3f);

尺寸适应

尺寸的适应采用高宽比的思路,如果宽度比 比 高度比高就适配宽度,反之则适配高度:

float WidRate = sp.texture.width / ImgAreaSize.x; 
float HeightRate = sp.texture.height / ImgAreaSize.y; ;//Screen.height;if (WidRate >= HeightRate)   //适配宽度
{/*float Width = ImgAreaSize.x;float Height = (ImgAreaSize.x / sp.texture.width) * sp.texture.height ;*/showImgRect.sizeDelta = new Vector2(ImgAreaSize.x, (ImgAreaSize.x / sp.texture.width) * sp.texture.height);
}
else  //适配高度
{/*float Width = ImgAreaSize.y / sp.texture.height * sp.texture.width;float Height = ImgAreaSize.y;*/showImgRect.sizeDelta = new Vector2(ImgAreaSize.y / sp.texture.height * sp.texture.width, ImgAreaSize.y);
}

调起接口

接口申明如下:

    /// <summary>/// 接口,展示公共弹窗/// </summary>/// <param name="sp">预览的Sprite</param>/// <param name="tran">弹出的节点</param>
public void ShowImgWindow(Sprite sp, Transform tran = null)

传入预览的Sprite和弹出的节点(用于动画位置计算),即可调起窗口。

多图查看器

上面的单图查看器在使用起来有个问题,面对图片列表使用该功能时,多个图片查看操作较为繁琐,比如同一个Scroll View下的图片,查看起来需要点开、关闭、点开、关闭的操作,这种情况下需要支持多张图片,可以快速下一张上一张的操作。有此需求,就需要支持多图查看的功能。多图的UI在单图的基础上新增了两个上一张/下一张的按钮:
在这里插入图片描述

多图切换

多图的逻辑是接口处发送多张图片,调起多图查看器,这时候将多张图放入到列表(List)中点击上一张、下一张时候直接切换对应的图片即可。

nowIndex = idx;
if (!isImg)
{if (sprites == null || sprites.Count == 0 || idx < 0 || idx >= sprites.Count)return;showImg.sprite = sprites[nowIndex];float WidRate = sprites[nowIndex].texture.width / ImgAreaSize.x;float HeightRate = sprites[nowIndex].texture.height / ImgAreaSize.y; ;//Screen.height;if (WidRate >= HeightRate)   //适配宽度{showImgRect.sizeDelta = new Vector2(ImgAreaSize.x, (ImgAreaSize.x / sprites[nowIndex].texture.width) * sprites[nowIndex].texture.height);}else  //适配高度{showImgRect.sizeDelta = new Vector2(ImgAreaSize.y / sprites[nowIndex].texture.height * sprites[nowIndex].texture.width, ImgAreaSize.y);}NextBtn.SetActive(nowIndex < sprites.Count - 1);
}if (isImg)
{if (images == null || images.Count == 0 || idx < 0 || idx >= images.Count)return;showImg.sprite = images[nowIndex].sprite;float WidRate = images[nowIndex].sprite.texture.width / ImgAreaSize.x;float HeightRate = images[nowIndex].sprite.texture.height / ImgAreaSize.y; if (WidRate >= HeightRate)   //适配宽度{showImgRect.sizeDelta = new Vector2(ImgAreaSize.x, (ImgAreaSize.x / images[nowIndex].sprite.texture.width) * images[nowIndex].sprite.texture.height);}else  //适配高度{showImgRect.sizeDelta = new Vector2(ImgAreaSize.y / images[nowIndex].sprite.texture.height * images[nowIndex].sprite.texture.width, ImgAreaSize.y);}NextBtn.SetActive(nowIndex < images.Count - 1);
}LastBtn.SetActive(nowIndex > 0);
ResetImage();

大致逻辑如上图,因为需要兼容Image和RawImage组件所以使用了 List和List两个列表。

调起接口

常用接口是将图片的父节点传入,自动区分Image和RawImage组件:

    /// <summary>/// 接口,展示公共弹窗/// 传入图片列表的父节点,适用图片所有都父节点的一级子节点。/// </summary>/// <param name="parentTran">父节点</param>/// <param name="idx">图片的下标(默认0)</param>/// <param name="tran">弹出的节点</param>
public void ShowImgWindow(Transform parentTran, bool isTypeImg = true, int idx = 0, Transform tran = null)

调用代码如下:

ImgShowListWindMgr.instance?.ShowImgWindow(sender.transform.parent, true,GetNodeActiveIndex(sender.transform), sender.transform);

传入Image列表的接口:

    //接口,展示公共弹窗/// <summary>/// Image列表预览图片/// </summary>/// <param name="imgList">Image列表</param>/// <param name="idx">图片的下标(默认0)</param>/// <param name="tran">弹出的节点</param>
public void ShowImgWindow(List<Image> imgList, int idx = 0, Transform tran = null)

传入Sprite列表的接口:

//接口,展示公共弹窗
/// <summary>
///  Sprite列表预览图片
/// </summary>
/// <param name="spList"> Sprite列表</param>
/// <param name="idx">图片的下标(默认0)</param>
/// <param name="tran">弹出的节点</param>
public void ShowImgWindow(List<Sprite> spList, int idx = 0, Transform tran = null)

传入RawImage列表的接口:

//接口,展示公共弹窗
/// <summary>
/// RawImage 列表预览图片
/// </summary>
/// <param name="rimgList"> RawImage 列表预览图片</param>
/// <param name="idx">图片的下标(默认0)</param>
/// <param name="tran">弹出的节点</param>
public void ShowRawImgWindow(List<RawImage> rimgList, int idx = 0, Transform tran = null)

源码工程

https://download.csdn.net/download/qq_33789001/90036779

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

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

相关文章

DVWA 在 Windows 环境下的部署指南

目录预览 一、靶场介绍二、前置准备1. 环境准备2.靶场下载 三、安装步骤1.配置Phpstudy2.配置数据库3.配置DVWA4.登入DVWA靶场 四、参考链接 一、靶场介绍 DVWA 一共包含了十个攻击模块&#xff0c;分别是&#xff1a; Brute Force&#xff08;暴力&#xff08;破解&#xff…

微软企业邮箱:安全可靠的企业级邮件服务!

微软企业邮箱的设置步骤&#xff1f;如何注册使用烽火域名邮箱&#xff1f; 微软企业邮箱作为一款专为企业设计的邮件服务&#xff0c;不仅提供了高效便捷的通信工具&#xff0c;更在安全性、可靠性和功能性方面树立了行业标杆。烽火将深入探讨微软企业邮箱的多重优势。 微软…

使用UE5.5的Animator Kit变形器

UE5.5版本更新了AnimatorKit内置插件&#xff0c;其中包含了一些内置变形器&#xff0c;可以辅助我们的动画制作。 操作步骤 首先打开UE5.5&#xff0c;新建第三人称模板场景以便测试&#xff0c;并开启AnimatorKit组件。 新建Sequence&#xff0c;放入测试角色 点击角色右…

应用案例丨坤驰科技双通道触发采集实时FFT数据处理系统

双通道触发采集实时FFT数据处理系统 应用案例 双通道采集&#xff0c;每路通道需要2GSPS的采样率&#xff0c;每2毫秒采集一次&#xff0c;每次采集数据量为65536*2 Sample。采集的信号频率满足奈奎斯特采样定律。采集数据后&#xff0c;每路通道的数据均做运算以及FFT实时处理…

OGRE 3D----3. OGRE绘制自定义模型

在使用OGRE进行开发时,绘制自定义模型是一个常见的需求。本文将介绍如何使用OGRE的ManualObject类来创建和绘制自定义模型。通过ManualObject,开发者可以直接定义顶点、法线、纹理坐标等,从而灵活地构建各种复杂的几何体。 Ogre::ManualObject 是 Ogre3D 引擎中的一个类,用…

如何用Excel做数据可视化自动化报表?

作为一个经常需要做数据报表的人&#xff0c;我最常用的工具是Excel&#xff0c;对于我来说用Excel处理繁琐冗杂的数据并不难&#xff0c;但是我发现身边很多人用Excel做的数据报表非常的耗时&#xff0c;而且最后的成品也是难以直视&#xff0c;逻辑和配色等都非常的“灾难”。…

基于FPGA的SD NAND读写测试(图文并茂+源代码+详细注释)

本实验所使用的源代码已同步至个人主页的资源处&#xff0c;可供读者自行学习...... 什么是SD NAND&#xff1f; 1.SD NAND 卡介绍 SD NAND 卡是一种基于 NAND 闪存技术的存储设备&#xff0c;其外观和接口类似于标准的 SD 卡。它将 NAND 闪存芯片和必要的控制电路集成在一个小…

机器学习6-梯度下降法

梯度下降法 目的 梯度下降法(Gradient Descent)是一个算法&#xff0c;但不是像多元线性回归那样是一个具体做回归任务的算法&#xff0c;而是一个非常通用的优化算法来帮助一些机器学习算法求解出最优解的&#xff0c;所谓的通用就是很多机器学习算法都是用它&#xff0c;甚…

(0基础保姆教程)-JavaEE开课啦!--11课程(初识Spring MVC + Vue2.0 + Mybatis)-实验9

一、什么是Spring MVC&#xff1f; Spring MVC 是一个基于 Java 的 Web 框架&#xff0c;遵循 MVC 设计模式&#xff0c;用于构建企业级应用程序。它通过控制器(Controller)处理用户请求&#xff0c;模型(Model)处理业务逻辑&#xff0c;视图(View)展示数据&#xff0c;实现了请…

微前端-MicroApp

微前端即是由一个主应用来集成多个微应用&#xff08;可以不区分技术栈进行集成&#xff09; 下面是使用微前端框架之一 MicroApp 对 react微应用 的详细流程 第一步 创建主应用my-mj-app 利用脚手架 npx create-react-app my-mj-app 快速创建 安装 npm install --save rea…

知识库助手的构建之路:ChatGLM3-6B和LangChain的深度应用

ChatGLM3-6B和LangChain构建知识库助手 安装依赖库 使用pip命令安装以下库&#xff1a; pip install modelscope langchain0.1.7 chromadb0.5.0 sentence-transformers2.7.0 unstructured0.13.7 markdown3.0.0 docx2txt0.8 pypdf4.2.0依赖库简介&#xff1a; ModelScope&a…

shell(2)永久环境变量和字符串显位

shell&#xff08;2&#xff09;永久环境变量和字符串显位 声明&#xff01; 学习视频来自B站up主 ​泷羽sec​​ 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章 笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习…

Java实现IP代理池

文章目录 Java实现IP代理池一、引言二、构建IP代理池1、代理IP的获取2、代理IP的验证1. 导入必要的库2. 设置代理IP和端口3. 发起HTTP请求4. 检查请求结果5. 完整的验证方法 注意事项 三、使用IP代理池四、总结 Java实现IP代理池 一、引言 在网络爬虫或者需要频繁请求网络资源…

微服务保护和分布式事务

文章目录 一、微服务保护1.1 微服务保护方案&#xff1a;1.1.1 请求限流&#xff1a;1.1.2 线程隔离&#xff1a;1.1.3 服务熔断&#xff1a; 1.2 Sentinel&#xff1a;1.2.1 介绍和安装&#xff1a;1.2.2 微服务整合&#xff1a; 1.3 请求限流&#xff1a;1.4 线程隔离&#x…

后端 Java发送邮件 JavaMail 模版 20241128测试可用

配置授权码 依赖 <dependency><groupId>javax.mail</groupId><artifactId>javax.mail-api</artifactId><version>1.5.5</version> </dependency> <dependency><groupId>com.sun.mail</groupId><artifa…

MySQL安装与卸载(linux)

MySQL安装与卸载 MySQL8.0.26-安装1. 准备一台Linux服务器2. 下载Linux版MySQL安装包3. 上传MySQL安装包4. 创建目录,并解压5. 安装mysql的安装包6. 启动MySQL服务7. 查询自动生成的root用户密码8. 修改root用户密码9. 创建用户10. 并给root用户分配权限11. 重新连接MySQL MySQ…

设置ip和代理DNS的WindowsBat脚本怎么写?

今天分享一个我们在工作时&#xff0c;常见的在Windows中通过批处理脚本&#xff08;.bat 文件&#xff09;来设置IP地址、代理以及DNS 相关配置的示例&#xff0c;大家可以根据实际需求进行修改调整。 一、设置静态IP地址脚本示例 以下脚本用于设置本地连接&#xff08;你可…

施工车辆,工程车类型识别,可识别装载机,搅拌车,挖掘机,拉土车等,支持YOLO,COCO,VOC三种格式带标记

1338总图像数 数据集分割 训练组 87&#xff05; 1170图片 有效集 8% 112图片 测试集 4% 56图片 预处理 自动定向&#xff1a; 已应用 调整大小&#xff1a; 拉伸至 640x640 增强 每个训练示例的输出&#xff1a; 3 旋转&#xff1a; -15 至 15 之间 …

新版布谷直播软件源码开发搭建功能更新明细

即将步入2025年也就是山东布谷科技专注直播系统开发,直播软件源码出售开发搭建等业务第9年,山东布谷科技不断更新直播软件功能&#xff0c;以适应当前新市场环境下的新要求。山东布谷科技始终秉承初心&#xff0c;做一款符合广大客户需求的直播系统软件。支持广大客户提交更多个…

科技赋能:企业如何通过新技术提升竞争力的策略与实践

引言 在当今瞬息万变的商业环境中&#xff0c;科技的迅猛发展正在重新定义行业的游戏规则。无论是小型企业还是跨国巨头&#xff0c;都感受到数字化转型的迫切需求。过去&#xff0c;企业竞争力更多依赖于成本控制、资源调配或市场覆盖&#xff0c;而如今&#xff0c;新技术的引…