MB

mikecheng1208/battletree

Developer tools
2 stars 品質 51 トレンド 16

Client 端的對戰系統,同時支援抽籤抽獎功能

概要

BattleTree 是一個純前端對戰賽程工具。它支援建立多份對戰表、設定參賽名單、依序或隨機產生賽程、分組賽程、三強循環決賽、季軍戰、對戰表縮放拖曳、勝者與比分紀錄、抽籤展示、JPG 匯出,以及可替換 Logo / 背景圖的風格設定。 目前沒有後端服務,對戰表資料存在 localStorage,圖片資產存在 IndexedDB。 - 首頁開場畫面,顯示 BattleTree Logo 與「開始對戰」按鈕。 - 重新整理後會保留目前所在頁面,不會強制回首頁。 - 支援 Chrome 式多對戰表分頁,可同時開啟多場比賽並快速切換;手機版使用下拉選單。 - 關閉分頁只會收起頁籤並保留資料,可從「所有對戰表」重新開啟;刪除才會永久移除。 - Header 左上角 Logo 可回首頁,並詢問是否保留目前輸入內容。 - 預設建立 4 位參賽者。 - 參賽人數最少 2 人,目前沒有 64 人限制。 - 支援匯入 Google 試算表匯出的 CSV,固定讀取 姓名 欄位並覆蓋目前名單。 - CSV 匯入旁提供教學彈窗,說明如何從 Google 表單與試算表下載 CSV。 - 編號由系統產生並顯示,不可編輯。 - 名單列支援移除參賽者、主辦確認報名狀態,以及手動重新排序參賽編號。 - 支援依序配對與隨機抽籤配對。 - 三種賽制:自由編排(預設,手選格數、空格自由填人)、單淘汰、預賽+淘汰(小組循環後晉級淘汰賽)。 - 自由編排支援 8/16/24/32/48/64 格;24/48 格會由三條平衡淘汰分支產生三強,再以循環賽決定前三名。 - 自由編排模式可將第一輪敗者填回空格再戰一次、手動新增選手、或將空格確認為輪空。 - 支援不分組、2 組、4 組、8 組(單淘汰)。 - 分組對戰表使用分頁切換組別與總決賽,避免大量組別同時擠在畫面上。 - 對戰表支援標準、橫向、分組視角。 - 四強敗者確定後會產生第三名爭奪戰,賽果完成後榮譽榜會列出冠軍、亞軍、季軍、第四名。 - 對戰表可拖曳平移、縮放、重置、適合畫面。 - 桌機支援全螢幕與下載 JPG。 - 手機版隱藏不適合手機的全螢幕與縮放控制,保留重置與適合畫面。 - 抽籤功能支援名單預覽、勾選排除、華麗抽籤動畫與抽中彩花。 - 風格設定支援多組主題、暗色模式、自訂 Header Logo、自訂背景圖片。

README

BattleTree

BattleTree 是一個純前端對戰賽程工具。它支援建立多份對戰表、設定參賽名單、依序或隨機產生賽程、分組賽程、三強循環決賽、季軍戰、對戰表縮放拖曳、勝者與比分紀錄、抽籤展示、JPG 匯出,以及可替換 Logo / 背景圖的風格設定。

目前沒有後端服務,對戰表資料存在 localStorage,圖片資產存在 IndexedDB。

功能特色

  • 首頁開場畫面,顯示 BattleTree Logo 與「開始對戰」按鈕。
  • 重新整理後會保留目前所在頁面,不會強制回首頁。
  • 支援 Chrome 式多對戰表分頁,可同時開啟多場比賽並快速切換;手機版使用下拉選單。
  • 關閉分頁只會收起頁籤並保留資料,可從「所有對戰表」重新開啟;刪除才會永久移除。
  • Header 左上角 Logo 可回首頁,並詢問是否保留目前輸入內容。
  • 預設建立 4 位參賽者。
  • 參賽人數最少 2 人,目前沒有 64 人限制。
  • 支援匯入 Google 試算表匯出的 CSV,固定讀取 姓名 欄位並覆蓋目前名單。
  • CSV 匯入旁提供教學彈窗,說明如何從 Google 表單與試算表下載 CSV。
  • 編號由系統產生並顯示,不可編輯。
  • 名單列支援移除參賽者、主辦確認報名狀態,以及手動重新排序參賽編號。
  • 支援依序配對與隨機抽籤配對。
  • 三種賽制:自由編排(預設,手選格數、空格自由填人)、單淘汰、預賽+淘汰(小組循環後晉級淘汰賽)。
  • 自由編排支援 8/16/24/32/48/64 格;24/48 格會由三條平衡淘汰分支產生三強,再以循環賽決定前三名。
  • 自由編排模式可將第一輪敗者填回空格再戰一次、手動新增選手、或將空格確認為輪空。
  • 支援不分組、2 組、4 組、8 組(單淘汰)。
  • 分組對戰表使用分頁切換組別與總決賽,避免大量組別同時擠在畫面上。
  • 對戰表支援標準、橫向、分組視角。
  • 四強敗者確定後會產生第三名爭奪戰,賽果完成後榮譽榜會列出冠軍、亞軍、季軍、第四名。
  • 對戰表可拖曳平移、縮放、重置、適合畫面。
  • 桌機支援全螢幕與下載 JPG。
  • 手機版隱藏不適合手機的全螢幕與縮放控制,保留重置與適合畫面。
  • 抽籤功能支援名單預覽、勾選排除、華麗抽籤動畫與抽中彩花。
  • 風格設定支援多組主題、暗色模式、自訂 Header Logo、自訂背景圖片。
  • 背景圖片支援多種呈現方式,包含完整顯示、填滿置中、填滿靠上、原始置中。

技術棧

  • Vue 3
  • Vite
  • @vueuse/core
  • GSAP
  • html-to-image
  • IndexedDB
  • localStorage

快速開始

npm install
npm run dev

Vite 預設會啟動本機開發伺服器。此專案設定了 base path,開發時依終端機顯示 URL 開啟即可。

可用指令

npm run dev

啟動本機開發伺服器。

npm run build

建立正式版輸出,輸出目錄為 dist/。

npm run preview

預覽正式版建置結果。請先執行 npm run build。

npm test

執行對戰引擎的賽制回歸測試。

使用流程

  1. 在首頁點擊「開始對戰」。
  2. 使用分頁列的 + 建立對戰表,先選擇賽制與空白/複製目前名單;也可從「所有對戰表」開啟既有資料。
  3. 在設定頁輸入比賽名稱。
  4. 設定參賽人數,系統會自動建立名單。
  5. 編輯選手姓名,或使用「匯入 CSV」從 Google 表單報名資料一次匯入。
  6. 可勾選綠色確認按鈕標記報名成功,或移除不需要的參賽者。
  7. 移除參賽者後,原參賽編號會先保留;需要連續編號時再點擊「重新排序參賽編號」。
  8. 選擇配對方式:
    • 依序配對:依照編號排序後相鄰配對,例如 1 vs 2、3 vs 4。
    • 隨機抽籤:隨機分配選手,首輪會避開編號相鄰的選手對上。
  9. 選擇分組數:
    • 不分組
    • 2 組
    • 4 組
    • 8 組
  10. 點擊「產生對戰表」。
  11. 在對戰表中點擊勝者按鈕推進下一輪。
  12. 已有結果的比賽可輸入比分。
  13. 需要輸出時,在桌機使用全螢幕或下載 JPG。

CSV 匯入

設定頁的「匯入 CSV」可讀取 Google 表單回覆試算表匯出的 CSV。

規格:

  • CSV 第一列必須是欄位名稱。
  • 只讀取欄位名稱完全等於 姓名 的欄位。
  • 匯入後會覆蓋目前名單。
  • 參賽人數自動等於有效姓名筆數。
  • 編號會重新由 1 開始依序產生。
  • 空白姓名列會被忽略。
  • 至少需要 2 位有效參賽者。
  • 支援標準 CSV 引號格式,例如姓名中包含逗號或雙引號。
  • 匯入按鈕旁的「教學」會開啟操作說明,指引使用者從 Google 表單回覆開啟試算表,並下載 逗號分隔值檔案 (.csv)。

名單管理

  • 每位參賽者包含姓名、參賽編號與報名確認狀態。
  • 參賽編號只顯示不可編輯,必須是正整數且不可重複。
  • 綠色勾勾代表主辦單位已確認該參賽者報名成功。
  • 移除參賽者會直接刪除該列,後方名單往上遞補,但原參賽編號會保留。
  • 「重新排序參賽編號」會依目前名單順序重新編為 1、2、3。
  • 匯入 CSV 會覆蓋目前名單,並將報名確認狀態全部設為未確認。

對戰表規則

  • 支援單淘汰、預賽+淘汰、自由編排三種賽制。
  • 單淘汰:參賽人數不必剛好是 2 的次方,系統會補齊到下一個 2 的次方(例如 9 人會產生 16 人表),空位視為 bye 自動晉級、輪空平均分散左右半區。
  • 空對空分支會隱藏,不會形成等待中的比賽。
  • 預賽+淘汰:先分組循環累積戰績,各組第 1 名(不足時補成績最佳第 2 名)晉級固定規模淘汰賽,淘汰賽零輪空。
  • 自由編排:主辦手動選 8/16/24/32/48/64 格,名單先排入並平均分佈;空格的對戰顯示「待定」不自動晉級,主辦可填入名單剩餘者、第一輪敗者(再戰一次)、手動新增的選手,或將該格確認為輪空。
  • 24/48 格自由編排分別由三條 8/16 格淘汰分支組成,各分支產生 1 名三強選手;三強互打 3 場後依「勝場 → 兩人同勝場時直接對戰 → 得失分差 → 總得分 → 編號」排名。三人各 1 勝 1 敗時必須補齊比分。
  • 自由編排可在單一待定格中隨機選擇 1 位可用的第一輪敗者,也提供「隨機填入敗者」與「剩餘全部輪空」批次操作;已填的格位可隨時換人或清空,受影響的下游成績會先告知場數並確認後連鎖清除。
  • 標準淘汰樹若有兩位四強敗者,系統會產生第三名爭奪戰;24/48 格則由三強循環直接產生前三名。
  • 冠軍戰與第三名爭奪戰都有結果後,榮譽榜會列出前四名。
  • 修改選手、移除選手、重新排序編號、配對方式、分組數後,已產生的對戰表會回到設定狀態並清空既有賽果。
  • 改變某場勝者時,後續輪次中不合法的結果會被清除,避免晉級資料不一致。
  • 分組時會先在各組內產生小型單淘汰表,再由各組勝者進入總決賽。

視角與操作

對戰表目前有三種呈現方式:

  • 標準:縱向樹狀,由下往上收斂到冠軍。
  • 橫向:以橫向輪次排列,適合部分寬螢幕檢視。
  • 分組:分頁顯示各組與總決賽,適合大量參賽者。

操作能力:

  • 滑鼠拖曳平移。
  • 滾輪縮放。
  • 桌機工具列可縮小、放大、重置、適合畫面。
  • 手機保留重置與適合畫面,避免工具列過度擁擠。
  • 勝者選取不會自動把畫面重設成適合畫面。

抽籤功能

工具列的「抽籤」會開啟抽籤展示視窗。

名單來源包含:

  • 全部選手。
  • 已有結果的指定輪次敗者。

抽籤流程:

  1. 先顯示名單預覽。
  2. 名單預設全部勾選。
  3. 取消勾選會把該人移出本次抽籤名單,卡片透明度降至 40%。
  4. 開始抽籤後不可再修改名單。
  5. 抽籤舞台顯示抽籤狀態與抽籤池。
  6. 抽中時顯示彩花動畫。
  7. 抽中者移入已抽出清單。

風格設定

Header 最右側與首頁桌機右上角有風格按鈕。點擊後會開啟風格設定彈窗。

彈窗包含:

  • 主題色方格選項。
  • 上傳 Header Logo。
  • 還原 Header Logo。
  • 上傳背景圖片。
  • 移除背景圖片。
  • 背景圖片呈現方式。

目前主題:

  • 黑白灰
  • 暗色模式
  • 冷藍
  • 森林
  • 赤銅

Logo 規格:

  • 只替換進入網站後 Header 左上角 Logo。
  • 首頁 BattleTree Logo 永遠保持預設,不會被商家 Logo 替換。
  • 暗色模式不會改變自訂 Logo 顏色,上傳什麼就顯示什麼。
  • Logo 檔案大小上限為 2MB。

背景圖規格:

  • 背景圖會以固定層蓋在頁面後方。
  • 目前背景圖透明度為 50%。
  • 對戰表 viewport 本身有 30% 透明主題底色,讓背景圖仍可透出。
  • 背景圖檔案大小上限為 6MB。
  • 背景圖呈現方式:
    • 完整:前景圖片完整顯示;背後同圖用 cover 放大填滿、水平垂直置中並 blur(6px)。
    • 填滿:cover,水平垂直置中。
    • 靠上:cover,水平置中並對齊上方。
    • 原始:原始大小,水平垂直置中。

資料儲存

BattleTree 不需要後端服務。

localStorage:

  • battletree:brackets:所有對戰表資料。
  • battletree:currentId:目前選取的對戰表 ID。
  • battletree:openTabs:目前開啟的對戰表分頁 ID 與順序。
  • battletree:view:目前停留在首頁或應用頁。
  • battletree:theme:目前主題。
  • battletree:background-fit:背景圖片呈現方式。

IndexedDB:

  • DB:battletree-images
  • Object store:images
  • custom-logo:自訂 Header Logo 圖片 Blob。
  • background-image:自訂背景圖片 Blob。

圖片顯示時會使用 URL.createObjectURL(blob) 產生暫時 URL,替換或移除時會釋放舊 object URL。

資料只存在目前瀏覽器與目前網域中。若清除瀏覽器資料、更換瀏覽器或更換裝置,資料不會自動同步。

專案結構

.
├── public/
│   ├── favicon.svg
│   └── logo.png
├── src/
│   ├── assets/
│   │   ├── logo.svg
│   │   └── logo-w.svg
│   ├── components/
│   │   ├── BracketTabs.vue
│   │   ├── BracketListModal.vue
│   │   ├── BracketSetup.vue
│   │   ├── BracketView.vue
│   │   ├── LotteryModal.vue
│   │   ├── MatchCard.vue
│   │   ├── NewBracketModal.vue
│   │   ├── PlayerSlot.vue
│   │   ├── ScorePopover.vue
│   │   ├── ThemePicker.vue
│   │   └── Toolbar.vue
│   ├── constants/
│   │   └── bracketOptions.js
│   ├── composables/
│   │   ├── useBracketEngine.js
│   │   ├── useBracketExport.js
│   │   ├── useBrackets.js
│   │   ├── useImageStorage.js
│   │   ├── useLottery.js
│   │   └── usePanZoom.js
│   ├── App.vue
│   ├── main.js
│   └── style.css
├── package.json
├── package-lock.json
├── vite.config.js
└── README.md

核心模組說明

  • src/App.vue:應用主入口,管理首頁/應用狀態、主題、圖片資產、工具列、設定頁、對戰表與彈窗。
  • src/components/Toolbar.vue:Header 工具列與風格設定入口。
  • src/components/BracketTabs.vue:桌機分頁列與手機對戰表下拉切換。
  • src/components/NewBracketModal.vue:選擇賽制及空白/複製名單後建立新分頁。
  • src/components/ThemePicker.vue:風格設定彈窗,處理主題切換、Logo 上傳、背景上傳與背景模式切換。
  • src/components/BracketSetup.vue:比賽名稱、參賽人數、配對方式、分組數與選手名單設定。
  • src/components/BracketView.vue:對戰表畫布、視角切換、SVG 連線、分組分頁、縮放拖曳與冠軍顯示。
  • src/components/MatchCard.vue:單場比賽卡片。
  • src/components/PlayerSlot.vue:選手顯示、勝敗狀態與晉級按鈕。
  • src/components/ScorePopover.vue:比分輸入。
  • src/components/LotteryModal.vue:抽籤展示與抽籤動畫。
  • src/composables/useBracketEngine.js:賽程大小、相鄰配對、bye、分組、季軍戰、晉級、冠軍與賽果清理等核心邏輯。
  • src/composables/useBrackets.js:對戰表 CRUD、localStorage 儲存、選手更新、分組更新、自由編排格位操作與賽果更新。
  • src/composables/useImageStorage.js:IndexedDB 圖片儲存。
  • src/composables/useBracketExport.js:全螢幕與 JPG 匯出。
  • src/composables/useLottery.js:抽籤名單、動畫狀態與抽出結果管理。
  • src/composables/usePanZoom.js:對戰表平移與縮放操作。

注意事項

  • 目前沒有帳號系統、伺服器同步或多人協作功能。
  • JPG 匯出使用目前對戰表 DOM 為來源,並以 2 倍 pixel ratio 輸出。
  • 全螢幕能力取決於瀏覽器 Fullscreen API;手機版已隱藏相關按鈕。
  • localStorage / IndexedDB 均屬瀏覽器本地資料,不適合跨裝置同步。
View this README on GitHub

推奨ツール

別のキーワードを試すか、フィルタを外してください。

インストール

npx skillfish add mikecheng1208/battletree