文字動畫

Ascii Art

將圖片轉為可動畫的 ASCII/像素藝術。

把任何圖片(或文字/emoji)即時降採樣成 ASCII 字元或像素色塊,並以打散、波動或掃描動畫進場。全程 canvas 2D 繪製,尊重「減少動態效果」。

把這個效果裝進你的專案

在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。

npx webberui@latest add ascii-art

還沒有專案,或安裝遇到問題?看快速開始 →

ASCII Art 是用 React 與 canvas 2D 做的圖片轉 ASCII 字元畫(ASCII art generator、文字藝術)元件:把圖片或一段文字降採樣成字元格,依亮度換成不同密度的字元,也能改成彩色像素色塊,並提供打散、波浪與對角揭露三種動畫。Motion 只用來讀取「減少動態效果」設定。

Playground

即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。

72
9
編輯中的呼叫預設屬性
<AsciiArt/>

完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。

適用情境

  • 開發者工具、CLI 產品或終端機風格網站的主視覺
  • 404 或維護頁面,用大字「404」做成會動的字元畫
  • 黑客松、技術活動頁的 Logo 或講者頭像
  • 作品集裡偏實驗性、復古電腦風格的區塊

安裝

npx webberui@latest add https://webberui.com/r/ascii-art.json

或在 components.json 設定 registries 後,改用 @webberui/ascii-art 安裝。

使用

以 src 傳入圖片(建議用 data: URI 保持元件自足),或改用 text 把文字/emoji 當作來源圖形。

import { AsciiArt } from "@/components/ui/ascii-art";

<AsciiArt src="/portrait.png" columns={90} animation="scramble" loop />

<AsciiArt text="★" mode="pixel" animation="reveal" />

提示:columns 是水平字元欄數,數字越大越精細也越吃效能。跨來源(cross-origin)圖片若未帶 CORS 標頭會污染 canvas 而無法取樣,改用同源資源或 data: URI 最穩。

範例

404 頁面

沒有傳 src 時,text 的內容會先畫成粗體大字再轉成字元;wave 動畫會持續播放。

import { AsciiArt } from "@/components/ui/ascii-art";

export default function NotFound() {
  return (
    <main className="grid min-h-[60vh] place-items-center gap-6 text-emerald-500">
      <AsciiArt text="404" alt="404 找不到頁面" columns={80} animation="wave" />
      <p className="text-neutral-500">這個頁面不存在或已經移除。</p>
    </main>
  );
}

color 沒指定時會讀取畫布的 currentColor,所以外層的 text-emerald-500 就決定了字色。

像素模式的 Logo 揭露

mode="pixel" 會保留圖片原本的顏色,以方形色塊輸出;reveal 會從左上往右下依對角線掃出畫面。

<AsciiArt
  src="/brand/logo.png"
  alt="公司 Logo"
  mode="pixel"
  animation="reveal"
  columns={48}
  fontSize={6}
  background="#0a0a0a"
/>

自訂字元梯度與亮色背景

chars 由暗到亮排列。在白底頁面上,深色的主體應該用較密的字元,這時加上 invert 反轉亮度對應。

<AsciiArt
  src="/team/avatar.jpg"
  alt="講者頭像"
  chars=" ░▒▓█"
  invert
  columns={64}
  animation="scramble"
  speed={0.8}
  className="text-neutral-900"
/>

Props

Prop型別預設值說明
srcstring—來源圖片 URL 或 data: URI
textstring"★"無 src 時,改把這段文字/emoji 當來源圖形
altstring—給輔助科技的替代文字
columnsnumber72水平解析度(字元欄數)
charsstring" .:-=+*#%@"由暗到亮的字元梯度,至少兩個字元
colorstringcurrentColorascii 模式的文字顏色
backgroundstring"transparent"底色
mode"ascii" | "pixel""ascii"輸出字元或色塊像素
animation"scramble" | "wave" | "reveal" | "none""scramble"動畫模式
speednumber1動畫速度倍率
fontSizenumber9單一單元的像素高度(ascii 為字級)
invertbooleanfalse反轉亮度對應
loopbooleanfalse動畫結束後是否持續循環

可及性

  • 使用者系統開啟「減少動態效果」時,直接繪製最終靜態畫面,不播放動畫
  • 畫布帶 role="img" 與 aria-label,朗讀時回報替代文字而非逐格字元

常見問題

輸出的尺寸怎麼算?

畫布寬度由 columns 和 fontSize 決定:ascii 模式每格寬約 fontSize × 0.6 px,pixel 模式每格是 fontSize 的正方形;列數依來源圖片比例自動算出。外層加了 max-w-full,不會超出容器寬度。

為什麼圖片沒有顯示?

元件需要讀取像素資料。跨來源圖片若伺服器沒有回傳 CORS 標頭,canvas 會被污染而無法取樣,元件會靜默略過。改用同源路徑或 data: URI 最穩。

長時間放在頁面上會一直耗效能嗎?

scramble 與 reveal 在動畫結束後就停止繪製(除非設 loop);wave 與 loop 會持續執行,但捲出畫面時會由 IntersectionObserver 暫停 requestAnimationFrame。columns 越大,每一幀要畫的字元越多。

切換深淺主題時字色會跟著變嗎?

預設字色是在元件繪製時讀取一次 currentColor,主題切換後若元件沒有重新渲染,字色不會更新。需要明確的配色時,直接傳 color。

可以在 Next.js App Router 使用嗎?

可以。原始碼已經有 "use client",圖片載入與繪製都在 effect 內執行,伺服器端只輸出一個空的 canvas。依賴是 motion、clsx、tailwind-merge,也可以從「手動」分頁直接複製原始碼。