イージング処理 : javascript
何らかの Flash(swf) を作成する際、私は以下のサイトを参考に、イージングを行うための数値を取得するクラスを作成し有用させてもらっています。
http://www.graviness.com/virgo/dhtml/mathematics/edging.html
ここ最近の業務では iPhone, iPad といった Flash 非対応の端末に対応すべく html ベースのサイト制作が続いているため、AS3 で作成していた簡易的なイージング処理用クラス(Edginger)を javascript に移植することに。
使い方 how to use
(1)Edginger クラスのコンストラクタに、イージング値(-100~100) と 動作分割数(1以上の値) を設定
(2-a)移動量一覧を取得するには getDistances メソッドを呼び出す
→ 移動総量を引数に指定
(2-b)移動地点一覧を取得するには getPoints メソッドを呼び出す
→ 初期位置と到達位置を引数に指定
var edginger = new Edginger(100, 5); this.distances = edginger.getDistances(200); this.points = edginger.getPoints(0, 200); //this.distances の内容 //[77.41957135154557, 63.12656693970699, 40, 16.873433060293024, 2.580428648454415] //this.points の内容 //[0, 77.41957135154557, 140.54613829125256, 180.54613829125256, 197.41957135154559, 200]
対象の移動量 or 移動先位置をあらかじめ配列で取得し、任意のタイミングで位置設定を行うことが可能となります。
対象を「移動」する事を目的としていますが、これは例えとなります。例えば「拡大縮小」用として Edgingerクラスを用いることも可能です。
利用例 example
jQuery と Edginger.getPoints を利用して、画面上の div 要素を 0 px から 200 px までイージング処理で移動する例は以下となります。index.html から Index.js を呼び出し、Index.js 内で Edginger.js を利用しています。
index.html
<html> <head> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> <script type="text/javascript" src="Edginger.js" ></script> <script type="text/javascript" src="Index.js" ></script> <script language="javascript"> $(function(){ new Index(); }); </script> </head> <body> <div id="box" style="position: relative; width:50px; background-color:#ffccaa;">ABC</div> </body> </html>
Index.js
function Index(){ this.init.apply(this, arguments); } Index.prototype.init = function(){ var edginger = new Edginger(100, 30); this.points = edginger.getPoints(0, 200); var sc = this; this.mainFunction = this.move; this.intervalId = setInterval(function(){ sc.run(); }, 30); }; Index.prototype.run = function(){ this.mainFunction(); }; Index.prototype.move = function(){ var point = Math.floor(this.points.shift()); $("#box").css("left", point); if(this.points.length == 0) this.mainFunction = this.end; }; Index.prototype.end = function(){ clearInterval(this.intervalId); };
実際の表示は以下となります。
http://www.dango-itimi.com/blog/swf/138/
ダウンロード download
利用例でのファイルを含むファイル一式は以下の URL よりダウンロードが可能です。
http://www.dango-itimi.com/blog/swf/138/Edginger.zip
以下 Edginger.js のソースとなります。
Edginger.js 内容
function Edginger(){ this.initialize.apply(this, arguments); } /** * -100 <= edging <= 100 * cut >= 1 */ Edginger.prototype.initialize = function(edging, cut){ this.edging = edging; this.cut = cut; }; /** * distance != 0 */ Edginger.prototype.getDistances = function(distance){ var vec = 1; if(distance < 0){ distance *= -1; vec = -1; } var distances = new Array(this.cut); var bpt = 0; for (var i = 0; i < this.cut; i++) { var c = (i+1) / this.cut; var pt = distance * (c + this.edging / (100 * Math.PI) * Math.sin(Math.PI * c)); distances[i] = (pt - bpt) * vec; bpt = pt; } return distances; }; /** * points.length == cut + 1 * points[0] == firstPt */ Edginger.prototype.getPoints = function(firstPt, endPt){ var points = new Array(); var p = endPt - firstPt; for (var i = 0; i < this.cut; i++) { var c = (i+1) / this.cut; points[i] = p * (c + this.edging / (100 * Math.PI) * Math.sin(Math.PI * c)) + firstPt; } points.unshift(firstPt); return points; };