-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
1867 lines (1679 loc) · 137 KB
/
Copy pathindex.html
File metadata and controls
1867 lines (1679 loc) · 137 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
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>5016B 智慧數控微課程</title>
<link rel="stylesheet" href="styles.css">
<!-- Lucide Icons -->
<script src="https://unpkg.com/lucide@latest"></script>
</head>
<body class="bg-gray-50 text-gray-800">
<!-- 導覽列 -->
<nav class="bg-white shadow-md fixed w-full z-50 top-0">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between h-16 items-center">
<div class="flex items-center gap-2">
<i data-lucide="cpu" class="text-primary w-8 h-8"></i>
<span class="font-bold text-xl text-primary tracking-wider">5016B 新手導覽</span>
</div>
</div>
</div>
</nav>
<!-- 橫幅區域 (Hero Section) -->
<section id="about" class="pt-24 pb-12 md:pt-32 md:pb-24 bg-gradient-to-br from-blue-50 to-indigo-100">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex flex-col md:flex-row items-center gap-10">
<div class="md:w-1/2 space-y-6">
<div class="inline-block bg-blue-100 text-primary px-3 py-1 rounded-full text-sm font-bold mb-2">
PBL-STEM+C 跨域統整
</div>
<h1 class="text-4xl md:text-5xl font-black text-gray-900 leading-tight">
動手做、開心學 <br>
<span class="text-primary">5016B 智慧微課程</span>
</h1>
<p class="text-lg text-gray-600 leading-relaxed">
本單元課程專為國中科技領域設計。帶領學生從圖像化程式拼塊入門,學習感測器應用、硬體控制,最終完成屬於自己的智慧微型專題。
</p>
<div class="flex flex-wrap gap-4 pt-4">
<a href="#detail-view" onclick="openCourseDetail(1, this); return false;" class="bg-primary text-white px-6 py-3 rounded-lg font-bold shadow-lg hover:bg-blue-700 hover:shadow-xl transition flex items-center gap-2 focus-visible:outline focus-visible:outline-4 focus-visible:outline-offset-4 focus-visible:outline-primary">
<i data-lucide="play" class="w-5 h-5"></i> 從單元一開始
</a>
<a href="#curriculum" class="border-2 border-primary text-primary px-6 py-3 rounded-lg font-bold hover:bg-blue-50 transition flex items-center gap-2 focus-visible:outline focus-visible:outline-4 focus-visible:outline-offset-4 focus-visible:outline-primary">
<i data-lucide="book-open" class="w-5 h-5"></i> 瀏覽全部課程
</a>
</div>
</div>
<div class="md:w-1/2 flex justify-center">
<!-- 示意圖替換為卡片設計 (新增點擊與 hover 效果) -->
<a href="#platform-view" class="relative block bg-white p-8 rounded-2xl shadow-2xl border-t-4 border-primary cursor-pointer hover:shadow-[0_20px_50px_rgba(30,64,175,0.15)] hover:-translate-y-2 transition-all duration-300 group focus-visible:outline focus-visible:outline-4 focus-visible:outline-offset-4 focus-visible:outline-primary" onclick="openPlatformDetail(this); return false;">
<div class="absolute -top-6 -right-6 bg-accent text-white w-16 h-16 rounded-full flex items-center justify-center font-bold text-xl shadow-lg group-hover:scale-110 transition-transform">
點擊
</div>
<i data-lucide="circuit-board" class="w-24 h-24 text-secondary mx-auto mb-6 group-hover:text-primary transition-colors"></i>
<h3 class="text-2xl font-bold text-center text-gray-800 mb-2">5016B 數控平台</h3>
<div class="text-center mb-4">
<span class="inline-block bg-blue-50 text-primary px-3 py-1 rounded-full text-sm font-medium">查看環境設定與連線</span>
</div>
<ul class="space-y-3 text-gray-600 mt-4">
<li class="flex items-center gap-3"><i data-lucide="check-circle" class="text-green-500 w-5 h-5"></i> 模組化防呆設計</li>
<li class="flex items-center gap-3"><i data-lucide="check-circle" class="text-green-500 w-5 h-5"></i> NKNUBLOCK 圖像化程式</li>
<li class="flex items-center gap-3"><i data-lucide="check-circle" class="text-green-500 w-5 h-5"></i> 跨域整合微型專題</li>
</ul>
</a>
</div>
</div>
</section>
<!-- 課程單元規劃 (Curriculum) -->
<section id="curriculum" class="py-20 bg-white">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="text-center mb-16">
<h2 class="text-3xl md:text-4xl font-bold text-gray-900 mb-4">微課程單元規劃</h2>
<p class="text-gray-500 max-w-2xl mx-auto text-lg">循序漸進的課程設計,從零基礎到完成專題。</p>
</div>
<!-- 時間軸/卡片網格設計 -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
<!-- Unit 1 -->
<a href="#detail-view" class="unit-card block bg-gray-50 rounded-2xl p-8 border border-gray-100 shadow-sm transition-all duration-300 group cursor-pointer hover:shadow-md hover:border-blue-200 focus-visible:outline focus-visible:outline-4 focus-visible:outline-offset-4 focus-visible:outline-primary" onclick="openCourseDetail(1, this); return false;">
<div class="w-14 h-14 bg-blue-100 rounded-xl flex items-center justify-center mb-6 group-hover:bg-primary transition-colors">
<i data-lucide="layout-grid" class="w-7 h-7 text-primary group-hover:text-white transition-colors"></i>
</div>
<div class="flex justify-between items-center mb-4">
<span class="text-sm font-bold text-primary bg-blue-50 px-3 py-1 rounded-full">單元一</span>
</div>
<h3 class="text-xl font-bold text-gray-900 mb-3">8x8 LED 矩陣:走路動畫</h3>
<p class="text-gray-600 mb-4 h-16">學習控制 LED 矩陣,透過座標與圖形編碼,設計出行人號誌動畫。</p>
<div class="border-t border-gray-200 pt-4 mt-auto">
<p class="text-sm font-bold text-gray-800 mb-2">🎯 實作目標:</p>
<ul class="text-sm text-gray-600 space-y-1 list-disc list-inside">
<li>理解 LED 矩陣座標系統</li>
<li>學習自訂陣列圖形編碼</li>
<li>使用迴圈製作切換動畫效果</li>
</ul>
</div>
</a>
<!-- Unit 2 -->
<a href="#detail-view" class="unit-card block bg-gray-50 rounded-2xl p-8 border border-gray-100 shadow-sm transition-all duration-300 group cursor-pointer hover:shadow-md hover:border-green-200 focus-visible:outline focus-visible:outline-4 focus-visible:outline-offset-4 focus-visible:outline-primary" onclick="openCourseDetail(2, this); return false;">
<div class="w-14 h-14 bg-green-100 rounded-xl flex items-center justify-center mb-6 group-hover:bg-green-600 transition-colors">
<i data-lucide="sparkles" class="w-7 h-7 text-green-600 group-hover:text-white transition-colors"></i>
</div>
<div class="flex justify-between items-center mb-4">
<span class="text-sm font-bold text-green-600 bg-green-50 px-3 py-1 rounded-full">單元二</span>
</div>
<h3 class="text-xl font-bold text-gray-900 mb-3">炫彩燈條:彩虹流光</h3>
<p class="text-gray-600 mb-4 h-16">認識數位全彩 LED 燈條,透過程式精準控制 RGB 色彩,打造華麗流光。</p>
<div class="border-t border-gray-200 pt-4 mt-auto">
<p class="text-sm font-bold text-gray-800 mb-2">🎯 實作目標:</p>
<ul class="text-sm text-gray-600 space-y-1 list-disc list-inside">
<li>認識數位 RGB 燈條控制原理</li>
<li>學習變數在色彩變化的應用</li>
<li>實作漸層與流動的燈光特效</li>
</ul>
</div>
</a>
<!-- Unit 3 -->
<a href="#detail-view" class="unit-card block bg-gray-50 rounded-2xl p-8 border border-gray-100 shadow-sm transition-all duration-300 group cursor-pointer hover:shadow-md hover:border-purple-200 focus-visible:outline focus-visible:outline-4 focus-visible:outline-offset-4 focus-visible:outline-primary" onclick="openCourseDetail(3, this); return false;">
<div class="w-14 h-14 bg-purple-100 rounded-xl flex items-center justify-center mb-6 group-hover:bg-purple-600 transition-colors">
<i data-lucide="monitor" class="w-7 h-7 text-purple-600 group-hover:text-white transition-colors"></i>
</div>
<div class="flex justify-between items-center mb-4">
<span class="text-sm font-bold text-purple-600 bg-purple-50 px-3 py-1 rounded-full">單元三</span>
</div>
<h3 class="text-xl font-bold text-gray-900 mb-3">OLED 顯示:文字掉落與圖片繪製</h3>
<p class="text-gray-600 mb-4 h-16">使用 OLED 螢幕顯示動態文字掉落動畫,並進階學習將圖片轉碼繪製出專屬的點陣圖案。</p>
<div class="border-t border-gray-200 pt-4 mt-auto">
<p class="text-sm font-bold text-gray-800 mb-2">🎯 實作目標:</p>
<ul class="text-sm text-gray-600 space-y-1 list-disc list-inside">
<li>認識 OLED 螢幕與通訊基礎</li>
<li>學習文字設定與動態掉落製作</li>
<li>掌握圖片轉換與螢幕繪圖</li>
</ul>
</div>
</a>
<!-- Unit 4 -->
<a href="#detail-view" class="unit-card block bg-gray-50 rounded-2xl p-8 border border-gray-100 shadow-sm transition-all duration-300 group cursor-pointer hover:shadow-md hover:border-amber-200 focus-visible:outline focus-visible:outline-4 focus-visible:outline-offset-4 focus-visible:outline-primary" onclick="openCourseDetail(4, this); return false;">
<div class="w-14 h-14 bg-amber-100 rounded-xl flex items-center justify-center mb-6 group-hover:bg-amber-500 transition-colors">
<i data-lucide="car" class="w-7 h-7 text-amber-600 group-hover:text-white transition-colors"></i>
</div>
<div class="flex justify-between items-center mb-4">
<span class="text-sm font-bold text-amber-600 bg-amber-50 px-3 py-1 rounded-full">單元四</span>
</div>
<h3 class="text-xl font-bold text-gray-900 mb-3">感測控制:停車場閘門</h3>
<p class="text-gray-600 mb-4 h-16">結合超音波感測器與伺服馬達,模擬真實世界的車輛偵測與自動閘門系統。</p>
<div class="border-t border-gray-200 pt-4 mt-auto">
<p class="text-sm font-bold text-gray-800 mb-2">🎯 實作目標:</p>
<ul class="text-sm text-gray-600 space-y-1 list-disc list-inside">
<li>學習超音波測距原理</li>
<li>控制伺服馬達轉動特定角度</li>
<li>整合輸入與輸出的條件判斷</li>
</ul>
</div>
</a>
<!-- Unit 5 -->
<a href="#detail-view" class="unit-card block bg-gray-50 rounded-2xl p-8 border border-gray-100 shadow-sm transition-all duration-300 group lg:col-span-2 cursor-pointer hover:shadow-md hover:border-rose-200 focus-visible:outline focus-visible:outline-4 focus-visible:outline-offset-4 focus-visible:outline-primary" onclick="openCourseDetail(5, this); return false;">
<div class="flex flex-col md:flex-row gap-6 items-start md:items-center">
<div class="w-14 h-14 bg-rose-100 rounded-xl flex shrink-0 items-center justify-center group-hover:bg-rose-500 transition-colors">
<i data-lucide="trophy" class="w-7 h-7 text-rose-600 group-hover:text-white transition-colors"></i>
</div>
<div class="flex-1">
<div class="flex justify-between items-center mb-2">
<span class="text-sm font-bold text-rose-600 bg-rose-50 px-3 py-1 rounded-full">單元五 (總結)</span>
</div>
<h3 class="text-xl md:text-2xl font-bold text-gray-900 mb-2">智慧停車場:出入口閘門管理</h3>
<p class="text-gray-600 mb-4">結合前四堂課的技術,將燈條、矩陣、OLED 與感測閘門完美結合,打造具備聲光效果的停車場出入口管理系統,同時處理車輛進出與行人通行。</p>
<div class="bg-white p-4 rounded-lg border border-gray-200">
<p class="text-sm font-bold text-gray-800 mb-2">🎯 專題整合挑戰:</p>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-3 text-sm text-gray-600">
<div class="flex items-start gap-2">
<i data-lucide="milestone" class="w-4 h-4 text-accent shrink-0 mt-0.5"></i>
<span><strong>車輛進出:</strong>超音波偵測車距,OLED顯示出入口指示,開啟閘門並切換紅綠燈號。</span>
</div>
<div class="flex items-start gap-2">
<i data-lucide="users" class="w-4 h-4 text-accent shrink-0 mt-0.5"></i>
<span><strong>行人通行:</strong>無車輛時,LED矩陣持續播放走路動畫給行人觀看,確保通行安全。</span>
</div>
</div>
</div>
</div>
</div>
</a>
</div>
</div>
</section>
<!-- 課程詳細介紹頁面 (預設隱藏) -->
<section id="detail-view" class="hidden pt-24 pb-20 bg-gray-50 min-h-screen">
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
<button onclick="closeCourseDetail()" class="flex items-center gap-2 text-gray-500 hover:text-primary transition mb-8 font-medium">
<i data-lucide="arrow-left" class="w-5 h-5"></i> 返回課程總覽
</button>
<div class="bg-white rounded-2xl shadow-lg border border-gray-100 overflow-hidden">
<!-- 標題區塊 -->
<div class="bg-gradient-to-r from-blue-50 to-indigo-50 p-8 border-b border-gray-100">
<div class="flex items-center justify-between gap-3 mb-4">
<span id="detail-badge" class="text-sm font-bold bg-primary text-white px-3 py-1 rounded-full">單元 X</span>
<span id="detail-progress" class="text-sm font-bold text-primary">學習進度 1 / 5</span>
</div>
<h2 id="detail-title" tabindex="-1" class="text-3xl md:text-4xl font-bold text-gray-900 mb-4">單元標題</h2>
<p id="detail-desc" class="text-lg text-gray-600 leading-relaxed">單元描述內容...</p>
<div class="mt-6 h-2 overflow-hidden rounded-full bg-blue-100" aria-hidden="true">
<div id="detail-progress-bar" class="h-full rounded-full bg-primary transition-all duration-300" style="width: 20%"></div>
</div>
</div>
<nav aria-label="單元內容導覽" class="flex flex-wrap gap-2 border-b border-gray-100 px-8 py-4 text-sm font-bold">
<a href="#detail-objectives-heading" class="rounded-full bg-blue-50 px-3 py-2 text-primary hover:bg-blue-100 focus-visible:outline focus-visible:outline-4 focus-visible:outline-offset-2 focus-visible:outline-primary">學習目標</a>
<a href="#detail-materials-heading" class="rounded-full bg-amber-50 px-3 py-2 text-amber-700 hover:bg-amber-100 focus-visible:outline focus-visible:outline-4 focus-visible:outline-offset-2 focus-visible:outline-primary">應用模組</a>
<a href="#detail-steps-heading" class="rounded-full bg-indigo-50 px-3 py-2 text-indigo-700 hover:bg-indigo-100 focus-visible:outline focus-visible:outline-4 focus-visible:outline-offset-2 focus-visible:outline-primary">課堂流程</a>
<a href="#detail-demo-container" class="rounded-full bg-gray-100 px-3 py-2 text-gray-700 hover:bg-gray-200 focus-visible:outline focus-visible:outline-4 focus-visible:outline-offset-2 focus-visible:outline-primary">實作預覽</a>
</nav>
<!-- 內容區塊 -->
<div class="p-8 grid grid-cols-1 md:grid-cols-2 gap-10">
<div class="space-y-8">
<div>
<h3 id="detail-objectives-heading" class="text-xl font-bold text-gray-900 mb-4 flex items-center gap-2">
<i data-lucide="target" class="w-6 h-6 text-primary"></i> 學習目標
</h3>
<ul id="detail-objectives" class="space-y-3 text-gray-600">
<!-- JS 動態載入 -->
</ul>
</div>
<div>
<h3 id="detail-materials-heading" class="text-xl font-bold text-gray-900 mb-4 flex items-center gap-2">
<i data-lucide="package" class="w-6 h-6 text-accent"></i> 應用模組
</h3>
<ul id="detail-materials" class="space-y-3 text-gray-600">
<!-- JS 動態載入 -->
</ul>
</div>
</div>
<div>
<h3 id="detail-steps-heading" class="text-xl font-bold text-gray-900 mb-4 flex items-center gap-2">
<i data-lucide="list-ordered" class="w-6 h-6 text-secondary"></i> 課堂流程
</h3>
<div id="detail-steps" class="space-y-4">
<!-- JS 動態載入 -->
</div>
</div>
</div>
<!-- 動態載入特製單元預覽區塊 (例如 8x8 LED 動畫) -->
<div id="detail-demo-container" class="hidden border-t border-gray-100 bg-gray-50 p-8">
<!-- JS 動態載入 -->
</div>
<nav id="course-pagination" aria-label="單元切換" class="flex items-center justify-between gap-4 border-t border-gray-100 bg-white p-6"></nav>
</div>
</div>
</section>
<!-- 5016B 平台詳細介紹頁面 (環境設定與連線方式) -->
<section id="platform-view" class="hidden pt-24 pb-20 bg-gray-50 min-h-screen">
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
<button onclick="closePlatformDetail()" class="flex items-center gap-2 text-gray-500 hover:text-primary transition mb-8 font-medium">
<i data-lucide="arrow-left" class="w-5 h-5"></i> 返回首頁
</button>
<div class="bg-white rounded-2xl shadow-lg border border-gray-100 overflow-hidden">
<div class="bg-gradient-to-r from-blue-50 to-indigo-50 p-8 border-b border-gray-100">
<div class="flex items-center gap-3 mb-4">
<span class="text-sm font-bold bg-secondary text-white px-3 py-1 rounded-full">環境建置</span>
</div>
<h2 id="platform-title" tabindex="-1" class="text-3xl md:text-4xl font-bold text-gray-900 mb-4 flex items-center gap-3">
<i data-lucide="settings" class="w-8 h-8 text-primary"></i>
環境設定與連線方式
</h2>
<p class="text-lg text-gray-600 leading-relaxed">在上課前,請確保您已熟悉 NKNUBLOCK 的硬體模擬功能,這樣即使沒有實體開發板,也能順利進行程式碼的測試與執行。</p>
</div>
<div class="p-8 space-y-12">
<!-- 步驟 1 -->
<div class="flex flex-col md:flex-row gap-6">
<div class="md:w-1/3">
<h3 class="text-xl font-bold text-gray-900 mb-2 flex items-center gap-2">
<span class="bg-primary text-white w-8 h-8 rounded-full flex items-center justify-center text-sm">1</span>
開啟軟體
</h3>
<p class="text-gray-600 mb-4">請在您的電腦桌面上,找到並開啟「NKNUBLOCK 圖像化程式」軟體。</p>
</div>
<div class="md:w-2/3">
<div class="bg-white rounded-xl overflow-hidden shadow-sm border border-gray-200 p-2">
<img src="images/501601.png" alt="NKNUBLOCK 軟體首頁" class="w-full h-auto rounded-lg" onerror="this.onerror=null; this.src='https://placehold.co/800x400/f3f4f6/a1a1aa?text=Image+Loading+Failed';">
</div>
</div>
</div>
<!-- 步驟 2 -->
<div class="flex flex-col md:flex-row gap-6">
<div class="md:w-1/3">
<h3 class="text-xl font-bold text-gray-900 mb-2 flex items-center gap-2">
<span class="bg-primary text-white w-8 h-8 rounded-full flex items-center justify-center text-sm">2</span>
打開硬體模擬介面
</h3>
<p class="text-gray-600 mb-4">在軟體主選單介面中,點擊並點選「顯示硬體模擬」,載入虛擬教具。</p>
</div>
<div class="md:w-2/3">
<div class="bg-white rounded-xl overflow-hidden shadow-sm border border-gray-200 p-2">
<img src="images/501602.png" alt="打開硬體模擬介面" class="w-full h-auto rounded-lg" onerror="this.onerror=null; this.src='https://placehold.co/800x400/f3f4f6/a1a1aa?text=Image+Loading+Failed';">
</div>
</div>
</div>
<!-- 步驟 3 -->
<div class="flex flex-col md:flex-row gap-6">
<div class="md:w-1/3">
<h3 class="text-xl font-bold text-gray-900 mb-2 flex items-center gap-2">
<span class="bg-primary text-white w-8 h-8 rounded-full flex items-center justify-center text-sm">3</span>
選擇教具
</h3>
<p class="text-gray-600 mb-4">在模擬介面的教具清單中,找到並選擇「5016B 智慧數控教具平台」作為本課程的開發硬體。</p>
</div>
<div class="md:w-2/3">
<div class="bg-white rounded-xl overflow-hidden shadow-sm border border-gray-200 p-2">
<img src="images/501603.png" alt="選擇 5016B 教具畫面" class="w-full h-auto rounded-lg" onerror="this.onerror=null; this.src='https://placehold.co/800x400/f3f4f6/a1a1aa?text=Image+Loading+Failed';">
</div>
</div>
</div>
<!-- 步驟 4 -->
<div class="flex flex-col md:flex-row gap-6">
<div class="md:w-1/3">
<h3 class="text-xl font-bold text-gray-900 mb-2 flex items-center gap-2">
<span class="bg-primary text-white w-8 h-8 rounded-full flex items-center justify-center text-sm">4</span>
連接模擬教具
</h3>
<p class="text-gray-600 mb-4">點選模擬教具上的 <strong>USB 線路圖示</strong>。</p>
</div>
<div class="md:w-2/3">
<div class="bg-white rounded-xl overflow-hidden shadow-sm border border-gray-200 p-2">
<img src="images/501604.png" alt="點選 USB 虛擬連線畫面" class="w-full h-auto rounded-lg" onerror="this.onerror=null; this.src='https://placehold.co/800x400/f3f4f6/a1a1aa?text=Image+Loading+Failed';">
</div>
</div>
</div>
<!-- 步驟 5 -->
<div class="flex flex-col md:flex-row gap-6">
<div class="md:w-1/3">
<h3 class="text-xl font-bold text-gray-900 mb-2 flex items-center gap-2">
<span class="bg-primary text-white w-8 h-8 rounded-full flex items-center justify-center text-sm">5</span>
連線與測試
</h3>
<p class="text-gray-600 mb-4">將連線模式設置為<strong>「模擬」</strong>,連線後確認狀態是否更改為<strong>「已連接(模擬)」</strong>。</p>
</div>
<div class="md:w-2/3">
<div class="bg-white rounded-xl overflow-hidden shadow-sm border border-gray-200 p-2">
<img src="images/501605.png" alt="連線模式與已連接狀態畫面" class="w-full h-auto rounded-lg" onerror="this.onerror=null; this.src='https://placehold.co/800x400/f3f4f6/a1a1aa?text=Image+Loading+Failed';">
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- 圖片放大對話框 -->
<div id="image-modal" class="fixed inset-0 z-[100] hidden items-center justify-center bg-black/80 p-4 opacity-0 transition-opacity duration-300" role="dialog" aria-modal="true" aria-label="教學圖片放大檢視">
<div class="relative max-h-full max-w-6xl">
<button id="close-image-modal" type="button" onclick="closeImageModal()" class="absolute -right-3 -top-3 z-10 flex h-10 w-10 items-center justify-center rounded-full bg-white text-gray-800 shadow-lg transition hover:bg-gray-100 focus-visible:outline focus-visible:outline-4 focus-visible:outline-offset-2 focus-visible:outline-white" aria-label="關閉放大圖片">
<i data-lucide="x" class="h-6 w-6"></i>
</button>
<img id="modal-image" src="" alt="放大檢視的教學圖片" class="max-h-[85vh] max-w-full rounded-lg shadow-2xl transition-transform duration-300 scale-95">
</div>
</div>
<!-- Footer -->
<footer class="bg-gray-900 text-gray-400 py-12 text-center">
<div class="max-w-7xl mx-auto px-4">
<div class="flex justify-center items-center gap-2 mb-4">
<i data-lucide="cpu" class="w-6 h-6 text-primary"></i>
<span class="text-xl font-bold text-white tracking-wider">5016B 新手導覽</span>
</div>
<p class="mb-4">基於國立高雄師範大學 (FabLab-NKNU) PBL-STEM+C 計畫公版教具開發</p>
<p class="text-sm">© 2026 前峰國中科技領域版權所有</p>
</div>
</footer>
<!-- 初始化 Icons 與互動腳本 -->
<script>
// 初始化 Lucide Icons
lucide.createIcons();
// --- 動畫相關資料與邏輯 ---
let animationInterval = null;
let countdownInterval = null;
let currentFrameIndex = 0;
let currentCountdownIndex = 0;
// 倒數計時陣列 (8 ~ 1)
const countdownFrames = [
[ "00111100", "01000010", "01000010", "00111100", "01000010", "01000010", "00111100", "00000000" ], // 8
[ "01111110", "00000010", "00000100", "00001000", "00010000", "00100000", "00100000", "00000000" ], // 7
[ "00111100", "01000000", "01111100", "01000010", "01000010", "01000010", "00111100", "00000000" ], // 6
[ "01111110", "01000000", "01111100", "00000010", "00000010", "01000010", "00111100", "00000000" ], // 5
[ "00001100", "00011100", "00101100", "01001100", "01111110", "00001100", "00001100", "00000000" ], // 4
[ "00111100", "01000010", "00000010", "00011100", "00000010", "01000010", "00111100", "00000000" ], // 3
[ "00111100", "01000010", "00000010", "00001100", "00110000", "01000000", "01111110", "00000000" ], // 2
[ "00011000", "00111000", "01011000", "00011000", "00011000", "00011000", "01111110", "00000000" ] // 1
];
// 走路陣列
const walkingFrames = [
[ "00011000", "00011000", "00001000", "00011100", "00101010", "00001000", "00010100", "01000010" ],
[ "00011000", "00011000", "00001000", "00011100", "00001000", "00010100", "00100100", "00000100" ],
[ "00011000", "00011000", "00001000", "00011000", "00001000", "00011000", "00011000", "00001000" ],
[ "00011000", "00011000", "00001000", "00111000", "00001000", "00010100", "00100100", "00100000" ],
[ "00011000", "00011000", "00001000", "00111000", "01010100", "00001000", "00010100", "01000010" ],
[ "00011000", "00011000", "00001000", "00111000", "00001000", "00010100", "00100100", "00000100" ],
[ "00011000", "00011000", "00001000", "00011000", "00001000", "00011000", "00011000", "00001000" ],
[ "00011000", "00011000", "00001000", "00011100", "00001000", "00010100", "00100100", "00100000" ]
];
function generateLEDGridHTML(frameData, isLarge = false, isRed = false) {
const dotClass = isLarge
? 'w-4 h-4 sm:w-5 sm:h-5 m-[1px] sm:m-[2px]'
: 'w-2 h-2 sm:w-2.5 sm:h-2.5 m-[1px]';
const onColorClass = isRed
? 'bg-red-500 shadow-[0_0_8px_#ef4444]'
: 'bg-green-400 shadow-[0_0_8px_#4ade80]';
let html = `<div class="bg-gray-800 p-2 rounded-lg inline-block border border-gray-600 shadow-inner"><div class="flex flex-col">`;
frameData.forEach(row => {
html += `<div class="flex">`;
row.split('').forEach(val => {
const stateClass = val === '1'
? onColorClass
: 'bg-gray-900 opacity-60';
html += `<div class="${dotClass} rounded-full transition-colors duration-100 ${stateClass}"></div>`;
});
html += `</div>`;
});
html += `</div></div>`;
return html;
}
function getUnit1DemoHTML() {
return `
<div class="bg-gray-900 text-gray-100 p-6 sm:p-8 rounded-2xl shadow-inner overflow-hidden space-y-12">
<div class="flex items-center gap-3 border-b border-gray-700 pb-4">
<i data-lucide="play-circle" class="w-8 h-8 text-green-400"></i>
<h3 class="text-xl sm:text-2xl font-bold text-white tracking-wide">實作預覽與分解圖</h3>
</div>
<!-- 實作一:倒數計時 -->
<div>
<h4 class="text-lg font-bold text-red-400 mb-6 flex items-center gap-2">
<span class="bg-red-500 text-white w-6 h-6 rounded-full flex items-center justify-center text-xs">1</span>
實作一:紅燈倒數計時
</h4>
<div class="flex flex-col lg:flex-row gap-8 lg:gap-10 items-center lg:items-start">
<div class="flex flex-col items-center shrink-0">
<h5 class="text-xs text-gray-400 mb-3 tracking-wider uppercase font-semibold">動態預覽</h5>
<div id="countdown-animation-container" class="p-4 bg-gray-950 rounded-2xl shadow-2xl border border-gray-700"></div>
</div>
<div class="flex-1 w-full">
<h5 class="text-xs text-gray-400 mb-3 tracking-wider uppercase font-semibold text-center lg:text-left">倒數 8 張分解圖 (8 ~ 1)</h5>
<div id="countdown-frames-container" class="grid grid-cols-2 md:grid-cols-4 gap-x-4 gap-y-6 justify-items-center"></div>
</div>
</div>
</div>
<div class="border-t border-gray-800"></div>
<!-- 實作二:走路動畫 -->
<div>
<h4 class="text-lg font-bold text-green-400 mb-6 flex items-center gap-2">
<span class="bg-green-500 text-white w-6 h-6 rounded-full flex items-center justify-center text-xs">2</span>
實作二:走路動畫
</h4>
<div class="flex flex-col lg:flex-row gap-8 lg:gap-10 items-center lg:items-start">
<div class="flex flex-col items-center shrink-0">
<h5 class="text-xs text-gray-400 mb-3 tracking-wider uppercase font-semibold">動態預覽</h5>
<div id="walking-animation-container" class="p-4 bg-gray-950 rounded-2xl shadow-2xl border border-gray-700"></div>
</div>
<div class="flex-1 w-full">
<h5 class="text-xs text-gray-400 mb-3 tracking-wider uppercase font-semibold text-center lg:text-left">走路 8 張分解圖</h5>
<div id="walking-frames-container" class="grid grid-cols-2 md:grid-cols-4 gap-x-4 gap-y-6 justify-items-center"></div>
</div>
</div>
</div>
</div>
`;
}
function initStaticFrames() {
const countdownContainer = document.getElementById('countdown-frames-container');
if (countdownContainer) {
let html = '';
countdownFrames.forEach((frame, index) => {
html += `
<div class="flex flex-col items-center group">
${generateLEDGridHTML(frame, false, true)}
<div class="mt-2 px-3 py-1 bg-gray-800 rounded-full text-xs text-gray-300 group-hover:bg-red-900 group-hover:text-red-300 transition-colors">
數字 ${8 - index}
</div>
</div>
`;
});
countdownContainer.innerHTML = html;
}
const walkingContainer = document.getElementById('walking-frames-container');
if (walkingContainer) {
let html = '';
walkingFrames.forEach((frame, index) => {
html += `
<div class="flex flex-col items-center group">
${generateLEDGridHTML(frame, false, false)}
<div class="mt-2 px-3 py-1 bg-gray-800 rounded-full text-xs text-gray-300 group-hover:bg-green-900 group-hover:text-green-300 transition-colors">
第 ${index + 1} 張
</div>
</div>
`;
});
walkingContainer.innerHTML = html;
}
}
function startAnimation() {
stopAnimation();
const countdownAnimContainer = document.getElementById('countdown-animation-container');
if (countdownAnimContainer) {
currentCountdownIndex = 0;
countdownAnimContainer.innerHTML = generateLEDGridHTML(countdownFrames[currentCountdownIndex], true, true);
countdownInterval = setInterval(() => {
currentCountdownIndex = (currentCountdownIndex + 1) % countdownFrames.length;
const ac = document.getElementById('countdown-animation-container');
if (ac) ac.innerHTML = generateLEDGridHTML(countdownFrames[currentCountdownIndex], true, true);
}, 1000);
}
const walkingAnimContainer = document.getElementById('walking-animation-container');
if (walkingAnimContainer) {
currentFrameIndex = 0;
walkingAnimContainer.innerHTML = generateLEDGridHTML(walkingFrames[currentFrameIndex], true, false);
animationInterval = setInterval(() => {
currentFrameIndex = (currentFrameIndex + 1) % walkingFrames.length;
const ac = document.getElementById('walking-animation-container');
if (ac) ac.innerHTML = generateLEDGridHTML(walkingFrames[currentFrameIndex], true, false);
}, 200);
}
lucide.createIcons();
}
function stopAnimation() {
if (animationInterval) {
clearInterval(animationInterval);
animationInterval = null;
}
if (countdownInterval) {
clearInterval(countdownInterval);
countdownInterval = null;
}
}
// --- 單元二專屬:程式碼區塊展示 ---
function getUnit2DemoHTML() {
return `
<div class="bg-gray-900 text-gray-100 p-6 sm:p-8 rounded-2xl shadow-inner overflow-hidden space-y-12">
<div class="flex items-center gap-3 border-b border-gray-700 pb-4">
<i data-lucide="code-2" class="w-8 h-8 text-green-400"></i>
<h3 class="text-xl sm:text-2xl font-bold text-white tracking-wide">積木邏輯解析與進階應用</h3>
</div>
<!-- 互動實驗:RGB 色彩混合器 -->
<div class="bg-gray-800 border border-gray-700 rounded-xl p-6 shadow-lg -mt-4">
<h4 class="text-lg font-bold text-gray-200 mb-6 flex items-center gap-2">
<i data-lucide="palette" class="w-5 h-5 text-accent"></i> 互動實驗:RGB 色彩混合器
</h4>
<p class="text-sm text-gray-400 mb-6">數位裝置透過疊加紅(R)、綠(G)、藍(B)三種光來產生顏色。在積木中數值範圍為 0~255。拉動滑桿,觀察光是如何混合的吧!</p>
<div class="flex flex-col md:flex-row gap-8">
<!-- Sliders -->
<div class="flex-1 space-y-6">
<!-- Red -->
<div>
<label class="flex justify-between text-sm font-bold text-red-400 mb-2">
<span>紅色 (R)</span>
<span id="rVal" class="font-mono text-gray-300 bg-gray-900 px-2 py-0.5 rounded shadow-inner">128</span>
</label>
<input type="range" id="rRange" min="0" max="255" value="128" class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer accent-red-500">
</div>
<!-- Green -->
<div>
<label class="flex justify-between text-sm font-bold text-green-400 mb-2">
<span>綠色 (G)</span>
<span id="gVal" class="font-mono text-gray-300 bg-gray-900 px-2 py-0.5 rounded shadow-inner">128</span>
</label>
<input type="range" id="gRange" min="0" max="255" value="128" class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer accent-green-500">
</div>
<!-- Blue -->
<div>
<label class="flex justify-between text-sm font-bold text-blue-400 mb-2">
<span>藍色 (B)</span>
<span id="bVal" class="font-mono text-gray-300 bg-gray-900 px-2 py-0.5 rounded shadow-inner">128</span>
</label>
<input type="range" id="bRange" min="0" max="255" value="128" class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer accent-blue-500">
</div>
<!-- Presets -->
<div class="pt-4 border-t border-gray-700">
<p class="text-xs text-gray-400 mb-3 flex items-center gap-1"><i data-lucide="target" class="w-3 h-3"></i> 實驗任務:試著調出以下顏色,或點擊快速套用</p>
<div class="flex flex-wrap gap-2">
<button class="preset-btn px-3 py-1.5 text-xs font-bold rounded bg-gray-900 text-gray-300 hover:text-white border border-gray-600 hover:border-yellow-400 hover:bg-gray-700 transition-colors" data-r="255" data-g="255" data-b="0">
<span class="inline-block w-2 h-2 rounded-full bg-yellow-400 mr-1 pointer-events-none"></span>黃色
</button>
<button class="preset-btn px-3 py-1.5 text-xs font-bold rounded bg-gray-900 text-gray-300 hover:text-white border border-gray-600 hover:border-cyan-400 hover:bg-gray-700 transition-colors" data-r="0" data-g="255" data-b="255">
<span class="inline-block w-2 h-2 rounded-full bg-cyan-400 mr-1 pointer-events-none"></span>青色
</button>
<button class="preset-btn px-3 py-1.5 text-xs font-bold rounded bg-gray-900 text-gray-300 hover:text-white border border-gray-600 hover:border-fuchsia-500 hover:bg-gray-700 transition-colors" data-r="255" data-g="0" data-b="255">
<span class="inline-block w-2 h-2 rounded-full bg-fuchsia-500 mr-1 pointer-events-none"></span>洋紅
</button>
<button class="preset-btn px-3 py-1.5 text-xs font-bold rounded bg-gray-900 text-gray-300 hover:text-white border border-gray-600 hover:border-orange-500 hover:bg-gray-700 transition-colors" data-r="255" data-g="165" data-b="0">
<span class="inline-block w-2 h-2 rounded-full bg-orange-500 mr-1 pointer-events-none"></span>橙色
</button>
<button class="preset-btn px-3 py-1.5 text-xs font-bold rounded bg-gray-900 text-gray-300 hover:text-white border border-gray-600 hover:border-white hover:bg-gray-700 transition-colors" data-r="255" data-g="255" data-b="255">
<span class="inline-block w-2 h-2 rounded-full bg-white mr-1 pointer-events-none"></span>白色
</button>
</div>
</div>
</div>
<!-- Preview Box -->
<div class="flex-1 flex flex-col justify-center items-center rounded-xl border border-gray-600 shadow-inner p-6 transition-colors duration-150 min-h-[200px]" id="colorPreview" style="background-color: rgb(128, 128, 128);">
<div class="bg-black/60 backdrop-blur-md px-6 py-4 rounded-xl text-center shadow-[0_0_20px_rgba(0,0,0,0.3)] w-full max-w-[200px] border border-white/10">
<div class="font-mono text-xl font-bold text-white mb-2 tracking-wider" id="rgbText">rgb(128,128,128)</div>
<div class="font-mono text-sm text-gray-400" id="hexText">#808080</div>
</div>
</div>
</div>
</div>
<!-- 實作一:單向流水燈 -->
<div>
<h4 class="text-lg font-bold text-blue-400 mb-6 flex items-center gap-2">
<span class="bg-blue-500 text-white w-6 h-6 rounded-full flex items-center justify-center text-xs">1</span>
實作一:單向流水燈
</h4>
<div class="space-y-4">
<p class="text-gray-400 leading-relaxed text-sm sm:text-base">
省去複雜的硬體設定,我們只需要利用一個「重複執行」的迴圈,依序對每一顆燈珠執行「開燈 ➔ 等待 ➔ 關燈」,就能輕鬆創造出單向流水燈的效果!
</p>
<div class="bg-[#1e1e1e] rounded-xl border border-gray-700 overflow-hidden shadow-2xl mt-4">
<div class="bg-[#2d2d2d] px-4 py-3 flex items-center gap-2 border-b border-gray-700">
<div class="w-3 h-3 rounded-full bg-red-500"></div>
<div class="w-3 h-3 rounded-full bg-yellow-500"></div>
<div class="w-3 h-3 rounded-full bg-green-500"></div>
<span class="ml-4 text-xs text-gray-400 font-mono">running_light_logic.block</span>
</div>
<div class="p-4 sm:p-6 overflow-x-auto text-sm sm:text-base font-mono leading-relaxed text-gray-300">
<pre><code class="grid grid-cols-[max-content_1fr] gap-x-4 sm:gap-x-8 gap-y-1">
<span class="col-span-2"><span class="text-blue-400">變數</span> 位置 <span class="text-pink-500">設為</span> <span class="text-purple-400">1</span></span>
<span class="col-span-2"><span class="text-pink-500">重複</span> <span class="text-purple-400">8</span> <span class="text-pink-500">次</span></span>
<span> <span class="text-yellow-200">設 WS2812燈條</span> <span class="text-purple-400">8</span> <span class="text-yellow-200">顆中的第</span> <span class="text-blue-400">位置</span> <span class="text-yellow-200">顆 紅</span> <span class="text-purple-400">50</span> <span class="text-yellow-200">綠</span> <span class="text-purple-400">50</span> <span class="text-yellow-200">藍</span> <span class="text-purple-400">50</span></span><span class="text-green-500">// 開燈並設定為白色</span>
<span> <span class="text-yellow-200">等待</span> <span class="text-purple-400">0.1</span> <span class="text-yellow-200">秒</span></span><span></span>
<span> <span class="text-yellow-200">設 WS2812燈條</span> <span class="text-purple-400">8</span> <span class="text-yellow-200">顆中的第</span> <span class="text-blue-400">位置</span> <span class="text-yellow-200">顆 紅</span> <span class="text-purple-400">0</span> <span class="text-yellow-200">綠</span> <span class="text-purple-400">0</span> <span class="text-yellow-200">藍</span> <span class="text-purple-400">0</span></span><span class="text-green-500">// 關燈</span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 位置 <span class="text-pink-500">改變</span> <span class="text-purple-400">1</span></span>
</code></pre>
</div>
</div>
</div>
</div>
<div class="border-t border-gray-800"></div>
<!-- 實作二:彩虹漸變 -->
<div>
<h4 class="text-lg font-bold text-purple-400 mb-6 flex items-center gap-2">
<span class="bg-purple-500 text-white w-6 h-6 rounded-full flex items-center justify-center text-xs">2</span>
實作二:彩虹漸變
</h4>
<div class="space-y-4">
<p class="text-gray-400 leading-relaxed text-sm sm:text-base">
若沒有內建的彩虹特效積木,我們也能自己動手寫!透過單一變數「偏移量」的不斷遞增與遞減,並搭配 6 組迴圈依序改變 RGB 的比例,就能手動調配出完美的彩虹漸變特效。
</p>
<div class="bg-[#1e1e1e] rounded-xl border border-gray-700 overflow-hidden shadow-2xl mt-4">
<div class="bg-[#2d2d2d] px-4 py-3 flex items-center gap-2 border-b border-gray-700">
<div class="w-3 h-3 rounded-full bg-red-500"></div>
<div class="w-3 h-3 rounded-full bg-yellow-500"></div>
<div class="w-3 h-3 rounded-full bg-green-500"></div>
<span class="ml-4 text-xs text-gray-400 font-mono">manual_rainbow_flow.block</span>
</div>
<div class="p-4 sm:p-6 overflow-x-auto text-sm sm:text-base font-mono leading-relaxed text-gray-300">
<pre><code class="grid grid-cols-[max-content_1fr] gap-x-4 sm:gap-x-6 gap-y-1">
<span class="col-span-2"><span class="text-blue-400">變數</span> 偏移量 <span class="text-pink-500">設為</span> <span class="text-purple-400">0</span></span>
<span class="col-span-2 text-green-500 mt-2">// 1. 紅 → 黃</span>
<span class="col-span-2"><span class="text-pink-500">重複</span> <span class="text-purple-400">50</span> <span class="text-pink-500">次</span></span>
<span class="col-span-2"> <span class="text-yellow-200">設 WS2812燈條</span> <span class="text-purple-400">8</span> <span class="text-yellow-200">顆中的第</span> <span class="text-purple-400">(全部-1)</span> <span class="text-yellow-200">顆 紅</span> <span class="text-purple-400">255</span> <span class="text-yellow-200">綠</span> <span class="text-blue-400">偏移量</span> <span class="text-yellow-200">藍</span> <span class="text-purple-400">0</span></span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 偏移量 <span class="text-pink-500">改變</span> <span class="text-purple-400">5</span></span>
<span class="col-span-2 text-green-500 mt-2">// 2. 黃 → 綠</span>
<span class="col-span-2"><span class="text-pink-500">重複</span> <span class="text-purple-400">50</span> <span class="text-pink-500">次</span></span>
<span class="col-span-2"> <span class="text-yellow-200">設 WS2812燈條</span> <span class="text-purple-400">8</span> <span class="text-yellow-200">顆中的第</span> <span class="text-purple-400">(全部-1)</span> <span class="text-yellow-200">顆 紅</span> <span class="text-blue-400">偏移量</span> <span class="text-yellow-200">綠</span> <span class="text-purple-400">255</span> <span class="text-yellow-200">藍</span> <span class="text-purple-400">0</span></span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 偏移量 <span class="text-pink-500">改變</span> <span class="text-purple-400">-5</span></span>
<span class="col-span-2 text-green-500 mt-2">// 3. 綠 → 青</span>
<span class="col-span-2"><span class="text-pink-500">重複</span> <span class="text-purple-400">50</span> <span class="text-pink-500">次</span></span>
<span class="col-span-2"> <span class="text-yellow-200">設 WS2812燈條</span> <span class="text-purple-400">8</span> <span class="text-yellow-200">顆中的第</span> <span class="text-purple-400">(全部-1)</span> <span class="text-yellow-200">顆 紅</span> <span class="text-purple-400">0</span> <span class="text-yellow-200">綠</span> <span class="text-purple-400">255</span> <span class="text-yellow-200">藍</span> <span class="text-blue-400">偏移量</span></span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 偏移量 <span class="text-pink-500">改變</span> <span class="text-purple-400">5</span></span>
<span class="col-span-2 text-green-500 mt-2">// 4. 青 → 藍</span>
<span class="col-span-2"><span class="text-pink-500">重複</span> <span class="text-purple-400">50</span> <span class="text-pink-500">次</span></span>
<span class="col-span-2"> <span class="text-yellow-200">設 WS2812燈條</span> <span class="text-purple-400">8</span> <span class="text-yellow-200">顆中的第</span> <span class="text-purple-400">(全部-1)</span> <span class="text-yellow-200">顆 紅</span> <span class="text-purple-400">0</span> <span class="text-yellow-200">綠</span> <span class="text-blue-400">偏移量</span> <span class="text-yellow-200">藍</span> <span class="text-purple-400">255</span></span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 偏移量 <span class="text-pink-500">改變</span> <span class="text-purple-400">-5</span></span>
<span class="col-span-2 text-green-500 mt-2">// 5. 藍 → 紫</span>
<span class="col-span-2"><span class="text-pink-500">重複</span> <span class="text-purple-400">50</span> <span class="text-pink-500">次</span></span>
<span class="col-span-2"> <span class="text-yellow-200">設 WS2812燈條</span> <span class="text-purple-400">8</span> <span class="text-yellow-200">顆中的第</span> <span class="text-purple-400">(全部-1)</span> <span class="text-yellow-200">顆 紅</span> <span class="text-blue-400">偏移量</span> <span class="text-yellow-200">綠</span> <span class="text-purple-400">0</span> <span class="text-yellow-200">藍</span> <span class="text-purple-400">255</span></span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 偏移量 <span class="text-pink-500">改變</span> <span class="text-purple-400">5</span></span>
<span class="col-span-2 text-green-500 mt-2">// 6. 紫 → 紅</span>
<span class="col-span-2"><span class="text-pink-500">重複</span> <span class="text-purple-400">50</span> <span class="text-pink-500">次</span></span>
<span class="col-span-2"> <span class="text-yellow-200">設 WS2812燈條</span> <span class="text-purple-400">8</span> <span class="text-yellow-200">顆中的第</span> <span class="text-purple-400">(全部-1)</span> <span class="text-yellow-200">顆 紅</span> <span class="text-purple-400">255</span> <span class="text-yellow-200">綠</span> <span class="text-purple-400">0</span> <span class="text-yellow-200">藍</span> <span class="text-blue-400">偏移量</span></span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 偏移量 <span class="text-pink-500">改變</span> <span class="text-purple-400">-5</span></span>
</code></pre>
</div>
</div>
</div>
</div>
<div class="border-t border-gray-800"></div>
<!-- 實作三:進階解析:彩虹流光 -->
<div>
<h4 class="text-lg font-bold text-rose-400 mb-6 flex items-center gap-2">
<span class="bg-rose-500 text-white w-6 h-6 rounded-full flex items-center justify-center text-xs">3</span>
進階解析:彩虹流光
</h4>
<div class="space-y-4">
<p class="text-gray-400 leading-relaxed text-sm sm:text-base">
結合前面的技巧,若要讓彩虹在燈條上「流動」起來,我們可以使用數學的「餘數 (mod)」來計算每顆燈珠在色輪上的位置。這段經典的演算法能精準算出紅、綠、藍的漸變比例!
</p>
<div class="bg-[#1e1e1e] rounded-xl border border-gray-700 overflow-hidden shadow-2xl mt-4">
<div class="bg-[#2d2d2d] px-4 py-3 flex items-center gap-2 border-b border-gray-700">
<div class="w-3 h-3 rounded-full bg-red-500"></div>
<div class="w-3 h-3 rounded-full bg-yellow-500"></div>
<div class="w-3 h-3 rounded-full bg-green-500"></div>
<span class="ml-4 text-xs text-gray-400 font-mono">rainbow_flow_advanced.block</span>
</div>
<div class="p-4 sm:p-6 overflow-x-auto text-sm sm:text-base font-mono leading-relaxed text-gray-300">
<pre><code class="grid grid-cols-[max-content_1fr] gap-x-4 sm:gap-x-6 gap-y-1">
<span class="col-span-2"><span class="text-pink-500">當綠旗被點擊</span></span>
<span class="col-span-2"><span class="text-blue-400">變數</span> 流光 <span class="text-pink-500">設為</span> <span class="text-purple-400">0</span></span>
<span class="col-span-2"></span>
<span class="col-span-2"><span class="text-pink-500">重複無限次</span></span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 位置 <span class="text-pink-500">設為</span> <span class="text-purple-400">1</span></span>
<span class="col-span-2"> </span>
<span class="col-span-2"> <span class="text-pink-500">重複</span> <span class="text-purple-400">8</span> <span class="text-pink-500">次</span></span>
<span> <span class="text-blue-400">變數</span> 偏移量 <span class="text-pink-500">設為</span> (<span class="text-blue-400">流光</span> + (<span class="text-blue-400">位置</span> - <span class="text-purple-400">1</span>) * <span class="text-purple-400">32</span>) <span class="text-pink-500">mod</span> <span class="text-purple-400">256</span></span><span class="text-green-500">// 算出每顆燈的色相</span>
<span class="col-span-2"> </span>
<span class="col-span-2 text-green-500"> // 🌈 彩虹顏色計算 (色輪切分三段)</span>
<span class="col-span-2"> <span class="text-pink-500">如果</span> <span class="text-blue-400">偏移量</span> < <span class="text-purple-400">85</span> <span class="text-pink-500">那麼</span></span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 紅色 <span class="text-pink-500">設為</span> (<span class="text-purple-400">255</span> - <span class="text-blue-400">偏移量</span> * <span class="text-purple-400">3</span>)</span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 綠色 <span class="text-pink-500">設為</span> (<span class="text-blue-400">偏移量</span> * <span class="text-purple-400">3</span>)</span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 藍色 <span class="text-pink-500">設為</span> <span class="text-purple-400">0</span></span>
<span class="col-span-2"> </span>
<span class="col-span-2"> <span class="text-pink-500">否則如果</span> <span class="text-blue-400">偏移量</span> < <span class="text-purple-400">170</span> <span class="text-pink-500">那麼</span></span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 偏移量 <span class="text-pink-500">設為</span> <span class="text-blue-400">偏移量</span> - <span class="text-purple-400">85</span></span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 紅色 <span class="text-pink-500">設為</span> <span class="text-purple-400">0</span></span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 綠色 <span class="text-pink-500">設為</span> (<span class="text-purple-400">255</span> - <span class="text-blue-400">偏移量</span> * <span class="text-purple-400">3</span>)</span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 藍色 <span class="text-pink-500">設為</span> (<span class="text-blue-400">偏移量</span> * <span class="text-purple-400">3</span>)</span>
<span class="col-span-2"> </span>
<span class="col-span-2"> <span class="text-pink-500">否則</span></span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 偏移量 <span class="text-pink-500">設為</span> <span class="text-blue-400">偏移量</span> - <span class="text-purple-400">170</span></span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 紅色 <span class="text-pink-500">設為</span> (<span class="text-blue-400">偏移量</span> * <span class="text-purple-400">3</span>)</span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 綠色 <span class="text-pink-500">設為</span> <span class="text-purple-400">0</span></span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 藍色 <span class="text-pink-500">設為</span> (<span class="text-purple-400">255</span> - <span class="text-blue-400">偏移量</span> * <span class="text-purple-400">3</span>)</span>
<span class="col-span-2"> </span>
<span class="col-span-2 text-green-500"> // 💡 設定燈</span>
<span class="col-span-2"> <span class="text-yellow-200">設 WS2812燈條</span> <span class="text-purple-400">8</span> <span class="text-yellow-200">顆中的第</span> <span class="text-blue-400">(位置)</span> <span class="text-yellow-200">顆 紅</span> <span class="text-blue-400">(紅色)</span> <span class="text-yellow-200">綠</span> <span class="text-blue-400">(綠色)</span> <span class="text-yellow-200">藍</span> <span class="text-blue-400">(藍色)</span></span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 位置 <span class="text-pink-500">改變</span> <span class="text-purple-400">1</span></span>
<span class="col-span-2"> </span>
<span> <span class="text-blue-400">變數</span> 流光 <span class="text-pink-500">改變</span> <span class="text-purple-400">5</span></span><span class="text-green-500">// 推進流光動畫</span>
<span> <span class="text-yellow-200">等待</span> <span class="text-purple-400">0.1</span> <span class="text-yellow-200">秒</span></span><span class="text-green-500">// 控制流動速度</span>
</code></pre>
</div>
</div>
</div>
</div>
</div>
`;
}
// --- 單元二 RGB 色彩混合器邏輯 ---
function initUnit2Demo() {
const rRange = document.getElementById('rRange');
const gRange = document.getElementById('gRange');
const bRange = document.getElementById('bRange');
const rVal = document.getElementById('rVal');
const gVal = document.getElementById('gVal');
const bVal = document.getElementById('bVal');
const colorPreview = document.getElementById('colorPreview');
const rgbText = document.getElementById('rgbText');
const hexText = document.getElementById('hexText');
const presetBtns = document.querySelectorAll('.preset-btn');
if (!rRange) return; // 防呆
function componentToHex(c) {
var hex = parseInt(c).toString(16);
return hex.length == 1 ? "0" + hex : hex;
}
function rgbToHex(r, g, b) {
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}
function updateColor() {
const r = rRange.value;
const g = gRange.value;
const b = bRange.value;
rVal.textContent = r;
gVal.textContent = g;
bVal.textContent = b;
const color = `rgb(${r}, ${g}, ${b})`;
const hex = rgbToHex(r, g, b).toUpperCase();
colorPreview.style.backgroundColor = color;
rgbText.textContent = `${r},${g},${b}`;
hexText.textContent = hex;
}
// 監聽滑桿
rRange.addEventListener('input', updateColor);
gRange.addEventListener('input', updateColor);
bRange.addEventListener('input', updateColor);
// 監聽快捷按鈕
presetBtns.forEach(btn => {
btn.addEventListener('click', (e) => {
rRange.value = e.target.getAttribute('data-r');
gRange.value = e.target.getAttribute('data-g');
bRange.value = e.target.getAttribute('data-b');
updateColor();
});
});
// 初始化顏色
updateColor();
}
// --- 單元三專屬:OLED 圖片轉換器與邏輯 ---
function getUnit3DemoHTML() {
return `
<div class="bg-gray-900 text-gray-100 p-6 sm:p-8 rounded-2xl shadow-inner overflow-hidden space-y-12">
<div class="flex items-center gap-3 border-b border-gray-700 pb-4">
<i data-lucide="layers" class="w-8 h-8 text-purple-400"></i>
<h3 class="text-xl sm:text-2xl font-bold text-white tracking-wide">積木邏輯解析與進階工具</h3>
</div>
<!-- 實作一:清單與文字掉落效果 -->
<div>
<h4 class="text-lg font-bold text-blue-400 mb-6 flex items-center gap-2">
<span class="bg-blue-500 text-white w-6 h-6 rounded-full flex items-center justify-center text-xs">1</span>
實作一:清單與文字掉落效果
</h4>
<p class="text-gray-400 leading-relaxed text-sm sm:text-base mb-4">
要製作文字掉落效果,我們可以利用變數不斷增加文字的「顯示列數」。由於 OLED 螢幕通常分為 4 列,當文字超過螢幕底部時,就換下一個句子從第 1 列重新掉落。搭配<strong>「清單 (List)」</strong>積木來存放多個句子,邏輯簡單又有趣!
</p>
<div class="bg-[#1e1e1e] rounded-xl border border-gray-700 overflow-hidden shadow-2xl mt-4">
<div class="bg-[#2d2d2d] px-4 py-3 flex items-center gap-2 border-b border-gray-700">
<div class="w-3 h-3 rounded-full bg-red-500"></div>
<div class="w-3 h-3 rounded-full bg-yellow-500"></div>
<div class="w-3 h-3 rounded-full bg-green-500"></div>
<span class="ml-4 text-xs text-gray-400 font-mono">falling_text_with_list.block</span>
</div>
<div class="p-4 sm:p-6 overflow-x-auto text-sm sm:text-base font-mono leading-relaxed text-gray-300">
<pre><code class="grid grid-cols-[max-content_1fr] gap-x-4 sm:gap-x-6 gap-y-2">
<span class="col-span-2"><span class="text-pink-500">清單</span> 顯示訊息 <span class="text-pink-500">新增</span> <span class="text-orange-300">"Hello 5016B!"</span></span>
<span class="col-span-2"><span class="text-pink-500">清單</span> 顯示訊息 <span class="text-pink-500">新增</span> <span class="text-orange-300">"NKNUBLOCK"</span></span>
<span class="col-span-2"><span class="text-blue-400">變數</span> 列數 <span class="text-pink-500">設為</span> <span class="text-purple-400">1</span></span>
<span class="col-span-2"><span class="text-blue-400">變數</span> 項目索引 <span class="text-pink-500">設為</span> <span class="text-purple-400">1</span></span>
<span class="col-span-2"></span>
<span class="col-span-2"><span class="text-pink-500">重複無限次</span></span>
<span> <span class="text-blue-400">變數</span> 當前文字 <span class="text-pink-500">設為</span> (<span class="text-pink-500">清單</span> 顯示訊息 <span class="text-pink-500">的第</span> <span class="text-blue-400">項目索引</span> <span class="text-pink-500">項</span>)</span><span class="text-green-500">// 取出目前要播的字</span>
<span> <span class="text-yellow-200">OLED 清除I2C 位址</span> <span class="text-purple-400">0x3C</span></span><span class="text-green-500">// 1. 清除上一幀畫面</span>
<span class="col-span-2"> </span>
<span> <span class="text-pink-500">如果</span> <span class="text-blue-400">列數</span> < <span class="text-purple-400">5</span> <span class="text-pink-500">則</span></span><span class="text-green-500">// OLED 畫面通常有 4 列</span>
<span> <span class="text-yellow-200">OLED 第</span> <span class="text-blue-400">列數</span> <span class="text-yellow-200">列 第</span> <span class="text-purple-400">1</span> <span class="text-yellow-200">格 顯示</span> (<span class="text-blue-400">當前文字</span>) <span class="text-yellow-200">I2C位址</span> <span class="text-purple-400">0x3C</span></span><span class="text-green-500">// 顯示在對應列</span>
<span class="col-span-2"> </span>
<span> <span class="text-blue-400">變數</span> 列數 <span class="text-pink-500">改變</span> <span class="text-purple-400">1</span></span><span class="text-green-500">// 列數增加,文字往下掉落</span>
<span> <span class="text-yellow-200">等待</span> <span class="text-purple-400">0.5</span> <span class="text-yellow-200">秒</span></span><span class="text-green-500">// 控制掉落速度</span>
<span class="col-span-2"> </span>
<span> <span class="text-pink-500">如果</span> <span class="text-blue-400">列數</span> > <span class="text-purple-400">4</span> <span class="text-pink-500">則</span></span><span class="text-green-500">// 當文字掉出畫面底部時</span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 列數 <span class="text-pink-500">設為</span> <span class="text-purple-400">1</span></span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 項目索引 <span class="text-pink-500">改變</span> <span class="text-purple-400">1</span></span>
<span> <span class="text-pink-500">如果</span> <span class="text-blue-400">項目索引</span> > <span class="text-pink-500">長度</span>(<span class="text-pink-500">清單</span> 顯示訊息) <span class="text-pink-500">則</span></span><span class="text-green-500">// 播完最後一項,回到第一項</span>
<span class="col-span-2"> <span class="text-blue-400">變數</span> 項目索引 <span class="text-pink-500">設為</span> <span class="text-purple-400">1</span></span>
</code></pre>
</div>
</div>
</div>
<div class="border-t border-gray-800"></div>
<!-- 實作二:字元圖案拼貼 (ASCII Art) -->
<div>
<h4 class="text-lg font-bold text-green-400 mb-6 flex items-center gap-2">
<span class="bg-green-500 text-white w-6 h-6 rounded-full flex items-center justify-center text-xs">2</span>
實作二:字元圖案拼貼 (ASCII Art)
</h4>
<p class="text-gray-400 leading-relaxed text-sm sm:text-base mb-4">
當積木只支援「列與格」的文字顯示時,我們依然能發揮創意繪圖!這稱為「字元畫」,只要利用鍵盤符號並分配在不同的列,就能拼湊出可愛的圖案。
</p>
<div class="bg-[#1e1e1e] rounded-xl border border-gray-700 overflow-hidden shadow-2xl mt-4">
<div class="bg-[#2d2d2d] px-4 py-3 flex items-center gap-2 border-b border-gray-700">
<div class="w-3 h-3 rounded-full bg-red-500"></div>
<div class="w-3 h-3 rounded-full bg-yellow-500"></div>
<div class="w-3 h-3 rounded-full bg-green-500"></div>
<span class="ml-4 text-xs text-gray-400 font-mono">ascii_art.block</span>
</div>
<div class="p-4 sm:p-6 overflow-x-auto text-sm sm:text-base font-mono leading-relaxed text-gray-300">
<pre><code class="grid grid-cols-[max-content_1fr] gap-x-4 sm:gap-x-6 gap-y-2">
<span class="col-span-2 text-green-500">// 🎨 例子一:小貓咪</span>
<span class="col-span-2"><span class="text-yellow-200">OLED 清除I2C 位址</span> <span class="text-purple-400">0x3C</span></span>
<span class="col-span-2"><span class="text-yellow-200">OLED 第</span> <span class="text-purple-400">1</span> <span class="text-yellow-200">列 第</span> <span class="text-purple-400">4</span> <span class="text-yellow-200">格 顯示</span> <span class="text-orange-300">" /\\_/\\ "</span> <span class="text-yellow-200">I2C位址</span> <span class="text-purple-400">0x3C</span></span><span class="text-green-500">// 貓咪耳朵</span>
<span class="col-span-2"><span class="text-yellow-200">OLED 第</span> <span class="text-purple-400">2</span> <span class="text-yellow-200">列 第</span> <span class="text-purple-400">4</span> <span class="text-yellow-200">格 顯示</span> <span class="text-orange-300">"( o.o )"</span> <span class="text-yellow-200">I2C位址</span> <span class="text-purple-400">0x3C</span></span><span class="text-green-500">// 貓咪眼睛</span>
<span class="col-span-2"><span class="text-yellow-200">OLED 第</span> <span class="text-purple-400">3</span> <span class="text-yellow-200">列 第</span> <span class="text-purple-400">4</span> <span class="text-yellow-200">格 顯示</span> <span class="text-orange-300">" > ^ < "</span> <span class="text-yellow-200">I2C位址</span> <span class="text-purple-400">0x3C</span></span><span class="text-green-500">// 貓咪嘴巴</span>
<span class="col-span-2"> </span>
<span class="col-span-2 text-green-500">// 🎨 例子二:小兔子</span>
<span class="col-span-2"><span class="text-yellow-200">OLED 清除I2C 位址</span> <span class="text-purple-400">0x3C</span></span>
<span class="col-span-2"><span class="text-yellow-200">OLED 第</span> <span class="text-purple-400">1</span> <span class="text-yellow-200">列 第</span> <span class="text-purple-400">4</span> <span class="text-yellow-200">格 顯示</span> <span class="text-orange-300">" (\\(\\ "</span> <span class="text-yellow-200">I2C位址</span> <span class="text-purple-400">0x3C</span></span><span class="text-green-500">// 兔子耳朵</span>
<span class="col-span-2"><span class="text-yellow-200">OLED 第</span> <span class="text-purple-400">2</span> <span class="text-yellow-200">列 第</span> <span class="text-purple-400">4</span> <span class="text-yellow-200">格 顯示</span> <span class="text-orange-300">" ( -.-) "</span> <span class="text-yellow-200">I2C位址</span> <span class="text-purple-400">0x3C</span></span><span class="text-green-500">// 兔子臉</span>
<span class="col-span-2"><span class="text-yellow-200">OLED 第</span> <span class="text-purple-400">3</span> <span class="text-yellow-200">列 第</span> <span class="text-purple-400">4</span> <span class="text-yellow-200">格 顯示</span> <span class="text-orange-300">" o_(\")(\")"</span> <span class="text-yellow-200">I2C位址</span> <span class="text-purple-400">0x3C</span></span><span class="text-green-500">// 兔子腳</span>
</code></pre>
</div>
</div>
</div>
<div class="border-t border-gray-800"></div>
<!-- 進階挑戰:預設收合,讓初學者先聚焦基礎實作 -->
<details class="group rounded-2xl border border-purple-500/30 bg-gray-800/40 p-5">
<summary class="cursor-pointer list-none text-lg font-bold text-purple-300 focus-visible:outline focus-visible:outline-4 focus-visible:outline-offset-4 focus-visible:outline-purple-300">
<span class="flex items-center justify-between gap-4">
進階挑戰:跑馬燈與圖片轉碼工具
<i data-lucide="chevron-down" class="h-5 w-5 transition-transform group-open:rotate-180"></i>
</span>
</summary>
<div class="mt-8 space-y-12">
<!-- 實作三:進階跑馬燈解析 -->
<div>
<h4 class="text-lg font-bold text-amber-400 mb-6 flex items-center gap-2">
<span class="bg-amber-500 text-white w-6 h-6 rounded-full flex items-center justify-center text-xs">3</span>
實作三:進階跑馬燈解析 (字串裁切挑戰)
</h4>
<div class="flex flex-col lg:flex-row gap-8 items-center lg:items-start">
<div class="lg:w-1/2 space-y-4">
<p class="text-gray-400 leading-relaxed text-sm sm:text-base">
雖然前面我們利用「文字掉落」避開了複雜的邏輯,但如果你想挑戰最完美的「跑馬燈」效果,讓文字從螢幕右側滑入,並在左側邊緣<strong>「一個字一個字消失」</strong>,可以參考右方的進階程式圖!
</p>
<div class="bg-gray-800 p-5 rounded-xl border border-gray-700 shadow-lg mt-4">
<h5 class="text-gray-300 font-bold mb-4 flex items-center gap-2">
<i data-lucide="lightbulb" class="w-5 h-5 text-amber-500"></i> 邏輯拆解
</h5>
<ul class="text-sm text-gray-300 space-y-4 list-decimal list-inside leading-relaxed">
<li>
<strong class="text-amber-400">第一階段 (滑入):</strong>
從螢幕最右側 (第 21 格) 開始,格數不斷遞減到第 1 格,讓文字完整向左移動。
</li>
<li>
<strong class="text-amber-400">第二階段 (裁切消失):</strong>
當文字碰到左邊緣 (第 1 格) 時,利用雙層迴圈與「字串組合」積木,每次都從字串中提取後面的字元重新組合,達成<strong>「去掉第一個字」</strong>的效果,創造出平滑消失的視覺魔術。
</li>
</ul>
</div>
</div>
<div class="lg:w-1/2 w-full">
<div class="bg-[#1e1e1e] rounded-xl border border-gray-700 overflow-hidden shadow-2xl p-2 md:p-4">
<!-- 加入相對定位與點擊事件 -->
<button type="button" class="relative block w-full group cursor-pointer focus-visible:outline focus-visible:outline-4 focus-visible:outline-offset-4 focus-visible:outline-amber-400" onclick="openImageModal('images/unit3-ticker.png', this)" aria-label="放大查看進階跑馬燈積木程式">