March 26, 2013

CSS Flex Box Layout

No comments:
前兩天看到了 CSS3 定義了 Flex 的排版方法,玩了一下效果如圖

每個方塊的大小會亂數改變,在一個固定寬度的 container 之中排放,如果超出 container 的寬度就自動換行,還能夠指定相反的 order。

不過這個 layout 的 spec 歷經許多重大改變,詳情可以閱讀 W3C Flexbox 或是 MDN 的 Using CSS flexible,話雖如此,現在的 Firefox 仍不支援 flexbox 的換行,上面那張圖我是從 chrome 裡面測試的。



一個簡單的 html
 
 
  
 
 
 
  
然後一個簡單的 css,主要的功能目前還需要註明 vendor (就是 chrome 用的 webkit)
.element {
 min-width: 100px;
 min-height: 100px;
 margin:10px;
 border: 5px;
 border-style:solid;

 display:-webkit-box;
 display:box;
 -moz-box-pack:center;
 -moz-box-align:center;
 -webkit-box-pack:center;
 -webkit-box-align:center;
}

#container {
 width: 50%;
 border: 1px;
 border-style:solid;
 border-color:#AAA;
 display: -webkit-flex;
 display: flex;
 flex-direction: row;
 -webkit-flex-direction: row;
 flex-wrap: wrap;
 -webkit-flex-wrap: wrap-reverse;
}
js code 也只是產生幾個方塊之後亂數改變大小
'use restrict';

function start(container) {
  var nodes,
      MAX = 9;

  function randomColor() {
    // 000000000000 to 000000FFFFFF, it might be 000000FF
    var num = '000000' +
      (((0xFFFFFF) * Math.random()) | 0).toString(16);
    return '#' + num.substring(num.length - 6);
  };

  function randomInt() {
    // -25 ~ 25
    return ((Math.random() * 51) | 0) - 25;
  };

  function Node(i) {
    this.elmnt = document.createElement('div');
    this.elmnt.className = 'element';
    this.elmnt.style.backgroundColor = randomColor();
    this.elmnt.style.borderColor = randomColor();
    this.elmnt.style.webkitOrder = i;
    this.elmnt.textContent = i;
  };

  Node.prototype.adj = function() {
    this.elmnt.style.width = 150 + randomInt();
    this.elmnt.style.height = 150 + randomInt();
    return this;
  };

  function init() {
    var node,
      counter;
    nodes = new Array();
    for (counter = 0; counter < MAX; counter++) {
      node = new Node(counter);
      container.appendChild(node.adj().elmnt);
      nodes.push(node);
    }
  };

  init();
}
html/js/css 上手之後還挺好玩的,只是現階段的 css 排版真痛苦,CSS3 的功能彷彿看得見吃不到,我覺得 fragment 的情況比 Android 還要慘烈。

January 14, 2013

台北市捷運地圖

5 comments:
不知道哪天我會在什麼地方用到這樣的一張圖,就隨手畫了一下,授權是 CC-BY-SA,只要在 Metadata 裡面把作者名字放進去,想要把左下角的圖示拿掉也沒關係。(我自己也覺得在那邊放張圖有點醜)



比較麻煩的是站名擺放的位置,一方面要貼近站點,又要保持間距增加可讀性,還不能讓圖片拉成太大張。反正捷運網站的圖片英文字小到眼睛都快瞎了,我也就懶得把英文站名放上去。(再加上英文站名的排版會瘋掉)

畫得沒有很好看,應該還算堪用,有需要的人就隨意挾去用吧,附 svg 檔,看不慣的鄉親歡迎發揮黑手精神動手改。

ps. svg 檔我有分幾個 Layer,圖片背景白色,要修改的時候記得 set layer as editable。

update:

December 29, 2012

立法院旁聽紀錄

No comments:
昨天 (Dec 28, 2012) 與幾位熱衷 Open Data 的阿宅朋友一同到立法院旁聽。既然現階段的焦點放在開放政府機關的資料,走訪一趟立法院實地感受乃是必然。

政治乃眾人之事,大到國家認同,小到兒童優惠票的衡量基準,無一不與政治有關。以前視政治話題如洪水猛獸,能避則避。長大才知道政治好像氧氣,攸關生死卻沒察覺無時無刻吸著它。

害怕政治議題無非是害怕遇上有理說不清的政治狂熱者,或是跟親朋好友吵起來。我認為反倒要有盡可能清楚的論述讓大家了解議題,才可能降低不理性者的噪音。因為是親朋好友擁有互信的基礎,委婉的討論更有機會取得共識。

離題了,總之,一般市井小民願意參與政治,了解前線現況絕對是好事。做些筆記,希望給想要去立法院旁聽的朋友些許幫助。

如何申請旁聽


旁聽的各種小細節散落在立法院網站各處,link 很有可能隨即失效就不貼了。基本上需要申請才方便行事(現階段,也許會有委員提出動議修改[1])

三人以上即可以團體身份在三天前送交旁聽的申請,送交的名冊會記載身份證字號,屆時進入立法院查驗身份證。立法院的工作人員告知,以團體單位送請會比較好。

一開始因為溝通有誤,我們五個人一起以個人身份進入,感受到不少關心,我想是因為平常太少鄉民會直接殺過去,一次來五人總不免會嚇一跳。會客室所讀到的申請規則,除了訂定三人以上三天前送交的規則,還有人數最高上限是一百人,我印象中並沒有閱讀到一、二人的臨時情況。沒有明定此規則,是否有什麼技術細節的問題我就不知道了。幸虧當時有黃委員的助理幫忙,讓我們順利進入旁聽。

旁聽限制

當然不能去叫囂,畢竟不是去抗議的,而且會有人陪伴你左右隨時提供協助。不過我們只有聽到九點至十點之間的國是論壇,十點之後休息時間由於多數委員正在他室協商,直至四十分左右才開始準備法案的表決。

此時我們就被請出去了

根據工作人員的說法,表決過程都能在網站上找到 (我沒找過,不確定),既然如此為何不能同時在場旁聽?工作人員沒有明白解釋。僅為走馬看花一下,沒有詳讀規則也不打算爭取些什麼,當然是十分配合地離開。不過注意到現場有幾位記者可以持續紀錄,我想媒體的優勢仍然勝過我們許多,希望他們多珍惜,而我們要多爭取。

筆記


既然走了一趟就隨手記記,並非原音呈現,僅表達接收方所被傳遞的訊息。委員的言詞有務實也有虛幻,言詞中挾著立場與想法,或是把意識形態以中立口吻掩蓋,台下雖然專注力各異,台上的表現還是要足夠專業。政治的精妙細節就是藏其中。

根據工作人員的解說,國是論壇會在 8:40 前抽籤決定,中籤委員每位可以上台發言三分鐘,三分鐘後會斷話請下台,頗有 lightening talk 的 fu。

依據上台的順序,委員的發言主旨是

  • 林正二委員:請歸還馬蘭部落土地
  • 李桐豪委員:關於馬總統的教育改革作為,高度肯定 12 年國教的方向,但是入學方案十分複雜,可能會造成一些階級的進入障礙,主張入學方案應通過立法院一關。
  • 李貴敏委員:少年 Pi 的影片看見了台灣的實力,但是人才應該要來自世界各地,所以行政團隊應該鬆綁外來人才的政策
  • 蘇清泉委員:要提昇醫療救護品質。好比提升救護車或公共場所的設備,且針對阻擾或濫用救護車的情事,修法全面加裝記錄器。
  • 張慶忠委員:無設限的環境乃毒品氾濫的核心,K 他命的刑責應該比照二級毒品
  • 廖國棟委員:交通部應該及期完成花東快速道路
  • 詹凱臣委員:社會各界對於景氣看好的比率有大幅提昇,我們應該予以肯定。而為了避免受到國際的景氣影響....blahblah  (抱歉本人才疏,除了讚揚之外抓不到重點)
  • 潘維剛:頁岩氣占美國的能源比例將會大幅提昇,反觀台灣?我們沒有能源政策,朝野應該要以愛止恨,合作開創新局。
  • 王育敏委員:擴大兒童優惠票,修改兒少法,以年齡取代身高,並且持續監督各單位避免民眾的福利縮水。
  • 許忠信委員:國內瀰漫著自由貿易的幻想,回頭看俾斯麥時代卻是取消了自由貿易而加強工業。自由貿易要看本事,我們卻大幅開放農業及服務業,削弱台灣的工作機會。
  • 張曉風委員:不需要金小刀上台,立法院就一直是個造口業的地方。每位美國總統宣示的時候,都會按著一本書發誓,是什麼書呢?是這本聖經 (接著張委員就開始讀經,直到三分鐘時間到了被斷話依然不停止,直至講完一個段落。我的宗教信仰是飛天拉麵神教,對於委員以半強迫的方式要我聆聽他教教義,本人在此提出嚴重抗議)
  • 陳鎮湘委員:由於在野黨擾民,使得本會期法案通過數量最少。深感 113 遊行不妥,會破壞投資信心,我們應該要共同支持馬總統的改革。
  • 陳碧涵委員:解決教育資源的「反重分配」。弱勢學生不應該因為經濟問題無法繼續升學,推內公費留學的台灣版,在台灣唸書的弱勢學生也能有獎學金補助,最快 102 年 8 月試辦。
  • 邱文彥委員:台灣的石頭最美,有資源就需要保護。陸客來台後有的撿拾,有的破壞石頭,相關單位卻無法保護。
  • 陳歐珀:寒凍水傷害農產,政府應該專案補助,並且及早提出因應對策,避免短期缺乏造成物價波動。

References


[1] 黃志雄委員便在立法院第8屆第2會期教育及文化委員會第22次全體委員會議提案,根據立法院議事規則第第61條規定,各種委員會開會時,除出、列席及會務工作人員外,不得進入旁聽。此提案並未通過,可以下載會議概況表看一看,其他紀錄可以在各委員會最新消息裡面下載,該提案紀錄在更新日期 2012-12-28 的檔案之中。

December 27, 2012

在 Blogger 貼上程式碼

No comments:
在 blogger/blogspot 想要貼程式碼並且提供比較清晰的外觀,之前找到的方法不外乎幾種
  1. 把程式碼貼到一些 formatting tool,把程式碼轉成帶有顏色的 html code 之後再貼回 blogger
  2. 把 javascript 檔放到另外一個 host,開啟網頁的時候載入 js 檔對 source code 做修改
第一個方法我不是很喜歡,文章的原始檔變成一堆 html code 完全看不出文意。第二個方法比較貼近我的需求,可惜要額外載入一些 js 檔,我希望盡量保持簡單。

恰好最近學了一點點 js,自己動手做很簡單的 pretty code。先定義幾個 css 格式,網頁下載完成之後,透過 javascript 對於帶有 code 類別的 pre 區塊做修改。

修改的邏輯也很簡單,僅僅只是用 regular expression 找出一些定義好的字串上點顏色罷了。我也不常貼上太多程式碼,因此正規表示式沒有寫得很認真,剛好我夠用而已。

使用方法

貼上程式碼的時候為 pre 加上類別 code 即可,好比
<pre class="code">
int main(void) {
    printf("blah\n"); 
}
</pre>

會變成
int main(void) {
    printf("blah\n")
}

設定方法

打開 blogspot 的設計,直接編輯 html,在 css 的部份加上這一塊

pre {
margin: 5px 20px;
border: 1px dashed #666;
padding: 5px;
color: #000;
background: #f8f8f8;
white-space: pre-wrap;       /* css-3 */
white-space: -moz-pre-wrap;  /* Mozilla, since 1999 */
white-space: -pre-wrap;      /* Opera 4-6 */
white-space: -o-pre-wrap;    /* Opera 7 */
word-wrap: break-word;       /* Internet Explorer 5.5+ */
}
span.control{
font-weight: bold;
color: #A00;
}
span.type {
font-weight: bold;
color: #0A0;
}
span.literal {
color: #00C;
}
span.comment {
font-weight: bold;
color: #AAA;
}

接下來找到 javascript 的區塊貼上程式碼,請注意「這一塊不能直接貼上」,這邊是看網頁原始碼的時候看到的結果。真正要貼上的是底下那一塊

onload = function () {
    var elmts,
        count = 0,
        regLiteral = /(('.*?'|".*?"))/g, // 'foo' or "foo"
        regType = /(\W|)(void|int|float|double|byte|struct)(\W)/g, // int foo
        regControl = /(\W|)(for|if|fi|while|do|done|return|each)(\W)/g, // while()
        regClearCmt = /(\/\*.*?)()(.*?)(<\/span>)/g,
        regClearCmts = /(\/\/.*?)()(.*?)(<\/span>)/g,
        regCmtsStart = /\/\*/g, //for /*
        regCmtsEnd = /\*\//g,   //for  */
        regCmt = /\/\/(.*)/g,   //for  //

        replaceLtGt = function (pre) {
            var text = pre.innerHTML;
            // <a> to &lt;a&gt;
            pre.innerHTML = text.replace(/<(.+?)>/gi, "<$1>");
        },

        setColor = function (pre) {
            var text = pre.innerHTML;

            text = text.replace(regLiteral, "$1");
            text = text.replace(regType, "$1$2$3");
            text = text.replace(regControl, "$1$2$3");
            text = text.replace(regClearCmt, "$1$3");
            text = text.replace(regClearCmts, "$1$3");
            text = text.replace(regCmtsStart, "/*");
            text = text.replace(regCmtsEnd, "*/");
            text = text.replace(regCmt, "//$1");
            pre.innerHTML = text;
        };

    elmts = document.querySelectorAll("pre.code"),
    count = elmts && elmts.length;
    while (count > 0) {
        count--;
        replaceLtGt(elmts[count]);
        setColor(elmts[count]);
    }
};


因為貼上的對象是 blogger 的 template,因此要把 & 或 < 或 > 再做一次轉換,實際上真正要貼進 blogger 的 js code 是這一段(看不懂了吧!所以我才要先貼上面比較有人性的部份XD)

onload = function () {
    var elmts,
        count = 0,
        regLiteral = /((&#39;.*?&#39;|&quot;.*?&quot;))/g, // &#39;foo&#39; or &quot;foo&quot;
        regType = /(\W|)(void|int|float|double|byte|struct)(\W)/g, // int foo
        regControl = /(\W|)(for|if|fi|while|do|done|return|each)(\W)/g, // while()
        regClearCmt = /(\/\*.*?)(&lt;span class=&quot;.*?&quot;&gt;)(.*?)(&lt;\/span&gt;)/g,
        regClearCmts = /(\/\/.*?)(&lt;span class=&quot;.*?&quot;&gt;)(.*?)(&lt;\/span&gt;)/g,
        regCmtsStart = /\/\*/g, //for /*
        regCmtsEnd = /\*\//g,   //for  */
        regCmt = /\/\/(.*)/g,   //for  //

        replaceLtGt = function (pre) {
            var text = pre.innerHTML;
            // &lt;a&gt; to &amp;lt;a&amp;gt;
            pre.innerHTML = text.replace(/&lt;(.+?)&gt;/gi, &quot;&amp;lt;$1&amp;gt;&quot;);
        },

        setColor = function (pre) {
            var text = pre.innerHTML;

            text = text.replace(regLiteral, &quot;&lt;span class=\&quot;literal\&quot;&gt;$1&lt;/span&gt;&quot;);
            text = text.replace(regType, &quot;$1&lt;span class=\&quot;type\&quot;&gt;$2&lt;/span&gt;$3&quot;);
            text = text.replace(regControl, &quot;$1&lt;span class=\&quot;control\&quot;&gt;$2&lt;/span&gt;$3&quot;);
            text = text.replace(regClearCmt, &quot;$1$3&quot;);
            text = text.replace(regClearCmts, &quot;$1$3&quot;);
            text = text.replace(regCmtsStart, &quot;&lt;span class=\&quot;comment\&quot;&gt;/*&quot;);
            text = text.replace(regCmtsEnd, &quot;*/&lt;/span&gt;&quot;);
            text = text.replace(regCmt, &quot;&lt;span class=\&quot;comment\&quot;&gt;//$1&lt;/span&gt;&quot;);
            pre.innerHTML = text;
        };

    elmts = document.querySelectorAll(&quot;pre.code&quot;),
    count = elmts &amp;&amp; elmts.length;
    while (count &gt; 0) {
        count--;
        replaceLtGt(elmts[count]);
        setColor(elmts[count]);
    }

};
要把「貼上 template 的醜陋內容再轉一次變成能夠貼上 blog 文章」這樣轉來轉去自己都快被搞混了,希望我沒有貼錯

December 25, 2012

Momome

No comments:
聖誕節的時候上傳了之前寫的一個小程式 Momome,請看 Google Play 的 Momome

這是 Open source 的程式,原始碼可以在 Github momome 裡面取得。

程式很單純,寫入一些簡單的筆記事項,以 ListView 的方式顯示。比較特別之處是,你寫入的東西會被加密儲存,讀取的時候再解開。解密需要你輸入之前設定的密碼,而且程式在關閉的時候會自動上鎖。

也就是說,設定一個密碼之後開始紀錄一些大小雜事,寫完直接離開程式即可。下一次開啟時會被詢問密碼,只有知道密碼的人才能夠看見你寫了什麼東西進去。

打開程式卻沒有輸入密碼,看不見任何內容

輸入密碼解鎖

解鎖後看見之前輸入的內容


生活中大多數會用到的東西 Market 上頭都有了,之前還真不知道要寫什麼小程式來玩玩。

娛樂性的 app 好比遊戲,大家會在手機裡面裝好幾個性質類似的程式,我相信許多人的手機裡面就好幾個不同版本的 Angry Birds。但是寫遊戲的成本非常高,需要程式、美工與企劃,除了熱血度破表的阿宅,個體戶實在很難推出遊戲 App。

工具類 App 的生存模式就不同,即使類似功能的程式有好幾個選擇,使用者最後都只會想要「選出一個」,然後一直用到它跟不上時代為止。要在夾縫中生存就必須持續打出差異化,讓人們覺得「這個程式比較好」才會捨棄另外一個選擇。還有一種工具類程式要與後端的服務做結合,好比摩斯漢堡的點餐程式iKala、Line 或 Whats app,人們是為了用後端的服務而選擇前端程式,角力的場所其實是後端,這種也不是個體戶的領域。

個人認為想要再寫新的 App 送上 Market,要嘛不斷整合各種功能愈寫愈大,要嘛在同質性高的族群裡頭找出貼心的小細節、或是把程式的主要功能做到最好,不然使用者很懶得換工具的。

若說大家手機裡面 80% 的程式相同,只有 20% 的程式會不一樣,把某個小細節抽出來特化到極點,對準 20% 的空間其實是個體戶的守備範圍。這個市場絕對不大,因此不會是商業應用的好對象,寫起來成本不高,又適合 Open Source 出來給大家一起改,自娛娛人的小程式針對這種方向來寫還不錯。

我也覺得,這種只專心做一件事情的小程式會愈來愈多。能夠飛天遁地的大玩意有幾隻就夠了,現實生活中每個人在小地方都很不一樣,也因此有些非常奇怪的需求並不容易被滿足,有隻 Just work 的程式滿足這種小需求真的是很貼心的事情。(這種程式麻煩的地方在於很難推銷出去給別人知道 XD)

恰好我很鼓勵老婆使用強度夠的密碼,最好還是每個網站都用不同組。但是太多複雜的密碼很難記憶,寫下來也不好。乾脆把「密碼的提示」紀錄在隨身會帶的手機裡頭,再用一組密碼去保護它,兼顧了方便性以及最低限度的安全。

這隻小程式是寫給老婆的,我自己也很常用。好比去朋友家裡偶爾要登入 Wifi,隨手把密碼紀錄到程式裡面就不需要每次都問,人家家裡的密碼用明碼記錄下來似乎不太好。

至於為什麼叫 Momome,因為老婆的外號是「桃」,而且這個程式用來當作 Memo,就取了這個簡單好記的名字。

到今天 12/25 跟老婆在一起滿三年了,老婆聖誕節快樂唷~