Cube Icons
Cube Icons 將小型像素繪圖渲染為 <canvas> 上的 3D 方塊。每個彩色像素會變成一個短方塊堆疊。引擎為 assets/cubes.js(約 9 KB gzipped,無依賴),圖示庫為 assets/icons.js。所有操作都在瀏覽器中執行。
工作流程
- 放置。 決定圖示的行為:懸停時組建(選單、按鈕、卡片)、滾動時組建(區段、英雄區)、僅顯示一次(空狀態、載入器),或跟隨指標(磁吸)。將實際文字保留在 Canvas 旁邊的 HTML 中。
- 安裝。 將
assets/cubes.js與assets/icons.js複製到專案的靜態資料夾,並使用兩個<script>標籤載入,icons.js在前。或者從 CDN 載入:https://cdn.jsdelivr.net/gh/atwalabs/[email protected]/icons.js與.../cubes.js。在框架中,僅在瀏覽器端載入(參見references/recipes.md中的「框架」)。 - 選擇或繪製圖示。 若合適則使用內建名稱(見下方列表)。否則依照下方「繪製圖示」的方法,將圖示繪製為調色盤鍵值的行。
- 撰寫程式碼。 在設定好尺寸的 Canvas 上建立舞台,然後呼叫
show、scroll、build、sequence或explode。從references/recipes.md中的對應範例開始。 - 完成。 為 Canvas 設定 CSS 寬高、加上
role="img"與aria-label(若為裝飾性則使用aria-hidden="true")、在鍵盤焦點時也執行懸停效果,並在元件卸載時呼叫stage.destroy()。
最小範例
<canvas id="hero-icon" style="width:360px;height:280px" role="img" aria-label="火箭"></canvas>
<script src="icons.js"></script>
<script src="cubes.js"></script>
<script>
const stage = CubeIcons.stage(document.getElementById("hero-icon"), { look: "soft" });
stage.show("rocket");
</script>
內建圖示
close, bolt, sword, briefcase, person, phone, browser, envelope, chart, terminal, heart, star, rocket, bulb, camera, gamepad, music, globe, lock, folder, coffee, chat, clock, check, search, download, cursor, home, bell, gear, calendar, pin, wifi, battery, play, arrow, trash, pencil, code, key, bag, cart, gift, trophy, diamond, crown, book, headphones, umbrella, flag, sun, moon, cloud, tree, leaf, fire, planet, sparkle, smile, ghost, robot.
繪製圖示
圖示是一個等長字串的陣列,由上到下像圖片一樣閱讀。每個字元是一個調色盤鍵值;. 代表空白。
| 鍵值 | 顏色 | 鍵值 | 顏色 |
|---|---|---|---|
B | 鈷藍 | G | 綠色 |
W | 紙白 | P | 淡紫 |
K | 灰色 | C | 青色 |
L | 淺灰 | M | 粉紅 |
D | 近黑 | N | 棕色 |
R | 紅色 | O | 橙色 |
Y | 黃色 |
讓圖示閱讀性良好的規則:
- 8–16 列寬,6–14 行高。 每行長度相同。太大會失去像素感;一個舞台預設容納 900 個方塊(單元格 × 深度)。
- 先畫輪廓。 先用單一顏色讓輪廓可辨識,再加入細節;快速瀏覽各行來確認。
- 輪廓與填充: 使用深色或對比色的輪廓(
K、D)搭配填充色,再加上一個重點細節(金色扣環、紅色旗幟、藍色窗戶)。 - 對稱 適用於對稱物體(獎盃、鈴鐺、臉孔):鏡像每一行。
- 避免單獨隔離的單元格,除非是刻意的細節如眼睛或閃光。
- 若要按名稱放置,請加入圖示庫:
Object.assign(window.CUBE_ICONS, { badge: [...] })。或直接將行陣列傳給stage.show(rows)。 - 自訂顏色: 圖示可攜帶額外的調色盤鍵值,格式為
{ colors: { a: "#eb234f", b: "#79a93e" }, rows: ["..aa..", "bbbbbb"] }。使用小寫字母代表它們。除非需求需要精確顏色,否則優先使用內建調色盤。
範例(咖啡杯):
coffee: [
"..W..W.....",
"...W..W....",
"...........",
"KKKKKKKKK..",
"KWWWWWWWKKK",
"KWWWWWWWK.K",
"KWWWWWWWKKK",
"KWWWWWWWK..",
".KKKKKKK...",
],
若要顯示文字,請使用 CubeIcons.text("Hello", { color: "B" }):一個 5 行的像素字體,支援 A–Z、0–9 及 . , : ! ? - + ' & /。
最重要的選項
CubeIcons.stage(canvas, {
look: "soft", // flat(預設)· soft · clay · candy · paper · outline · pixel · glass · neon · wire · holo
view: "front", // front(預設)· iso
depth: 2, // 方塊深度,1–5
gap: 0.06, // 方塊之間的間距,0–0.4
tint: null, // 單一品牌色調,例如 "#2f3cff":所有顏色以該色調的深淺重新繪製
ease: "expo", // expo(預設,柔和落地)· cubic · back · elastic · linear
duration: 700, // 每個方塊飛行毫秒數
stagger: 260, // 每個方塊的隨機延遲毫秒數
spin: 0.25, // 飛行時旋轉圈數
from: "auto", // auto · below · above · left · right · center
magnet: 0, // 靠近指標的方塊向前彈出(嘗試 1.5)
glow: 0, // 方塊周圍的發光效果,0–1(在深色頁面上搭配 tint 效果很好)
float: 0, // 閒置時的動作,0–1:圖示搖晃晃動,鬆散的方塊漂浮
tilt: true, // 深度隨滑鼠傾斜
});
根據頁面選擇風格:soft、clay、candy、paper 與 outline 適合淺色頁面;glass、neon 與 holo 適合深色頁面;wire 搭配淺色 tint 適合深色或有顏色的區段;pixel 是任何地方都適用的平面復古像素藝術。完整的選項與 API 表格請見 references/api.md。
方法
stage.show(icon):建立一個圖示(名稱或行陣列)。顯示不同的圖示時會變形成它。stage.clear():飛散並淡出。stage.build(icon, progress):部分建立,0–1,從底行開始。可透過滾動、上傳進度、計時器驅動。stage.explode(clientX?, clientY?):將方塊打散;它們會再恢復。stage.burst():方塊朝觀眾快速飛來並淡出(選單或頁面過渡)。stage.scatter(count, { icon }):在 Canvas 上散落方塊;之後的show()會將它們聚集為圖示。stage.set(options)、stage.destroy()。CubeIcons.scroll(stage, icon, { mode: "scrub" | "trigger" })、CubeIcons.sequence(stage, icons, { every })、CubeIcons.still(canvas, icon, options)用於靜態縮圖。
常見錯誤
- 沒有 Canvas 尺寸。 Canvas 需要 CSS 寬高,否則會渲染為 0 像素高。
- 腳本順序。 在呼叫
show()(使用名稱)之前先載入icons.js,在呼叫CubeIcons之前先載入cubes.js。 - 伺服端渲染。 在 Next.js、Nuxt 或 SvelteKit 中,不要在模組頂層接觸
CubeIcons;請在 effect 或 mount 鉤子中建立舞台。 - 太多方塊。 一個 20×20 的圖示在深度 3 時有 1,200 個方塊;降低深度、畫小一點,或提高
max。 - 僅限懸停。 也應在
focus時觸發,讓鍵盤使用者看到效果。
參考資料
references/recipes.md:可直接複製的程式碼,涵蓋選單、按鈕、空狀態、變形序列、爆炸、磁吸、文字、功能卡片、滾動區段及所有框架。references/api.md:每個選項、方法與輔助函式,附預設值。assets/cubes.js、assets/icons.js:引擎與圖示庫,可複製到專案中。