Hatena::ブログ(Diary)

放浪するエンジニアの覚え書き このページをアンテナに追加 RSSフィード

2008-11-23

Button Control: Slider Button

| 09:22 |  Button Control: Slider Button - 放浪するエンジニアの覚え書き のブックマークコメント

このExampleは、写真を表示して、スライダーでその透過度を変えるというもの。

初期画面は以下。YUIのExampleがFlickrをイメージ・ソースにしていたので、自分がFlickrFlickrへはこちら)にupしている写真に張り替えてみた。

初期画面では、不透過度100%(写真そのもの)にセットされる。

f:id:tetsuya_odaka:20081118203609p:image

Opacityラベルのボタンを押すとスライダーが現れる。

以下が半分まで透過度を上げたときの画面である。

f:id:tetsuya_odaka:20081118203607p:image

このサンプルも戦略的には、「Button Control: Color Picker Button」と同じ方法を採用している。

以下にJavascriptを含む、htmlファイルを示すが、このサンプルもmodule patternに書き直した。

Button Control: Color Picker Button」のソースコードと比較してもらえれば、カラーピッカーもスライダーも(そして、カレンダーピッカーも)、まったく同様のコードによって生成されることがわかる。

<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>Ajax_Sampling</TITLE>
<style type="text/css">
body {
	margin:0;
	padding:0;
}
</style>
<link rel="stylesheet" type="text/css" href="scripts/yui/fonts/fonts-min.css" />
<link rel="stylesheet" type="text/css" href="scripts/yui/button/assets/skins/sam/button.css" />
<link rel="stylesheet" type="text/css" href="scripts/yui/menu/assets/skins/sam/menu.css" />
<link rel="stylesheet" type="text/css" href="scripts/yui/slider/assets/skins/sam/slider.css" />

<script type="text/javascript" src="scripts/yui/yahoo-dom-event/yahoo-dom-event.js"></script>
<script type="text/javascript" src="scripts/yui/dragdrop/dragdrop-min.js"></script>
<script type="text/javascript" src="scripts/yui/slider/slider-min.js"></script>
<script type="text/javascript" src="scripts/yui/container/container_core-min.js"></script>
<script type="text/javascript" src="scripts/yui/menu/menu-min.js"></script>
<script type="text/javascript" src="scripts/yui/element/element-beta-min.js"></script>
<script type="text/javascript" src="scripts/yui/button/button-min.js"></script>

<style type="text/css" id="defaultstyle">
#container {
	margin: 2px;
	padding: 3px;
	width: 500px;
/*	height: auto; */
	border:1px dashed #999999;
}

#example {
	padding: 1em;
}

#photo {
	border: solid 1px #000;
}

/*
	Set the "zoom" property to "normal" since it is set to "1" by the 
	".example-container .bd" rule in yui.css and this causes a Menu
	instance's width to expand to 100% of the browser viewport.
*/
div.yuimenu .bd {
	zoom: normal;
	}

    /* Style the <div> element containing the Button instance */
#opacitycontrols {
	border-top: solid 1px #000;
	padding: .5em .25em;
	margin-top: .5em;
}

/* Style the Slider instance */
#slider-bg {
	position: relative;
	background: url(http://developer.yahoo.com/yui/examples/button/assets/bg-fader.gif) 7px 12px no-repeat;
	height: 28px;
	width: 217px; 
}

#slider-thumb {
	cursor: default;
	position: absolute;
	top: 4px;
}
    
/*
	Give the <em> element wrapping the Button instance's text label a 
	fixed width so that the Button doesn't grow or shrink as the 
	text label is updated.
*/

#opacitybutton-currentopacity {
	width: 3em;
	font-style: normal;
	display: block;
	text-align: left;
}

#opacitybutton  {
	vertical-align: middle;
}

</style>

<script type="text/javascript">
//
//モジュールパターンで実装する。
//
YAHOO.namespace("EGP");

YAHOO.EGP.SliderButton = function() {

	var Event = YAHOO.util.Event;
	var Dom = YAHOO.util.Dom;
	var oSlider;
	var oOpacityMenu;
    var oCurrentOpacity;
    var oButton;
    
	// MenuインスタンスのbeforeShowイベントでスライダーインスタンスを生成する。
	// 1回だけ実行される。
	var onMenuBeforeShow = function () {

    	// Sliderインスタンスの生成(staticメソッド)
    	// http://developer.yahoo.com/yui/docs/YAHOO.widget.Slider.html
    	// sliderのid、thumb(つまみ)のid、幅[0pix,200pix]、1pixずつ動く。
	    oSlider = YAHOO.widget.Slider.getHorizSlider("slider-bg", 
	    	    "slider-thumb", 0, 200, 1);

    	// Thumbの初期値を設定、その間、アニメーションは動かない。
	    oSlider.setValue(200, true);

    	// スライダーエレメントの取得
	    var oSliderEl = Dom.get("slider-bg");

    	// スライダーのchangeイベントにハンドラをsubscribeする。
	    oSlider.subscribe("change", function() {

	        /*
            Divide the pixel offset in half to get a value between 
            0 and 100 - used to convey the current opacity via the
            Button instance's label. 
    	    */
			// スライダーの位置から透過度を求める。	
    	    // 200pxで100%を表しているために、0.5を掛ける。
    	    var nValue = (Math.round(oSlider.getValue() * .5)),
            nOpacity = (nValue * .01);

			// スライダーインスタンスのタイトルをupdateする。
        	oSliderEl.title = "slider value = " + nOpacity;

	        // id=photoのopacity属性を計算値にupdateする。
	        Dom.setStyle("photo", "opacity", nOpacity);

	        // ボタンインスタンスのテキストを変更
    	    oCurrentOpacity.innerHTML = (nValue + "%");
	    });

    	// スライダーにフォーカスを当てる。
		focusSlider();

	    // スライダーが現れる際に、いつも、スライダーにフォーカスを当てる。
    	oOpacityMenu.subscribe("show", focusSlider);

		// 1回だけ実行するので、このメソッドをunsubscribeする。
	    oOpacityMenu.unsubscribe("beforeShow", onMenuBeforeShow);

	};


	var focusSlider = function () {
        if ((YAHOO.env.ua.ie || YAHOO.env.ua.gecko) && oSliderEl) {
            window.setTimeout(
    	            function () {                    
            			oSliderEl.focus();}, 
            		0);
		}                    
	};
		
	return{
    	init: function() {

	    	// ボタンのためにエレメントを追加し、ラベルを設定し、exampleにappendする。
		    var oDIV = document.createElement("div")
    		oDIV.id = "opacitycontrols";
    		oDIV.innerHTML = '<label for="opacitybutton-button">Opacity:</label>';

    		Dom.get("example").appendChild(oDIV);

			// スライダーインスタンスを入れるため箱を作る。
    		oOpacityMenu = new YAHOO.widget.Menu("opacitymenu", 
    	    					{ width: "220px" });

			// ボタンインスタンスを生成する。
			// labelをemで指定するのは、テキストラベル変更時(スライダーを動かしたとき)
			// に、ボタンの幅を固定するため。
	    	oButton = new YAHOO.widget.Button({ 
                                  type: "menu", 
                                  id: "opacitybutton", 
                                  label: '<em id="opacitybutton-currentopacity">100%</em>', 
                                  menu: oOpacityMenu,  
                                  container: "opacitycontrols" });

	    /*
        Maintain a reference to the <em> element inside the label
        so that its text can easily be updated in response to the firing
        of the Slider instance's "change" event.
    	*/
			
			oButton.on("appendTo", function () {
	
				// 上で作成した箱のボディーにスライダ用のMarkupを作成する。
    	    	oOpacityMenu.setBody('<div id="slider-bg" tabindex="1" title="Slider">' + 
    	            '<div id="slider-thumb"><img src="http://developer.yahoo.com/yui/examples/button/assets/thumb-n.gif"></div></div>');

				// メニューインスタンスを作成。
    		    oOpacityMenu.render(oButton.get("container"));			
				oCurrentOpacity = Dom.get("opacitybutton-currentopacity");
			});
    
    	// ボタンタグにidを設定する。
    	// ラベルをクリックした際にボタンにフォーカスをあてるため。
    	var oHTMLButton = oButton.get("element").getElementsByTagName("button")[0];
    	oHTMLButton.id = "opacitybutton-button";

        oOpacityMenu.subscribe("beforeShow", onMenuBeforeShow);
		}
	};
}();

//DOMが完全にloadされたら、サンプルを初期化する。
YAHOO.util.Event.onDOMReady(
	//DomReadyイベントで発火するハンドラ
	YAHOO.EGP.SliderButton.init,
	//ハンドラに渡すオブジェクト(関数)
	YAHOO.EGP.SliderButton,
	//ハンドラは、上記のオブジェクトのスコープをもつ。   
	true
);

</script>
</HEAD>

<BODY class="yui-skin-sam">
<div id="container">
<p>
Slider Buttonの作り方のサンプルです。
</p>
<div id="example">
	<a href="http://www.flickr.com/photos/wanderingse/2086774207/in/set-72157603291379113/" title="Photo Sharing">
	<img id="photo" src="http://farm3.static.flickr.com/2116/2086774207_d1e63234a9.jpg?v=0" width="450" height="350" alt="Acer in late autumn">
	</a>
</div>


</div>
</BODY>		
</HTML>