DCS/ruiyiweiUX/Assets/Scripts/Tool/ImageSlider.cs

288 lines
8.6 KiB
C#

using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class ImageSlider : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
public List<RectTransform> images; // 所有图片的 RectTransform
GraphicRaycaster raycaster;
public int currentIndex = 0; // 当前居中图片索引
float largeSpacing = 1000f; // 图片之间的水平间距
float smallSpacing = 800f; // 图片之间的水平间距
float sideScale = 1.0f; // 侧边图片的缩放比例
float sideRotation = 60f; // 侧边图片的倾斜角度
private Vector2 dragStartPos;
private bool isDragging = false;
private Dictionary<RectTransform, Sprite> originalSprites = new Dictionary<RectTransform, Sprite>();
void Start()
{
raycaster = GetComponentInParent<Canvas>().GetComponent<GraphicRaycaster>();
foreach (var img in images)
{
var imageComp = img.GetComponent<Image>();
if (imageComp != null)
{
originalSprites[img] = imageComp.sprite; // 缓存原始图像
}
}
UpdateLayout(true);
}
public void OnBeginDrag(PointerEventData eventData)
{
// Debug.Log("开始拖动");
dragStartPos = eventData.position;
isDragging = true;
}
public void OnEndDrag(PointerEventData eventData)
{
// Debug.Log("结束拖动");
isDragging = false;
float dragDelta = eventData.position.x - dragStartPos.x;
if (Mathf.Abs(dragDelta) > 100f) // 你可以根据需要调整阈值
{
if (dragDelta > 0)
SlideLeft();
else
SlideRight();
}
}
public void SlideLeft()
{
currentIndex = (currentIndex - 1 + images.Count) % images.Count; // 循环索引
UpdateLayout();
}
public void SlideRight()
{
currentIndex = (currentIndex + 1) % images.Count; // 循环索引
UpdateLayout();
}
// 用于处理循环偏移
int GetWrappedOffset(int index, int center, int count)
{
int offset = index - center;
if (offset > count / 2)
offset -= count;
else if (offset < -count / 2)
offset += count;
return offset;
}
void ReplaceCenterImage(RectTransform img)
{
Image imageComp = img.GetComponent<Image>();
if (imageComp == null) return;
string name = img.name;
// 加载新的图像(可以放在 Resources 文件夹中)
Sprite newSprite = Resources.Load<Sprite>("CenterImages/" + name);
if (newSprite != null)
{
imageComp.sprite = newSprite;
}
else
{
Debug.LogWarning("找不到对应的中心图像: " + name);
}
}
void RestoreOriginalImage(RectTransform img)
{
Image imageComp = img.GetComponent<Image>();
if (imageComp == null) return;
if (originalSprites.ContainsKey(img))
{
imageComp.sprite = originalSprites[img];
}
}
void UpdateLayout(bool instant = false)
{
for (int i = 0; i < images.Count; i++)
{
var img = images[i];
// int offset = i - currentIndex;
int offset = GetWrappedOffset(i, currentIndex, images.Count);
if (Mathf.Abs(offset) > 2)
{
img.gameObject.SetActive(false);
continue;
}
else
{
img.gameObject.SetActive(true);
}
// 判断是否是中心图
if (offset == 0)
{
ReplaceCenterImage(img);
}
else
{
RestoreOriginalImage(img);
}
float spacing = (Mathf.Abs(offset) == 1) ? largeSpacing : smallSpacing;
float posX = offset * spacing;
float posZ = Mathf.Abs(offset) * 500f;
Vector3 targetPos = new Vector3(posX, 0, posZ);
float alpha = 1.0f;
// Vector3 targetPos = new Vector3(offset * spacing, 0, 0);
// Vector3 targetPos = new Vector3(offset * spacing, 0, Mathf.Abs(offset) * 200f); // 加入Z轴位移
Vector3 targetScale = new Vector3(1f, 1f, 1f) * sideScale;
Vector3 targetRotation = Vector3.zero;
if (offset < 0)
{
// targetScale = Vector3.one * sideScale;
targetRotation = new Vector3(0, -sideRotation, 0);
}
else if (offset > 0)
{
// targetScale = Vector3.one * sideScale;
targetRotation = new Vector3(0, sideRotation, 0);
}
if (Mathf.Abs(offset) > 1)
{
img.GetComponent<Image>().DOFade(alpha, 0.5f);
}
if (instant)
{
img.anchoredPosition3D = targetPos;
img.localScale = targetScale;
img.localRotation = Quaternion.Euler(targetRotation);
img.GetComponent<Image>().color = new Color(1, 1, 1, alpha);
}
else
{
img.DOAnchorPos3D(targetPos, 0.5f).SetEase(Ease.OutExpo);
img.DOScale(targetScale, 0.8f).SetEase(Ease.OutExpo);
img.DOLocalRotate(targetRotation, 0.5f).SetEase(Ease.OutExpo);
}
// img.SetSiblingIndex(images.Count - Mathf.Abs(offset));
// 让中间图最高层,左右两边根据距离决定层级
int sortingOrder = 100 - Mathf.Abs(offset) * 10;
img.SetSiblingIndex(sortingOrder);
List<(RectTransform img, int offsetx)> sorted = new();
for (int j = 0; j < images.Count; j++)
{
int offsetx = GetWrappedOffset(j, currentIndex, images.Count);
sorted.Add((images[j], offsetx));
}
// 按 offset 的绝对值升序排序,中心的图在最上
sorted.Sort((a, b) => Mathf.Abs(b.offsetx).CompareTo(Mathf.Abs(a.offsetx)));
for (int k = 0; k < sorted.Count; k++)
{
sorted[k].img.SetSiblingIndex(k);
}
}
}
public void OnDrag(PointerEventData eventData)
{
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
dragStartPos = Input.mousePosition;
isDragging = false;
}
if (Input.GetMouseButtonUp(0))
{
float dragDistance = (Input.mousePosition - (Vector3)dragStartPos).magnitude;
if (dragDistance > 50f)
{
isDragging = true; // 视为拖动
}
else
{
isDragging = false; // 视为点击
}
if (!isDragging)
{
// 执行点击检测(只允许点击中心图)
DetectClick();
}
}
}
void DetectClick()
{
PointerEventData pointerData = new PointerEventData(EventSystem.current);
pointerData.position = Input.mousePosition;
List<RaycastResult> results = new List<RaycastResult>();
raycaster.Raycast(pointerData, results);
if (results.Count > 0)
{
GameObject clicked = results[0].gameObject;
Debug.Log("🖱️ 点击了: " + clicked.name);
// 判断是否是当前居中的图像
if (clicked == images[currentIndex].gameObject)
{
// 判断是否是指定区域
string name = clicked.name;
if (name == "杭州市淳安县" ||
name == "湖州市安吉县" ||
name == "湖州市长兴县" ||
name == "金华浦江县金狮湖" ||
name == "金华浦江县三江口湿地" ||
name == "金华义乌市水系统" ||
name == "宁波市三江口" ||
name == "宁波象山县" ||
name == "宁波月湖整治" ||
name == "绍兴诸暨市浦阳江" ||
name == "温州市龙湾区")
{
// InPanel inpanel = UIManager.Instance.ShowPanel<InPanel>();
// inpanel.setImage(clicked.name);
// UIManager.Instance.HidePanel<MainPanel>();
}
}
else
{
Debug.Log("点击了非中心图,不响应点击");
}
}
}
}