-
-
-
- {/* */}
-
- {/* */}
-
-
+
+
+
+
+
+ }
+ />
+ } />
+ } />
+
diff --git a/src/data/1.jsx b/src/data/1.jsx
new file mode 100644
index 0000000..5e96a81
--- /dev/null
+++ b/src/data/1.jsx
@@ -0,0 +1,26 @@
+export function Component() {
+ return (
+
+
+ 主要希望使用者可以透過此網站找到適合自己抒發情緒的方式,並以不帶來更多壓力為前提。
+
+
網頁主要提供以下內容:
+
+ 1. 輕鬆有趣的前導測驗。
+ 2. 推薦抒發情緒的地點。
+ 3. 簡單AR互動。
+ 4. 留言板。
+
+
+ );
+}
+
+export function Motive() {
+ return (
+
+
+ 看到一位葡萄牙藝術家為城市做了一張哭泣地圖,覺得用不同角度去看城市這點很新奇、很有趣。經過多次討論後衍生成想做一份提供人們抒發情緒、找回自己的地圖,因此取名為「在生活中迷路了」。
+
+
+ );
+}
diff --git a/src/data/10.jsx b/src/data/10.jsx
new file mode 100644
index 0000000..4f39f33
--- /dev/null
+++ b/src/data/10.jsx
@@ -0,0 +1,23 @@
+export function Component() {
+ return (
+
+
+ 本專題特色在於採用更具體化指標, 以性格形容詞分辨適合科系,更準確判定,
+ 以考慮校風,具體行為表現及個人情況進行分析並運用ai提升精確度,
+ 更有互動性和趣味,
+ 以遊戲作為媒介並整合其它升學資訊如ioh等以方便使用者進一步分析
+
+
+ );
+}
+
+export function Motive() {
+ return (
+
+
+ 曾經作為高中生一員的我們也曾受到升學問題困擾,
+ 所以是次專題動機就是希望借專題讓未來的高中生們不再為此而煩惱
+
+
+ );
+}
diff --git a/src/data/11.jsx b/src/data/11.jsx
new file mode 100644
index 0000000..824e024
--- /dev/null
+++ b/src/data/11.jsx
@@ -0,0 +1,33 @@
+export function Component() {
+ return (
+
+
本專題為一款適用於高齡族群的情境式台語學習平台,內容包含:
+
+ 1. 介面設計:簡潔明瞭,搭配鮮明圖樣與防呆機制,操作簡易。
+
+ 2.
+ 情境式學習:藉由本平台真實情境的場景模擬,並透過聽與說的練習,讓使用者更貼近生活中的常見用語,提升趣味性與應用性的同時可促進學習遷移,讓使用者更具學習動力。{" "}
+
+
+ 3.
+ 語音評分:針對使用者錄音進行判斷給予星等評分,讓使用者自我檢視學習情況並加強自我學習。{" "}
+
+
+ 4. 響應式設計:藉由網絡世界的串接,使得多個媒介都可使用本平台。
+ 藉由上述特點,增強與高齡族群的學習互動及平台實用性,望使用者使用本專題之情境式台語學習平台能助於提升學習效益,並達終身學習。
+
+
+
+ );
+}
+
+export function Motive() {
+ return (
+
+
+ 台灣已於2018年成為高齡社會,面對銀髮族平均壽命延長的情況,除照顧資源不敷使用外,終身學習亦需要重視,銀髮族透過學習因應生活並提升自主能力,更是「成功老化」(successful
+ aging)的重要關鍵。透過與銀髮族本人及銀髮族照顧機構之照顧人員的訪談,了解到銀髮族對於人際互動溝通特別重視,對語言學習也有較多興趣,其中銀髮族熟悉的本土語言──台語,更是他們生活經驗中經常使用的。目前台灣的台語資源網大多著重在單字介紹與拼音念法這兩大面向,無法結合生活中日常用語、語句進行搭配學習,與實際生活應用脫節,因此根據銀髮族對語言學習的興趣與不願意嘗試新事物特性,以及現有台語學習資源的不足,我們希望打造情境式銀髮族台語學習平台,將銀髮族所熟習的台語,與現實生活情境相呼應的教學設計進行結合,讓其更符合實際社交溝通的應用,使銀髮族更容易接受,進行再學習,吸引銀髮族的學習興趣並增加主動學習的動機,以此促進銀髮族在高齡社會中的終身學習。
+
+
+ );
+}
diff --git a/src/data/12.jsx b/src/data/12.jsx
new file mode 100644
index 0000000..336ab01
--- /dev/null
+++ b/src/data/12.jsx
@@ -0,0 +1,22 @@
+export function Component() {
+ return (
+
+
+ 虛擬實境技術在數位教學領域扮演重要角色,並有許多相關研究和可行性探討。然而,目前在生活科技課程中尚未廣泛應用。本專題計畫預計將虛擬實境(VR)結合專家系統,製作一款幫助學習者熟悉木工製作及其原理的學習情境。透過虛擬實境,學習者可獲得身歷其境且互動性強的學習體驗,並由專家系統構建更專業的學習環境,特別是在木工製作、工具應用與工業安全的學習過程中。虛擬實境讓學習者能實際參與虛擬環境中的木工製作過程,深入了解相關應用與原理,專家系統則能引導學生更有效地提升學習成效。這種數位教學方法能激發學習動機,使學習者更積極參與學習,提升效果。引入虛擬實境技術有助於降低真實環境中的風險,減少器材消耗和空間需求,同時由專業人士構建專家系統,提供學生專業需求,避免因資源不足或專業人員稀缺導致的學習差異。此方法不僅為學生提供安全、便捷且專業的學習環境,還有助於節省資源和成本,體現現代教育科技的可持續發展。
+
+
+ );
+}
+
+export function Motive() {
+ return (
+
+
+ 現如今虛擬實境早已於教育界佔據了一席之地,而寓教於樂更是現代教學中不可或缺的一部份,但是在生活科技的領域中,尚有許多知識能藉此技術去進行更加深入的研發和教學內容。
+
+
+ 因此本專題希望藉由將現實中的生活科技常見的加工機具,以放入虛擬實境世界中的方式,讓同學們以一人一台獨立教學的方式,來實現更為深入的機具接觸和更為詳盡的知識解說,並同時結合專家系統,使其能夠針對學生現有學習上的問題去進行特定的教學講解,以期最終能達成透過事先接觸虛擬實境中的加工機具,來為同學們進行更為完善且有趣的實作前教學,使同學們未來能夠更有信心和興趣來面對生活科技這門學科。
+
+
+ );
+}
diff --git a/src/data/13.jsx b/src/data/13.jsx
new file mode 100644
index 0000000..ebee8c7
--- /dev/null
+++ b/src/data/13.jsx
@@ -0,0 +1,29 @@
+export function Component() {
+ return (
+
+
+ 本平台希望能讓各地的高中生可以有更多的交流,從中找到多元背景、志同道合的夥伴。
+
+
具體而言,本平台有三大特色功能:
+
+
+ 1.
+ 夥伴媒合:從發起、瀏覽新奇點子,媒合交流,找到志同道合的夥伴,一起實踐點子{" "}
+
+ 2. 歷程紀錄:保存每一段經驗,成為未來的路途的基石
+ 3. 個人化比賽推廣:推薦最適合的比賽增加得獎機會,讓專案走得更遠
+
+
+ );
+}
+
+export function Motive() {
+ return (
+
+
+ 專題成員們在高中時期都有過「腦中浮現出很讚的想法,但因外在因素無法實踐」的經驗,其中一個主要外在因素是「缺乏志同道合的夥伴」。在108課綱實施後,學生們更願意將時間投入在自己喜歡的領域。因此,我們希望透過
+ Ideashare,減少高中生在實踐自己想法時遇到的困難,不再因缺少夥伴而止步不前。
+
+
+ );
+}
diff --git a/src/data/2.jsx b/src/data/2.jsx
new file mode 100644
index 0000000..0f6ef41
--- /dev/null
+++ b/src/data/2.jsx
@@ -0,0 +1,27 @@
+export function Component() {
+ return (
+
+
+ 結合SDGs永續致展目標,促進食物控管,減少食物浪費以達成負責任的消費方式,並且推廣消除飢餓的理念,也避免重複購買品項以減少不必要支出。
+
+
+ 由此,我們發想出Pantry
+ Pal,提供給想減少食物浪費的群眾,有一個輕鬆、便利的管道妥善管理他們的食材,透過智能提醒功能確保不會遺漏任何重要事項
+ !
+ 其中,連結了google日曆的行事曆顯示食材過期日,並且可以設定過期提醒,減少繁瑣的整理和管理食材的時間。並且結合掃描和影像辨識技術、食譜推薦功能提升使用者操作的便利性。以及增設群組功能方便與親友共同管理食材,家庭或室友群組的建立讓多位使用者輕鬆共享資訊,即時了解共享食材庫存情況,避免重複購買導致食材浪費。無論是在家裡做菜,還是外出購物,Pantry
+ Pal都能成為最貼心的助手,為使用者帶來更加輕鬆、方便的質感生活體驗 !{" "}
+
+
+ );
+}
+
+export function Motive() {
+ return (
+
+
+ 現代生活中,繁忙的生活節奏常使我們無暇關注食材的購買與管理,導致了許多不必要的食物浪費,為了解決這一問題,我們開發了一個專為管理食材而設計的網站:Pantry
+ Pal,目的是協助想要減少食材等浪費的群眾可以有效管理食材,減少浪費。
+
+
+ );
+}
diff --git a/src/data/3.jsx b/src/data/3.jsx
new file mode 100644
index 0000000..c233683
--- /dev/null
+++ b/src/data/3.jsx
@@ -0,0 +1,37 @@
+export function Component() {
+ return (
+
+
+ 本專題是以露營作為使用情境,針對「便攜帶、易收納、好清潔」等概念進行進一步的設計,並以達到「保冷及致冷、適應不同環境使用、攜帶與收納便利、簡易零件更換與方便清潔」等效果進行探討、研究與產品實作。
+
+
+ 這項產品有三項主要特色;其一為以致冷晶片達到保冷與致冷;其二為方便收納、攜帶與清潔的組裝式設計;其三為能夠簡易更換零件的模組化設計,分為「致冷模組」、「溫溼度模組」、「箱體部分」等部分。
+
+
+ 使用致冷晶片能減少冰箱的重量,我們也能配合所學,以arduino、各項電子電路元件進行致冷系統的設計,這樣的實作,亦與便攜、組裝等特色更好結合。
+
+
+ 組裝式設計則是本項產品的亮點,現今市場中,我們並沒有發現組裝式冰箱這樣的設計,透過此次專題,我們便能嘗試創新,並進行預期概念與效果的融入。
+
+
+ 模組化設計則是讓冰箱更符合使用者需求,其一為零件的簡易更換,其二為不同功能模組的融入。
+
+
+ 透過以上設計、對於露營的需求、使用情境的實際使用,本產品的發展性未來可期,若能持續進行改進、並融合更多技術,也能有更多目標的設立與實踐。
+
+
+ );
+}
+
+export function Motive() {
+ return (
+
+
+ 疫情解封後,露營風氣在國內漸增,各式露營用品都有新型設計,但市面上的冰箱較少針對露營需求做設計,價格亦較昂貴。因此我們針對露營的使用情境,做外觀與內部的改良與設計。預期把「便攜帶、易收納、好清潔」的概念放進冰箱設計。
+
+
+ 針對露營用冰箱,我們希望將上述概念融入,因此這次產品預計能達到「保冷及致冷、適應不同環境使用、攜帶與收納便利、簡易零件更換與方便清潔」的效果。
+
+
+ );
+}
diff --git a/src/data/4.jsx b/src/data/4.jsx
new file mode 100644
index 0000000..8c6fff9
--- /dev/null
+++ b/src/data/4.jsx
@@ -0,0 +1,28 @@
+export function Component() {
+ return (
+
+
+ 在人手一杯手搖的時代,ECO
+ LID旨在幫助使用者了解自身與家人的飲水紀錄,來改善其正確的飲水觀念與意識。ECO
+ LID結合了藍牙、聲波感測、APP功能等技術,使數據能夠及時的回傳至使用者的手機中,來觀察家人們的飲水習慣,以注重於自身與家庭成員的健康。
+
+
+ );
+}
+
+export function Motive() {
+ return (
+
+
+ 隨著環保意識持續高漲,雖然紙杯和近年推動的循環杯能有效減少塑膠用量,但塑膠杯蓋和塑膠封膜無法重複使用,容易被丟棄,對環境造成極大的負擔。
+
+
+ 此外,飲水是維持健康不可或缺的一環,但國民普遍缺乏正確的飲水習慣與觀念。因此,我們結合環保與健康兩大議題,成立了ECO
+ LID研究計畫。ECO取自eco-friendly的前三個字,代表環保,也利用諧音「一口、一口」提醒大家培養良好的飲水習慣。
+
+
+ 我們希望透過蒐集正確的飲水觀念和分析市售產品,製作出環保杯蓋及概念環保杯。這些產品將透過飲水提醒與飲水量紀錄,引導使用者達到健康飲水的目的,並了解飲水對健康的重要性。
+
+
+ );
+}
diff --git a/src/data/5.jsx b/src/data/5.jsx
new file mode 100644
index 0000000..28325a8
--- /dev/null
+++ b/src/data/5.jsx
@@ -0,0 +1,70 @@
+export function Component() {
+ return (
+
+
+ 本產品旨在結合CAD建模技術、CAM加工技術、人因分析製作一創新設計替換式螺絲起子以解決使用效率、螺絲頭遺失、舒適性等問題。
+
+
材料:
+
+ 高強度材料:採用金屬材料和耐磨塑膠材料,確保耐用性和使用壽命。
+ 輕便設計:整體輕量化設計,減少手部負擔,方便長時間使用。
+
+
設計理念:
+
+
+ 人體工學:符合人體工學的握把設計,提供極佳的握持感,減少手部疲勞。
+
+ 精密設計:替換式螺絲頭的安裝和拆卸簡便,保證操作的流暢性。
+ 安全性:防滑握把設計和穩固的螺絲頭固定機制,提升使用安全性。
+
+
功能:
+
+ 高效操作:結合先進的CAD和CAM技術,大幅提升使用效率和精準度。
+ 多用途:提供多種螺絲規格,滿足不同工作需求。
+ 防遺失設計:有效降低螺絲頭遺失的機率,保證工作的連續性和效率。
+ 便捷替換:螺絲頭替換簡單快速,適合各種工作場景。
+
+
+ );
+}
+
+export function Motive() {
+ return (
+
+
+ 螺絲起子作為現代人工作和生活中的一個重要工具,無論是在家庭修補、DIY專案還是工業製造中,
+ 都扮演著關鍵的角色。而人們期望工具不僅僅具有功能性的,更希望它們能夠提高效率、節省時間,甚至提供更好的使用體驗。因此,我們決定設計與開發新的螺絲起子,以滿足人們對工具的需求和期望。
+
+
+ 當我們開始著手設計這款新的螺絲起子時,首先進行了市場調查,透過分析現有之螺絲起子組,並深入了解用戶的需求和痛點。從調查中我們發現,多數用戶希望螺絲起子能夠具備以下特點:
+
+
需求:
+
+
+ 多功能性:現代生活和工作中涉及的應用場景多樣,用戶希望一把螺絲起子能夠應對不同種類的螺絲,減少更換工具的麻煩。
+
+
+ 人體工學設計:長時間使用工具容易引發疲勞和不適,因此用戶希望螺絲起子能夠符合人體工學設計,握持舒適,減少手部壓力。
+
+
+ 便攜性和收納便利性:隨著生活節奏的加快,便於攜帶和收納的工具越來越受到青睞。用戶希望螺絲起子能夠易於攜帶,並且配有合理的收納設計。
+
+
+ 耐用性:用戶希望螺絲起子能夠長時間使用而不損壞,對材料和製作工藝有著較高的要求。
+
+
+
痛點:
+
+
+ 螺絲頭丟失:使用傳統螺絲起子時,螺絲頭經常容易丟失,導致工作進度受阻,增加了使用者的困擾。
+
+
+ 過多無用螺絲頭:許多工具套裝中包含大量用戶不常用的螺絲頭,導致浪費和收納困難。用戶希望螺絲起子配置的螺絲頭更具針對性,符合常見的使用需求。
+
+
+
+ 基於這些需求和痛點,我們決定研發一款新的螺絲起子,以解決用戶面臨的問題。我們的目標是創造一款功能多樣、設計符合人體工學、便於攜帶和收納且耐用的螺絲起子,並且有效解決螺絲頭容易丟失的問題。透過這些努力,我們希望能夠提升用戶的使用體驗,讓他們在工作和生活中更加高效和便捷。
+
+
+ );
+}
diff --git a/src/data/6.jsx b/src/data/6.jsx
new file mode 100644
index 0000000..a75b1cb
--- /dev/null
+++ b/src/data/6.jsx
@@ -0,0 +1,36 @@
+export function Component() {
+ return (
+
+
+ 本專題旨在開發一款專為大學生設計的記帳APP,旨在解決大學生在日常財務管理中的諸多挑戰。核心功能包括將「想要的開銷」獨立分類、利用KANO模型分析消費滿意度,以及提供校園論壇以便分享生活優惠消息,從而全面提升財務管理效能。
+
+
+ 最初,我們透過問卷調查發現許多大學生都有記帳的習慣。他們希望通過記帳來控制開銷,理清財務狀況,然而,很少有人能夠因為記帳而顯著降低自己的生活開支。此現象引發了我們的思考:為什麼記帳這個行為,沒有帶來預期的財務改善效果?經過進一步研究,我們發現單純記錄開支數據並不足以改變消費行為,需要更多的分析和引導來幫助用戶做出更明智的財務決策。
+
+
+ 所以,我們設計了這款APP,旨在幫助大學生更好地管理財務,從而實現更高效的生活開支控制。首先,我們將「想要的開銷」與其他必要開支分開記錄,用戶可以更清楚地了解哪些是必需的開銷,哪些是想要的消費。這種分類不僅有助於用戶在回顧開支時可以調整自己的消費習慣,還能在往後消費時做出更明智的選擇。
+
+
+ {" "}
+ 此外,我們引入了KANO模型來分析不同功能對用戶滿意度的影響。通過定期收集消費習慣的數據,我們可以識別出哪些消費是用戶需要與不需要的,從而持續改進APP的功能和使用體驗。這種以用戶需求為導向的設計思路,保證了我們的APP能夠不斷適應用戶的需求變化,提供更加貼心和高效的服務。
+
+
+ {" "}
+ 最後,校園論壇為用戶提供了一個互相交流、分享省錢技巧和優惠訊息的平台。在這裡,用戶可以分享自己的記帳經驗、省錢妙招和各種校園周邊生活優惠信息。這不僅豐富了用戶的記帳體驗,也促進了用戶間的連結。
+
+
+ 總之,我們的目標是通過這款APP,幫助大學生更好地理解和管理自己的財務,實現更明智的消費和更高效的生活開支控制。
+
+
+ );
+}
+
+export function Motive() {
+ return (
+
+
+ 多數大學生面臨著經濟壓力與消費誘惑,儘管許多人已養成記帳習慣,但常因缺乏有效的財務規劃與分析工具,未能達成「省錢」之目的,使得記帳只能流於形式的紀錄。
+
+
+ );
+}
diff --git a/src/data/7.jsx b/src/data/7.jsx
new file mode 100644
index 0000000..8ec8446
--- /dev/null
+++ b/src/data/7.jsx
@@ -0,0 +1,19 @@
+export function Component() {
+ return (
+
+
+ 透過分析碳權相關資料的圖形關聯性,利用各個節點之間的關係來研究未來碳市場的可能動向。同時因為區塊鏈上的資料是透明、公開且不可竄改的,所以我們選擇藉由區塊鏈上的碳權貨幣交易作為研究的主要內容。製作網站,簡潔俐落的UI介面向觀看者解說何謂碳權以及所延伸的相關議題,給予想了解相關知識的人一個入門的管道。
+
+
+ );
+}
+
+export function Motive() {
+ return (
+
+
+ 碳權是一種讓公司或國家能夠合法排放一定量溫室氣體的許可證。碳權交易是指企業或國家之間買賣溫室氣體排放許可證的行為。因此碳交易也讓各國和產業可以共同努力實現減排目標,推動低碳技術的發展,並促進全球減少碳排放。所以碳權是當今重要的社會議題之一,我們認為研究此議題有一定的發展性,同時因為對於學生的我們來說,其實大部分人對於碳權是什麼都不太了解,所以希望透過我們的網站可以讓更多不清楚此議題的人對其有初步的認識,並且透過視覺化的方式代替密密麻麻的數據來讓使用者更能一眼得知此筆資料的意義。
+
+
+ );
+}
diff --git a/src/data/8.jsx b/src/data/8.jsx
new file mode 100644
index 0000000..175cc38
--- /dev/null
+++ b/src/data/8.jsx
@@ -0,0 +1,29 @@
+export function Component() {
+ return (
+
+
+ 遊戲玩法與機制:
+ 每回合,玩家會抽出3間受災戶,並通過一回合三個行動去救援房屋。每經過幾個回合,會有隨機事件發生,增加遊戲的挑戰性和變數。遊戲的目標是在指定時間內確保20間房屋沒有損毀,並最終結算各玩家獲得的物資,物資多者獲勝。
+
+
地圖卡:展示城市及其各個區域。
+
獎勵卡:玩家完成任務後獲得的獎勵。
+
角色卡:玩家所扮演的角色,包含特定技能和能力。
+
隨機事件卡:描述城市中突發的危機事件。
+
+
+ 核心理念:
+ 遊戲的核心理念是通過桌遊拉近人與人之間的距離,並在輕鬆有趣的氛圍中,讓玩家學習和體會團隊合作的重要性。透過設定具體的遊戲目標,玩家達成目標的過程中,間接地證明學會了團隊合作,達到教育的目的。
+
+
+ );
+}
+
+export function Motive() {
+ return (
+
+
+ 我們的製作動機是通過桌遊這種輕鬆有趣的方式,強調團隊合作的重要性,並將其應用於教育中。隨著現代社會對於團隊合作能力的需求不斷增長,我們希望通過這款遊戲,讓玩家在享受遊戲樂趣的同時,學會有效的溝通、協作和問題解決技巧,並提升個人及團隊的成長和績效。
+
+
+ );
+}
diff --git a/src/data/9.jsx b/src/data/9.jsx
new file mode 100644
index 0000000..ea05aac
--- /dev/null
+++ b/src/data/9.jsx
@@ -0,0 +1,26 @@
+export function Component() {
+ return (
+
+
+ 《星海尋航》是一款以 MBTI 性格類型為 核心的策略桌遊,旨在促
+ 進團隊合作與理解。遊戲背景設置在刺激的太空探索場景中 ,玩家
+ 們需要在各個星球上蒐集散落的飛船零件,並利用各自基 於 MBTI
+ 的特殊能力來修復飛船。遊戲的核心目標是讓玩家快速了解並發揮
+ 彼此的優勢,進而形成有效的合作。透過這款沉浸式的遊戲,參與
+ 者將親身體驗到不同性格如何在團隊中 補,達成共同目標。
+
+
+ );
+}
+
+export function Motive() {
+ return (
+
+
+ 在一個團隊當中 ,人與人之間能否順利 的互 相了解,進而用對的方 法合作
+ 將會成為該團隊關鍵。因此我們想要製作出一個可以讓團隊
+ 成員彼此之間可以用最短的時間了解彼此並 找 到共事方法的桌遊。
+
+
+ );
+}
diff --git a/src/data/project.json b/src/data/project.json
index 5ec9eaf..4a0cb38 100644
--- a/src/data/project.json
+++ b/src/data/project.json
@@ -1,59 +1,156 @@
- [
+[
{
"id": 1,
"title": "在生活中迷路了",
"description": "希望可以在人們迷惘時給予一點點溫暖。",
- "imageUrl": "/UFO.png",
- "group": "第一組"
+ "detail": "/data/1.md",
+ "imageUrl": "/logo/8.png",
+ "projectImg": "/logo2/8.png",
+ "groupImg": "/group/8.webp",
+ "groupMember": "林彥妤、劉亞臻",
+ "type": "virtual"
},
{
"id": 2,
"title": "行食曆Pantry Pal",
"description": "「Pantry Pal」是一款能幫助使用者紀錄食材的小幫手,透過掃描紀錄買過的食材,顯示在行事曆上,讓使用者能夠一目瞭然的知道食材剩餘狀況。",
- "imageUrl": "/UFO.png",
- "group": "第一組"
+ "motive": "現代生活中,繁忙的生活節奏常使我們無暇關注食材的購買與管理,導致了許多不必要的食物浪費,為了解決這一問題,我們開發了一個專為管理食材而設計的網站:Pantry Pal,目的是協助想要減少食材等浪費的群眾可以有效管理食材,減少浪費。",
+ "imageUrl": "/logo/13.png",
+ "projectImg": "/logo2/13.png",
+ "groupImg": "/group/13.webp",
+ "groupMember": "林鈺茹、李苡嘉、王依仁、柯幸孜、陳思岑",
+ "type": "code"
},
{
"id": 3,
- "title": "科技應用之數位教材 3",
- "description": "簡介介紹 3",
- "imageUrl": "/UFO.png",
- "group": "第三組"
+ "title": "便攜式露營冰箱",
+ "description": "便攜式露營用冰箱是融合「便攜帶、易收納、好清潔」等概念的冰箱;此產品以致冷晶片系統、組裝式、模組化等特色進行實作,以滿足概念與露營的便攜設計。",
+ "motive": "",
+ "imageUrl": "/logo/5.png",
+ "projectImg": "/logo2/5.png",
+ "groupImg": "/group/5.webp",
+ "groupMember": "徐倍玄、陳奕廷、陳亮竹、李嘉明、蔡宗廷",
+ "type": "product"
},
{
"id": 4,
- "title": "科技應用之數位教材 4",
- "description": "簡介介紹 3",
- "imageUrl": "/UFO.png",
- "group": "第三組"
+ "title": "ECO ID",
+ "description": "ECO LID為一款智能環保杯蓋,運用藍芽、聲波感測、APP多樣化功能等技術,結合環保、健康議題,致力於改善飲水習慣與觀念,幫助使用者注重自身與家庭成員的健康。",
+ "motive": "",
+ "detail": "",
+ "imageUrl": "/logo/4.png",
+ "projectImg": "/logo2/4.png",
+ "groupImg": "/group/4.webp",
+ "groupMember": "王常峻、楊士寬、莊翔鈞、林逸豪、李宸逸",
+ "type": "product"
},
{
"id": 5,
- "title": "科技應用之數位教材 5",
- "description": "簡介介紹 5",
- "imageUrl": "/UFO.png",
- "group": "第三組"
+ "title": "啟動人生",
+ "description": "起動人生是一款創新設計的替換式螺絲起子,結合了先進的CAD和CAM技術,大幅提升使用效率。其設計不僅降低了螺絲頭遺失的機率,同時符合人體工學,確保長時間使用的舒適性,為客戶提供更優質使用體驗的解決方案。",
+ "motive": "螺絲起子作為現代人工作和生活中的一個重要工具,無論是在家庭修補、DIY專案還是工業製造中, 都扮演著關鍵的角色。而人們期望工具不僅僅具有功能性的,更希望它們能夠提高效率、節省時間,甚至提供更好的使用體驗。因此,我們決定設計與開發新的螺絲起子,以滿足人們對工具的需求和期望。",
+ "detail": "",
+ "imageUrl": "/logo/3.png",
+ "projectImg": "/logo2/3.jpg",
+ "groupImg": "/group/3.webp",
+ "groupMember": "洪鈺凱、汪威廷、陳彥愷、林鈺翔",
+ "type": "product"
},
{
"id": 6,
- "title": "科技應用之數位教材 6",
- "description": "簡介介紹 3",
- "imageUrl": "/UFO.png",
- "group": "第三組"
+ "title": "MoneyCat校園記帳APP",
+ "description": "本專題旨在開發一款大學生記帳APP,核心功能包括將「想要的開銷」獨立分類、利用KANO模型分析消費滿意度、以及提供校園論壇以便分享生活優惠消息,提升財務管理效能。",
+ "motive": "",
+ "detail": "",
+ "imageUrl": "/logo/1.jpg",
+ "projectImg": "/logo2/1.jpg",
+ "groupImg": "/group/1.webp",
+ "groupMember": "施宏儒、黃鈺娟、羅浚佑",
+ "type": "code"
},
{
"id": 7,
- "title": "科技應用之數位教材 7",
- "description": "簡介介紹 3",
- "imageUrl": "/UFO.png",
- "group": "第三組"
+ "title": "碳權於區塊鏈的追蹤與研究",
+ "description": "我們的網站不僅提供了學習碳權相關知識的管道,還藉由區塊鏈上的碳權貨幣交易資料做深入的分析,並透過視覺化的方式帶領使用者一同探討、了解當今碳市場的動向。",
+ "motive": "",
+ "detail": "",
+ "imageUrl": "/logo/9.jpg",
+ "projectImg": "/logo2/9.jpg",
+ "groupImg": "/group/9.webp",
+ "groupMember": "黃思齊、徐嫚謙、丁煦芊、關煒培、李承恩",
+ "type": "code"
},
{
"id": 8,
- "title": "科技應用之數位教材 8",
- "description": "簡介介紹 3",
- "imageUrl": "/UFO.png",
- "group": "第三組"
+ "title": "技續城市:生存之都",
+ "description": "「技續城市:生存之都」是一款以團隊合作為核心的教育性桌遊。在遊戲中,玩家將扮演不同的角色,如消防員、除蟲師、水電工和建築工人,合作解決城市中的各種危機,確保城市的生存和發展。通過應對火災、停電、建築倒塌和害蟲侵襲等挑戰,玩家需要共同努力,在指定時間內讓房屋保持完整,並最終用各自獲得的物資排名。",
+ "motive": "我們的製作動機是通過桌遊這種輕鬆有趣的方式,強調團隊合作的重要性,並將其應用於教育中。隨著現代社會對於團隊合作能力的需求不斷增長,我們希望通過這款遊戲,讓玩家在享受遊戲樂趣的同時,學會有效的溝通、協作和問題解決技巧,並提升個人及團隊的成長和績效。",
+ "detail": "地圖卡:展示城市及其各個區域。獎勵卡:玩家完成任務後獲得的獎勵。角色卡:玩家所扮演的角色,包含特定技能和能力。隨機事件卡:描述城市中突發的危機事件。遊戲玩法與機制: 每回合,玩家會抽出3間受災戶,並通過一回合三個行動去救援房屋。每經過幾個回合,會有隨機事件發生,增加遊戲的挑戰性和變數。遊戲的目標是在指定時間內確保20間房屋沒有損毀,並最終結算各玩家獲得的物資,物資多者獲勝。核心理念: 遊戲的核心理念是通過桌遊拉近人與人之間的距離,並在輕鬆有趣的氛圍中,讓玩家學習和體會團隊合作的重要性。透過設定具體的遊戲目標,玩家達成目標的過程中,間接地證明學會了團隊合作,達到教育的目的。",
+ "imageUrl": "/logo/12.png",
+ "projectImg": "/logo2/12.png",
+ "groupImg": "/group/12.webp",
+ "groupMember": "陳翰駿、林奕嫻、張博凱",
+ "type": "hr"
+ },
+ {
+ "id": 9,
+ "title": "星海尋航",
+ "description": "星海尋航是一款以MBTI為核心的桌遊;玩家們需透過自己各自擁有的特殊能力找到最有效的合作方式以完成任務。",
+ "motive": "",
+ "detail": "",
+ "imageUrl": "/logo/11.png",
+ "projectImg": "/logo2/11.png",
+ "groupImg": "/group/11.webp",
+ "groupMember": "盧梓銓、林志遠、邱致瑋、魏士凱",
+ "type": "hr"
+ },
+ {
+ "id": 10,
+ "title": "個人興趣取向大學選擇器",
+ "description": "本專題以可以解決現存指標的問題並能真正的為學生分配到適合科系為主目標, 透過進行有趣的遊戲讓學生可以在進行測試享受同時提供具參考的分析結果, 解決升學生的需求 ",
+ "motive": "",
+ "detail": "",
+ "imageUrl": "/logo/6.png",
+ "projectImg": "/logo2/6.png",
+ "groupImg": "/group/6.webp",
+ "groupMember": "翁健哲、杜洺鋒、李承曄",
+ "type": "edu"
+ },
+ {
+ "id": 11,
+ "title": "銀 îng 作伙學台語",
+ "description": "銀 îng 作伙學台語是一個情境式銀髮族台語學習平台,以簡單清晰的介面設計,真實生活情境為背景,注重聽與說的練習,另針對錄音進行語音評分,讓使用者可檢視自我、激勵自己。",
+ "motive": "",
+ "detail": "",
+ "imageUrl": "/logo/10.png",
+ "projectImg": "/logo2/10.png",
+ "groupImg": "/group/10.webp",
+ "groupMember": "陳星、李米蕙、盧紫妍、吳亞蓉、古于育",
+ "type": "edu"
+ },
+ {
+ "id": 12,
+ "title": "專家系統虛擬實境",
+ "description": "本計畫將虛擬實境(VR)與專家系統結合,製作幫助學習者熟悉木工製作與原理及機具操作的學習情境。透過身歷其境的虛擬體驗,提升學習效果,降低真實環境中的風險,並節省資源。",
+ "motive": "",
+ "detail": "",
+ "imageUrl": "/logo/7.png",
+ "projectImg": "/logo2/7.png",
+ "groupImg": "/group/7.webp",
+ "groupMember": "陳淑鈃,王于萱,孫源智,葉芷伃,黃麟堯",
+ "type": "virtual"
+ },
+ {
+ "id": 13,
+ "title": "Ideashare - 高中生專案媒合平台",
+ "description": "希望大家可以讓自己的所思所想,不再只是「夢想」。而是有機會被實踐的。我們希望可以透過 Ideashare - 高中生專案媒合平台,讓高中生可以更順利的實踐夢想,不因為找不到夥伴而讓自己的夢想止步。",
+ "motive": "",
+ "detail": "",
+ "imageUrl": "/logo/2.svg",
+ "projectImg": "/logo2/2.png",
+ "groupImg": "/group/2.webp",
+ "groupMember": "張乃云、劉媞欣、簡珮軒、潘允蕙、胡亞莉",
+ "type": "edu"
}
- ]
+]
diff --git a/src/index.css b/src/index.css
index e4cc266..664c614 100644
--- a/src/index.css
+++ b/src/index.css
@@ -3,6 +3,7 @@
@tailwind utilities;
body {
+ background-color: #D1E0F3;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
@@ -29,6 +30,24 @@ code {
font-style: normal;
}
+.Yu-Mincho-Pr6n {
+ font-family: yu-mincho-pr6n, sans-serif;
+ font-style: normal;
+ font-weight: 400;
+}
+.Source-Han-Serif{
+ font-family: source-han-serif-tw-subset, sans-serif;
+ font-style: normal;
+}
+@font-face {
+ font-family: 'ChenYuluoyan';
+ src: url(/ChenYuluoyan-Thin.ttf);
+}
+.ChenYuluoyan {
+ font-family: 'ChenYuluoyan', sans-serif;
+ font-style: normal;
+ font-weight: 500;
+}
.fade-in {
opacity: 1;
visibility: visible;
diff --git a/src/pages/AboutPage.css b/src/pages/AboutPage.css
deleted file mode 100644
index e293690..0000000
--- a/src/pages/AboutPage.css
+++ /dev/null
@@ -1,71 +0,0 @@
-* {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
-}
-/* body {
- background-color: #D4E9F8;
-} */
-.container {
- max-width: 1280px;
- width: 100%;
- padding-left: 5%;
- padding-right: 5%;
- padding-top: 5%;
- padding-bottom: 5%;
- box-sizing: border-box;
-}
-
-.title-block {
- padding-top: 5%;
-
- position: relative;
- text-align: center;
-}
-
-
-img {
- display: block;
- object-fit: cover;
- object-position: center center;
- margin-left: auto;
- margin-right: auto;
- width: 100%;
- height: 499px;
- opacity: 0.6;
-}
-
-.p-title {
- background-color: white;
- overflow: hidden;
- border-radius: 36px;
- padding: 42px 28px 42px 28px;
- box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
-}
-
-.centered {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
-}
-
-.content {
- padding-top: 128px;
-}
-.content h1 {
- color: black;
- font-size: 72px;
- padding-bottom: 32px;
-}
-
-.content p {
- color: black;
- font-size: 28px;
-}
-
-canvas {
- /* background: #D4E9F8; */
- height: 100vh;
- width: 100%;
-}
\ No newline at end of file
diff --git a/src/pages/AboutPage.jsx b/src/pages/AboutPage.jsx
deleted file mode 100644
index b966be3..0000000
--- a/src/pages/AboutPage.jsx
+++ /dev/null
@@ -1,89 +0,0 @@
-import "./AboutPage.css";
-import Card from "react-bootstrap/Card";
-import data from "../data/project.json";
-
-export default function About() {
- return (
-
-
-
About Us
-
TAHRD 114
-
- This is your About page. This space is a great opportunity to give a
- full background on who you are, what you do and what your site has to
- offer. Your users are genuinely interested in learning more about you,
- so don’t be afraid to share personal anecdotes to create a more
- friendly quality.{" "}
-
-
-
-
-
- {/*
-
MEET THE TEAM
- */}
- {/*
- {data.map((card) => (
-
-
-
- {card.title}
-
-
-
- {card.group}
-
-
- ))}
-
*/}
-
-
MEET THE SPONSORS
-
-
- );
-}
diff --git a/src/pages/BlogPage.jsx b/src/pages/BlogPage.jsx
deleted file mode 100644
index 38ee473..0000000
--- a/src/pages/BlogPage.jsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import "./BlogPage.css";
-import ProjectCard from "./ProjectCard";
-// import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
-import data from "../data/project.json";
-
-const Blog = () => {
- return (
-
-
- OUR PROJECT
-
-
- {data.map((project, index) => (
-
- ))}
-
-
- {/*
*/}
-
- );
-};
-
-export default Blog;
diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx
index 69a50b6..54bdbd6 100644
--- a/src/pages/Home.jsx
+++ b/src/pages/Home.jsx
@@ -1,58 +1,63 @@
import Card from "react-bootstrap/Card";
import data from "../data/project.json";
+import Nav from "./components/Nav";
+import BlogPage from "./projects/BlogPage";
+import About from "./components/AboutPage";
+import TrafficInfo from "./components/TrafficInfo";
+import { useLocation } from "react-router-dom";
+import { useEffect, useRef } from "react";
+import Slide from "./components/Slide";
+
+function ScrollToAnchor() {
+ const location = useLocation();
+
+ useEffect(() => {
+ const hash = location.hash;
+ if (hash) {
+ const element = document.getElementById(hash.slice(1));
+ if (element) {
+ element.scrollIntoView({ behavior: "smooth" });
+ }
+ }
+ }, [location]);
+
+ return null;
+}
export default function Home() {
+ const scrollTo = (elementRef) => {
+ elementRef.current?.scrollIntoView({ behavior: "smooth" });
+ };
+
+ const homeRef = useRef(null);
+ const blogRef = useRef(null);
+ const trafficRef = useRef(null);
+ const aboutRef = useRef(null);
+ const gameRef = useRef(null);
+
+ // useEffect(() => {
+ // setBlogRef(blogRef);
+ // }, [blogRef, setBlogRef]);
+
return (
<>
- {/*
*/}
-
- OUR PROJECT
-
-
- {data.map((card) => (
-
-
-
- {card.title}
-
-
- {card.group}
- {/* {card.date} */}
-
-
- ))}
-
+
+
+
+
+
+
>
);
}
diff --git a/src/pages/Nav.jsx b/src/pages/Nav.jsx
deleted file mode 100644
index e3217b0..0000000
--- a/src/pages/Nav.jsx
+++ /dev/null
@@ -1,232 +0,0 @@
-import React, { useEffect, useState } from "react";
-import { Link } from "react-router-dom";
-
-function FixedNav({ scrollTo, refs }) {
- return (
- <>
-
-
-
-
-
-
-
-
{
- e.preventDefault();
- window.scrollTo({ top: 0, behavior: "smooth" });
- }}
- className="no-underline h-full"
- >
-
-
-
{
- e.preventDefault();
- scrollTo(refs.blogRef);
- }}
- className="no-underline h-full"
- >
-
-
-
{
- e.preventDefault();
- scrollTo(refs.projectRef);
- }}
- className="no-underline h-full"
- >
-
-
-
{
- e.preventDefault();
- scrollTo(refs.aboutRef);
- }}
- className="no-underline h-full"
- >
-
-
-
-
- >
- );
-}
-
-function MainNav({ scrollTo, refs }) {
- const backgroundImageUrl = "url(/keyVisual.png)";
- const style = {
- position: "relative",
- height: "100vh",
- width: "100%",
- overflow: "hidden",
- };
-
- const backgroundStyle = {
- content: '""',
- backgroundImage: backgroundImageUrl,
- backgroundSize: "cover",
- backgroundPosition: "top",
- backgroundRepeat: "no-repeat",
- opacity: 0.3,
- position: "absolute",
- top: 0,
- left: 0,
- height: "100%",
- width: "100%",
- zIndex: -1,
- };
- return (
-
-
-
-
-
-
-
-
114 TAHRD
- CAPSTONE PROJECT
-
-
-
-
-
- CONTACT US
-
-
-
-
-
{
- e.preventDefault();
- window.scrollTo({ top: 0, behavior: "smooth" });
- }}
- className="no-underline h-full"
- >
-
-
-
{
- e.preventDefault();
- scrollTo(refs.blogRef);
- }}
- className="no-underline h-full"
- >
-
-
-
{
- e.preventDefault();
- scrollTo(refs.projectRef);
- }}
- className="no-underline h-full"
- >
-
-
-
{
- e.preventDefault();
- scrollTo(refs.aboutRef);
- }}
- className="no-underline h-full"
- >
-
-
-
-
-
-
-
-
-
-
-
-
TAHRD
-
- "Technology is not just a tool. It can give learners a voice that
- they may not have had before." - George Couros
-
-
-
-
-
- );
-}
-
-export default function Nav({ scrollTo, refs }) {
- const [showFixedNav, setShowFixedNav] = useState(false);
-
- useEffect(() => {
- const handleScroll = () => {
- setShowFixedNav(window.scrollY > 200); // 當滾動超過 200px 時顯示固定導航欄
- };
-
- window.addEventListener("scroll", handleScroll);
- return () => window.removeEventListener("scroll", handleScroll);
- }, []);
- return (
-
- );
-}
diff --git a/src/pages/Project.css b/src/pages/Project.css
deleted file mode 100644
index 86e0543..0000000
--- a/src/pages/Project.css
+++ /dev/null
@@ -1,73 +0,0 @@
-* {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
-}
-body {
- background-color: #D1E0F3;
-}
-.container {
- width: 100%;
- padding-left: 10%;
- padding-right: 10%;
- padding-top: 5%;
- padding-bottom: 5%;
- box-sizing: border-box;
-}
-
-.title-block {
- position: relative;
- text-align: center;
-}
-
-.title-block span {
- font-size: 40px;
- text-align: center;
- color:black;
-}
-
-img {
- display: block;
- object-fit: cover;
- object-position: center center;
- margin-left: auto;
- margin-right: auto;
- width: 100%;
- height: 499px;
- opacity: 0.6;
-}
-
-.p-title {
- background-color: white;
- overflow: hidden;
- border-radius: 36px;
- padding: 42px 28px 42px 28px;
- box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
-}
-
-.centered {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
-}
-
-.content {
- padding-top: 128px;
-}
-.content h1 {
- color: black;
- font-size: 72px;
- padding-bottom: 32px;
-}
-
-.content p {
- color: black;
- font-size: 28px;
-}
-
-canvas {
- background: #D4E9F8;
- height: 100vh;
- width: 100%;
-}
\ No newline at end of file
diff --git a/src/pages/Project.jsx b/src/pages/Project.jsx
deleted file mode 100644
index d479111..0000000
--- a/src/pages/Project.jsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import "./Project.css";
-
-export default function Project() {
- return (
-
-
-
-
科技應用之數位教材
-
-
-
-
About Us
-
項目概述: 智能語言學習平台是一個旨在幫助使用者輕鬆學習語言的線上平台。透過結合人工智能和語言學習技術,我們提供了一種創新的學習方式,使使用者能夠以更加愉快和高效的方式掌握目標語言。
-
-
- );
-};
\ No newline at end of file
diff --git a/src/pages/ProjectCard.jsx b/src/pages/ProjectCard.jsx
deleted file mode 100644
index d8a363b..0000000
--- a/src/pages/ProjectCard.jsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import React from "react";
-import "./ProjectCard.css";
-
-function ProjectCard({ id, title, description, imageUrl, group, isEven }) {
- return (
-
- {isEven ? (
- <>
-
-
{title}
-
{description}
- {/*
-
BY {group}
*/}
-
-
-
-
- >
- ) : (
- <>
-
-
-
-
-
{title}
-
{description}
- {/*
-
BY {group}
*/}
-
- >
- )}
-
- );
-}
-
-export default ProjectCard;
diff --git a/src/pages/components/AboutPage.jsx b/src/pages/components/AboutPage.jsx
new file mode 100644
index 0000000..ad37743
--- /dev/null
+++ b/src/pages/components/AboutPage.jsx
@@ -0,0 +1,24 @@
+export default function About() {
+ return (
+ <>
+
+
+
關於科技系
+
+
+
+ 本系根源於民國42年所成立的工業教育系「工藝教育組」,專責培育我國中學「工藝」課程之師資,配合課程內涵之調整與修訂,在民國61年更名為「工業技術教育組」,並於民國71年正式獨立設系為「工藝教育學系」,為配合學校藝術學院成立,本系隸屬於藝術學院。
+
+
+ 民國80年增設碩士班,民國87年增設博士班。隨著社會環境的變遷與課程改革的需求,外加上師資培育多元化的衝擊,在民國83年正式將系名更改為「工業科技教育學系」,專責培育中學「生活科技」課程之師資,民國87年本系改隸屬於當年新成立的科技學院。
+
+
+ 為符合本系培育科技產業教育訓練人才之目標,本系獲教育部同意,從98學年度起更名為「科技應用與人力資源發展學系」,並簡稱為科技系。
+
+
+ 為拓展本系畢業學生之就業機會並開啟本系畢業生至業界就業的契機,本系自民國83年開始,以既有的師資培育為基礎,先後在「大學部」實施課程分組,目前的大學部課程則分為「學習與科技組」及「設計與科技組」,以培養科技產業界所須之人力資源人才。在「碩士班」階段則先後規劃「科技與工程教育」、「人力資源」與「網路學習」等多元之課程內涵,協助學生發展各該領域之專業與研究能力;在「博士班」則設有「科技與工程教育」與「人力資源」兩組課程,培育各該領域之專業「教學」與「研究」之人才。
+
+
+ >
+ );
+}
diff --git a/src/pages/Footer.jsx b/src/pages/components/Footer.jsx
similarity index 59%
rename from src/pages/Footer.jsx
rename to src/pages/components/Footer.jsx
index 1f5fbd2..721bd96 100644
--- a/src/pages/Footer.jsx
+++ b/src/pages/components/Footer.jsx
@@ -1,5 +1,5 @@
export default function Footer() {
- const backgroundImageUrl = "url(/keyVisual.png)";
+ const backgroundImageUrl = "url(/keyVisual.webp)";
const style = {
position: "relative",
height: "100%",
@@ -22,36 +22,38 @@ export default function Footer() {
};
return (
-
+
-
-
+
+ {/*
-
+
Resources
-
+
Follow us
-
+
Legal
-
-
-
+ */}
+ {/*
*/}
+
2024 國立臺灣師範大學 科技應用與人力資源發展學系
114級畢業專題成果展網站
-
-
-
-
© Copyright
-
+
+
+
+
+ © Copyright 2024 臺師大科技系畢業專題成果展
+
+
diff --git a/src/pages/components/Nav.jsx b/src/pages/components/Nav.jsx
new file mode 100644
index 0000000..24779b8
--- /dev/null
+++ b/src/pages/components/Nav.jsx
@@ -0,0 +1,422 @@
+import React, { useEffect, useState } from "react";
+import { Link } from "react-router-dom";
+
+function ToggleMenu({ scrollTo, refs }) {
+ const [isOpen, setIsOpen] = useState(false);
+
+ const handleClick = () => {
+ setIsOpen(!isOpen);
+ };
+
+ const handleClose = () => {
+ setIsOpen(false);
+ };
+
+ return (
+
+
+
+
+ {isOpen && (
+
+
+
{
+ e.preventDefault();
+ window.scrollTo({ top: 0, behavior: "smooth" });
+ }}
+ className="no-underline h-full"
+ >
+
+
+
+
{
+ e.preventDefault();
+ scrollTo(refs.blogRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+
+ {/*
{
+ e.preventDefault();
+ scrollTo(refs.projectRef);
+ }}
+ className="no-underline h-full"
+ >
+
+ */}
+
{
+ e.preventDefault();
+ scrollTo(refs.trafficRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+
+
{
+ e.preventDefault();
+ scrollTo(refs.aboutRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+
+
{
+ e.preventDefault();
+ scrollTo(refs.gameRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+
+
+ )}
+
+ );
+}
+
+function FixedNav({ scrollTo, refs }) {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
{
+ e.preventDefault();
+ window.scrollTo({ top: 0, behavior: "smooth" });
+ }}
+ className="no-underline h-full"
+ >
+
+
+
{
+ e.preventDefault();
+ scrollTo(refs.blogRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+ {/*
{
+ e.preventDefault();
+ scrollTo(refs.projectRef);
+ }}
+ className="no-underline h-full"
+ >
+
+ */}
+
{
+ e.preventDefault();
+ scrollTo(refs.trafficRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+
{
+ e.preventDefault();
+ scrollTo(refs.aboutRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+
{
+ e.preventDefault();
+ scrollTo(refs.gameRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+
+
+ >
+ );
+}
+
+function MainNav({ scrollTo, refs }) {
+ const backgroundImageUrl = "url(/keyVisual.webp)";
+ const style = {
+ position: "relative",
+ height: "100vh",
+ width: "100%",
+ overflow: "hidden",
+ };
+
+ const backgroundStyle = {
+ backgroundImage: backgroundImageUrl,
+ backgroundSize: "cover",
+ backgroundPosition: "top",
+ backgroundRepeat: "no-repeat",
+ opacity: 0.3,
+ position: "absolute",
+ top: 0,
+ left: 0,
+ width: "100%",
+ zIndex: -1,
+ };
+ return (
+
+
+
+
+
+
+
+
+ 114 TAHRD
+
+
+ CAPSTONE PROJECT
+
+
+
+
+
+
+
+
+
{
+ e.preventDefault();
+ window.scrollTo({ top: 0, behavior: "smooth" });
+ }}
+ className="no-underline h-full"
+ >
+
+
+
{
+ e.preventDefault();
+ scrollTo(refs.blogRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+ {/*
{
+ e.preventDefault();
+ scrollTo(refs.projectRef);
+ }}
+ className="no-underline h-full"
+ >
+
+ */}
+
{
+ e.preventDefault();
+ scrollTo(refs.trafficRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+
{
+ e.preventDefault();
+ scrollTo(refs.aboutRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+
{
+ e.preventDefault();
+ scrollTo(refs.gameRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
TAHRD
+
+ "Technology is not just a tool. It can give learners a voice that
+ they may not have had before." - George Couros
+
+
+
+
+
+ );
+}
+
+export default function Nav({ scrollTo, refs }) {
+ const [showFixedNav, setShowFixedNav] = useState(false);
+
+ useEffect(() => {
+ const handleScroll = () => {
+ setShowFixedNav(window.scrollY > 200); // 當滾動超過 200px 時顯示固定導航欄
+ };
+
+ window.addEventListener("scroll", handleScroll);
+ return () => window.removeEventListener("scroll", handleScroll);
+ }, []);
+ return (
+
+ );
+}
diff --git a/src/pages/components/ProjectNav.jsx b/src/pages/components/ProjectNav.jsx
new file mode 100644
index 0000000..7a9bd8a
--- /dev/null
+++ b/src/pages/components/ProjectNav.jsx
@@ -0,0 +1,395 @@
+import React, { useEffect, useState } from "react";
+import { Link } from "react-router-dom";
+
+function ToggleMenu({ scrollTo, refs, id }) {
+ const [isOpen, setIsOpen] = useState(false);
+
+ const handleClick = () => {
+ setIsOpen(!isOpen);
+ };
+
+ const handleClose = () => {
+ setIsOpen(false);
+ };
+
+ return (
+
+
+
+
+ {isOpen && (
+
+
+
{
+ e.preventDefault();
+ window.scrollTo({ top: 0, behavior: "smooth" });
+ }}
+ className="no-underline h-full"
+ >
+
+
+
+
{
+ e.preventDefault();
+ scrollTo(refs.memberRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+
+
{
+ e.preventDefault();
+ scrollTo(refs.motiveRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+
+
{
+ e.preventDefault();
+ scrollTo(refs.introRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+
+
{
+ e.preventDefault();
+ scrollTo(refs.aboutRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+
+
+ )}
+
+ );
+}
+
+function FixedNav({ scrollTo, refs, id }) {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
{
+ e.preventDefault();
+ window.scrollTo({ top: 0, behavior: "smooth" });
+ }}
+ className="no-underline h-full"
+ >
+
+
+
{
+ e.preventDefault();
+ scrollTo(refs.memberRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+
{
+ e.preventDefault();
+ scrollTo(refs.motiveRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+
{
+ e.preventDefault();
+ scrollTo(refs.introRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+
{
+ e.preventDefault();
+ scrollTo(refs.aboutRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+ {/*
{
+ e.preventDefault();
+ scrollTo(refs.blogRef);
+ }}
+ className="no-underline h-full"
+ >
+
+ */}
+ {/*
{
+ e.preventDefault();
+ scrollTo(refs.aboutRef);
+ }}
+ className="no-underline h-full"
+ >
+
+ */}
+
+
+ >
+ );
+}
+
+function MainNav({ scrollTo, refs, id, blogRef }) {
+ return (
+
+
+
+
+
+
+
+ 114 TAHRD
+
+
+ CAPSTONE PROJECT
+
+
+
+
+
+
+
+
+
{
+ e.preventDefault();
+ window.scrollTo({ top: 0, behavior: "smooth" });
+ }}
+ className="no-underline h-full"
+ >
+
+
+
{
+ e.preventDefault();
+ scrollTo(refs.memberRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+
{
+ e.preventDefault();
+ scrollTo(refs.motiveRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+
{
+ e.preventDefault();
+ scrollTo(refs.introRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+
{
+ e.preventDefault();
+ scrollTo(refs.introRef);
+ }}
+ className="no-underline h-full"
+ >
+
+
+ {/*
{
+ e.preventDefault();
+ scrollTo(refs.blogRef);
+ }}
+ className="no-underline h-full"
+ >
+
+ */}
+ {/*
{
+ e.preventDefault();
+ scrollTo(refs.aboutRef);
+ }}
+ className="no-underline h-full"
+ >
+
+ */}
+
+
+ );
+}
+
+export default function Nav({ scrollTo, refs, id }) {
+ const [showFixedNav, setShowFixedNav] = useState(false);
+
+ useEffect(() => {
+ const handleScroll = () => {
+ setShowFixedNav(window.scrollY > 200); // 當滾動超過 200px 時顯示固定導航欄
+ };
+
+ window.addEventListener("scroll", handleScroll);
+ return () => window.removeEventListener("scroll", handleScroll);
+ }, []);
+ return (
+
+ );
+}
diff --git a/src/pages/components/PuzzleGame.jsx b/src/pages/components/PuzzleGame.jsx
new file mode 100644
index 0000000..b9bbd9b
--- /dev/null
+++ b/src/pages/components/PuzzleGame.jsx
@@ -0,0 +1,222 @@
+import React, { useState, useEffect } from "react";
+import { Link } from "react-router-dom";
+import "./game.css";
+
+function FixedNav() {
+ return (
+ <>
+
+
+
+
+
+
+
+
{
+ // e.preventDefault();
+ // window.scrollTo({ top: 0, behavior: "smooth" });
+ // }}
+ className="no-underline h-full"
+ >
+
+
+
+
+ >
+ );
+}
+
+const gridSize = 3;
+const emptyIndex = gridSize * gridSize - 1;
+
+function App() {
+ const [tiles, setTiles] = useState([]);
+ const [shuffled, setShuffled] = useState(false);
+ const [steps, setSteps] = useState(0);
+ const [time, setTime] = useState(0);
+ const [isSolved, setIsSolved] = useState(false);
+ const [showTargetImage, setShowTargetImage] = useState(false);
+ const [buttonText, setButtonText] = useState("開始遊戲");
+
+ useEffect(() => {
+ const initialTiles = Array.from(
+ { length: gridSize * gridSize },
+ (_, i) => i
+ );
+ setTiles(initialTiles);
+ }, []);
+
+ useEffect(() => {
+ let timer;
+ if (shuffled && !isSolved) {
+ timer = setInterval(() => {
+ setTime((prevTime) => prevTime + 1);
+ }, 1000);
+ } else if (isSolved) {
+ clearInterval(timer);
+ }
+ return () => clearInterval(timer);
+ }, [shuffled, isSolved]);
+
+ const shuffleTiles = () => {
+ let shuffledTiles;
+ do {
+ shuffledTiles = [...tiles];
+ for (let i = shuffledTiles.length - 1; i > 0; i--) {
+ const j = Math.floor(Math.random() * (i + 1));
+ [shuffledTiles[i], shuffledTiles[j]] = [
+ shuffledTiles[j],
+ shuffledTiles[i],
+ ];
+ }
+ } while (!isSolvable(shuffledTiles) || isPuzzleSolved(shuffledTiles));
+
+ setTiles(shuffledTiles);
+ setShuffled(true);
+ setSteps(0);
+ setTime(0);
+ setIsSolved(false);
+ setButtonText("重新挑戰");
+ };
+
+ const resetGame = () => {
+ setTiles(Array.from({ length: gridSize * gridSize }, (_, i) => i));
+ setShuffled(false);
+ setSteps(0);
+ setTime(0);
+ setIsSolved(false);
+ setButtonText("開始遊戲");
+ };
+
+ const isSolvable = (tiles) => {
+ let inversions = 0;
+ for (let i = 0; i < tiles.length - 1; i++) {
+ for (let j = i + 1; j < tiles.length; j++) {
+ if (
+ tiles[i] !== emptyIndex &&
+ tiles[j] !== emptyIndex &&
+ tiles[i] > tiles[j]
+ ) {
+ inversions++;
+ }
+ }
+ }
+ return inversions % 2 === 0;
+ };
+
+ const moveTile = (index) => {
+ if (!shuffled || isSolved) return;
+ const newTiles = [...tiles];
+ const emptyPos = tiles.indexOf(emptyIndex);
+ const row = Math.floor(index / gridSize);
+ const col = index % gridSize;
+ const emptyRow = Math.floor(emptyPos / gridSize);
+ const emptyCol = emptyPos % gridSize;
+
+ if (Math.abs(row - emptyRow) + Math.abs(col - emptyCol) === 1) {
+ [newTiles[index], newTiles[emptyPos]] = [
+ newTiles[emptyPos],
+ newTiles[index],
+ ];
+ setTiles(newTiles);
+ setSteps(steps + 1);
+ if (isPuzzleSolved(newTiles)) {
+ setIsSolved(true);
+ setButtonText("開始遊戲");
+ }
+ }
+ };
+
+ const isPuzzleSolved = (tiles) =>
+ tiles.every((tile, index) => tile === index);
+
+ const formatTime = (seconds) => {
+ const mins = Math.floor(seconds / 60);
+ const secs = seconds % 60;
+ return `${String(mins).padStart(2, "0")}:${String(secs).padStart(2, "0")}`;
+ };
+
+ const isMovable = (index) => {
+ const emptyPos = tiles.indexOf(emptyIndex);
+ const row = Math.floor(index / gridSize);
+ const col = index % gridSize;
+ const emptyRow = Math.floor(emptyPos / gridSize);
+ const emptyCol = emptyPos % gridSize;
+
+ return Math.abs(row - emptyRow) + Math.abs(col - emptyCol) === 1;
+ };
+
+ return (
+
+
+
+
+
+ {buttonText}
+
+ setShowTargetImage(!showTargetImage)}
+ >
+ {showTargetImage ? "隱藏目標圖片" : "查看目標圖片"}
+
+
+
+ 3x3
+ |
+ 時間: {formatTime(time)}
+ |
+ 步數: {steps}步
+
+
+
+ {showTargetImage ? (
+
+
+
+ ) : (
+
+
+ {tiles.map((tile, index) => (
+
moveTile(index)}
+ style={{
+ backgroundPosition: `${(tile % gridSize) * -150}px ${
+ Math.floor(tile / gridSize) * -150
+ }px`,
+ }}
+ >
+ ))}
+
+
+ )}
+
+
+ {isSolved && (
+
+
+
恭喜!你完成了拼圖!
+
+ )}
+
+ );
+}
+
+export default App;
diff --git a/src/pages/components/Slide.jsx b/src/pages/components/Slide.jsx
new file mode 100644
index 0000000..e77fc7e
--- /dev/null
+++ b/src/pages/components/Slide.jsx
@@ -0,0 +1,49 @@
+import Carousel from "react-bootstrap/Carousel";
+import { Link } from "react-router-dom";
+
+function IndividualIntervalsExample() {
+ return (
+ <>
+
+
+
互動遊戲
+
+
+
+
+
+
+
+ 馬上來玩!
+
+
+
+
+ 互動小遊戲
+
+
+
+
+
+ 投票
+
+
+ {/*
+
+
+ Third slide label
+
+ Praesent commodo cursus magna, vel scelerisque nisl consectetur.
+
+
+ */}
+
+ >
+ );
+}
+
+export default IndividualIntervalsExample;
diff --git a/src/pages/components/TrafficInfo.jsx b/src/pages/components/TrafficInfo.jsx
new file mode 100644
index 0000000..14e2178
--- /dev/null
+++ b/src/pages/components/TrafficInfo.jsx
@@ -0,0 +1,61 @@
+export default function About() {
+ return (
+ <>
+
+
+
交通資訊
+
+
+
+
+
+
+
+
+
+
+
時間
+
+
+
+ 2024年12月06日(五) 12:30 ~ 18:00
+
+
+ 2024年12月07日(六) 08:30 ~ 15:30
+
+
+
+
+
地址
+
+
+ 台北市大安區和平東路一段135號
+
+
+
+
交通方式
+
+
+
+ 1. 捷運古亭站:
+ 中和新蘆線(橘線)、松山新店線(綠線)於『古亭站』5號出口直行約八分鐘可抵達校區大門。
+
+
+ 2. 捷運台電大樓站:
+ 松山新店線(綠線)於『台電大樓站』3號出口,師大路直行約十分鐘後在和平東路一段左轉即可抵達校區大門。
+
+
+
+
+
+ >
+ );
+}
diff --git a/src/pages/components/game.css b/src/pages/components/game.css
new file mode 100644
index 0000000..6e55d34
--- /dev/null
+++ b/src/pages/components/game.css
@@ -0,0 +1,73 @@
+
+
+ .button{
+ width : 100px;
+ height: 30px;
+ text-align:center;
+ margin-bottom:5px;
+ cursor:pointer;
+ line-height:30px;
+ margin-right:10px;
+ background-color : #04434F;
+ color : white;
+ font-weight: bold;
+ border-radius:5px;
+ float:left;
+ }
+
+ .button-container {
+ display: flex;
+ gap: 10px;
+ padding-right: 40px;
+ }
+
+
+
+ .puzzle {
+ display: grid;
+ grid-template-columns: repeat(3, 150px);
+ grid-template-rows: repeat(3, 150px);
+ }
+
+ .target-image {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 450px;
+ height: 450px;
+ margin: 0 auto;
+ }
+
+ .tile {
+ width: 150px;
+ height: 150px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ background-image: url('../logo2.png');
+ background-size: 450px 450px;
+ cursor: pointer;
+ transition: transform 0.2s;
+ }
+
+ .tile.movable:hover {
+ transform: scale(1.1);
+ }
+
+ .tile.empty {
+ background-color: transparent;
+ background-image: none;
+ }
+
+ .target-image img {
+ max-width: 100%;
+ height: auto;
+ }
+
+ .congrats-message {
+ color: green;
+ text-align: center;
+ font-weight: bold;
+ font-size: 1.5em;
+ margin-top: 20px;
+ }
\ No newline at end of file
diff --git a/src/pages/components/loading.jsx b/src/pages/components/loading.jsx
new file mode 100644
index 0000000..029ae69
--- /dev/null
+++ b/src/pages/components/loading.jsx
@@ -0,0 +1,10 @@
+export default function Loading() {
+ return (
+
+ );
+}
diff --git a/src/pages/BlogPage.css b/src/pages/projects/BlogPage.css
similarity index 94%
rename from src/pages/BlogPage.css
rename to src/pages/projects/BlogPage.css
index db42031..61b23cc 100644
--- a/src/pages/BlogPage.css
+++ b/src/pages/projects/BlogPage.css
@@ -43,7 +43,9 @@
justify-content: center;
align-items: center;
padding: 20px;
- width: 100%;
+ background-color: #203f49;
+ margin: 0 auto;
+ border-radius: 20px;
}
.project-card {
diff --git a/src/pages/projects/BlogPage.jsx b/src/pages/projects/BlogPage.jsx
new file mode 100644
index 0000000..a5443bf
--- /dev/null
+++ b/src/pages/projects/BlogPage.jsx
@@ -0,0 +1,100 @@
+import "./BlogPage.css";
+import ProjectCard from "./ProjectCard";
+import data from "../../data/project.json";
+import { useState } from "react";
+
+function TypeTabs({ onSelect }) {
+ const [key, setKey] = useState("code");
+
+ const handleSelect = (key) => {
+ setKey(key);
+ onSelect(key);
+ };
+
+ return (
+
+
+ handleSelect("code")}
+ style={{ transition: "all 0.3s ease" }}
+ >
+ 軟體開發
+
+ handleSelect("virtual")}
+ style={{ transition: "all 0.3s ease" }}
+ >
+ 虛擬實境
+
+ handleSelect("product")}
+ style={{ transition: "all 0.3s ease" }}
+ >
+ 產品設計
+
+ handleSelect("edu")}
+ style={{ transition: "all 0.3s ease" }}
+ >
+ 教育導向
+
+ handleSelect("hr")}
+ style={{ transition: "all 0.3s ease" }}
+ >
+ 人資桌遊
+
+
+
+ );
+}
+
+const Blog = () => {
+ const [selectedType, setSelectedType] = useState("code");
+
+ const handleTypeSelect = (type) => {
+ setSelectedType(type);
+ };
+
+ const filteredData = data.filter((project) => project.type === selectedType);
+
+ return (
+
+
+
+
作品集
+
+
+
+ {filteredData.map((project, index) => (
+
+ ))}
+
+
+ );
+};
+
+export default Blog;
diff --git a/src/pages/ProjectCard.css b/src/pages/projects/ProjectCard.css
similarity index 54%
rename from src/pages/ProjectCard.css
rename to src/pages/projects/ProjectCard.css
index b3bfd1f..93a0a16 100644
--- a/src/pages/ProjectCard.css
+++ b/src/pages/projects/ProjectCard.css
@@ -1,13 +1,15 @@
.project-card {
display: flex;
- width: 80%;
+ width: 95%;
+ min-width: 95%;
margin: 10px auto;
border-radius: 10px;
+ border: none;
overflow: hidden;
- box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
+ /* box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); */
text-decoration: none;
color: inherit;
- background-color: white;
+ background-color: #feffe8;
}
.project-card-link {
@@ -51,4 +53,20 @@
.project-card.odd .project-card-link {
flex-direction: row;
}
-
\ No newline at end of file
+
+ .ink-box {
+ border-width: 4px 5px 4px 6px;
+ border-radius: 90% 6% 93% 5% / 5% 94% 7% 95%;
+ /* 做出傾斜的視覺感 */
+ transform: rotate(2deg);
+ padding: 5px; /* 添加内边距 */
+ box-sizing: border-box; /* 确保内边距和边框包含在元素的总宽度和高度内 */
+ }
+ .box-inner {
+ /* 將傾斜的部分修正 */
+ transform: rotate(-2deg);
+ width: 100%;
+ height: 100%;
+ object-fit: cover; /* 确保图片覆盖整个容器 */
+ border-radius: inherit; /* 确保图片的边角与容器一致 */
+ }
\ No newline at end of file
diff --git a/src/pages/projects/ProjectCard.jsx b/src/pages/projects/ProjectCard.jsx
new file mode 100644
index 0000000..112eaa1
--- /dev/null
+++ b/src/pages/projects/ProjectCard.jsx
@@ -0,0 +1,128 @@
+import React from "react";
+import "./ProjectCard.css";
+import { Link } from "react-router-dom";
+import { useState } from "react";
+//import Modal from "react-bootstrap/Modal";
+
+const Modal = ({ show, onClose, title, imageUrl, description, id }) => {
+ if (!show) {
+ return null;
+ }
+
+ return (
+
+
+
+
{title}
+
+
+
+
{description}
+
+
+
+ 前往作品頁
+
+
+
+ 返回
+
+
+
+
+
+ );
+};
+
+function ProjectCard({ id, title, description, imageUrl, isEven }) {
+ const [show, setShow] = useState(false);
+
+ return (
+ <>
+
+
+ {isEven ? (
+
+
+
+
+ {title}
+
+
{description}
+
+
+
+
+
+
+ ) : (
+
+
+
+
+
+
+
+ {title}
+
+
{description}
+
+
+
+ )}
+
+
+
+ {/* 手機版 */}
+
+
+ {/*
*/}
+
setShow(true)}
+ >
+
+
+
+
setShow(false)}
+ title={title}
+ imageUrl={imageUrl}
+ description={description}
+ id={id}
+ />
+ >
+ );
+}
+
+export default ProjectCard;
diff --git a/src/pages/projects/ProjectPage.jsx b/src/pages/projects/ProjectPage.jsx
new file mode 100644
index 0000000..f97e2d0
--- /dev/null
+++ b/src/pages/projects/ProjectPage.jsx
@@ -0,0 +1,139 @@
+import data from "../../data/project.json";
+import { useEffect, useState, lazy, Suspense, useRef } from "react";
+import { useParams, useLocation } from "react-router-dom";
+import ProjectNav from "../components/ProjectNav";
+import Loading from "../components/loading";
+
+function ScrollToAnchor() {
+ const location = useLocation();
+
+ useEffect(() => {
+ const hash = location.hash;
+ if (hash) {
+ const element = document.getElementById(hash.slice(1));
+ if (element) {
+ element.scrollIntoView({ behavior: "smooth" });
+ }
+ }
+ }, [location]);
+
+ return null;
+}
+
+export default function ProjectPage() {
+ const { id } = useParams();
+ const [Motive, setMotive] = useState(null);
+ const [Component, setComponent] = useState(null);
+ const project = data.find((project) => project.id === parseInt(id));
+
+ const scrollTo = (elementRef) => {
+ elementRef.current?.scrollIntoView({ behavior: "smooth" });
+ };
+
+ const memberRef = useRef(null);
+ const motiveRef = useRef(null);
+ const introRef = useRef(null);
+ const recordRef = useRef(null);
+ //const gameRef = useRef(null);
+
+ useEffect(() => {
+ const loadComponent = async () => {
+ try {
+ const component = await import(`../../data/${id}.jsx`);
+ setComponent(() => component.Component);
+ setMotive(() => component.Motive);
+ } catch (error) {
+ console.error("Error loading the component:", error);
+ }
+ };
+
+ loadComponent();
+ }, [id]);
+
+ if (!project) {
+ return Project not found
;
+ }
+
+ const backgroundImageUrl = "url(/keyVisual.webp)";
+
+ const backgroundStyle = {
+ backgroundImage: backgroundImageUrl,
+ backgroundSize: "cover",
+ backgroundPosition: "top",
+ backgroundRepeat: "no-repeat",
+ opacity: 0.2,
+ position: "absolute",
+ top: 0,
+ left: 0,
+ width: "100%",
+ zIndex: -1,
+ };
+
+ return (
+ <>
+
+
+
+
+ {project.title}
+
+
+ {/*
*/}
+
+ {/*
*/}
+
+ {/* */}
+
+
+
+
專題組員
+
+
+
+
+
{project.groupMember}
+
(由左至右)
+
+
+
+
+
+
+
+
製作動機
+
+
+
}>{Component &&
}
+
+
+
+
+
+
專題介紹
+
+
+
}>
+ {Component &&
}
+
+
+
+ >
+ );
+}
diff --git a/tailwind.config.js b/tailwind.config.js
index 9bb7c0a..2da3536 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -18,6 +18,12 @@ export default {
"4/5": "80%",
},
},
+ colors: {
+ "light-yellow": "#feffe8",
+ "dark-yellow": "#ecf0a7",
+ "nav-blue": "#04434F",
+ pink: "#8E7EB9",
+ },
},
plugins: [],
};