2026-09-23

Devlog - 放在 README 上的隨機每日金句

因為逛了一下別人的 GitHub,發現大家的 profile README 都在比 hi-hua(稱讚意味)的,所以想說也來做點東西塞進去 XDD

於是做了這個!隨機每日金句(有些很靠杯 XD):

Testing Quote of the Day

用下面這段 HTML 就可以插入隨機每日金句:

<img src="https://testing-quotes.goescat1024.workers.dev/" width="500" />

這個 API 放在 Cloudflare Workers。Cloudflare Workers 是 Cloudflare 提供的 Serverless 執行環境,可以把 JavaScript / TypeScript 程式直接部署到 Cloudflare 的網路上執行。

它的概念很簡單:

收到 HTTP Request
        ↓
執行你的程式
        ↓
回傳 HTTP Response

不需要自己管理傳統 Server,也不用處理 VM、作業系統或 Nginx。Cloudflare 負責底層的執行環境與網路基礎設施,你只需要寫要執行的程式。


建立 Worker

進入 Cloudflare Dashboard:Workers & Pages → Create → Worker

建立後可以直接在 Cloudflare 的線上 Editor 編輯程式。Deploy 後,Cloudflare 會提供一個像這樣的網址:

https://<worker-name>.<subdomain>.workers.dev

最基本的 Worker

Worker 最核心的概念就是:

export default {
  async fetch(request) {
    return new Response("Hello World!");
  }
};

每次有人 request Worker,都會經過:

HTTP Request
     ↓
fetch(request)
     ↓
HTTP Response

所以 Worker 本質上就是一個可以直接接收 HTTP Request、執行程式邏輯,再回傳 Response 的 Serverless endpoint。

這次的 Testing Quote of the Day,就是在這個 fetch() 裡隨機選一句 Quote,再動態產生 SVG 回傳。

用陣列管理 Quote

所有名言直接定義在 QUOTES 陣列中:

const QUOTES = [
  {
    quote: "Testing shows the presence, not the absence of bugs.",
    translation: "測試可以證明 Bug 存在,卻不能證明 Bug 不存在。",
    source: "Edsger W. Dijkstra"
  }
];

每次收到 Request 時,利用 Math.random() 隨機挑選一筆:

const item =
  QUOTES[Math.floor(Math.random() * QUOTES.length)];

因此每次請求都有機會得到不同的 Quote(沒快取的話,放在 Github profile 會有一層他們的 CDN,不會每次都 request 一次)。

直接產生 SVG

沒有準備圖片素材,而是讓 Worker 即時產生 SVG

SVG 本身就是文字格式,所以可以直接透過 template string 組出完整的 <svg>,再用 <text><tspan> 等元素控制文字與排版。

這樣做的好處是圖片中的文字仍然是 SVG 內容,不需要預先產生幾十張圖片。

處理文字排版

不同 Quote 的長度不一樣,因此簡單做了一層排版:

  • fontSize():依英文長度調整字體大小
  • wrapText():超過指定長度時自動換行
  • translationFontSize():中文翻譯另外調整字體大小

例如較長的 Quote 就會自動縮小:

if (text.length <= 40) return 27;
if (text.length <= 60) return 24;
if (text.length <= 80) return 21;
return 18;

雖然不是完整的排版引擎,但對這種固定尺寸的小型 SVG 已經夠用。

不要忘記 Escape

因為 Quote 最後會被插入 SVG/XML,所以不能直接把原始文字塞進去。

這裡用 escapeXML() 處理:

.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")

避免 Quote 裡面的特殊字元破壞 SVG markup。

Worker 最後只需要回傳 SVG

產生完成後直接:

return new Response(svg, {
  headers: {
    "Content-Type": "image/svg+xml; charset=utf-8",
    "Cache-Control": "no-store"
  }
});

因此這個 Worker 本質上就是一個很小的 dynamic SVG endpoint

Request → 隨機選 Quote → 產生 SVG → Response

沒有資料庫、沒有前端,也沒有圖片儲存最後得到的是一個可以直接嵌入 README、網站或其他地方的動態圖片 URL~

2026-07-08

Charles 4.x.x - Profiles 功能,快速切換一堆 map 和 rewrite

最近使用 Charles 的場景,常常不同的專案有一堆不同的 map 和 rewrite 要設定。

一開始苦於不知道怎麼一鍵切換一整組 map、rewrite、proxy 設定,後來終於發現原來可以用 Profiles 來設定:

一開始只有一個 default profile,可以 Add 新增一個 profile,使用不同的 profile 當下設定的 map、rewrite、proxy 都會保存在選取的 profile 裡。


以後不同專案就能用直接切不同 profiles 修改 map、rewrite、proxy 等各種設定了!
 

2026-05-05

[AVD] Android 步數模擬


在 AVD 的更多選項中,sensors 的 move,拉動 Y 軸可以模擬前後晃動,對部分 app 有模擬步數的效果。

不想一直手拉,可以用下面的指令不斷重複,直到 crtl + c 離開:

trap "echo Stopped; exit" INT while true; do { echo "auth $(cat ~/.emulator_console_auth_token)" echo "sensor set acceleration 0:9:0" } | nc localhost 5554 sleep 0.1 { echo "auth $(cat ~/.emulator_console_auth_token)" echo "sensor set acceleration 0:13:0" } | nc localhost 5554 sleep 0.1 done


上面 5554 為 AVD port,可以先用指令確認 port:
adb devices 
若輸出為 emulator-5556 或是其他數字可以自行修改。

2026-04-29

Devlog 離職集點小卡(???

🦩㊗️🎉 大家期待(沒有人期待)的離職集點小卡上線啦!!

先上網址: https://goescat.github.io/quit-stamp-card/


 

(我後來搜尋一下發現有人做過 app 了,app 留給大神來做,幸好小的做的是網頁版。)

離職集點小卡是個非常陽春的網頁,反正就是想離職就蓋一點,還可以紀錄一下原因⋯⋯

可以不照順序蓋,但集滿30點就鼓勵你離職(??

總之是個非常銀杏、非常耐斯的工具🤪 

⚠️目前還沒有清除、重新集點功能,可以自助 F12 clear data ⋯⋯
⚠️作為趣味性的小品,資料是儲存在使用者瀏覽器的 local storage。local storage 嘛,你知道的,系統也可能清除網站資料,簡單來說資料可能遺失~

2026-01-16

Devlog 易經籌策占卦網頁 I-Ching Stalk Divination v2.0

先上網頁連結 https://goescat.github.io/i-ching-stalk-divination/ 。


-

其實我先前就做了易經籌策占卦,v1.0 還在這裡 https://goescat.github.io/iching_test.html)。



應該可以感受到 v1.0的界面非常陽春,不過最重要的是裡面取卦的方式是依照傳統籌策占卦的方式取出,沒有馬虎,所以到 v2.0這部分就沒有更動了。

-

先介紹一下占卦方式,畢竟是 P1 在 v1.0 時就完成的功能,整個工具最核心的部分XD,我從 v2.0 repo 裡的 README 複製一下:

1. 籌策占卦需要準備 50 根籌策,第一步是取出一根至於上方不動(如界面呈現)代表太極。 下方可撥動的籌策為 49 根。

2. 在心中想好問題,誠心的提問。

3. 將 49 根籌策絡在一起,從中間分一半。

4. 將左邊的籌策取出一根至於手上(程式中會將左邊絡 -1)。

5. 將左邊的籌策以4根一組做計算,剩下不足4根即取出,若都沒有剩下,即取出4根(程式中會左邊絡會減去餘數,同樣餘數為0則-4)。

6. 換右邊的籌策,不需取出一根,直接4根一組計算,取出的規則如上。

7. 三變成一爻。因此將剩下的籌策再絡在一起,從中間分一半,如上操作再進行2次(共3次,所以程式中會引導分半3次。)

8. 進行 3 次後,剩餘的組數必定為6、7、8、9其中一數。 單數為陽爻,雙數為陰爻。9為老陽,6為老陰,將變爻。(若有變爻,程式在結果會註明。) 此時得到1爻。

9. 重複上述6次,即得6爻,也就是完整的一卦。

具體操作影片可參考臺大開放式課程傅佩榮教授 影片 示範。

-

總之 v2.0我幫卦象加上了卦辭、爻辭的介紹:


總共64卦的頁面,內容都來自中國哲學書電子化計劃 http://ctext.org/zh。做完實在滿開心的。

之後應該還可以補充上怎麼解卦的說明,方便大家加減參考XDD