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

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

相关文章:

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

前言 Unity3d实现的数字沙盘系统中&#xff0c;总有一些图片或者图片列表需要点击后弹窗显示大图&#xff0c;这个弹窗在不同尺寸分辨率的图片查看处理起来比较麻烦&#xff0c;所以&#xff0c;需要图片能够根据容器的大小自适应地进行缩放&#xff0c;兼容不太尺寸下的横竖图…...

【es6进阶】vue3中的数据劫持的最新实现方案的proxy的详解

vuejs中实现数据的劫持,v2中使用的是Object.defineProperty()来实现的&#xff0c;在大版本v3中彻底重写了这部分&#xff0c;使用了proxy这个数据代理的方式&#xff0c;来修复了v2中对数组和对象的劫持的遗留问题。 proxy是什么 Proxy 用于修改某些操作的默认行为&#xff0…...

w~视觉~3D~合集3

我自己的原文哦~ https://blog.51cto.com/whaosoft/12538137 #SIF3D 通过两种创新的注意力机制——三元意图感知注意力&#xff08;TIA&#xff09;和场景语义一致性感知注意力&#xff08;SCA&#xff09;——来识别场景中的显著点云&#xff0c;并辅助运动轨迹和姿态的预测…...

IT服务团队建设与管理

在 IT 服务团队中&#xff0c;需要明确各种角色。例如系统管理员负责服务器和网络设备的维护与管理&#xff1b;软件工程师专注于软件的开发、测试和维护&#xff1b;运维工程师则保障系统的稳定运行&#xff0c;包括监控、故障排除等。通过清晰地定义每个角色的职责&#xff0…...

一文学习开源框架OkHttp

OkHttp 是一个开源项目。它由 Square 开发并维护&#xff0c;是一个现代化、功能强大的网络请求库&#xff0c;主要用于与 RESTful API 交互或执行网络通信操作。它是 Android 和 Java 开发中非常流行的 HTTP 客户端&#xff0c;具有高效、可靠、可扩展的特点。 核心特点 高效…...

自研芯片逾十年,亚马逊云科技Graviton系列芯片全面成熟

在云厂商自研芯片的浪潮中&#xff0c;亚马逊云科技无疑是最早践行这一趋势的先驱。自其迈出自研芯片的第一步起&#xff0c;便如同一颗石子投入平静的湖面&#xff0c;激起了层层涟漪&#xff0c;引领着云服务和云上算力向着更高性能、更低成本的方向演进。 早在2012年&#x…...

Stable Diffusion 3 部署笔记

SD3下载地址&#xff1a;https://huggingface.co/stabilityai/stable-diffusion-3-medium/tree/main https://huggingface.co/spaces/stabilityai/stable-diffusion-3-medium comfyui 教程&#xff1a; 深度测评&#xff1a;SD3模型表现如何&#xff1f;实用教程助你玩转Stabl…...

微信小程序WXSS全局样式与局部样式的使用教程

微信小程序WXSS全局样式与局部样式的使用教程 引言 在微信小程序的开发中,样式的设计与实现是提升用户体验的关键部分。WXSS(WeiXin Style Sheets)作为微信小程序的样式表语言,不仅支持丰富的样式功能,还能通过全局样式与局部样式的灵活运用,帮助开发者构建美观且易于维…...

Docker 部署 MongoDB

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f343; vue-uniapp-template &#x1f33a; 仓库主页&#xff1a; GitCode&#x1f4ab; Gitee &#x1f…...

Unity图形学之法线贴图原理

1.正常贴图&#xff1a;RGBA 4通道 每个通道取值范围 0-255 贴图里面取值是 0-1 2.法线贴图&#xff1a;法线怎么存入正常贴图的过程 每个通道里面存储的是一个向量(x,y,z,w) 通常我们会对应xyzw为rgba 存储值的范围也是0-1向量的取值范围是 -1到1法线怎么存入正常贴图的过程&…...

爬虫开发(5)如何写一个CSDN热门榜爬虫小程序

笔者 綦枫Maple 的其他作品&#xff0c;欢迎点击查阅哦~&#xff1a; &#x1f4da;Jmeter性能测试大全&#xff1a;Jmeter性能测试大全系列教程&#xff01;持续更新中&#xff01; &#x1f4da;UI自动化测试系列&#xff1a; SeleniumJava自动化测试系列教程❤ &#x1f4da…...

JVM系列之OOM观测准备

OOM, 全称 “Out Of Memory”&#xff0c;即内存用完的意思。JVM 因为没有足够的内存来为对象分配空间并且垃圾回收器也已经没有空间可回收时&#xff08;可分配内存大于需要分配的内存&#xff09;, 就会抛出 java.lang.OutOfMemoryError。在实际的生产应用中&#xff0c;一旦…...

Qt | 开发技能提升档次哈

点击上方"蓝字"关注我们 01、Creator常用快捷键 >>> F1 查看帮助 F2 跳转到函数定义 Shift+F2 声明和定义之间切换 F3 查找下一个 F4 头文件和源文件之间切换 Ctrl+1 欢迎模式 Ctrl+2 编辑模…...

D79【 python 接口自动化学习】- python基础之HTTP

day79 requests模块发送请求 学习日期&#xff1a;20241125 学习目标&#xff1a;http定义及实战 -- requests模块进行get请求带参数&requests模块进行post请求 学习笔记&#xff1a; requests模块进行get请求 import requestsparams{"shouji":"130999…...

C++【日志模块中的writer类】前文中 循环队列用法

用到前文中的循环队列模板 /* ** File name: LogWriter.h ** Author: ** Date: 2024-11-4 ** Brief: 日志写入类 ** Note: 日志写入类&#xff0c;负责将日志写入文件和连接客户端。 ** Copyright (C) 1392019713qq.com All rights reserve…...

Linux:文件管理(一)——文件描述符fd

目录 一、文件基础认识 二、C语言操作文件的接口 1.> 和 >> 2.理解“当前路径” 三、相关系统调用 1.open 2.文件描述符 3.一切皆文件 4.再次理解重定向 一、文件基础认识 文件 内容 属性。换句话说&#xff0c;如果在电脑上新建了一个空白文档&#xff0…...

【C++初阶】第3课—类和对象(类的默认成员函数)

文章目录 1. 类的默认成员函数2. 构造函数3. 拷贝构造函数3.1 传值传参3.2 传值返回3.3 深拷贝和浅拷贝3.4 总结 4. 析构函数5. 赋值运算符重载5.1 运算符重载5.2 赋值运算符重载5.3 日期类的实现 6. 取地址运算符重载6.1 const 成员函数6.2 取地址运算符重载 1. 类的默认成员函…...

uni-app初学笔记:文件路径与作用

components:可复用的组件pages:页面&#xff08;可见/不可见&#xff09;static:静态资源&#xff0c;存放图片视频等 &#xff08;相当于vue项目的 assets&#xff09;mainjs:Vue初始化入口文件App.vue:应用配置&#xff0c;用来配置App全局样式以及监听pages.json :配置页面路…...

小程序-使用 iconfont 图标库报错:Failed to load font

官方默认可以忽略此错误&#xff0c;在清除缓存后首次刷新会显示此错误&#xff0c;重新渲染错误消失 解决方法&#xff1a; 在 iconfont 图标库选择项目设置 选中 Base64 保存&#xff0c;重新点击链接 -> 复制代码到项目中 操作步骤&#xff1a;...

【计网】自定义协议与序列化(一) —— Socket封装于服务器端改写

&#x1f30e; 应用层自定义协议与序列化 文章目录&#xff1a; Tcp协议Socket编程 应用层简介 序列化和反序列化       重新理解read/write/recv/send及tcp的全双工       Socket封装       服务器端改写 &#x1f680;应用层简介 我们程序员写的一个个解决…...

速度革命:esbuild如何改变前端构建游戏 (1)

什么是 esbuild&#xff1f; esbuild 是一款基于 Go 语言开发的 JavaScript 构建打包工具&#xff0c;以其卓越的性能著称。相比传统的构建工具&#xff08;如 Webpack&#xff09;&#xff0c;esbuild 在打包速度上有着显著的优势&#xff0c;能够将打包速度提升 10 到 100 倍…...

大语言模型---什么是注意力机制?LlaMA 中注意力机制的数学定义

摘要 注意力机制&#xff08;Attention Mechanism&#xff09;是一种在深度学习和人工智能中广泛使用的技术&#xff0c;旨在使模型在处理信息时能够重点关注重要的部分&#xff0c;从而提升任务的效率和精度。它最初应用于自然语言处理&#xff08;NLP&#xff09;&#xff0…...

LSA详情与特殊区域

LSA是构成LSDB的重要原材料&#xff0c;在OSPF中发挥很大作用。 报文 通用头部 LS age&#xff1a;LSA寿命&#xff0c;0-3600s Options&#xff1a;可选项 LS type&#xff1a;LSA类型&#xff0c;三要素之一 Link State ID&#xff1a;LSAID 三要素之一 Advertising Ro…...

Python爬虫能处理动态加载的内容吗?

Python爬虫确实可以处理动态加载的内容。动态加载的内容通常是通过JavaScript在客户端执行&#xff0c;这意味着当网页首次加载时&#xff0c;服务器返回的HTML可能并不包含最终用户看到的内容。相反&#xff0c;JavaScript代码会在页面加载后从服务器请求额外的数据&#xff0…...

Spring Boot Web应用开发:数据访问

数据访问是Web应用的关键部分&#xff0c;Spring Boot简化了这一流程&#xff0c;特别是通过集成Java Persistence API (JPA) 来实现数据持久化。以下是如何在Spring Boot中配置数据源、使用JPA进行数据持久化以及创建访问数据的REST接口。 配置数据源 在Spring Boot中&#…...

【Linux】进程控制-----进程创建与进程终止

目录 前言&#xff1a; 一、进程创建&#xff1a; 1、fork函数 2、创建多个进程&#xff1a; 3、写时拷贝&#xff1a; 二、进程终止&#xff1a; 进程退出码&#xff1a; 退出方式&#xff1a; ​编辑 进程异常退出&#xff1a; 缓冲区&#xff1a; 前言&#xff1…...

【软考速通笔记】系统架构设计师③——信息安全技术基础知识

文章目录 一、前言二、信息安全基础知识2.1 信息安全的基本要求2.2 信息安全的范围2.3 网络安全表现2.4 安全措施包括 三、信息安全系统的组成框架3.1 技术体系&#xff1a;3.2 组织机构体系&#xff1a;3.3 管理体系 四、信息加解密技术4.1 对称密钥加密算法4.2 非对称密钥加密…...

AI安全:从现实关切到未来展望

近年来&#xff0c;人工智能技术飞速发展&#xff0c;从简单的图像识别到生成对话&#xff0c;从自动驾驶到医疗诊断&#xff0c;AI技术正深刻改变着我们的生活。然而&#xff0c;伴随着这些进步&#xff0c;AI的安全性和可控性问题也日益凸显。这不仅涉及技术层面的挑战&#…...

YOLO格式数据集介绍

yolo数据集 yolo数据集标注格式主要是 yolov5 项目需要用到。 标签使用txt文本进行保存。yolo的目录如下所示&#xff1a; dataset ├─images │ ├─train │ │ ├─ flip_mirror_himg0026393.jpg │ │ ├─ flip_mirror_himg0026394.jpg │ │ ├─ flip_…...

Doris 数据集成 LakeSoul

Doris 数据集成 LakeSoul 作为一种全新的开放式的数据管理架构,湖仓一体(Data Lakehouse)融合了数据仓库的高性能、实时性以及数据湖的低成本、灵活性等优势,帮助用户更加便捷地满足各种数据处理分析的需求,在企业的大数据体系中已经得到越来越多的应用。 在过去多个版本…...

网站建设的问题/站长工具的使用seo综合查询运营

目录 概述 1应用问题 1数据来源 2实现算法 3 4.1 软件界面 3 4.2 优化算法 4 4.3 实现细节 8实验结果与分析 9 5.1 目标函数值可视化 9 5.2 结果 9 5.2.1 暴力算法 10 5.2.2 梯度下降法 11 5.2.3 模拟退火算法 11 5.3 参数调整 12 5.4 分析与结论 12 1.概述 本次实验中&#…...

成都网站平台建设/网络广告案例以及分析

1:标识符&#xff1a;在程序里给类&#xff0c;对象&#xff0c;方法&#xff0c;属性等起的名字 标识符由大小写字母&#xff0c;下划线&#xff0c;数字&#xff0c;$符号组成 开头可以是大小写字母&#xff0c;下划线和$符号&#xff0c;数字不能开头 标识符长度没有限制 不…...

怎么做商业服务网站/百度官方推广平台

这两天接受了一个新任务&#xff0c;就是学在iphone和android平台上编译openSSL&#xff0c;因为我对Apple知之甚少&#xff0c;所以在做的过程中遇到了一些困难和问题&#xff0c;经过学习和尝试&#xff0c;终于弄出来了&#xff0c;网上的好多教程有问题&#xff0c;所以自己…...

外贸网站好做吗/网络推广是什么工作内容

介绍 此款源码是彻底解放劳动人民的双手&#xff0c;全自动采集&#xff0c;模板代码也进行了全面优化&#xff0c;更加有助于SEO 下载链接 http://www.bytepan.com/iTHwNKE6vZD 图片...

做文案用什么网站/上海专业做网站

首先展示下我的终端吧。 这就是我们为什么要配置iTerm2Zshoh-my-zsh环境的原因&#xff1a; 我们使用zsh解释器&#xff0c;当然等你使用 zsh时就会知道zsh与bash对比的强大之处了。 至于我们的git库颜色分级是因为oh-my-zsh&#xff0c;oh-my-zsh有很多中主题供我们选择&#…...

沧州住房和城乡建设部网站/百度推广优化师

下列表格中除了个别函数外&#xff0c;其余函数都是图像处理工具箱提供的关于图像处理的函数&#xff0c;现摘录到此以备查找。 表1 图像显示函数名功能说明函数名功能说明colorbar颜色条显示montage按矩形剪辑方式显示多帧图像getimage从坐标系中获取图像数据immovie从多帧索引…...