uberpong/dev/lib/impact/image.js
2013-04-03 21:02:06 +02:00

178 lines
4.3 KiB
JavaScript
Executable file

ig.module(
'impact.image'
)
.defines(function(){ "use strict";
ig.Image = ig.Class.extend({
data: null,
width: 0,
height: 0,
loaded: false,
failed: false,
loadCallback: null,
path: '',
staticInstantiate: function( path ) {
return ig.Image.cache[path] || null;
},
init: function( path ) {
this.path = path;
this.load();
},
load: function( loadCallback ) {
if( this.loaded ) {
if( loadCallback ) {
loadCallback( this.path, true );
}
return;
}
else if( !this.loaded && ig.ready ) {
this.loadCallback = loadCallback || null;
this.data = new Image();
this.data.onload = this.onload.bind(this);
this.data.onerror = this.onerror.bind(this);
this.data.src = ig.prefix + this.path + ig.nocache;
}
else {
ig.addResource( this );
}
ig.Image.cache[this.path] = this;
},
reload: function() {
this.loaded = false;
this.data = new Image();
this.data.onload = this.onload.bind(this);
this.data.src = this.path + '?' + Date.now();
},
onload: function( event ) {
this.width = this.data.width;
this.height = this.data.height;
this.loaded = true;
if( ig.system.scale != 1 ) {
this.resize( ig.system.scale );
}
if( this.loadCallback ) {
this.loadCallback( this.path, true );
}
},
onerror: function( event ) {
this.failed = true;
if( this.loadCallback ) {
this.loadCallback( this.path, false );
}
},
resize: function( scale ) {
// Nearest-Neighbor scaling
// The original image is drawn into an offscreen canvas of the same size
// and copied into another offscreen canvas with the new size.
// The scaled offscreen canvas becomes the image (data) of this object.
var origPixels = ig.getImagePixels( this.data, 0, 0, this.width, this.height );
var widthScaled = this.width * scale;
var heightScaled = this.height * scale;
var scaled = ig.$new('canvas');
scaled.width = widthScaled;
scaled.height = heightScaled;
var scaledCtx = scaled.getContext('2d');
var scaledPixels = scaledCtx.getImageData( 0, 0, widthScaled, heightScaled );
for( var y = 0; y < heightScaled; y++ ) {
for( var x = 0; x < widthScaled; x++ ) {
var index = (Math.floor(y / scale) * this.width + Math.floor(x / scale)) * 4;
var indexScaled = (y * widthScaled + x) * 4;
scaledPixels.data[ indexScaled ] = origPixels.data[ index ];
scaledPixels.data[ indexScaled+1 ] = origPixels.data[ index+1 ];
scaledPixels.data[ indexScaled+2 ] = origPixels.data[ index+2 ];
scaledPixels.data[ indexScaled+3 ] = origPixels.data[ index+3 ];
}
}
scaledCtx.putImageData( scaledPixels, 0, 0 );
this.data = scaled;
},
draw: function( targetX, targetY, sourceX, sourceY, width, height ) {
if( !this.loaded ) { return; }
var scale = ig.system.scale;
sourceX = sourceX ? sourceX * scale : 0;
sourceY = sourceY ? sourceY * scale : 0;
width = (width ? width : this.width) * scale;
height = (height ? height : this.height) * scale;
ig.system.context.drawImage(
this.data, sourceX, sourceY, width, height,
ig.system.getDrawPos(targetX),
ig.system.getDrawPos(targetY),
width, height
);
ig.Image.drawCount++;
},
drawTile: function( targetX, targetY, tile, tileWidth, tileHeight, flipX, flipY ) {
tileHeight = tileHeight ? tileHeight : tileWidth;
if( !this.loaded || tileWidth > this.width || tileHeight > this.height ) { return; }
var scale = ig.system.scale;
var tileWidthScaled = Math.floor(tileWidth * scale);
var tileHeightScaled = Math.floor(tileHeight * scale);
var scaleX = flipX ? -1 : 1;
var scaleY = flipY ? -1 : 1;
if( flipX || flipY ) {
ig.system.context.save();
ig.system.context.scale( scaleX, scaleY );
}
ig.system.context.drawImage(
this.data,
( Math.floor(tile * tileWidth) % this.width ) * scale,
( Math.floor(tile * tileWidth / this.width) * tileHeight ) * scale,
tileWidthScaled,
tileHeightScaled,
ig.system.getDrawPos(targetX) * scaleX - (flipX ? tileWidthScaled : 0),
ig.system.getDrawPos(targetY) * scaleY - (flipY ? tileHeightScaled : 0),
tileWidthScaled,
tileHeightScaled
);
if( flipX || flipY ) {
ig.system.context.restore();
}
ig.Image.drawCount++;
}
});
ig.Image.drawCount = 0;
ig.Image.cache = {};
ig.Image.reloadCache = function() {
for( var path in ig.Image.cache ) {
ig.Image.cache[path].reload();
}
};
});