<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>nouv.labo &#187; JavaScriptグラフィックス</title>
	<atom:link href="http://nouv.biz/wp/tag/javascript%e3%82%b0%e3%83%a9%e3%83%95%e3%82%a3%e3%83%83%e3%82%af%e3%82%b9/feed/" rel="self" type="application/rss+xml" />
	<link>http://nouv.biz/wp</link>
	<description>nouv.biz 代表の戯言</description>
	<lastBuildDate>Sat, 05 Nov 2022 10:11:22 +0000</lastBuildDate>
	<language>ja</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=3.9.40</generator>
	<item>
		<title>フレームレートとパフォーマンスモニタについて</title>
		<link>http://nouv.biz/wp/2012/10/06/%e3%83%95%e3%83%ac%e3%83%bc%e3%83%a0%e3%83%ac%e3%83%bc%e3%83%88%e3%81%a8%e3%83%91%e3%83%95%e3%82%a9%e3%83%bc%e3%83%9e%e3%83%b3%e3%82%b9%e3%83%a2%e3%83%8b%e3%82%bf%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6/</link>
		<comments>http://nouv.biz/wp/2012/10/06/%e3%83%95%e3%83%ac%e3%83%bc%e3%83%a0%e3%83%ac%e3%83%bc%e3%83%88%e3%81%a8%e3%83%91%e3%83%95%e3%82%a9%e3%83%bc%e3%83%9e%e3%83%b3%e3%82%b9%e3%83%a2%e3%83%8b%e3%82%bf%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6/#comments</comments>
		<pubDate>Sat, 06 Oct 2012 10:25:52 +0000</pubDate>
		<dc:creator><![CDATA[nouv]]></dc:creator>
				<category><![CDATA[ActionScript3]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Flash Hacks]]></category>
		<category><![CDATA[JavaScriptグラフィックス]]></category>

		<guid isPermaLink="false">http://nouv.biz/wp/?p=169</guid>
		
        

        <description><![CDATA[<p>フレームレートとは元々は映像で用いられる言葉である。<br />
アニメーションなどで1秒間に何コマ絵を動かしますか、という意味だ。1秒間に24コマの場合は24FPS（フレームパーセコンド）などと表される。FlashやJavaScriptなどで動作させるアニメーションでも用いられることが多い。</p>
<p>このフレームレート、Flashの場合直接フレームレートの指定が可能（デフォルトは12）だが、Javascriptの場合はtimer(setTimeoutなど）で逆算して指定することになる。<br />
timerはブラウザにより大きく性能が異なるため、ゲーム等を制作する場合大きな障害となる。例えばキャラクタが画面を移動するとき、あるブラウザでは0.5秒かかり、別のブラウザでは2秒かかるなど、差異が大きすぎるとゲームとして成立しない。</p>
<p>この問題はオライリー・ジャパンの<a href="http://www.amazon.co.jp/gp/product/4873115280/ref=as_li_tf_tl?ie=UTF8&amp;camp=247&amp;creative=1211&amp;creativeASIN=4873115280&amp;linkCode=as2&amp;tag=nouvlog-22" target="_blank">「JavaScriptグラフィックス」</a><img style="border: none !important; margin: 0px !important;" src="http://www.assoc-amazon.jp/e/ir?t=nouvlog-22&amp;l=as2&amp;o=9&amp;a=4873115280" alt="" width="1" height="1" border="0" />では以下の方法で対処している。</p>
<ol>
<li>どの程度のフレームレートが実現しているか調べる</li>
<li>実現したい速度と実際の速度の比率（＝係数）を調べる</li>
<li>1フレームあたりのキャラクターの移動距離を標準の距離×係数で再設定する</li>
<li>フレーム毎にキャラクターを再設定した距離移動させる</li>
</ol>
<p>一方Flashサイトの場合、ゲーム用途よりバナーやトップページフラッシュなど演出目的のものが多いため、滑らかな動作が重要視される。滑らかに動かした方がより高級感を醸し出せるからだ。<br />
滑らかに動かすためには、アニメーションは1秒のコマ数を増やせばよい。そこで多くの製作者は極力高いフレームレートを設定することになる。</p>
<p>ところが高くすればするほどパソコンに負荷がかかり、スペックの低いパソコンでは設定したフレームレートの半分も出せないことがある。結果カクカクした動きになっしまう。</p>
<p>その対策については、こちらもオライリー・ジャパンの<a href="http://www.amazon.co.jp/gp/product/4873112354/ref=as_li_tf_tl?ie=UTF8&amp;camp=247&amp;creative=1211&amp;creativeASIN=4873112354&amp;linkCode=as2&amp;tag=nouvlog-22" target="_blank">「Flash Hacks」</a><img style="border: none !important; margin: 0px !important;" src="http://www.assoc-amazon.jp/e/ir?t=nouvlog-22&amp;l=as2&amp;o=9&amp;a=4873112354" alt="" width="1" height="1" border="0" />にわかりやすく記載されている。<br />
まず上記１同様、「どの程度のフレームレートが実現しているか」を調べ、オブジェクトが多数動くことが負担になっている場合は、動作しているオブジェクト（キャラクターや粒子など）の数を減らしている。<br />
上記書籍は2005年発売でActionScript1.0又は2.0で記述されているので、今回はActionScript3.0に置き換えつつ、より実践的にしたPerformanceMonitorクラスを作成した。<br />
<a title="performance monitor sample" href="http://nouv.biz/labo/20121004_performance_montor/" target="_blank">以下</a>がそのサンプルとなる(<a href="http://nouv.biz/labo/20121004_performance_montor/">http://nouv.biz/labo/20121004_performance_montor/</a>)。<br />
大量のパーティクル（粒子）を生成し、ランダムにY回転させている(重いので他作業中の方は注意）。<br />
<a href="http://nouv.biz/labo/20121004_performance_montor/" target="_blank"><img class="aligncenter size-full wp-image-182" title="particle100000" src="http://nouv.biz/wp/wp-content/uploads/2012/10/particle100000.jpg" alt="" width="500" height="327" /></a></p>
<p>右下に、実現しているフレームレートと、パーティクルの数を表示している。<br />
フレームレートは24FPS、パーティクルの初期生成数は10万個を初期値にしているが、フレームレートが24フレームに達しないと、序々にパーティクルの個数を減らし調整する。</p>
<p>フレームレートが目標に達しているか調査する部分のスクリプトを以下に記載。</p>
<pre>  private function onEnterframe(event:Event):void {
   var nowTime:Number = new Date().getTime();
   var pastTime = nowTime-oldTime ; 
   var fps:Number = 1000 / pastTime;

   if (interCount &gt; 100) {
    //過去の累積が悪影響をおよぼすので、ある程度の回数でクリアする
     totalFPS = 0;
     interCount = 0;
   }
   totalFPS += fps;
   interCount++;
   oldTime = nowTime;
  }

  /*
   * 
   */
  public function get _averageFps():int {
   var averageFPS:Number = Math.floor(totalFPS / interCount );
   return averageFPS;
  }

  /**
   *達成したいフレームレートを指定する
   * 達成できているかどうかを返す
   */
  public function fpsBool(targetFPS:int):Boolean {
   var bool:Boolean;
   if (_averageFps &gt;= targetFPS) {
    bool = true;
   }else {
    bool = false;
   }
   return bool;
  }</pre>
<p>現時刻から前に通過した時刻を引き、そこからフレームレートを求めその値を返す。<br />
一方、パーティクルはその結果を受けて個数調整を行なっている。<br />
numBallsは生成するパーティクルの個数。上限下限を設けている。</p>
<pre>	
performanceBool = performanceMonitor.fpsBool(24);
if (!performanceBool) {
	numBalls = (numBalls - 100) &gt; 0? numBalls - 100 : numBalls;
}else {
	numBalls = (numBalls + 100) &lt;= makeNum ? numBalls + 100 : makeNum;
}</pre>
<p>&nbsp;</p>
<p><iframe style="width: 120px; height: 240px;" src="http://rcm-jp.amazon.co.jp/e/cm?t=nouvlog-22&amp;o=9&amp;p=8&amp;l=as1&amp;asins=4873112354&amp;ref=tf_til&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" width="320" height="240"></iframe></p>
<p><iframe style="width: 120px; height: 240px;" src="http://rcm-jp.amazon.co.jp/e/cm?t=nouvlog-22&amp;o=9&amp;p=8&amp;l=as1&amp;asins=4873115280&amp;ref=tf_til&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" width="320" height="240"></iframe></p>
]]></description>        
        
        
				<content:encoded><![CDATA[<p>フレームレートとは元々は映像で用いられる言葉である。<br />
アニメーションなどで1秒間に何コマ絵を動かしますか、という意味だ。1秒間に24コマの場合は24FPS（フレームパーセコンド）などと表される。FlashやJavaScriptなどで動作させるアニメーションでも用いられることが多い。</p>
<p>このフレームレート、Flashの場合直接フレームレートの指定が可能（デフォルトは12）だが、Javascriptの場合はtimer(setTimeoutなど）で逆算して指定することになる。<br />
timerはブラウザにより大きく性能が異なるため、ゲーム等を制作する場合大きな障害となる。例えばキャラクタが画面を移動するとき、あるブラウザでは0.5秒かかり、別のブラウザでは2秒かかるなど、差異が大きすぎるとゲームとして成立しない。</p>
<p>この問題はオライリー・ジャパンの<a href="http://www.amazon.co.jp/gp/product/4873115280/ref=as_li_tf_tl?ie=UTF8&amp;camp=247&amp;creative=1211&amp;creativeASIN=4873115280&amp;linkCode=as2&amp;tag=nouvlog-22" target="_blank">「JavaScriptグラフィックス」</a><img style="border: none !important; margin: 0px !important;" src="http://www.assoc-amazon.jp/e/ir?t=nouvlog-22&amp;l=as2&amp;o=9&amp;a=4873115280" alt="" width="1" height="1" border="0" />では以下の方法で対処している。</p>
<ol>
<li>どの程度のフレームレートが実現しているか調べる</li>
<li>実現したい速度と実際の速度の比率（＝係数）を調べる</li>
<li>1フレームあたりのキャラクターの移動距離を標準の距離×係数で再設定する</li>
<li>フレーム毎にキャラクターを再設定した距離移動させる</li>
</ol>
<p>一方Flashサイトの場合、ゲーム用途よりバナーやトップページフラッシュなど演出目的のものが多いため、滑らかな動作が重要視される。滑らかに動かした方がより高級感を醸し出せるからだ。<br />
滑らかに動かすためには、アニメーションは1秒のコマ数を増やせばよい。そこで多くの製作者は極力高いフレームレートを設定することになる。</p>
<p>ところが高くすればするほどパソコンに負荷がかかり、スペックの低いパソコンでは設定したフレームレートの半分も出せないことがある。結果カクカクした動きになっしまう。</p>
<p>その対策については、こちらもオライリー・ジャパンの<a href="http://www.amazon.co.jp/gp/product/4873112354/ref=as_li_tf_tl?ie=UTF8&amp;camp=247&amp;creative=1211&amp;creativeASIN=4873112354&amp;linkCode=as2&amp;tag=nouvlog-22" target="_blank">「Flash Hacks」</a><img style="border: none !important; margin: 0px !important;" src="http://www.assoc-amazon.jp/e/ir?t=nouvlog-22&amp;l=as2&amp;o=9&amp;a=4873112354" alt="" width="1" height="1" border="0" />にわかりやすく記載されている。<br />
まず上記１同様、「どの程度のフレームレートが実現しているか」を調べ、オブジェクトが多数動くことが負担になっている場合は、動作しているオブジェクト（キャラクターや粒子など）の数を減らしている。<br />
上記書籍は2005年発売でActionScript1.0又は2.0で記述されているので、今回はActionScript3.0に置き換えつつ、より実践的にしたPerformanceMonitorクラスを作成した。<br />
<a title="performance monitor sample" href="http://nouv.biz/labo/20121004_performance_montor/" target="_blank">以下</a>がそのサンプルとなる(<a href="http://nouv.biz/labo/20121004_performance_montor/">http://nouv.biz/labo/20121004_performance_montor/</a>)。<br />
大量のパーティクル（粒子）を生成し、ランダムにY回転させている(重いので他作業中の方は注意）。<br />
<a href="http://nouv.biz/labo/20121004_performance_montor/" target="_blank"><img class="aligncenter size-full wp-image-182" title="particle100000" src="http://nouv.biz/wp/wp-content/uploads/2012/10/particle100000.jpg" alt="" width="500" height="327" /></a></p>
<p>右下に、実現しているフレームレートと、パーティクルの数を表示している。<br />
フレームレートは24FPS、パーティクルの初期生成数は10万個を初期値にしているが、フレームレートが24フレームに達しないと、序々にパーティクルの個数を減らし調整する。</p>
<p>フレームレートが目標に達しているか調査する部分のスクリプトを以下に記載。</p>
<pre>  private function onEnterframe(event:Event):void {
   var nowTime:Number = new Date().getTime();
   var pastTime = nowTime-oldTime ; 
   var fps:Number = 1000 / pastTime;

   if (interCount &gt; 100) {
    //過去の累積が悪影響をおよぼすので、ある程度の回数でクリアする
     totalFPS = 0;
     interCount = 0;
   }
   totalFPS += fps;
   interCount++;
   oldTime = nowTime;
  }

  /*
   * 
   */
  public function get _averageFps():int {
   var averageFPS:Number = Math.floor(totalFPS / interCount );
   return averageFPS;
  }

  /**
   *達成したいフレームレートを指定する
   * 達成できているかどうかを返す
   */
  public function fpsBool(targetFPS:int):Boolean {
   var bool:Boolean;
   if (_averageFps &gt;= targetFPS) {
    bool = true;
   }else {
    bool = false;
   }
   return bool;
  }</pre>
<p>現時刻から前に通過した時刻を引き、そこからフレームレートを求めその値を返す。<br />
一方、パーティクルはその結果を受けて個数調整を行なっている。<br />
numBallsは生成するパーティクルの個数。上限下限を設けている。</p>
<pre>	
performanceBool = performanceMonitor.fpsBool(24);
if (!performanceBool) {
	numBalls = (numBalls - 100) &gt; 0? numBalls - 100 : numBalls;
}else {
	numBalls = (numBalls + 100) &lt;= makeNum ? numBalls + 100 : makeNum;
}</pre>
<p>&nbsp;</p>
<p><iframe style="width: 120px; height: 240px;" src="http://rcm-jp.amazon.co.jp/e/cm?t=nouvlog-22&amp;o=9&amp;p=8&amp;l=as1&amp;asins=4873112354&amp;ref=tf_til&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" width="320" height="240"></iframe></p>
<p><iframe style="width: 120px; height: 240px;" src="http://rcm-jp.amazon.co.jp/e/cm?t=nouvlog-22&amp;o=9&amp;p=8&amp;l=as1&amp;asins=4873115280&amp;ref=tf_til&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" width="320" height="240"></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://nouv.biz/wp/2012/10/06/%e3%83%95%e3%83%ac%e3%83%bc%e3%83%a0%e3%83%ac%e3%83%bc%e3%83%88%e3%81%a8%e3%83%91%e3%83%95%e3%82%a9%e3%83%bc%e3%83%9e%e3%83%b3%e3%82%b9%e3%83%a2%e3%83%8b%e3%82%bf%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScriptのクラス記述方式(継承)</title>
		<link>http://nouv.biz/wp/2012/09/20/javascript%e3%81%ae%e3%82%af%e3%83%a9%e3%82%b9%e8%a8%98%e8%bf%b0%e6%96%b9%e5%bc%8f%e7%b6%99%e6%89%bf/</link>
		<comments>http://nouv.biz/wp/2012/09/20/javascript%e3%81%ae%e3%82%af%e3%83%a9%e3%82%b9%e8%a8%98%e8%bf%b0%e6%96%b9%e5%bc%8f%e7%b6%99%e6%89%bf/#comments</comments>
		<pubDate>Wed, 19 Sep 2012 23:48:40 +0000</pubDate>
		<dc:creator><![CDATA[nouv]]></dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[目からウロコの覚書]]></category>
		<category><![CDATA[JavaScriptグラフィックス]]></category>

		<guid isPermaLink="false">http://nouv.biz/wp/?p=161</guid>
		
        

        <description><![CDATA[<p>前回作成したDHTMLSpriteクラスを継承した、bouncySpriteクラスを作成する。<br />
関数を用いたクラス生成方式の場合、継承は以下のとおりとてもわかりやすい。</p>
<pre>var bouncySprite=function(params){
	var x=params.x;
	var y=params.y;
	var xDir=params.xDir;
	var yDir=params.yDir;
	var maxX=params.maxX;
	var maxY=params.maxY;
	var animIndex=0;
	var that=DHTMLSprite(params);
	that.moveAndDraw=function(){
		x+=xDir;
		y+=yDir;
		animIndex+=xDir&gt;0 ? 1:-1;
		//進行方向に合わせて歯車の回転も変える。
		animIndex%=5;
		//1行4列　５の余りをx軸（列数）とする
		animIndex+=animIndex0 &amp;&amp; x&gt;=maxX)){
			xDir=-xDir;
		}
		if( (yDir0 &amp;&amp; y&gt;=maxY)){
			yDir=-yDir;
		}
		that.changeImage(animIndex);
		that.draw(x , y);
	}

	return that;
}</pre>
<p>使うプロパティと追加のプロパティを自分で引き受け、thatとしてDHTMLSpriteのインスタンスをthatとして生成する。そして、そのthatに新たなメソッドを付け加える。</p>
<p>一方、パターン２の教科書的方法は少々ややこしい（まだバグ無くならず）。<a href="http://nouv.biz/wp/2012/09/01/%E3%80%8Cactionscript3-0%E3%82%A2%E3%83%8B%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%80%8D%E3%82%92canvas%E3%81%A7%E7%BD%AE%E3%81%8D%E6%8F%9B%E3%81%88%E3%82%8B%E3%80%803d%E5%9B%9E%E8%BB%A2/" target="_blank">こちら</a>を参照。<br />
<ins datetime="2012-09-21T06:21:39+00:00"><br />
2012.9.12 バグ解消。全文記載<br />
</ins></p>
<pre>function BouncySprite(params){
	//新たに追加されたプロパティを記述する
	this.x=params.x;
	this.y=params.y;
	this.xDir=params.xDir;
	this.yDir=params.yDir;
	this.maxX=params.maxX;
	this.maxY=params.maxY;
	this.animIndex=0;
	DHTMLSprite.call(this , params);
	//親のオブジェクトのコンストラクタを呼び出す
}
BouncySprite.prototype=new DHTMLSprite();
BouncySprite.prototype.moveAndDraw=function(xPos , yPos){
	with(this){
		xPos+=xDir;
		yPos+=yDir;
		animIndex+=xDir&gt;0 ? 1:-1 ; 
		//進行方向に合わせて歯車の回転方向を変える
		animIndex%5; 
		//１行４列　５の余りをx軸（列数とする）	
		animIndex+=animIndex0 &amp;&amp; xPos&gt;maxX)){
			xDir=-xDir;	
		}
		if( (yDir0 &amp;&amp; yPos&gt;=maxY)   ){
			yDir=-yDir;
		}
		changeImage(animIndex)	;
		draw(xPos, yPos);
	}
}</pre>
<p>継承は関数形式の方がはるかに使いやすそう。</p>
]]></description>        
        
        
				<content:encoded><![CDATA[<p>前回作成したDHTMLSpriteクラスを継承した、bouncySpriteクラスを作成する。<br />
関数を用いたクラス生成方式の場合、継承は以下のとおりとてもわかりやすい。</p>
<pre>var bouncySprite=function(params){
	var x=params.x;
	var y=params.y;
	var xDir=params.xDir;
	var yDir=params.yDir;
	var maxX=params.maxX;
	var maxY=params.maxY;
	var animIndex=0;
	var that=DHTMLSprite(params);
	that.moveAndDraw=function(){
		x+=xDir;
		y+=yDir;
		animIndex+=xDir&gt;0 ? 1:-1;
		//進行方向に合わせて歯車の回転も変える。
		animIndex%=5;
		//1行4列　５の余りをx軸（列数）とする
		animIndex+=animIndex0 &amp;&amp; x&gt;=maxX)){
			xDir=-xDir;
		}
		if( (yDir0 &amp;&amp; y&gt;=maxY)){
			yDir=-yDir;
		}
		that.changeImage(animIndex);
		that.draw(x , y);
	}

	return that;
}</pre>
<p>使うプロパティと追加のプロパティを自分で引き受け、thatとしてDHTMLSpriteのインスタンスをthatとして生成する。そして、そのthatに新たなメソッドを付け加える。</p>
<p>一方、パターン２の教科書的方法は少々ややこしい（まだバグ無くならず）。<a href="http://nouv.biz/wp/2012/09/01/%E3%80%8Cactionscript3-0%E3%82%A2%E3%83%8B%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%80%8D%E3%82%92canvas%E3%81%A7%E7%BD%AE%E3%81%8D%E6%8F%9B%E3%81%88%E3%82%8B%E3%80%803d%E5%9B%9E%E8%BB%A2/" target="_blank">こちら</a>を参照。<br />
<ins datetime="2012-09-21T06:21:39+00:00"><br />
2012.9.12 バグ解消。全文記載<br />
</ins></p>
<pre>function BouncySprite(params){
	//新たに追加されたプロパティを記述する
	this.x=params.x;
	this.y=params.y;
	this.xDir=params.xDir;
	this.yDir=params.yDir;
	this.maxX=params.maxX;
	this.maxY=params.maxY;
	this.animIndex=0;
	DHTMLSprite.call(this , params);
	//親のオブジェクトのコンストラクタを呼び出す
}
BouncySprite.prototype=new DHTMLSprite();
BouncySprite.prototype.moveAndDraw=function(xPos , yPos){
	with(this){
		xPos+=xDir;
		yPos+=yDir;
		animIndex+=xDir&gt;0 ? 1:-1 ; 
		//進行方向に合わせて歯車の回転方向を変える
		animIndex%5; 
		//１行４列　５の余りをx軸（列数とする）	
		animIndex+=animIndex0 &amp;&amp; xPos&gt;maxX)){
			xDir=-xDir;	
		}
		if( (yDir0 &amp;&amp; yPos&gt;=maxY)   ){
			yDir=-yDir;
		}
		changeImage(animIndex)	;
		draw(xPos, yPos);
	}
}</pre>
<p>継承は関数形式の方がはるかに使いやすそう。</p>
]]></content:encoded>
			<wfw:commentRss>http://nouv.biz/wp/2012/09/20/javascript%e3%81%ae%e3%82%af%e3%83%a9%e3%82%b9%e8%a8%98%e8%bf%b0%e6%96%b9%e5%bc%8f%e7%b6%99%e6%89%bf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScriptのクラス記述方式</title>
		<link>http://nouv.biz/wp/2012/09/11/javascript%e3%81%ae%e3%82%af%e3%83%a9%e3%82%b9%e8%a8%98%e8%bf%b0%e6%96%b9%e5%bc%8f/</link>
		<comments>http://nouv.biz/wp/2012/09/11/javascript%e3%81%ae%e3%82%af%e3%83%a9%e3%82%b9%e8%a8%98%e8%bf%b0%e6%96%b9%e5%bc%8f/#comments</comments>
		<pubDate>Tue, 11 Sep 2012 12:50:00 +0000</pubDate>
		<dc:creator><![CDATA[nouv]]></dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[目からウロコの覚書]]></category>
		<category><![CDATA[JavaScriptグラフィックス]]></category>

		<guid isPermaLink="false">http://nouv.biz/wp/?p=150</guid>
		
        

        <description><![CDATA[<p>数冊JavaScript本を読んだところ、クラス（もどき）の記述方法が数パターンあるみたいなのでまとめておく。<br />
サンプルとしては前回同様オライリーの「JavaScriptグラフィックス」で用いられているスプライト描画を使わせていただきました。</p>
<p>パターンその１：<br />
関数を用いる方法。「JavaScriptグラフィックス」で推奨されている方法である。</p>
<pre>myClass=function(引数){
 that={
  xxx.....
 };
 return that;
}
var インスタンス=myClass(引数）</pre>
<p><a href="http://www.oreilly.co.jp/pub/9784873115283/ch02/ex0201.html" target="_blank">http://www.oreilly.co.jp/pub/9784873115283/ch02/ex0201.html</a><br />
パターン１のソースについてはオライリーの書籍と上記URLを参照いただきたい。</p>
<p>パターンその２：<br />
「教科書的」と言われている方法。<br />
クラス風にインスタンスを生成する。</p>
<pre>var インスタンス=new MyClass( 引数 )</pre>
<p>それではパターン１の関数を用いる方式から。<br />
サンプルの流れは以下の通り<br />
１．htmlでid指定されているエリア</p>
<pre>&lt;div id="draw-target"&gt;&lt;/div&gt;</pre>
<p>を取得し、背景画像にcssで幅・高さ・該当画像（スプライトシート：（いくつかの画像が固定ピクセル毎に行と列で描かれているもの）を指定する</p>
<pre>	
var DHTMLSprite=function(params){
	var width=params.width;
	var height=params.height;
	var imagesWidth=params.imagesWidth;
	//html記載 id:draw-targetにdivを追加。
	//そのdiv(即ち今追加したdiv)を$element変数に格納する
	var $element=  params.$drawTarget.append('&lt;div/&gt;').find(':last');
	$element.css({
		position:'absolute',
		width:width , 	
		height:height,
		backgroundImage:'url('+params.images+ ')'
	});
	var elemStyle=$element[0].style;//$elementのスタイルシートを格納。</pre>
<p>２．スプライトシート中の何番目の画像を使うか指定するメソッドを作る</p>
<pre>changeImage:function(index){
	index*=width;
	var vOffset=-mathFloor(index/imagesWidth)*height;//y座標
	var hOffset=-index%imagesWidth; //x座標
	elemStyle.backgroundPosition=hOffset+'px' + ' '+ vOffset +'px';
} ,</pre>
<p>３．描画の際の座標を指定するメソッドを作る</p>
<pre>darw:function(x , y){
	elemStyle.left=x+'px';
	elemStyle.top=y+'px';
},</pre>
<p>生成は以下のとおり関数の受けで行う。</p>
<pre>		var sprite1=DHTMLSprite(params);		
		var sprite2=DHTMLSprite(params);</pre>
<p>サンプルではスプライトシート１つめ(指定していない場合デフォルト１つめ）の歯車の画像が座標x=64 y=64に、５つめのグラデーション画像がx=352　y=192に、それぞれ描画されている。</p>
<pre>		sprite2.changeImage(5);
		sprite1.draw(64 , 64);
		sprite2.draw(352 , 192);</pre>
<p>一方、パターン２の教科書的方法は少々ややこしい。DHTMLSpriteクラスを作ってみた。全文記載。</p>
<pre>function DHTMLSprite(params){
	this.width=params.width;
	this.height=params.height;
	this.imagesWidth=params.imagesWidth;
	this.$element=params.$drawTarget.append("&lt;div/&gt;").find(":last");
	this.$element.css(
		{
			position:"absolute" , 
			width:this.width , 
			height:this.height,
			backgroundImage:"url("+ params.images + ")"
		}
	)
	this.elemStyle=this.$element[0].style;
	//要素を引数にしたjQueryオブジェクトは
	//DOM要素が配列で格納されている状態なので
	//$('#xxxx')[0]でDOM要素の参照となる。
	this.mathFloor=Math.floor;
 //高速化のためMath.floorのローカル参照を持つ

}
DHTMLSprite.prototype.draw=function(x , y){
	with(this){
		elemStyle.left=x+"px";
		elemStyle.top=y+"px";		
	}

}
DHTMLSprite.prototype.changeImage=function(index){
	with(this){
		index*=width;
		var vOffset=-mathFloor(index/imagesWidth)*height ; 
			//y座標
		var hOffset=-index%imagesWidth ; 
			//x座標
		elemStyle.backgroundPosition
			=hOffset+'px' + " "+vOffset+'px';
	}
}
DHTMLSprite.prototype.show=function(){
	with(this){
		elemStyle.display="block";
	}
}

DHTMLSprite.prototype.hide=function(){
	with(this){
		elemStyle.display="none"
	}
}
DHTMLSprite.prototype.destroy=function(){
	with(this){
		$element.remove();
	}
}</pre>
<p>生成は</p>
<pre>		var sprite1=new DHTMLSprite(params);		
		var sprite2=new DHTMLSprite(params);</pre>
<p>で行う。描画の指定方法は変わらない。<br />
thisが多いためやや汚く見えるが、生成がActionScript風なのでこちらの方が好みではある。次回は継承についてまとめる。</p>
]]></description>        
        
        
				<content:encoded><![CDATA[<p>数冊JavaScript本を読んだところ、クラス（もどき）の記述方法が数パターンあるみたいなのでまとめておく。<br />
サンプルとしては前回同様オライリーの「JavaScriptグラフィックス」で用いられているスプライト描画を使わせていただきました。</p>
<p>パターンその１：<br />
関数を用いる方法。「JavaScriptグラフィックス」で推奨されている方法である。</p>
<pre>myClass=function(引数){
 that={
  xxx.....
 };
 return that;
}
var インスタンス=myClass(引数）</pre>
<p><a href="http://www.oreilly.co.jp/pub/9784873115283/ch02/ex0201.html" target="_blank">http://www.oreilly.co.jp/pub/9784873115283/ch02/ex0201.html</a><br />
パターン１のソースについてはオライリーの書籍と上記URLを参照いただきたい。</p>
<p>パターンその２：<br />
「教科書的」と言われている方法。<br />
クラス風にインスタンスを生成する。</p>
<pre>var インスタンス=new MyClass( 引数 )</pre>
<p>それではパターン１の関数を用いる方式から。<br />
サンプルの流れは以下の通り<br />
１．htmlでid指定されているエリア</p>
<pre>&lt;div id="draw-target"&gt;&lt;/div&gt;</pre>
<p>を取得し、背景画像にcssで幅・高さ・該当画像（スプライトシート：（いくつかの画像が固定ピクセル毎に行と列で描かれているもの）を指定する</p>
<pre>	
var DHTMLSprite=function(params){
	var width=params.width;
	var height=params.height;
	var imagesWidth=params.imagesWidth;
	//html記載 id:draw-targetにdivを追加。
	//そのdiv(即ち今追加したdiv)を$element変数に格納する
	var $element=  params.$drawTarget.append('&lt;div/&gt;').find(':last');
	$element.css({
		position:'absolute',
		width:width , 	
		height:height,
		backgroundImage:'url('+params.images+ ')'
	});
	var elemStyle=$element[0].style;//$elementのスタイルシートを格納。</pre>
<p>２．スプライトシート中の何番目の画像を使うか指定するメソッドを作る</p>
<pre>changeImage:function(index){
	index*=width;
	var vOffset=-mathFloor(index/imagesWidth)*height;//y座標
	var hOffset=-index%imagesWidth; //x座標
	elemStyle.backgroundPosition=hOffset+'px' + ' '+ vOffset +'px';
} ,</pre>
<p>３．描画の際の座標を指定するメソッドを作る</p>
<pre>darw:function(x , y){
	elemStyle.left=x+'px';
	elemStyle.top=y+'px';
},</pre>
<p>生成は以下のとおり関数の受けで行う。</p>
<pre>		var sprite1=DHTMLSprite(params);		
		var sprite2=DHTMLSprite(params);</pre>
<p>サンプルではスプライトシート１つめ(指定していない場合デフォルト１つめ）の歯車の画像が座標x=64 y=64に、５つめのグラデーション画像がx=352　y=192に、それぞれ描画されている。</p>
<pre>		sprite2.changeImage(5);
		sprite1.draw(64 , 64);
		sprite2.draw(352 , 192);</pre>
<p>一方、パターン２の教科書的方法は少々ややこしい。DHTMLSpriteクラスを作ってみた。全文記載。</p>
<pre>function DHTMLSprite(params){
	this.width=params.width;
	this.height=params.height;
	this.imagesWidth=params.imagesWidth;
	this.$element=params.$drawTarget.append("&lt;div/&gt;").find(":last");
	this.$element.css(
		{
			position:"absolute" , 
			width:this.width , 
			height:this.height,
			backgroundImage:"url("+ params.images + ")"
		}
	)
	this.elemStyle=this.$element[0].style;
	//要素を引数にしたjQueryオブジェクトは
	//DOM要素が配列で格納されている状態なので
	//$('#xxxx')[0]でDOM要素の参照となる。
	this.mathFloor=Math.floor;
 //高速化のためMath.floorのローカル参照を持つ

}
DHTMLSprite.prototype.draw=function(x , y){
	with(this){
		elemStyle.left=x+"px";
		elemStyle.top=y+"px";		
	}

}
DHTMLSprite.prototype.changeImage=function(index){
	with(this){
		index*=width;
		var vOffset=-mathFloor(index/imagesWidth)*height ; 
			//y座標
		var hOffset=-index%imagesWidth ; 
			//x座標
		elemStyle.backgroundPosition
			=hOffset+'px' + " "+vOffset+'px';
	}
}
DHTMLSprite.prototype.show=function(){
	with(this){
		elemStyle.display="block";
	}
}

DHTMLSprite.prototype.hide=function(){
	with(this){
		elemStyle.display="none"
	}
}
DHTMLSprite.prototype.destroy=function(){
	with(this){
		$element.remove();
	}
}</pre>
<p>生成は</p>
<pre>		var sprite1=new DHTMLSprite(params);		
		var sprite2=new DHTMLSprite(params);</pre>
<p>で行う。描画の指定方法は変わらない。<br />
thisが多いためやや汚く見えるが、生成がActionScript風なのでこちらの方が好みではある。次回は継承についてまとめる。</p>
]]></content:encoded>
			<wfw:commentRss>http://nouv.biz/wp/2012/09/11/javascript%e3%81%ae%e3%82%af%e3%83%a9%e3%82%b9%e8%a8%98%e8%bf%b0%e6%96%b9%e5%bc%8f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQueryとDOM操作の最適化</title>
		<link>http://nouv.biz/wp/2012/09/08/jquery%e3%81%a8dom%e6%93%8d%e4%bd%9c%e3%81%ae%e6%9c%80%e9%81%a9%e5%8c%96/</link>
		<comments>http://nouv.biz/wp/2012/09/08/jquery%e3%81%a8dom%e6%93%8d%e4%bd%9c%e3%81%ae%e6%9c%80%e9%81%a9%e5%8c%96/#comments</comments>
		<pubDate>Sat, 08 Sep 2012 08:11:33 +0000</pubDate>
		<dc:creator><![CDATA[nouv]]></dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[目からウロコの覚書]]></category>
		<category><![CDATA[高速化]]></category>
		<category><![CDATA[JavaScriptグラフィックス]]></category>

		<guid isPermaLink="false">http://nouv.biz/wp/?p=130</guid>
		
        

        <description><![CDATA[<p>前回同様、O’REILLYの「JavaScriptグラフィックス」１章効率化についてメモ。</p>
<p>キモは</p>
<ol>
<li>「要素が見つかったら極力再検索しない」</li>
<li>「要素の追加は、文字列で一括して行う」</li>
</ol>
<p>１．要素の検索について</p>
<pre>$('#elem1').css('color' , '#ff0000');//赤
$('#elem1').css('color' , '#00FF00');//緑
$('#elem1').css('color' , '#0000FF');//青
$('#elem1').css('left' , '100px');//x座標を動かす</pre>
<p>このサンプルではelem1を毎回検索しているので、効率が悪い。<br />
そこで検索結果を変数に保存する。</p>
<pre>$alien=$('#elem1');</pre>
<p>となる。</p>
<p><em>※ここまでは想像していたのだが、この章の説明は検索範囲の指定まで踏み込んでいる。<br />
曰く「jQueryが検索する要素の範囲を指定したほうが速い」。<br />
$alien=$(&#8216;#element1&#8242; , container);//特定のDOM要素から検索する<br />
個人的にはあまり使わないような気がするが一応覚えておく。</em></p>
<p>まだjQueryのcss()関数が残っている。これも変数に格納。</p>
<pre>var elemStyle=$('#elem1')[0].style;</pre>
<p>そしてcssスタイルを設定する。</p>
<pre>elemStyle.color='#ff0000';
elemStyle.color='#00ff00';
elemStyle.color='#0000ff';
elemStyle.left='100px';</pre>
<p>(なぜかelemStyle.colorをアラート表示できない）</p>
<p>２．要素の追加は文字列で一括して行う<br />
DOMへの要素挿入は遅いので、</p>
<p>文字列+=追加文字列<br />
で文字列を作成し、<br />
$elem.append(文字列);<br />
で一気に追加する。</p>
<p>これらを踏まえたサンプル。<br />
<a href="http://nouv.biz/labo/20120908_jQuery_speed/ex0100_css.html" target="_blank">http://nouv.biz/labo/20120908_jQuery_speed/ex0100_css.html</a></p>
<p>css操作はcssが設定されていないと動作しないので注意。コードは以下のとおり。</p>
<pre>[html]
＜ｄｉｖ ｉｄ＝”ｅｌｅｍｅｎｔ１”＞＜ｄｉｖ＞
[css]
#element1{
	position:absolute;
	left:0;
	top:0;
	font-size:80px;
	color: #000000;
}
[JavaScript]
var $elem;//jQueryから取得
var elemStyle;//取得した要素のスタイル
var divs='';//追加する要素

//検索し、変数に格納　idを取得しているのに、配列のようなものになるらしい
$elem=$('#element1');
//$elem[0].addEventListener("click" , onClicked , false);
AddEvent.addEvent($elem[0] , "click" , onClicked);//オリジナルクラス

//変数からstyleを格納
//var elemStyle=$elem.style;
//Debugger.log(elemStyle);//undefinedになる
var elemStyle=$elem[0].style;//なぜか添字０をつけなければならない。
Debugger.log(elemStyle);

//makeDivs
//makeDivs
for(var i=0 ; i divs+=''//文字列追加省略
}

function onClicked(event){
Debugger.log("clicked");
elemStyle.color="#ff0000";
elemStyle.left="50px";
elemStyle.top="50px";
$elem.append(divs);
}</pre>
]]></description>        
        
        
				<content:encoded><![CDATA[<p>前回同様、O’REILLYの「JavaScriptグラフィックス」１章効率化についてメモ。</p>
<p>キモは</p>
<ol>
<li>「要素が見つかったら極力再検索しない」</li>
<li>「要素の追加は、文字列で一括して行う」</li>
</ol>
<p>１．要素の検索について</p>
<pre>$('#elem1').css('color' , '#ff0000');//赤
$('#elem1').css('color' , '#00FF00');//緑
$('#elem1').css('color' , '#0000FF');//青
$('#elem1').css('left' , '100px');//x座標を動かす</pre>
<p>このサンプルではelem1を毎回検索しているので、効率が悪い。<br />
そこで検索結果を変数に保存する。</p>
<pre>$alien=$('#elem1');</pre>
<p>となる。</p>
<p><em>※ここまでは想像していたのだが、この章の説明は検索範囲の指定まで踏み込んでいる。<br />
曰く「jQueryが検索する要素の範囲を指定したほうが速い」。<br />
$alien=$(&#8216;#element1&#8242; , container);//特定のDOM要素から検索する<br />
個人的にはあまり使わないような気がするが一応覚えておく。</em></p>
<p>まだjQueryのcss()関数が残っている。これも変数に格納。</p>
<pre>var elemStyle=$('#elem1')[0].style;</pre>
<p>そしてcssスタイルを設定する。</p>
<pre>elemStyle.color='#ff0000';
elemStyle.color='#00ff00';
elemStyle.color='#0000ff';
elemStyle.left='100px';</pre>
<p>(なぜかelemStyle.colorをアラート表示できない）</p>
<p>２．要素の追加は文字列で一括して行う<br />
DOMへの要素挿入は遅いので、</p>
<p>文字列+=追加文字列<br />
で文字列を作成し、<br />
$elem.append(文字列);<br />
で一気に追加する。</p>
<p>これらを踏まえたサンプル。<br />
<a href="http://nouv.biz/labo/20120908_jQuery_speed/ex0100_css.html" target="_blank">http://nouv.biz/labo/20120908_jQuery_speed/ex0100_css.html</a></p>
<p>css操作はcssが設定されていないと動作しないので注意。コードは以下のとおり。</p>
<pre>[html]
＜ｄｉｖ ｉｄ＝”ｅｌｅｍｅｎｔ１”＞＜ｄｉｖ＞
[css]
#element1{
	position:absolute;
	left:0;
	top:0;
	font-size:80px;
	color: #000000;
}
[JavaScript]
var $elem;//jQueryから取得
var elemStyle;//取得した要素のスタイル
var divs='';//追加する要素

//検索し、変数に格納　idを取得しているのに、配列のようなものになるらしい
$elem=$('#element1');
//$elem[0].addEventListener("click" , onClicked , false);
AddEvent.addEvent($elem[0] , "click" , onClicked);//オリジナルクラス

//変数からstyleを格納
//var elemStyle=$elem.style;
//Debugger.log(elemStyle);//undefinedになる
var elemStyle=$elem[0].style;//なぜか添字０をつけなければならない。
Debugger.log(elemStyle);

//makeDivs
//makeDivs
for(var i=0 ; i divs+=''//文字列追加省略
}

function onClicked(event){
Debugger.log("clicked");
elemStyle.color="#ff0000";
elemStyle.left="50px";
elemStyle.top="50px";
$elem.append(divs);
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://nouv.biz/wp/2012/09/08/jquery%e3%81%a8dom%e6%93%8d%e4%bd%9c%e3%81%ae%e6%9c%80%e9%81%a9%e5%8c%96/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ルックアップテーブルとビット演算</title>
		<link>http://nouv.biz/wp/2012/09/07/%e3%83%ab%e3%83%83%e3%82%af%e3%82%a2%e3%83%83%e3%83%97%e3%83%86%e3%83%bc%e3%83%96%e3%83%ab%e3%81%a8%e3%83%93%e3%83%83%e3%83%88%e6%bc%94%e7%ae%97/</link>
		<comments>http://nouv.biz/wp/2012/09/07/%e3%83%ab%e3%83%83%e3%82%af%e3%82%a2%e3%83%83%e3%83%97%e3%83%86%e3%83%bc%e3%83%96%e3%83%ab%e3%81%a8%e3%83%93%e3%83%83%e3%83%88%e6%bc%94%e7%ae%97/#comments</comments>
		<pubDate>Fri, 07 Sep 2012 06:56:49 +0000</pubDate>
		<dc:creator><![CDATA[nouv]]></dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[目からウロコの覚書]]></category>
		<category><![CDATA[高速化]]></category>
		<category><![CDATA[JavaScriptグラフィックス]]></category>

		<guid isPermaLink="false">http://nouv.biz/wp/?p=110</guid>
		
        

        <description><![CDATA[<p>O&#8217;REILLYの「JavaScriptグラフィックス」１章効率化についてメモ。<br />
<img class="aligncenter size-full wp-image-111" title="20120907_sinCurve" src="http://nouv.biz/wp/wp-content/uploads/2012/09/20120907_sinCurve.jpg" alt="" width="474" height="315" /><br />
O&#8217;REILLYの書籍サイトではサンプルとして以下が掲載されている。<br />
<a href="http://www.oreilly.co.jp/pub/9784873115283/ch01/ex0100.html" target="_blank">http://www.oreilly.co.jp/pub/9784873115283/ch01/ex0100.html<br />
</a>サインカーブを描くシンプルなもの。</p>
<p>特徴は</p>
<ul>
<li>Canvasを用いず、ブロック要素(div)をhtml側に記述しcssで幅・高さを指定</li>
<li>ブロック要素内に幅1pxの縦線を幅の分の数描画する（この場合480本)</li>
<li>描画の開始位置と高さはJavaScriptで変動させアニメーション化する</li>
</ul>
<p>効率化のメインは</p>
<ol>
<li>ルックアップテーブル</li>
<li>ビット演算</li>
</ol>
<p>の２つ。<br />
１つ目のルックアップテーブルは、都度sinを計算するのではなく、前もってsinを計算し、配列に格納することにより速度向上を図るということ。wonderFL(flash)でもスクリプトで絵柄をビットマップ描画し、それを配列に格納することで超高速化していたサンプルがあった（<a href="http://wonderfl.net/c/c0Gi" target="_blank">http://wonderfl.net/c/c0Gi</a>）。</p>
<p>一方、２つ目のビット演算は少々わかりづらい。<br />
なんの前置きも無く、</p>
<pre id="src">        drawGraph(x * 50, 32 - (sinTable[(x * 20) &amp; 4095] * 16),
                  50 - (sinTable[(x * 10) &amp; 4095] * 20));</pre>
<p>とか</p>
<pre id="src">bars[i].style.top = 160 - height + 
                 sinTable[(ang + (i * freq)) &amp; 4095] * height + 'px';</pre>
<p>など唐突に4095という数字が出てくる。<br />
結局<br />
配列の生成数4096は16の3乗、0&#215;1000<br />
配列範囲(添字）の最大値 4095は16の3乗-1　   0xFFF<br />
ということにさえ気づければなんということは無かったのだけれど。</p>
<p>このサンプルでは360度（Math.2PI)を4096分割し、そのsin値を配列に格納している。<br />
タイマー内の変数xを単純な足し算(x++)でどんどん増やしているため、このxから0～4095（配列範囲）の添字を算出する必要がある。そこでビット単位のAND(&amp;)計算を用い<br />
0&#215;1000　（＝4096)<br />
0x  FFF（＝4095)        ＆<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
0X  000（＝０　配列の先頭の添字）<br />
などと計算し、範囲溢れを防ぎつつ添字を求めている。<br />
私はこういう場合、余り（%、MOD）を求めて算出するのが通常だった。<br />
余りで計算する場合、配列数（length=４０９６）を用いる。<br />
上記の例だと<br />
4096%4096=0 余り0　配列の先頭<br />
4097&amp;4096=0 余り1　配列の2つ目<br />
となる。</p>
<p>ところがこの「余り」の計算は四則演算の中で最も遅いらしい<br />
(参考にさせていただきました <a href="http://ufcpp.net/study/algorithm/col_circular.html" target="_blank">http://ufcpp.net/study/algorithm/col_circular.html</a>) 。</p>
<p>このサンプルでは高速化のため、これをAND演算に切り替えている。<br />
なるほど。<br />
確かにカーブを書く都度「余り」計算を行なっているので計算回数も多い。ここの高速化は全体への影響も大きいだろう。<br />
これを流用したサンプルはまた後日。</p>
]]></description>        
        
        
				<content:encoded><![CDATA[<p>O&#8217;REILLYの「JavaScriptグラフィックス」１章効率化についてメモ。<br />
<img class="aligncenter size-full wp-image-111" title="20120907_sinCurve" src="http://nouv.biz/wp/wp-content/uploads/2012/09/20120907_sinCurve.jpg" alt="" width="474" height="315" /><br />
O&#8217;REILLYの書籍サイトではサンプルとして以下が掲載されている。<br />
<a href="http://www.oreilly.co.jp/pub/9784873115283/ch01/ex0100.html" target="_blank">http://www.oreilly.co.jp/pub/9784873115283/ch01/ex0100.html<br />
</a>サインカーブを描くシンプルなもの。</p>
<p>特徴は</p>
<ul>
<li>Canvasを用いず、ブロック要素(div)をhtml側に記述しcssで幅・高さを指定</li>
<li>ブロック要素内に幅1pxの縦線を幅の分の数描画する（この場合480本)</li>
<li>描画の開始位置と高さはJavaScriptで変動させアニメーション化する</li>
</ul>
<p>効率化のメインは</p>
<ol>
<li>ルックアップテーブル</li>
<li>ビット演算</li>
</ol>
<p>の２つ。<br />
１つ目のルックアップテーブルは、都度sinを計算するのではなく、前もってsinを計算し、配列に格納することにより速度向上を図るということ。wonderFL(flash)でもスクリプトで絵柄をビットマップ描画し、それを配列に格納することで超高速化していたサンプルがあった（<a href="http://wonderfl.net/c/c0Gi" target="_blank">http://wonderfl.net/c/c0Gi</a>）。</p>
<p>一方、２つ目のビット演算は少々わかりづらい。<br />
なんの前置きも無く、</p>
<pre id="src">        drawGraph(x * 50, 32 - (sinTable[(x * 20) &amp; 4095] * 16),
                  50 - (sinTable[(x * 10) &amp; 4095] * 20));</pre>
<p>とか</p>
<pre id="src">bars[i].style.top = 160 - height + 
                 sinTable[(ang + (i * freq)) &amp; 4095] * height + 'px';</pre>
<p>など唐突に4095という数字が出てくる。<br />
結局<br />
配列の生成数4096は16の3乗、0&#215;1000<br />
配列範囲(添字）の最大値 4095は16の3乗-1　   0xFFF<br />
ということにさえ気づければなんということは無かったのだけれど。</p>
<p>このサンプルでは360度（Math.2PI)を4096分割し、そのsin値を配列に格納している。<br />
タイマー内の変数xを単純な足し算(x++)でどんどん増やしているため、このxから0～4095（配列範囲）の添字を算出する必要がある。そこでビット単位のAND(&amp;)計算を用い<br />
0&#215;1000　（＝4096)<br />
0x  FFF（＝4095)        ＆<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
0X  000（＝０　配列の先頭の添字）<br />
などと計算し、範囲溢れを防ぎつつ添字を求めている。<br />
私はこういう場合、余り（%、MOD）を求めて算出するのが通常だった。<br />
余りで計算する場合、配列数（length=４０９６）を用いる。<br />
上記の例だと<br />
4096%4096=0 余り0　配列の先頭<br />
4097&amp;4096=0 余り1　配列の2つ目<br />
となる。</p>
<p>ところがこの「余り」の計算は四則演算の中で最も遅いらしい<br />
(参考にさせていただきました <a href="http://ufcpp.net/study/algorithm/col_circular.html" target="_blank">http://ufcpp.net/study/algorithm/col_circular.html</a>) 。</p>
<p>このサンプルでは高速化のため、これをAND演算に切り替えている。<br />
なるほど。<br />
確かにカーブを書く都度「余り」計算を行なっているので計算回数も多い。ここの高速化は全体への影響も大きいだろう。<br />
これを流用したサンプルはまた後日。</p>
]]></content:encoded>
			<wfw:commentRss>http://nouv.biz/wp/2012/09/07/%e3%83%ab%e3%83%83%e3%82%af%e3%82%a2%e3%83%83%e3%83%97%e3%83%86%e3%83%bc%e3%83%96%e3%83%ab%e3%81%a8%e3%83%93%e3%83%83%e3%83%88%e6%bc%94%e7%ae%97/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
