Unity照片墙简易圆形交互效果总结

还要很多可以优化的点地方,有兴趣的可以做
比如对象的销毁和生成可以做成对象池,走到最左边后再移动到最右边循环利用

分析过程文件,采用Blender,资源已上传,可以播放动画看效果,下面截个图:
在这里插入图片描述

视频效果如下:

anim

Untiy结构如下:
在这里插入图片描述
上面的ImageItem是我手动添加展示关系用的,默认就一个Target,PictureWall挂PictureWall脚本,ImageItem(预制体)挂ImageItemController 脚本即可

using UnityEngine;public class ImageItemController : MonoBehaviour
{public RectTransform target;public float speed = 10;[SerializeField]private float radiusScale = 1;public float horizontalOffset = 0;private RectTransform rect;private float radius = 0;private Vector2 originalPos = Vector2.zero;private bool isCheck = false;private bool isStartRotate = false;private Vector2 circleCenter;private float xDelta = 0;private float offset = 0;void Start(){rect = transform as RectTransform;rect.anchoredPosition = new Vector2(rect.anchoredPosition.x - horizontalOffset, rect.anchoredPosition.y);radius = target.rect.width * radiusScale;// * Random.Range(0.8f, 1); 半径可以在范围内随机}/* 1.现根据接触点计算出圆的路径:目标移动的位移,计算在圆的的位置,只需修改x即可,y保持不变* 2.计算出的位置x加上移动的距离,得出最总x的位置* 3.设置位置即可* 4.走远时的接触点:开始接触时的关于x对称位置  * 5.添加移动:平移原点和圆点即可*///移动void Update(){if (!isCheck){var dis = Vector2.Distance(target.anchoredPosition, rect.anchoredPosition);if (dis <= radius){isCheck = true;originalPos = rect.anchoredPosition;float y = Mathf.Abs(originalPos.y - target.anchoredPosition.y);float xToCircleCenter = Mathf.Sqrt(radius * radius - y * y);float x = originalPos.x - xToCircleCenter;circleCenter = new Vector2(x, target.anchoredPosition.y);isStartRotate = true;rect.SetSiblingIndex(transform.parent.childCount - 2);}}xDelta = Time.deltaTime * speed;rect.anchoredPosition = new Vector2(rect.anchoredPosition.x - xDelta, rect.anchoredPosition.y);if (isStartRotate){circleCenter.x -= xDelta;originalPos.x -= xDelta;float moveXDistance = target.anchoredPosition.x - circleCenter.x;float x = originalPos.x - circleCenter.x - moveXDistance;float y = Mathf.Sqrt(radius * radius - x * x);float maxY = radius;if (originalPos.y < circleCenter.y){y = -y;maxY = -radius;}Vector2 circlePoint = new Vector2(x, y);if (rect.anchoredPosition.x >= target.anchoredPosition.x){var v1 = circlePoint - (originalPos - circleCenter);var v2 = (originalPos - circleCenter) + new Vector2(0, maxY);v2.Normalize();offset = Vector2.Dot(v1, v2);}else{float tempX = originalPos.x - circleCenter.x;Vector2 originalPos2 = originalPos + 2 * new Vector2(-tempX, 0);var v1 = circlePoint - new Vector2(0, maxY);var v2 = originalPos2 - circleCenter + new Vector2(0, maxY);v2.Normalize();offset = -Vector2.Dot(v1, v2);}if (float.IsNaN(offset)){offset = 0;}x += moveXDistance + offset;Vector2 pos = circleCenter + new Vector2(x, y);rect.anchoredPosition = pos;if (target.anchoredPosition.x >= originalPos.x + originalPos.x - circleCenter.x){rect.anchoredPosition = originalPos;rect.SetAsFirstSibling();}else if (target.anchoredPosition.x <= circleCenter.x){rect.anchoredPosition = originalPos;rect.SetAsFirstSibling();}}if (rect.anchoredPosition.x < -rect.rect.width){Destroy(gameObject);}}
}
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.UI;
using Utility;public class PictureWall : MonoBehaviour
{[SerializeField]private GameObject prefab;private const float WIDTH = 3072;private const float HEIGHT = 1664;private int row = 6;private int column;private float intervalDistance = 20;[SerializeField]private float offset = 200;private float itemWidth;private float itemHeight;public float speed = 10;private float time = 0;[SerializeField]private RectTransform target;private string path = "/PictureWall/";private List<string> texturePaths;private int currentIndex = 0;private List<Texture2D> textureList;void Start(){textureList = new List<Texture2D>();path = Application.streamingAssetsPath + path;ReadImage();CalculateRowColumn();enabled = false;}private void ReadImage(){if (!Directory.Exists(path)){Directory.CreateDirectory(path);return;}texturePaths = new List<string>();var jpgs = Directory.GetFiles(path, "*.jpg");texturePaths.AddRange(jpgs);texturePaths.Reverse();if (texturePaths.Count > 100){for (int i = texturePaths.Count - 1; i == 100; i--){File.Delete(texturePaths[i]);texturePaths.RemoveAt(i);}}foreach (var filePath in texturePaths){UtilityLoadImage.I.LoadImage(filePath, tex =>{textureList.Add(tex);addNum++;if (addNum == texturePaths.Count){Spawn();}});}}float addNum = 0;private void Spawn(){float x = 0;float y = 0;for (int i = 0; i < row; i++){y = i * (itemHeight + intervalDistance);for (int j = 0; j < column; j++){x = j * (itemWidth + intervalDistance);if (i % 2 != 0){//x -= offset;}RectTransform rect = Instantiate(prefab, transform).transform as RectTransform;rect.pivot = new Vector2(0.5f, 0.5f);rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, itemWidth);rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, itemHeight);rect.anchoredPosition = new Vector2(x, -y) + new Vector2(rect.rect.width / 2, -rect.rect.height / 2);var controller = rect.GetComponent<ImageItemController>();controller.speed = speed;controller.target = target;if (i % 2 != 0){controller.horizontalOffset = offset;}SetTexture(rect);}}target.SetAsLastSibling();  enabled = true;}private void CalculateRowColumn(){itemHeight = (HEIGHT - (row - 1) * intervalDistance) / row;itemWidth = itemHeight * 16 / 9;//offset = itemWidth / 2;column = (int)(WIDTH / (itemWidth + intervalDistance)) + 3;time = itemWidth / speed;}bool isSpawned = false;private void Update(){if (!isSpawned && transform.childCount <= (column - 1) * row + 1){isSpawned = true;SpawnColumn();}}private void SpawnColumn(){float x = 0;float y = 0;for (int i = 0; i < row; i++){y = i * (itemHeight + intervalDistance);for (int j = 0; j < 1; j++){x = (column - 1) * (itemWidth + intervalDistance);RectTransform rect = Instantiate(prefab, transform).transform as RectTransform;rect.pivot = new Vector2(0.5f, 0.5f);rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, itemWidth);rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, itemHeight);rect.anchoredPosition = new Vector2(x, -y) + new Vector2(intervalDistance - Time.deltaTime * speed, -rect.rect.height / 2);var controller = rect.GetComponent<ImageItemController>();controller.speed = speed;controller.target = target;if (i % 2 != 0){controller.horizontalOffset = offset;}SetTexture(rect);}}target.SetAsLastSibling();StartCoroutine(Delay());}private void SetTexture(RectTransform rect){        rect.GetComponent<RawImage>().texture = textureList[currentIndex];currentIndex = (currentIndex + 1) % texturePaths.Count;}private IEnumerator Delay(){//yield return new WaitForSeconds(0.1f);yield return null;isSpawned = false;}
}
工具类
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;namespace Utility
{public class UtilityLoadImage{public class MonoHelper : MonoBehaviour { }public static UtilityLoadImage I;private static MonoHelper helper;static UtilityLoadImage(){var go = new GameObject("UtilityLoadImage");helper = go.AddComponent<MonoHelper>();UnityEngine.Object.DontDestroyOnLoad(go);I = new UtilityLoadImage();}private UtilityLoadImage() { }#region  inner methodprivate IEnumerator LoadTexture2D(string path, Action<Texture2D> callback){           //Debug.Log("path:" + path);           UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(path);yield return uwr.SendWebRequest();if (uwr.downloadHandler.isDone){var tex = DownloadHandlerTexture.GetContent(uwr);callback?.Invoke(tex);}}private void LoadTexture2DByFile(string path, Action<Texture2D> callback){if (path.StartsWith("file://")){var bytes = File.ReadAllBytes(path);Texture2D tex = new Texture2D(1, 1);if (tex.LoadImage(bytes))callback?.Invoke(tex);}}private IEnumerator LoadByte(string path, Action<byte[]> callback){UnityWebRequest uwr = UnityWebRequest.Get(path);yield return uwr.SendWebRequest();if (uwr.downloadHandler.isDone){var data = uwr.downloadHandler.data;callback?.Invoke(data);}}private void DeleteFolder(string savedFolder, bool clearSavedPath, bool isRecursive = false){if (!Directory.Exists(savedFolder)){Debug.LogError("要删除的文件夹不存在!");return;}if (clearSavedPath){Directory.Delete(savedFolder, isRecursive);Directory.CreateDirectory(savedFolder);}}private byte[] Texture2DToByte(string path, Texture2D tex){byte[] data = null;int index = path.LastIndexOf('.');if (index != -1){string expandedName = path.Substring(index + 1);switch (expandedName){case "jpeg":case "jpg":data = tex.EncodeToJPG();break;case "png":data = tex.EncodeToPNG();break;default:Debug.Log("");break;}}else{Debug.Log("path is not correct!!!");}return data;}private IEnumerator LoadAudio(string path, string savedFolder, string fileName, Action<AudioClip> callback){UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(path, AudioType.MPEG);yield return request.SendWebRequest();if (request.downloadHandler.isDone){File.WriteAllBytes(savedFolder + "/" + fileName, request.downloadHandler.data);AudioClip clip = DownloadHandlerAudioClip.GetContent(request);callback?.Invoke(clip);}}private IEnumerator LoadAudio(string path, string savePath, Action<AudioClip> callback){UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(path, AudioType.MPEG);yield return request.SendWebRequest();if (request.downloadHandler.isDone){File.WriteAllBytes(savePath, request.downloadHandler.data);AudioClip clip = DownloadHandlerAudioClip.GetContent(request);callback?.Invoke(clip);}}private IEnumerator LoadAudio(string path, Action<AudioClip> callback){UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(path, AudioType.MPEG);yield return request.SendWebRequest();if (request.downloadHandler.isDone){AudioClip clip = DownloadHandlerAudioClip.GetContent(request);if (callback != null)callback(clip);elseDebug.Log("加载音频回调为null");}}#endregion#region load and download imagepublic void LoadImage(string path, Action<Texture2D> callback){helper.StartCoroutine(LoadTexture2D(path, callback));}public void LoadImageByFile(string path, Action<Texture2D> callback){LoadTexture2DByFile(path, callback);}public void LoadImages(string[] paths, Action<List<Texture2D>> callback){Debug.Log("start!!!!!");List<Texture2D> list = new List<Texture2D>();for (int i = 0; i < paths.Length; i++){LoadImage(paths[i], tex => list.Add(tex));}callback?.Invoke(list);Debug.Log("end!!!!!" + list.Count);}public void LoadImagesByFile(string[] paths, Action<List<Texture2D>> callback){List<Texture2D> list = new List<Texture2D>();for (int i = 0; i < paths.Length; i++){var data = File.ReadAllBytes(paths[i]);Texture2D tex = new Texture2D(1, 1);if (tex.LoadImage(data))list.Add(tex);}callback?.Invoke(list);}public void DownloadImageAndSave(string url, string savedFolder, string fileName, Action callback = null){helper.StartCoroutine(LoadTexture2D(url, tex =>{File.WriteAllBytes(savedFolder + "/" + fileName, Texture2DToByte(url, tex));callback?.Invoke();}));}public void DownloadImageAndSave(string url, string savePath, Action callback = null){helper.StartCoroutine(LoadTexture2D(url, tex =>{File.WriteAllBytes(savePath, Texture2DToByte(url, tex));callback?.Invoke();}));}public void DownloadImageAndSave_Texture2D(string url, string savedFolder, string fileName, Action<Texture2D> callback = null){helper.StartCoroutine(LoadTexture2D(url, tex =>{File.WriteAllBytes(savedFolder + "/" + fileName, Texture2DToByte(url, tex));callback?.Invoke(tex);}));}public void DownloadImageAndSave_Texture2D(string url, string savePath, Action<Texture2D> callback = null){helper.StartCoroutine(LoadTexture2D(url, tex =>{File.WriteAllBytes(savePath, Texture2DToByte(url, tex));callback?.Invoke(tex);}));}public void DownloadImageAndSave_FilePath(string url, string savedFolder, string fileName, Action<string> callback = null){helper.StartCoroutine(LoadTexture2D(url, tex =>{string path = savedFolder + "/" + fileName;File.WriteAllBytes(path, Texture2DToByte(url, tex));callback?.Invoke(path);}));}public void DownloadImageAndSave_FilePath(string url, string savePath, Action<string> callback = null){helper.StartCoroutine(LoadTexture2D(url, tex =>{File.WriteAllBytes(savePath, Texture2DToByte(url, tex));callback?.Invoke(savePath);}));}public void DownloadImagesAndSave(string[] urls, string savedFolder, string[] fileNames, Action completedCallback = null, bool deleteFolder = false, bool recursive = false){if (urls.Length != fileNames.Length){Debug.Log("下载数量和保存的文件数量不一致!");return;}DeleteFolder(savedFolder, deleteFolder, recursive);int completedNum = 0;for (int i = 0; i < urls.Length; i++){DownloadImageAndSave(urls[i], savedFolder, fileNames[i], () =>{++completedNum;if (completedNum == urls.Length){completedCallback?.Invoke();Debug.Log("所以文件下载完成!");}});}}public void DownloadImagesAndSave_Texture2DPaths(string[] urls, string savedFolder, string[] fileNames, Action<string[]> callback = null, bool deleteFolder = false, bool recursive = false){if (urls.Length != fileNames.Length){Debug.Log("下载数量和保存的文件数量不一致!");return;}DeleteFolder(savedFolder, deleteFolder, recursive);int completedNum = 0;string[] filePaths = new string[fileNames.Length];for (int i = 0; i < urls.Length; i++){DownloadImageAndSave_FilePath(urls[i], savedFolder, fileNames[i], path =>{filePaths[completedNum] = path;++completedNum;if (completedNum == urls.Length){callback?.Invoke(filePaths);Debug.Log("所以图片下载完成!");}});}}public void DownloadImagesAndSave_Texture2DPaths(string[] urls, string[] savePaths, Action<string[]> callback = null){if (urls.Length != savePaths.Length){Debug.Log("下载数量和保存的文件数量不一致!");return;}int completedNum = 0;string[] filePaths = new string[savePaths.Length];for (int i = 0; i < urls.Length; i++){DownloadImageAndSave_FilePath(urls[i], savePaths[i], path =>{filePaths[completedNum] = path;++completedNum;if (completedNum == urls.Length){callback?.Invoke(filePaths);Debug.Log("所以图片下载完成!");}});}}public void DownloadImagesAndSave_Texture2Ds(string[] urls, string savedFolder, string[] fileNames, Action<Texture2D[]> callback = null, bool deleteFolder = false, bool recursive = false){if (urls.Length != fileNames.Length){Debug.Log("下载数量和保存的文件数量不一致!");return;}DeleteFolder(savedFolder, deleteFolder, recursive);int completedNum = 0;Texture2D[] textures = new Texture2D[fileNames.Length];for (int i = 0; i < urls.Length; i++){DownloadImageAndSave_Texture2D(urls[i], savedFolder, fileNames[i], tex =>{textures[completedNum] = tex;++completedNum;if (completedNum == urls.Length){callback?.Invoke(textures);Debug.Log("所以图片下载完成!");}});}}public void DownloadImagesAndSave_Texture2Ds(string[] urls, string[] savePaths, Action<Texture2D[]> callback = null){if (urls.Length != savePaths.Length){Debug.Log("下载数量和保存的文件数量不一致!");return;}int completedNum = 0;Texture2D[] textures = new Texture2D[savePaths.Length];for (int i = 0; i < urls.Length; i++){DownloadImageAndSave_Texture2D(urls[i], savePaths[i], tex =>{textures[completedNum] = tex;++completedNum;if (completedNum == urls.Length){callback?.Invoke(textures);Debug.Log("所以图片下载完成!");}});}}#endregion#region download filepublic void DownloadFileAndSave(string url, string savedFolder, string fileName, Action callback = null){helper.StartCoroutine(LoadByte(url, data =>{File.WriteAllBytes(savedFolder + "/" + fileName, data);callback?.Invoke();}));}public void DownloadFileAndSave(string url, string savePath, Action callback = null){helper.StartCoroutine(LoadByte(url, data =>{File.WriteAllBytes(savePath, data);callback?.Invoke();}));}public void DownloadFileAndSave_FilePath(string url, string savedFolder, string fileName, Action<string> callback = null){helper.StartCoroutine(LoadByte(url, data =>{string path = savedFolder + "/" + fileName;File.WriteAllBytes(path, data);callback?.Invoke(path);}));}public void DownloadFileAndSave_FilePath(string url, string savePath, Action<string> callback = null){helper.StartCoroutine(LoadByte(url, data =>{File.WriteAllBytes(savePath, data);callback?.Invoke(savePath);}));}public void DownloadFileAndSave_FileData(string url, string savedFolder, string fileName, Action<byte[]> callback = null){helper.StartCoroutine(LoadByte(url, data =>{string path = savedFolder + "/" + fileName;File.WriteAllBytes(path, data);callback?.Invoke(data);}));}public void DownloadFileAndSave_FileData(string url, string savePath, Action<byte[]> callback = null){helper.StartCoroutine(LoadByte(url, data =>{File.WriteAllBytes(savePath, data);callback?.Invoke(data);}));}public void DownloadFilesAndSave(string[] urls, string savedFolder, string[] fileNames, Action completedCallback = null, bool deleteFolder = false, bool recursive = false){if (urls.Length != fileNames.Length){Debug.Log("下载数量和保存的文件数量不一致!");return;}DeleteFolder(savedFolder, deleteFolder, recursive);int completedNum = 0;for (int i = 0; i < urls.Length; i++){DownloadFileAndSave(urls[i], savedFolder, fileNames[i], () =>{++completedNum;if (completedNum == fileNames.Length){completedCallback?.Invoke();}});}}public void DownloadFilesAndSave(string[] urls, string[] savePath, Action callback = null){if (urls.Length != savePath.Length){Debug.Log("下载数量和保存的文件数量不一致!");return;}int completedNum = 0;for (int i = 0; i < urls.Length; i++){DownloadFileAndSave(urls[i], savePath[i], () =>{++completedNum;if (completedNum == savePath.Length){callback?.Invoke();}});}}public void DownloadFilesAndSave_FilePaths(string[] urls, string savedFolder, string[] fileNames, Action<string[]> completedCallback = null, bool deleteFolder = false, bool recursive = false){if (urls.Length != fileNames.Length){Debug.Log("下载数量和保存的文件数量不一致!");return;}DeleteFolder(savedFolder, deleteFolder, recursive);int completedNum = 0;string[] filePaths = new string[fileNames.Length];for (int i = 0; i < urls.Length; i++){DownloadFileAndSave_FilePath(urls[i], savedFolder, fileNames[i], path =>{filePaths[completedNum] = path;++completedNum;if (completedNum == fileNames.Length){completedCallback?.Invoke(filePaths);}});}}public void DownloadFilesAndSave_FilePaths(string[] urls, string[] savePath, Action<string[]> completedCallback = null){if (urls.Length != savePath.Length){Debug.Log("下载数量和保存的文件数量不一致!");return;}int completedNum = 0;string[] filePaths = new string[savePath.Length];for (int i = 0; i < urls.Length; i++){DownloadFileAndSave_FilePath(urls[i], savePath[i], path =>{filePaths[completedNum] = path;++completedNum;if (completedNum == savePath.Length){completedCallback?.Invoke(filePaths);}});}}public void DownloadFilesAndSave_FileDatas(string[] urls, string savedFolder, string[] fileNames, Action<List<byte[]>> completedCallback = null, bool deleteFolder = false, bool recursive = false){if (urls.Length != fileNames.Length){Debug.Log("下载数量和保存的文件数量不一致!");return;}DeleteFolder(savedFolder, deleteFolder, recursive);int completedNum = 0;List<byte[]> allDatas = new List<byte[]>(fileNames.Length);for (int i = 0; i < urls.Length; i++){DownloadFileAndSave_FileData(urls[i], savedFolder, fileNames[i], data =>{allDatas.Add(data);++completedNum;if (completedNum == fileNames.Length){completedCallback?.Invoke(allDatas);}});}}public void DownloadFilesAndSave_FileDatas(string[] urls, string[] savePath, Action<List<byte[]>> completedCallback = null){if (urls.Length != savePath.Length){Debug.Log("下载数量和保存的文件数量不一致!");return;}int completedNum = 0;List<byte[]> allDatas = new List<byte[]>(savePath.Length);for (int i = 0; i < urls.Length; i++){DownloadFileAndSave_FileData(urls[i], savePath[i], data =>{allDatas.Add(data);++completedNum;if (completedNum == savePath.Length){completedCallback?.Invoke(allDatas);}});}}#endregion#region download audiopublic void DownloadAudioAndSave_FileData(string url, string savedFolder, string fileName, Action<AudioClip> callback = null){helper.StartCoroutine(LoadAudio(url, savedFolder, fileName, callback));}public void DownloadAudioAndSave_FileData(string url, string savePath, Action<AudioClip> callback = null){helper.StartCoroutine(LoadAudio(url, savePath, callback));}public void LoadAudioClip(string url, Action<AudioClip> callback = null){helper.StartCoroutine(LoadAudio(url, callback));}#endregion}
}

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

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

相关文章

Redis开源协议变更!Garnet:微软开源代替方案?

Garnet&#xff1a;微软开源的高性能替代方案&#xff0c;秉承兼容 RESP 协议的同时&#xff0c;以卓越性能和无缝迁移能力重新定义分布式缓存存储&#xff01; - 精选真开源&#xff0c;释放新价值。 概览 最近&#xff0c;Redis修改了开源协议&#xff0c;从BSD变成了 SSPLv…

主流公链 - Filecoin

探索Filecoin&#xff1a;去中心化存储网络 1. Filecoin简介 Filecoin是一个去中心化的存储网络&#xff0c;旨在通过区块链技术实现全球性的分布式文件存储和检索市场。Filecoin允许用户将文件存储在网络中的节点上&#xff0c;并通过加密、分片和复制等技术保证数据的安全性…

八大技术趋势案例(虚拟现实增强现实)

科技巨变,未来已来,八大技术趋势引领数字化时代。信息技术的迅猛发展,深刻改变了我们的生活、工作和生产方式。人工智能、物联网、云计算、大数据、虚拟现实、增强现实、区块链、量子计算等新兴技术在各行各业得到广泛应用,为各个领域带来了新的活力和变革。 为了更好地了解…

【数学符合】

数学符合 ■ ∑ ■ ∑

Javascript — 异步方法与异常捕获问题

问题&#xff1a;try catch为什么不能捕获未被 await 修饰的异步方法异常 async function throwError() {throw new Error("自定义Error&#xff01;") }let testOne async () > {console.debug("start testOne")try {throwError()} catch (e) {conso…

HSF:阿里RPC框架

简介 HSF&#xff08;High-speed Service Framework&#xff09;是一种广泛应用于阿里巴巴内部的分布式RPC服务框架。 作为阿里巴巴的基础中间件&#xff0c;HSF连接了不同的业务系统&#xff0c;解耦了系统间的实现依赖。HSF从分布式应用的角度统一了服务的发布和调用方式&a…

智慧工地安全生产与风险预警大平台的构建,需要哪些技术?

随着科技的不断发展&#xff0c;智慧工地已成为现代建筑行业的重要发展趋势。智慧工地方案是一种基于先进信息技术的工程管理模式&#xff0c;旨在提高施工效率、降低施工成本、保障施工安全、提升施工质量。一般来说&#xff0c;智慧工地方案的构建&#xff0c;需要通过集成物…

Rust编程(五)终章:查漏补缺

闭包 & 迭代器 闭包&#xff08;Closure&#xff09;通常是指词法闭包&#xff0c;是一个持有外部环境变量的函数。外部环境是指闭包定义时所在的词法作用域。外部环境变量&#xff0c;在函数式编程范式中也被称为自由变量&#xff0c;是指并不是在闭包内定义的变量。将自…

OpenHarmony中的LLDB高性能调试器

概述 LLDB&#xff08;Low Lever Debugger&#xff09;是新一代高性能调试器。详细说明参考 LLDB官方文档 。 当前OpenHarmony中的LLDB工具是在 llvm15.0.4 基础上适配演进出来的工具&#xff0c;是HUAWEI DevEco Studio工具中默认的调试器&#xff0c;支持调试C和C应用。 工…

将ENVI的roi转为mask图像

方法1&#xff1a; 直接使用ENVI step1: 将roi文件存储为.roi格式 [1] 链接: link step2: 将.roi转为mask [2] 链接: link [3] 链接: link 方法2&#xff1a; 使用Matlab step1: 将roi文件存储为.xlm 文件 step2&#xff1a;针对把每个roi存储为一个单独文件 [4] 读取xlm文…

【React】onClick点击事件传参的4种方式

记录React onClick 点击事件传参的 4 种方式 方式一&#xff1a;使用内联箭头函数 import React, { MouseEvent } from "react";function App() {const handleClick (event: MouseEvent<HTMLButtonElement>, name: string) > {console.log(event)console.…

HWOD:字符的排序

一、知识点 char的最大值是127&#xff0c;最小值是-128 自己填充的char型数组&#xff0c;以字符串打印&#xff0c;打印之前要手动在末尾加上 \0 二、题目 1、描述 Lily上课时使用字母数字图片教小朋友们学习英语单词&#xff0c;每次都需要把这些图片按照大小&#x…