  | 
    
       HTML5テクニカルノート 
      PreloadJS 0.6.0: 古いコードのイメージ読込みをImageLoaderクラスで書直す
      
         
          | ID: FN1501006 | 
          Technique: HTML5 and JavaScript | 
          Library: EaselJS 0.8.0 and PreloadJS 0.6.0 | 
         
       
PreloadJS 0.6.0から、コンテンツの形式に応じたローダをクラスとして備えました。イメージファイルはImageLoaderクラスで読込みます。LoadQueueクラスは、コンテンツの形式が何か調べてローダーを選びます。けれど、読込むのが初めからイメージとわかっているときは、ImageLoaderクラスを使った方がひと手間省けるのです。本稿では、古いバージョンで書いたコードを、ImageLoaderクラスで書替えてみます。 
 
01 お題「ドラッグする軌跡でアルファマスクを描く」
コード書替えのお題は、gihyo.jp連載「HTML5のCanvasでつくるダイナミックな表現―CreateJSを使う」 第10回「ドラッグの軌跡を滑らかな曲線で描く」コード1「ドラッグする軌跡でアルファマスクを描く」です(サンプル001)。読込んだ画像イメージをフィルタでぼかし、ドラッグでアルファマスクを描いています。使ったライブラリは、EaselJS 0.6.1とPreloadJS 0.3.1です。 
サンプル001■Wiping out blur from a image with AlphaMaskFilter New 
 
EaselJS 0.6.1はライブラリのデータサイズを気づかって、フィルタのクラスが含まれておらず、別に読込んでいました。けれど、使いにくい・わかりにくいという声から、つぎの0.7.0でフィルタも含まれるようになりました。また、同バージョンで、ぼかしフィルタのクラス名がBoxBlurFilterからBlurFilterに変わりました。前掲サンプル001は、つぎのようにこのクラス名さえ改めれば正しく動きます。 
  
  
    | 
 
function draw(eventObject) {
 
  blurBitmap = createBitmap(image, nX, nY); 
  // blurBitmap.filters = [new createjs.BoxBlurFilter(15, 15, 2)]; 
  blurBitmap.filters = [new createjs.BlurFilter(15, 15, 2)]; 
  blurBitmap.cache(0, 0, imageWidth, imageHeight);
 
}
 
 | 
 
 
 
 
02 LoadQueueをImageLoaderクラスに差替える
ImageLoaderクラスは、イメージファイルをつぎのような手順で読込みます。なお、ImageLoader()コンストラクタに渡す引数は、読込むファイルを示すオブジェクトまたはパスの文字列です(詳しくは「ImageLoaderクラス」参照)。 
- ImageLoader()コンストラクタに読込むファイルを引数で渡す
 
- 読込みの終わりはAbstractLoader.completeイベントで捉える
 
- ファイルはImageLoader.load()メソッドで読込む[*1]
 
 
すると、前掲サンプル001のコードは、つぎのように書替えることになりそうです。なお、抜書きの行番号は、後にまとめたコード001にもとづきます。ImageLoader()コンストラクタに読込むファイルを与えますので、ImageLoader.load()メソッドは引数をとりません。 
  
  
    
- function initialize() {
 
-   var canvasElement = document.getElementById("myCanvas");
 
-   var canvasSize = new createjs.Point(canvasElement.width, canvasElement.height);
 
-   var file = {
 
    src: "images/image.png", 
    data: canvasSize 
  }; 
 
  // var loader = new createjs.LoadQueue(false);
-   var loader = new createjs.ImageLoader(file);
 
  // loader.addEventListener("fileload", draw); 
-   loader.addEventListener("complete", draw);
 
  /* loader.loadFile({ 
    src: "images/image.png", 
    data: canvasSize 
    }); */ 
 
-   loader.load();
 
- }
 
 
 | 
 
 
 
ところが、これだけではつぎのようなエラーが出て、コードが動きません。このエラーは、AbstractLoader.completeイベントのリスナー関数の受取ったイベントオブジェクト(eventObject)が、itemというプロパティをもっていないことから起こりました。 
TypeError: undefined is not an object (evaluating 'eventObject.item.data')
 
  
    | 
 [*1] 「PreloadJS v0.6.0 API Documentation」で「ImageLoader Class」の「load()」の項を見ると、 AbstractLoader.load()メソッドを継承すると書かれています。けれど、ImageLoaderクラスの実装では、メソッドがオーバーライドされています。 
 | 
 
 
 
03 AbstractLoader.completeイベントのリスナー関数にデータを渡す
LoadQueue.loadFile()メソッドを用いると、引数のオブジェクトのdataというプロパティに定めた値が、LoadQueue.fileloadイベントのリスナー関数に渡されるイベントオブジェクトのitemプロパティに加えられます。前掲サンプル001は、つぎのようにしてリスナー関数(draw())にdataプロパティを受け渡していました。ところが、ImageLoaderクラスにはloadFile()メソッドが備わっておらず、AbstractLoader.completeイベントのリスナー関数が受取るイベントオブジェクトにitemというプロパティはないのです。 
  
  
    | 
 
function initialize() {
 
  var loader = new createjs.LoadQueue(false); 
  loader.addEventListener("fileload", draw); 
  loader.loadFile({ 
    src: "images/image.png",  
    data: canvasSize 
    }); 
} 
function draw(eventObject) {
 
  var canvasSize = eventObject.item.data;
 
}
 
 | 
 
 
 
リスナー関数(draw())にdataプロパティでデータを渡すことは、あきらめるより仕方ありません。そのかわり、ローダーのImageLoaderオブジェクト(loader)に、プロパティ(canvasSize)としてデータを与えることにしました(第19行目)。リスナー関数は受取ったイベントオブジェクト(eventObject)のEvent.targetプロパティから、読込んだローダーの参照が得られます(第24行目)。なお、dataプロパティが使えませんので、ImageLoader()コンストラクタに渡す引数(file)は、パスの文字列としました(第15行目)。 
  
  
    
	- function initialize() {
 
 
	-   var file = "images/image.png";
 
 
	-   var loader = new createjs.ImageLoader(file);
 
 
	-   loader.canvasSize = canvasSize;
 
 
	- }
 
	- function draw(eventObject) {
 
 
	-   var canvasSize = eventObject.target.canvasSize;
 
 
	- }
 
 
 | 
 
 
 
これで、ImageLoaderクラスを使ってコードが動くようになりました。手直ししたスクリプトは、つぎのコード001にまとめてあります。併せて、jsdo.itにも改訂したサンプルのコードを掲げました(サンプル002)。 
コード001■ドラッグする軌跡でアルファマスクを描く
	
		
	
	- var stage;
 
	- var wipingShape;
 
	- var imageBitmap;
 
	- var blurBitmap;
 
	- var imageSize = new createjs.Point();
 
	- var radius = 10;
 
	- var bitmapPoint = new createjs.Point();
 
	- var oldPoint = new createjs.Point();
 
	- var oldMidPoint = new createjs.Point();
 
	- var isDrawing;
 
	- var cursor;
 
	- function initialize() {
 
	-   var canvasElement = document.getElementById("myCanvas");
 
	-   var canvasSize = new createjs.Point(canvasElement.width, canvasElement.height);
 
	-   var file = "images/image.png";
 
	-   stage = new createjs.Stage(canvasElement);
 
	-   var loader = new createjs.ImageLoader(file);
 
	-   loader.addEventListener("complete", draw);
 
	-   loader.canvasSize = canvasSize;
 
	-   loader.load();
 
	- }
 
	- function draw(eventObject) {
 
	-   var image = eventObject.result;
 
	-   var canvasSize = eventObject.target.canvasSize;
 
	-   var imageWidth = imageSize.x = image.width;
 
	-   var imageHeight = imageSize.y = image.height;
 
	-   var nX = bitmapPoint.x = (canvasSize.x - imageWidth) / 2;
 
	-   var nY = bitmapPoint.y = (canvasSize.y - imageHeight) / 2;
 
	-   stage.addEventListener("stagemousedown", startWipe);
 
	-   stage.addEventListener("stagemouseup", stopWipe);
 
	-   stage.enableMouseOver();
 
	-   wipingShape = new createjs.Shape();
 
	-   blurBitmap = createBitmap(image, nX, nY);
 
	-   blurBitmap.filters = [new createjs.BlurFilter(15, 15, 2)];
 
	-   blurBitmap.cache(0, 0, imageWidth, imageHeight);
 
	-   blurBitmap.alpha = 0.8;
 
	-   imageBitmap = createBitmap(image, nX, nY);
 
	-   createCursor();
 
	-   updateCacheImage(false);
 
	-   createjs.Ticker.addEventListener("tick", wipe);
 
	- }
 
	- function createBitmap(image, nX, nY) {
 
	-   var myBitmap = new createjs.Bitmap(image);
 
	-   myBitmap.x = nX;
 
	-   myBitmap.y = nY;
 
	-   stage.addChild(myBitmap);
 
	-   return myBitmap;
 
	- }
 
	- function createCursor() {
 
	-   cursor = new createjs.Shape();
 
	-   cursor.graphics
 
	-   .beginFill("white")
 
	-   .drawCircle(0, 0, radius);
 
	-   cursor.cursor = "pointer";
 
	-   cursor.alpha = 0.3;
 
	-   stage.addChild(cursor);
 
	- }
 
	- function startWipe(eventObject) {
 
	-   var mousePoint = getMousePoint();
 
	-   oldMidPoint.x = oldPoint.x = mousePoint.x;
 
	-   oldMidPoint.y = oldPoint.y = mousePoint.y;
 
	-   isDrawing = true;
 
	-   wipingShape.graphics
 
	-   .setStrokeStyle(radius * 2, "round", "round");
 
	- }
 
	- function wipe(eventObject) {
 
	-   cursor.x = stage.mouseX;
 
	-   cursor.y = stage.mouseY;
 
	-   if (isDrawing) {
 
	-     var mousePoint = getMousePoint();
 
	-     var mouseX = mousePoint.x;
 
	-     var mouseY = mousePoint.y;
 
	-     var oldX = oldPoint.x;
 
	-     var oldY = oldPoint.y;
 
	-     var midX = (oldX + mouseX) / 2;
 
	-     var midY = (oldY + mouseY) / 2;
 
	-     wipingShape.graphics
 
	-     .beginStroke(createjs.Graphics.getRGB(0x0, 0.15))
 
	-     .moveTo(oldMidPoint.x, oldMidPoint.y)
 
	-     .quadraticCurveTo(oldX, oldY, midX, midY);
 
	-     oldPoint.x = mouseX;
 
	-     oldPoint.y = mouseY;
 
	-     oldMidPoint.x = midX;
 
	-     oldMidPoint.y = midY;
 
	-     updateCacheImage(true);
 
	-   } else {
 
	-     stage.update();
 
	-   }
 
	- }
 
	- function stopWipe(event) {
 
	-   isDrawing = false;
 
	- }
 
	- function getMousePoint() {
 
	-   var mouseX = stage.mouseX - bitmapPoint.x;
 
	-   var mouseY = stage.mouseY - bitmapPoint.y;
 
	-   return new createjs.Point(mouseX, mouseY);
 
	- }
 
	- function updateCacheImage(update) {
 
	-   updateCache(update, wipingShape);
 
	-   var maskFilter = new createjs.AlphaMaskFilter(wipingShape.cacheCanvas);
 
	-   imageBitmap.filters = [maskFilter];
 
	-   updateCache(update, imageBitmap);
 
	-   stage.update();
 
	- }
 
	- function updateCache(update, instance) {
 
	-   if (update) {
 
	-     instance.updateCache();
 
	-   } else {
 
	-     instance.cache(0, 0, imageSize.x, imageSize.y);
 
	-   }
 
	- }
 
	 
	 | 
	 
 
 
サンプル002■EaselJS 0.8.0 & PreloadJS 0.6.0: Wiping out blur from a image with AlphaMaskFilter 
 
 
 
作成者: 野中文雄 
作成日: 2015年1月26日 
    
    	 Copyright © 
2001-2015 Fumio Nonaka.  All rights reserved.
     |