HTML5 文字雲

Update: Here is the introduction in English.

猜猜看這是哪個 blog 的最常出現的詞彙?

文字雲是最近在嘗試的 HTML5 瀏覽器 Demo,目標是使用前端技術來完成 Java 撰寫的 Wordle,順便可以拿來測試瀏覽器效能,以及分析一些文字來源。

目前程式可以接受硬碟裡的檔案或是 RSS Feed 的文字(從 Google Feed API 拉資料),經過詞頻分析,以出現的數量來決定文字大小,排進 HTML5 canvas,像這是這個 blog 的分析結果:


最前面貼的第一張圖則是來自地圖會說話,其他像是 New York Times 的文字雲可以看出最近的新聞 buzz word 是什麼。

文章詞頻分析

中文用的是很標準的 N-gram(我做到 N=6),把字組切出來算頻率。英文的話則引用了資料庫常用的 Porter Stemming Algorithm 來歸一化字的變形(複數型、正在進行式等等)。想起來中文的分析還真的是知難行易,完全不做任何過濾效果就會很好(後來有濾掉一些不是詞的字組就是),而且唯一的 stop word 只有「的」。

測試的時候懷疑瀏覽器執行這些文字操作的效能,所以就把這段程式碼放進 Web Workers。放完發現效能沒有提昇多少,真正卡住的東西是畫 canvas … 不過還是保持這樣,因為使用者有可能會放大量文字進來(但只差 Web Workers 就可以執行的 IE9 就抱歉了)

使用前端額外的好處是使用者可以載入自己的檔案來分析,而且檔案不需要傳到主機上。測試的時候曾經跟別人要了在學校寫的報告,圖像很好玩。大部分的部落格最大的詞都是「可以」,不知道是不是口語中文的現象。

文字雲圖像

圖則是仰賴 canvas 的填入文字(fillText)功能。有一個二維 Array 來儲存哪裡還有空間的資訊,每次填入文字之後再用 getPixelData 偵測文字筆劃的位置,更新 Array。在 Chrome 上面,文字大小會受設定裡面的最小字型大小的影響,所以最後會有很多不太小的小字。另外就是 Firefox 的 getPixelData 效能有問題,只有別人的 1/6 甚至更慢,為了避免瀏覽器卡死只好放了偵測所花時間,超過就跳出警告訊息的程式碼。Firefox 另外還有一個 canvas 有更新但是卻不顯示結果的 bug,不是很 reproducible 而且好像每台電腦行為都不一樣,只好先放著(canvas 的效能和問題都跟硬體加速有關)。

使用者介面

這東西為何會被我放在硬碟裡快一個月就是因為 UI 搞不定 orz … 做了兩個版本,每次 show 給別人看的時候都很容易操作錯誤;現在這個是 2.5 版,流程變成仰賴網址的 Hash 和 onhashchange 事件。對於寫出有用但是 UI 失敗的程式,我也感到很無奈 orz

接下來?

歡迎大家玩玩看。字頻分析和文字雲兩個功能都包成 library 了,拿去做其他應用應該很方便。不過我希望先保留程式碼兩個星期,之後再公開;目前網站上的是 minified script。

有空的話會想要支援更多自然語言(日文、韓文等),還有拿字頻做其他 visual(或是 audio?Bob 給了一個的點子,我才注意到其實字頻分布跟 FFT 轉換後的聲音頻譜還滿像的?)

最後,喜歡的話賞我一個讚吧 XD 寫不少東西但是不太知道反應,也不知道要去哪裡推。

IE9 Hackathon

Skip to IE9toss demo, source code and explanation.

星期六去了 IE9 黑客松,算是一場輕鬆的寫程式、認識其他 Web Developer 的比賽。滿錯愕的,因為以為是個 50/60 人以上,類似 Yahoo! Open Hack Day 一樣的大型活動,結果簽到簿只有少少 20 人,超緊張的,本來想說如果人多,做不出來可以打混… XD。到的時候有點晚,感謝 josephj 收留讓他坐他旁邊的位子。食物果然如活動介紹上面寫的一樣相當誇張,早上麥當勞,中午吃了海壽司,下午有星巴克,最後外面的零食跟雞排就 pass 了。

回到活動本身。上官大大出的比賽題目是寫出 2D 迷宮遊戲,或是 Paper Toss 遊戲。我選了 Paper Toss,因為感覺動態遊戲效果比較好,而且迷宮遊戲要求的滑鼠、鍵盤控制我比較不會。後來把握時間把 spec (XD)要求的功能都寫進去了,也盡量用了想到用的到的 IE9 新的 HTML5 技術。也因為不會做 Art,剛好為了搞笑,所以我就做了個把 IE9 Logo 丟進 HTML5 標誌的遊戲:

DemoSource

用到的技術可以在 Github 上面的 README 看到。寫一些感想:

  • 大部分的同好都是選迷宮,原因是因為不知怎麼處理丟東西的物理。其實 free fall 不需要真的解方程式來套或是像強者如 whsienc 把 box2D 拿來用,只要跑 loop,假設 loop 每次執行的時間為單位時間(要不用這個假設,實際量瀏覽器跑 setInterval/setTimeout的時間也可以,jQuery animation 就是這樣),每次執行位移的變化量就是速度乘單位時間、速度的變化量就是加速度(重力)乘單位時間。而且自由落體是各方向獨立的,X/Y 可以分開計算。
  • 風阻力用高中物理的近似,造成的加速度和速度成正比,所以每個 loop 再把加速度減掉設定的係數乘上目前的速度。不過這就沒有各方向獨立了,但我在程式還是把他當成方向獨立,因為這是黑客送不是物理模擬 XD。寫這些計算程式大概花了 1/3 的時間。
  • 知道可以這樣寫是因為大一物理系計概 … 這個運動不難,解出來其實是二元偏微分方程組,把方程式丟進程式也可以把動畫套出來(以我現在的工數能力可能解不出來就是orz)。但也是因為計概才會知道運動模擬應該要這樣寫,因為真實世界有方程式解的運動相當有限。說來也滿好笑的,雖然很喜歡寫程式,但當時其實很討厭那門課。
  • 在跑的動的情況下,東西上 canvas 滿方便的。而且預設的底是透明的,所以可以浮在任何背景的前面,裡面的東西只要 clearRect 就可以清掉。
  • Webkit 的 drawImage 對 SVG 的原生大小判斷是有錯誤的(所以上面的 screenshot 裡 HTML5 logo 才會比例錯誤),同樣的程式碼在 IE9 是對的,所以就保持那樣
  • Firefox 因為不明原因會 JavaScript Error,無法執行遊戲,我還沒 trace (大概也不會管了。Pull Request anyone?)
  • 撞到了 jQuery 這個 Issue:jQuery.camelCase() & jQuery.css() incompatible with IE prefixed properties。後來寫的 Wordaround 是 josephj 教我的。
  • 寫完 -ms-text-shadow: 發現沒效之後問了 ericsk 才發現 IE9 沒有XD text-shadow 本來就沒有 vender prefix,IE 也沒有支援就是。

再來,講一下主角,IE9,其實活動前後我的看法沒有什麼變化:

  • IE9 還是可以套進原本的開發流程:用 Webkit Nightly + 文字編輯器,全部寫好上 feature detection 之後再到其他瀏覽器調 style 和小的 JS 錯誤。但好處是相較於其他 IE,因為它更接近標準而且終於有堪用的開發者工具,所以調起來又更輕鬆了一點,終於不是為了支援 IE 程式碼要增加 50% 這樣。我猜是參考了很多 Webkit 的行為。
  • 但是呢,HTML5 DocType 沒有正確的在 ddsakura 的電腦上觸發 IE9 模式,於是就壞掉了。不知道是之前有設定 overwrite 掉還是真的有問題。
  • 另外,雖然效能終於趕上了其他瀏覽器(明天正式推出,正式版一字排開 Fx 就要被比下去了),但是還是少了一些功能,所以功能偵測和 fallback 還是不能少(至少我上兩個星期寫的兩個程式都不能用,我想要 Web Workers 和 FormData Interface 啊啊啊)
  • 還有一個不幸的事實是,因為 WinXP 不能裝 IE9,故 IE6 很有可能再活個一兩年…

一直都認為一群人組成的團體是沒有靈魂的;一家公司為股東追求利益天經地義,所做決定無關善惡道德。某家公司做了和我們相信的理念相同或是相反的事情,都只是剛好而已。如果 MS 往符合理念的方向移動,該給的肯定還是要給啦。上官大大主辦的開發者的活動真的不錯,大家有空真的可以把握機會投投看。我也是在那天才真的認識了 josephj,經由他和 hlb 聊天開釋才真的搞懂最近那些 JS Loader 和 AMD Spec 在幹嘛。啊,還有在同一間學校 ID 看很久但是都不認識的 grassboy

嗯,以上絕對不是因為拿了 peer vote 第三名抱了 XBox 360 + Kinect 回家才這樣說的 XD 你看我沒有都講好話嘛。