288 lines
8.6 KiB
C#
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("点击了非中心图,不响应点击");
|
|
}
|
|
}
|
|
}
|
|
}
|