WenYang.cs
14.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.Video;
public class WenYang : UIBase
{
//纹样名称
public TextMeshProUGUI wenYangName;
public Image wenYangImage; //纹样图片(闪烁的父载体)
public GameObject pointItemPrefab; // 纹样闪烁点预制体
public TextMeshProUGUI wenYangIntroduction;
public Transform contentScrollView;
public Image wenYangExplainCoverImage;
public Transform explainImageScrollView;
public Image wenYangColorImage;
public Image wenYangExplainImage;
public Image wenWuImage;
public Image wenWuContainer;
public TextMeshProUGUI wenWuIntroduction;
public Image wenYangUnChooseBtn;
public Image wenYangChooseBtn;
public Image wenWuUnChooseBtn;
public Image wenWuChooseBtn;
public Image pre;
public Image next;
public Transform itemGrid; // 父对象
public GameObject itemPrefab; // 预制体
//当前选中的纹样
Dictionary<int, WenYangData> wenYangDataMap = new Dictionary<int, WenYangData>();
private GameObject current;
private int currentIndex;
private string choosed = "Choosed";
private string unchoose = "Unchoose";
int itemWidth = 160;
void Start()
{
StartCoroutine(JsonLoaderManager.LoadJson("https://h5.edcc.cn/QuGouChengWen/json/WenYangData.json","Jsons/WenYangData",data =>
{
Debug.Log("最终获取到的 JSON 数据:\n" + data);
InitWenYang(data);
}));
}
private void InitWenYang(string jsonText)
{
int scrollDefaultWidth = 1600;
int scrollWidth = 0;
WenYangDataList data = JsonUtility.FromJson<WenYangDataList>(jsonText);
//初始化纹样,第一个自动选中,并赋值给current
for (int i = 0; i < data.list.Count; i++) {
WenYangData wenYangData = data.list[i];
wenYangDataMap[i] = wenYangData;
GameObject itemObj = Instantiate(itemPrefab, itemGrid);
// var choosedObj = itemObj.transform.Find(choosed).gameObject;
// StartCoroutine(ImageLoader.LoadImage(wenYangData.scrollChooseImage, choosedObj.GetComponent<Image>()));
var unchoosedObj = itemObj.transform.Find(unchoose).gameObject;
StartCoroutine(ImageLoader.LoadImage(wenYangData.scrollUnChooseImage, unchoosedObj.GetComponent<Image>()));
var finalI = i;
itemObj.GetComponent<Button>().onClick.AddListener(() =>
{
updateChoosed(finalI,current, itemObj,wenYangData);
});
if (i==0)
{
current = itemObj;
updateChoosed(i,null, current,wenYangData);
}
scrollWidth += itemWidth;
}
if (scrollWidth < scrollDefaultWidth)
{
scrollWidth = scrollDefaultWidth;
}
RectTransform scrollContentRt = itemGrid.GetComponent<RectTransform>();
scrollContentRt.sizeDelta = new Vector2(scrollWidth, scrollContentRt.sizeDelta.y);
//纹样文物切换按钮
wenYangUnChooseBtn.GetComponent<Button>().onClick.AddListener(() =>
{
wenYangChooseBtn.gameObject.SetActive(true);
wenYangUnChooseBtn.gameObject.SetActive(false);
wenWuUnChooseBtn.gameObject.SetActive(true);
wenWuChooseBtn.gameObject.SetActive(false);
//展示纹样、隐藏文物
wenYangImage.gameObject.SetActive(true);
wenWuContainer.gameObject.SetActive(false);
wenWuIntroduction.gameObject.SetActive(false);
contentScrollView.gameObject.SetActive(true);
});
//纹样文物切换按钮
wenWuUnChooseBtn.GetComponent<Button>().onClick.AddListener(() =>
{
wenYangChooseBtn.gameObject.SetActive(false);
wenYangUnChooseBtn.gameObject.SetActive(true);
wenWuUnChooseBtn.gameObject.SetActive(false);
wenWuChooseBtn.gameObject.SetActive(true);
//隐藏纹样、展示文物
wenYangImage.gameObject.SetActive(false);
wenWuContainer.gameObject.SetActive(true);
wenWuIntroduction.gameObject.SetActive(true);
contentScrollView.gameObject.SetActive(false);
//关闭解析弹窗
wenYangExplainCoverImage.gameObject.SetActive(false);
});
//纹样解析按钮
wenYangImage.GetComponent<Button>().onClick.AddListener(() =>
{
bool isActive = wenYangExplainCoverImage.gameObject.activeSelf;
wenYangExplainCoverImage.gameObject.SetActive(!isActive); // 取反后赋值
});
wenYangExplainCoverImage.GetComponent<Button>().onClick.AddListener(() =>
{
wenYangExplainCoverImage.gameObject.SetActive(true);
});
//文物放大按钮
wenWuImage.GetComponent<Button>().onClick.AddListener(() =>
{
ImageViewerManager.Instance.ShowImage(wenYangDataMap[currentIndex].wenWuImage);
});
pre.GetComponent<Button>().onClick.AddListener(() =>
{
Debug.Log("pre");
int index = current.transform.GetSiblingIndex();
if (index > 0)
{
// 获取上一个兄弟节点
Transform previous = current.transform.parent.GetChild(index - 1);
updateChoosed(index - 1,current, previous.gameObject,wenYangDataMap[index - 1]);
// 滚动到所在位置
ScrollToItem(previous.GetComponent<RectTransform>(), itemGrid.GetComponentInParent<ScrollRect>());
}
});
next.GetComponent<Button>().onClick.AddListener(() =>
{
Debug.Log("next");
int index = current.transform.GetSiblingIndex();
int siblingCount = current.transform.parent.childCount;
if (index < siblingCount - 1)
{
// 获取下一个兄弟节点
Transform nextSibling = current.transform.parent.GetChild(index + 1);
updateChoosed(index + 1,current, nextSibling.gameObject,wenYangDataMap[index + 1]);
// 滚动到所在位置
ScrollToItem(nextSibling.GetComponent<RectTransform>(), itemGrid.GetComponentInParent<ScrollRect>());
}
});
}
// Update is called once per frame
void Update()
{
}
public void ShowLog()
{
Debug.Log("this is UI: " + gameObject.name);
}
protected override void CloseComplete()
{
base.CloseComplete();
Debug.Log("关闭完成: " + gameObject.name);
}
protected override void OpenComplete()
{
base.OpenComplete();
Debug.Log("打开完成: " + gameObject.name);
}
private void SetChoosed(GameObject obj)
{
if (!obj)
{
return;
}
var choosedObj = obj.transform.Find(choosed).gameObject;
if (choosedObj != null)
choosedObj.SetActive(true);
// var unchoosedObj = obj.transform.Find(unchoose).gameObject;
// if (unchoosedObj != null)
// unchoosedObj.SetActive(false);
}
private void SetUnchoose(GameObject obj)
{
if (!obj)
{
return;
}
var choosedObj = obj.transform.Find(choosed).gameObject;
if (choosedObj != null)
choosedObj.SetActive(false);
// var unchoosedObj = obj.transform.Find(unchoose).gameObject;
// if (unchoosedObj != null)
// unchoosedObj.SetActive(true);
}
/**
* 功能描述: 更改选中的纹样
* @param unChooseObj 未选中的纹样
* @param chooseObj 选中的纹样
* @param wenYangData 选中的纹样数据
* @author wangQc
* @date 2025/7/7 13:59
*/
private void updateChoosed(int currentIndex,GameObject unChooseObj, GameObject chooseObj,WenYangData wenYangData)
{
this.currentIndex = currentIndex;
SetUnchoose(unChooseObj);
SetChoosed(chooseObj);
// 更新 current 引用
current =chooseObj;
//更新详情页的文案 图片等
WenYangUpdate(wenYangData);
//初始化纹样图片上的点
InitWenYangPoints(wenYangData);
}
/**
* 功能描述: 初始化纹样图片上的点
* @author wangQc
* @date 2025/7/8 13:53
*/
private void InitWenYangPoints(WenYangData wenYangData)
{
foreach (Transform child in wenYangImage.transform)
{
Destroy(child.gameObject);
}
//初始化纹样图片上的点
var wenYangPoints = wenYangData.wenYangPoints;
if (null!=wenYangPoints)
{
foreach (var wenYangPoint in wenYangPoints)
{
GameObject point = Instantiate(pointItemPrefab, wenYangImage.transform);
//定位点的坐标
point.transform.localPosition = new Vector3(wenYangPoint.x, wenYangPoint.y, 0);
//闪烁动效
point.transform.DOScale(1.5f, 2f).SetLoops(-1, LoopType.Yoyo).SetEase(Ease.InOutSine);
}
}
}
private void ScrollToItem(RectTransform target, ScrollRect scrollRect)
{
if (target == null || scrollRect == null) return;
// 强制刷新布局,确保 UI 位置是最新的
// Canvas.ForceUpdateCanvases();
bool fullyVisible = IsFullyVisible(target, scrollRect.viewport);
if (fullyVisible) return;
float x = target.anchoredPosition.x;
Debug.Log("rectX: " + x);
float offset = -(x-724);
offset=offset>-800?-800:offset;
RectTransform content = scrollRect.content;
Vector2 anchoredPosition = content.anchoredPosition;
anchoredPosition.x = offset;
content.anchoredPosition = anchoredPosition;
}
/// <summary>
/// 判断 target RectTransform 是否完全在 viewport RectTransform 可视范围内
/// </summary>
bool IsFullyVisible(RectTransform target, RectTransform viewport)
{
// 1. 先拿到 target 的四个世界角点
Vector3[] worldCorners = new Vector3[4];
target.GetWorldCorners(worldCorners);
// 2. 拿到 viewport 的本地矩形
Rect rect = viewport.rect;
// 3. 把每个角点转换到 viewport 的本地坐标系中,检查是否都在 rect 里
for (int i = 0; i < 4; i++)
{
// worldCorners[i] 是世界坐标
Vector3 localPos = viewport.InverseTransformPoint(worldCorners[i]);
// 如果任何一个角点不在 viewport.rect 范围内,就说明没有完全可见
if (localPos.x < rect.xMin || localPos.x > rect.xMax ||
localPos.y < rect.yMin || localPos.y > rect.yMax)
{
return false;
}
}
// 都在范围内,说明完全可见
return true;
}
//纹样更新
public void WenYangUpdate(WenYangData wenYangData)
{
wenYangName.text = wenYangData.name;
//默认显示纹样大图
StartCoroutine(ImageLoader.LoadImage( wenYangData.wenYangImage, wenYangImage));
wenYangImage.SetNativeSize();
//文物图片
StartCoroutine(ImageLoader.LoadImage(wenYangData.wenWuImage, wenWuImage, (width, height) => {
Debug.Log($"图片原始宽高 = {width} x {height}");
float maxWidth = 600f;
float maxHeight = 600f;
float widthRatio = maxWidth / width;
float heightRatio = maxHeight / height;
// 取较小的缩放因子,保证不超出限制,并始终进行缩放(无论放大或缩小)
float scaleFactor = Mathf.Min(widthRatio, heightRatio);
float finalWidth = width * scaleFactor;
float finalHeight = height * scaleFactor;
wenWuImage.rectTransform.sizeDelta = new Vector2(finalWidth, finalHeight);
Debug.Log($"最终显示宽高 = {finalWidth} x {finalHeight}");
}));
// wenWuImage.SetNativeSize();
//文物简介
wenWuIntroduction.text = wenYangData.wenWuIntroduction;
//简介/结构布局
wenYangIntroduction.text = "纹样简介:\n" + wenYangData.wenYangIntroduction + "\n\n结构布局:\n" + wenYangData.wenYangStructure;
//根据文字长度计算滑动块的高度
var height = wenYangIntroduction.preferredHeight;
var rectTransform = contentScrollView.GetComponent<RectTransform>();
rectTransform.sizeDelta= new Vector2(rectTransform.sizeDelta.x, height+140);
//颜色
StartCoroutine(ImageLoader.LoadImage( wenYangData.wenYangColorImage, wenYangColorImage));
//解析图片
StartCoroutine(ImageLoader.LoadImage( wenYangData.wenYangExplainImage, wenYangExplainImage));
//根据解析图片高度设置滑动块高度
var explainHeight = wenYangExplainImage.preferredHeight;
var explainRectTransform = explainImageScrollView.GetComponent<RectTransform>();
explainRectTransform.sizeDelta= new Vector2(explainRectTransform.sizeDelta.x, explainHeight);
wenYangImage.gameObject.SetActive(true);
wenWuContainer.gameObject.SetActive(false);
wenYangExplainCoverImage.gameObject.SetActive(false);
contentScrollView.gameObject.SetActive(true);
wenWuIntroduction.gameObject.SetActive(false);
wenYangChooseBtn.gameObject.SetActive(true);
wenYangUnChooseBtn.gameObject.SetActive(false);
wenWuChooseBtn.gameObject.SetActive(false);
wenWuUnChooseBtn.gameObject.SetActive(true);
}
}