topical media & game development
mobile-graphic-enchant-dev-src-CanvasLayer.js / js
@scope enchant.CanvasLayer.prototype
enchant.CanvasLayer = enchant.Class.create(enchant.Group, {
@name enchant.CanvasLayer
@class
[lang:ja]
Canvas を用いた描画を行うクラス.
子を Canvas を用いた描画に切り替えるクラス
[/lang]
[lang:en]
A class which is using HTML Canvas for the rendering.
The rendering of children will be replaced by the Canvas rendering.
[/lang]
[lang:de]
Eine Klasse die HTML Canvas für das Rendern nutzt.
Das Rendern der Kinder wird durch das Canvas Rendering ersetzt.
[/lang]
@constructs
initialize: function() {
var core = enchant.Core.instance;
enchant.Group.call(this);
this._cvsCache = {
matrix: [1, 0, 0, 1, 0, 0],
detectColor: '#000000'
};
this._cvsCache.layer = this;
this._element = document.createElement('canvas');
this._element.style.position = 'absolute';
// issue 179
this._element.style.left = this._element.style.top = '0px';
this._detect = document.createElement('canvas');
this._detect.style.position = 'absolute';
this._lastDetected = 0;
this.context = this._element.getContext('2d');
this._dctx = this._detect.getContext('2d');
this._colorManager = new enchant.DetectColorManager(16, 256);
this.width = core.width;
this.height = core.height;
var touch = [
enchant.Event.TOUCH_START,
enchant.Event.TOUCH_MOVE,
enchant.Event.TOUCH_END
];
touch.forEach(function(type) {
this.addEventListener(type, function(e) {
if (this._scene) {
this._scene.dispatchEvent(e);
}
});
}, this);
var __onchildadded = function(e) {
var child = e.node;
var self = e.target;
var layer;
if (self instanceof enchant.CanvasLayer) {
layer = self._scene._layers.Canvas;
} else {
layer = self.scene._layers.Canvas;
}
enchant.CanvasLayer._attachCache(child, layer, __onchildadded, __onchildremoved);
var render = new enchant.Event(enchant.Event.RENDER);
if (self._dirty) {
self._updateCoordinate();
}
child._dirty = true;
enchant.Matrix.instance.stack.push(self._matrix);
enchant.CanvasRenderer.instance.render(layer.context, child, render);
enchant.Matrix.instance.stack.pop(self._matrix);
};
var __onchildremoved = function(e) {
var child = e.node;
var self = e.target;
var layer;
if (self instanceof enchant.CanvasLayer) {
layer = self._scene._layers.Canvas;
} else {
layer = self.scene._layers.Canvas;
}
enchant.CanvasLayer._detachCache(child, layer, __onchildadded, __onchildremoved);
};
this.addEventListener('childremoved', __onchildremoved);
this.addEventListener('childadded', __onchildadded);
},
width: {
get: function() {
return this._width;
},
set: function(width) {
this._width = width;
this._element.width = this._detect.width = width;
}
},
height: {
get: function() {
return this._height;
},
set: function(height) {
this._height = height;
this._element.height = this._detect.height = height;
}
},
addChild: function(node) {
this.childNodes.push(node);
node.parentNode = this;
var childAdded = new enchant.Event('childadded');
childAdded.node = node;
childAdded.next = null;
this.dispatchEvent(childAdded);
node.dispatchEvent(new enchant.Event('added'));
if (this.scene) {
node.scene = this.scene;
var addedToScene = new enchant.Event('addedtoscene');
node.dispatchEvent(addedToScene);
}
},
insertBefore: function(node, reference) {
var i = this.childNodes.indexOf(reference);
if (i !== -1) {
this.childNodes.splice(i, 0, node);
node.parentNode = this;
var childAdded = new enchant.Event('childadded');
childAdded.node = node;
childAdded.next = reference;
this.dispatchEvent(childAdded);
node.dispatchEvent(new enchant.Event('added'));
if (this.scene) {
node.scene = this.scene;
var addedToScene = new enchant.Event('addedtoscene');
node.dispatchEvent(addedToScene);
}
} else {
this.addChild(node);
}
},
[lang:ja]
レンダリングを開始.
[/lang]
@private
_startRendering: function() {
this.addEventListener('exitframe', this._onexitframe);
this._onexitframe(new enchant.Event(enchant.Event.RENDER));
},
[lang:ja]
レンダリングを停止.
[/lang]
@private
_stopRendering: function() {
this.removeEventListener('render', this._onexitframe);
this._onexitframe(new enchant.Event(enchant.Event.RENDER));
},
_onexitframe: function() {
var core = enchant.Core.instance;
var ctx = this.context;
ctx.clearRect(0, 0, core.width, core.height);
var render = new enchant.Event(enchant.Event.RENDER);
enchant.CanvasRenderer.instance.render(ctx, this, render);
},
_determineEventTarget: function(e) {
return this._getEntityByPosition(e.x, e.y);
},
_getEntityByPosition: function(x, y) {
var core = enchant.Core.instance;
var ctx = this._dctx;
if (this._lastDetected < core.frame) {
ctx.clearRect(0, 0, this.width, this.height);
enchant.CanvasRenderer.instance.detectRender(ctx, this);
this._lastDetected = core.frame;
}
var color = ctx.getImageData(x, y, 1, 1).data;
return this._colorManager.getSpriteByColor(color);
}
});
enchant.CanvasLayer._attachCache = function(node, layer, onchildadded, onchildremoved) {
var child;
if (!node._cvsCache) {
node._cvsCache = {};
node._cvsCache.matrix = [ 1, 0, 0, 1, 0, 0 ];
node._cvsCache.detectColor = 'rgba(' + layer._colorManager.attachDetectColor(node) + ')';
node.addEventListener('childadded', onchildadded);
node.addEventListener('childremoved', onchildremoved);
}
if (node.childNodes) {
for (var i = 0, l = node.childNodes.length; i < l; i++) {
child = node.childNodes[i];
enchant.CanvasLayer._attachCache(child, layer, onchildadded, onchildremoved);
}
}
};
enchant.CanvasLayer._detachCache = function(node, layer, onchildadded, onchildremoved) {
var child;
if (node._cvsCache) {
layer._colorManager.detachDetectColor(node);
node.removeEventListener('childadded', onchildadded);
node.removeEventListener('childremoved', onchildremoved);
delete node._cvsCache;
}
if (node.childNodes) {
for (var i = 0, l = node.childNodes.length; i < l; i++) {
child = node.childNodes[i];
enchant.CanvasLayer._detachCache(child, layer, onchildadded, onchildremoved);
}
}
};
(C) Æliens
04/09/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.