Monday, May 17, 2010

使いやすそうなカラーピッカーを作ってみた

YUIの colorpicker + button をちょっと修正しました。
サンプル

 
<script type="syntaxhighlighter" class="brush:html">
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/combo?2.8.1/build/assets/skins/sam/skin.css">
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.8.1/build/fonts/fonts-min.css" />
<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.8.1/build/yahoo-dom-event/yahoo-dom-event.js&2.8.1/build/element/element-min.js&2.8.1/build/button/button-min.js&2.8.1/build/dragdrop/dragdrop-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.1/build/slider/slider-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.1/build/colorpicker/colorpicker-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.1/build/container/container_core-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.1/build/menu/menu-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.1/build/button/button-min.js"></script>

<style type="text/css">
    body {
        margin:0;
        padding:0;
    }
    div.yuimenu .bd {
        zoom: normal;
    }
    .current-color {
        display: block;
        width: 1em;
        height: 1em;
        overflow: hidden;
        text-indent: 1em;
        background-color: #fff;
        white-space: nowrap;
        border: solid 1px #000;
    }
    .yui-menu-button-menu .yui-picker-controls,
    .yui-menu-button-menu .yui-picker-swatch,
    .yui-menu-button-menu .yui-picker-websafe-swatch {
        display: none;
    }
    .yui-skin-sam .yui-button{
        background:none;
        border:none;
        margin:0;
    }
    .yui-skin-sam .yui-button .first-child{
        background:none;
        border:none;
    }
    .yui-skin-sam .yui-menu-button button{
        background:none;
        margin:0;
        padding:0;
    }
</style>
<div class="yui-skin-sam">
<script type="text/javascript">
    YAHOO.namespace('ypicker');

    YAHOO.ypicker = function(container, input){
        this.container = container;
        this.input = input;
        this.menu = YAHOO.util.Dom.generateId();
        this.button = YAHOO.util.Dom.generateId();
        this.pickerContainer = YAHOO.util.Dom.generateId();
        this.pickerMenu = YAHOO.util.Dom.generateId();
        this.currentColor = YAHOO.util.Dom.generateId();

        YAHOO.util.Event.onContentReady(this.container, this.bind(this.init));
    }
    YAHOO.ypicker.prototype = {
        bind:function(func, args){
            if('undefined' == typeof args){
                args = [];
            }
            var self = this;
            return function(){
                return func.apply(self, args);
            };
        },
        onButton:function(){
            if( this.isColorPickerInit ){
                return;
            }
            this.isColorPickerInit = true;
            this.oColorPicker = new YAHOO.widget.ColorPicker(this.oColorPickerMenu.body.id, {
                                    showcontrols: false,
                                    images: {
                                        PICKER_THUMB: "http://developer.yahoo.com/yui/build/colorpicker/assets/picker_thumb.png",
                                        HUE_THUMB: "http://developer.yahoo.com/yui/build/colorpicker/assets/hue_thumb.png"
                                    }
                                });

            this.oColorPicker.on("rgbChange", this.bind(function(e){
                var sColor = "#" + this.oColorPicker.get("hex");
                this.oColorPicker.set("value", sColor);
                YAHOO.util.Dom.setStyle(this.currentColor, "backgroundColor", sColor);
                YAHOO.util.Dom.get(this.input).value = sColor;
            }));
        },
        init:function(){
            // Create a Menu instance to house the ColorPicker instance
            this.oColorPickerMenu = new YAHOO.widget.Menu(this.pickerMenu);

            // Create a Button instance of type "split"
            this.oButton = new YAHOO.widget.Button({
                                                type: "menu",
                                                id: this.button,
                                                label: '<span id="'+this.currentColor+'" class="current-color"></span>',
                                                menu: this.oColorPickerMenu,
                                                container: this.container });

            this.oButton.on("appendTo", this.bind(function () {
                this.oColorPickerMenu.setBody(" ");
                this.oColorPickerMenu.body.id = this.pickerContainer;
                YAHOO.util.Dom.setStyle( this.oColorPickerMenu.body, 'width', '220px');
                YAHOO.util.Dom.setStyle( this.oColorPickerMenu.body, 'height', '190px');

                // Render the Menu into the Button instance's parent element
                this.oColorPickerMenu.render(this.oButton.get("container"));
            }));

            this.isColorPickerInit = false;
            this.oButton.on("click", this.bind(this.onButton));
        }
    }

</script>
<script>
    (new YAHOO.ypicker("ybutton", "ybutton-value")),
    (new YAHOO.ypicker("ybutton2", "ybutton-value2"));
</script>
<input id="ybutton-value" type="text" style="font-size:11px;"/><span id="ybutton"></span>
<input id="ybutton-value2" type="text" style="font-size:11px;"/><span id="ybutton2"></span>
</div>
</script>

Sunday, May 9, 2010

ループバック用のIPアドレスの割り当て方(linux編)

ループバック用のIPアドレスの割り当て方。
とりあえず、192.56.76.4 に割り当ててみる。

 
$ sudo /sbin/route add -host 192.56.76.4 dev eth0
$ sudo /sbin/ifconfig eth0:0 192.56.76.4
ping を送ってみる。
 
$ ping 192.56.76.4 -c 1
PING 192.56.76.4 (192.56.76.4) 56(84) bytes of data.
64 bytes from 192.56.76.4: icmp_seq=1 ttl=64 time=0.073 ms

--- 192.56.76.4 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.073/0.073/0.073/0.000 ms
成功した。

削除するときは、

 
$ sudo /sbin/route del -host 192.56.76.4 dev eth0
$ sudo /sbin/ifconfig eth0:0 down
route は、ネットマスクを使って以下のように書いてもいい
 
sudo /sbin/route add -net 192.56.76.0 netmask 255.255.255.0 dev eth0

Monday, April 26, 2010

UnitTestしやすいクラスの作り方

以下の要約。
http://misko.hevery.com/2008/07/08/how-to-think-about-the-new-operator/

Unit Test しやすいクラスは、クラス間の依存グラフにおいて、 終端に位置するクラス(以下、leafクラス)である。 なぜなら、それだけを Unit Test することができるから。 例えば、以下のようなクラス。

 
class House {
  private boolean isLocked;

  private boolean isLocked() {
    return isLocked;
  }

  private boolean lock() {
    isLocked = true;
  }
}

しかし、以下のようなクラスでは、Kitchenクラスを生成せずに、 House クラスだけを生成できない。 理由は、House のロジック内に、Kitchen の new 演算子が 含まれているから。 そのため、House クラスのみを Unit Test することができない。

 
class House {
  private final Kitchen kitchen = new Kitchen();
  private boolean isLocked;

  private boolean isLocked() {
    return isLocked;
  }

  private boolean lock() {
    kitchen.lock();
    isLocked = true;
  }
}

Houseだけを個別に Unit Test するには、偽の Kitchen で、Houseを生成する必要がある。

 
class House {
  private final Kitchen kitchen;
  private boolean isLocked;

   public House(Kitchen kitchen) {
    this.kitchen = kitchen;
  }

  private boolean isLocked() {
    return isLocked;
  }

  private boolean lock() {
    kitchen.lock();
    isLocked = true;
  }
}

上のように、new演算子をロジックから取り除けば、 テストを簡単に行える。 Kitchen のモックを作れば、Houseだけを Unit Test できる。 これにより、leaf クラスでなくても、個別にテストを行える。

どこで、new演算子を使えばいいかというと、 以下のようにFactoryクラスを作ってやればよい。

 
class ApplicationBuilder {
  House build() {
    return new House(new Kitchen(
               new Sink(),
               new Dishwasher(),
               new Refrigerator())
           );
  }
}

Main メソッドでは、このFactoryを使ってオブジェクトの依存関係を 生成すればよい。

 
class Main {
  public static void main(String...args) {
    House house = new ApplicationBuilder().build();
    house.lock();
  }
}

コードがシンプルで多機能なlight box系js

コードがシンプルで多機能なlight box系js
http://colorpowered.com/colorbox/

サンプル

iframe なども画像と同じように表示できたり、動的に生成されるURLに対しても問題なく使える。 ソース読み込み以外で js を書いてるところをタグ内に完全に埋めれるようにしたり、コード内でべた書き class 名を使ってしまってるところをキレイにしたい。 あと、会社でYUIを使ってるのでYUIバージョンを作りたい。

Sunday, April 18, 2010

googleに学ぶ角丸の作り方(html、css)2

さっきの方法だと、背景色が透過しないので、以下のようにすると透過する
角丸の中の
テキスト

googleに学ぶ角丸の作り方(html、css)

グーグルがこの前始めた、最新検索では、 吹き出しのような表示がある。

そこの吹き出しから軽量な角丸の作り方を学ぶことができる。
一つ目の画像:
二つ目の画像:

グーグルが置いてる画像はこの二つだけ。
それに対し角丸を置いてるサイトの画像を見てみると、四角形の上部の辺を全て画像にしているサイトも多い。
グーグルの方法だと
・横幅を柔軟に変更できる
・画像サイズがもっとも軽量
という利点がある。

吹き出し部分の画像は特に必要ないので、それを取り除いて実際に角丸を作ってみた。

角丸の中の
テキスト

ここでは、2つの画像を使っている。

http://sikaku-chat.com/stt/circle/bg0.png
用途:角丸の角、四角形の左辺と右辺に対応

http://sikaku-chat.com/stt/circle/bg1.png
用途:四角形の上辺、下辺に対応

ソース部分のポイントは3つだけ
・background-position を指定し、円の画像からうまく角丸を作成
・全体的にtable を使用
・角丸部分には box のfloatを使用

こう見るとたいしたことはやっていない。
知らなかったのは、float container に table の要素が使えることだろうか。
float container ってtable使えばよかったのか?

Saturday, April 17, 2010

透過PNGをマルチブラウザで指定する方法

CSS で以下のように指定すればよい
 ・block 要素に background で画像を指定
 ・アンダースコアハックでIE6だけAlphaImageLoaderを使用 サンプル:

参考:http://developer.yahoo.com/yui/examples/button/btn_example11.html