konva/src/Layer.js

237 lines
7.9 KiB
JavaScript
Raw Normal View History

(function() {
/**
* Layer constructor. Layers are tied to their own canvas element and are used
* to contain groups or shapes
* @constructor
* @augments Kinetic.Container
* @param {Object} config
* @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want
* to clear the canvas before each layer draw. The default value is true.
* {{NodeParams}}
* {{ContainerParams}}
*/
Kinetic.Layer = function(config) {
this._initLayer(config);
};
Kinetic.Layer.prototype = {
_initLayer: function(config) {
this.setDefaultAttrs({
clearBeforeDraw: true
});
this.nodeType = 'Layer';
this.beforeDrawFunc = undefined;
this.afterDrawFunc = undefined;
this.canvas = new Kinetic.SceneCanvas();
this.canvas.getElement().style.position = 'absolute';
this.hitCanvas = new Kinetic.HitCanvas();
// call super constructor
Kinetic.Container.call(this, config);
},
/**
* draw children nodes. this includes any groups
* or shapes
* @name draw
* @methodOf Kinetic.Layer.prototype
*/
draw: function() {
var context = this.getContext();
// before draw handler
if(this.beforeDrawFunc !== undefined) {
this.beforeDrawFunc.call(this);
}
Kinetic.Container.prototype.draw.call(this);
// after draw handler
if(this.afterDrawFunc !== undefined) {
this.afterDrawFunc.call(this);
}
},
/**
* draw children nodes on hit. this includes any groups
* or shapes
* @name drawHit
* @methodOf Kinetic.Layer.prototype
*/
drawHit: function() {
this.hitCanvas.clear();
Kinetic.Container.prototype.drawHit.call(this);
},
/**
* draw children nodes on scene. this includes any groups
* or shapes
* @name drawScene
* @methodOf Kinetic.Layer.prototype
* @param {Kinetic.Canvas} [canvas]
*/
drawScene: function(canvas) {
canvas = canvas || this.getCanvas();
if(this.attrs.clearBeforeDraw) {
canvas.clear();
}
Kinetic.Container.prototype.drawScene.call(this, canvas);
},
toDataURL: function(config) {
config = config || {};
var mimeType = config.mimeType || null, quality = config.quality || null, canvas, context, x = config.x || 0, y = config.y || 0;
// if dimension or position is defined, use Node toDataURL
if(config.width || config.height || config.x || config.y) {
return Kinetic.Node.prototype.toDataURL.call(this, config);
}
// otherwise get data url of the currently drawn layer
else {
return this.getCanvas().toDataURL(mimeType, quality);
}
},
/**
* set before draw handler
* @name beforeDraw
* @methodOf Kinetic.Layer.prototype
* @param {Function} handler
*/
beforeDraw: function(func) {
this.beforeDrawFunc = func;
},
/**
* set after draw handler
* @name afterDraw
* @methodOf Kinetic.Layer.prototype
* @param {Function} handler
*/
afterDraw: function(func) {
this.afterDrawFunc = func;
},
/**
* get layer canvas
* @name getCanvas
* @methodOf Kinetic.Layer.prototype
*/
getCanvas: function() {
return this.canvas;
},
/**
* get layer canvas context
* @name getContext
* @methodOf Kinetic.Layer.prototype
*/
getContext: function() {
return this.canvas.context;
},
/**
* clear canvas tied to the layer
* @name clear
* @methodOf Kinetic.Layer.prototype
*/
clear: function() {
this.getCanvas().clear();
},
// extenders
setVisible: function(visible) {
Kinetic.Node.prototype.setVisible.call(this, visible);
if(visible) {
this.canvas.element.style.display = 'block';
this.hitCanvas.element.style.display = 'block';
}
else {
this.canvas.element.style.display = 'none';
this.hitCanvas.element.style.display = 'none';
}
},
setZIndex: function(index) {
Kinetic.Node.prototype.setZIndex.call(this, index);
var stage = this.getStage();
if(stage) {
stage.content.removeChild(this.canvas.element);
if(index < stage.getChildren().length - 1) {
stage.content.insertBefore(this.canvas.element, stage.getChildren()[index + 1].canvas.element);
}
else {
stage.content.appendChild(this.canvas.element);
}
}
},
moveToTop: function() {
Kinetic.Node.prototype.moveToTop.call(this);
var stage = this.getStage();
if(stage) {
stage.content.removeChild(this.canvas.element);
stage.content.appendChild(this.canvas.element);
}
},
moveUp: function() {
if(Kinetic.Node.prototype.moveUp.call(this)) {
var stage = this.getStage();
if(stage) {
stage.content.removeChild(this.canvas.element);
if(this.index < stage.getChildren().length - 1) {
stage.content.insertBefore(this.canvas.element, stage.getChildren()[this.index + 1].canvas.element);
}
else {
stage.content.appendChild(this.canvas.element);
}
}
}
},
moveDown: function() {
if(Kinetic.Node.prototype.moveDown.call(this)) {
var stage = this.getStage();
if(stage) {
var children = stage.getChildren();
stage.content.removeChild(this.canvas.element);
stage.content.insertBefore(this.canvas.element, children[this.index + 1].canvas.element);
}
}
},
moveToBottom: function() {
if(Kinetic.Node.prototype.moveToBottom.call(this)) {
var stage = this.getStage();
if(stage) {
var children = stage.getChildren();
stage.content.removeChild(this.canvas.element);
stage.content.insertBefore(this.canvas.element, children[1].canvas.element);
}
}
},
getLayer: function() {
return this;
},
/**
* remove layer from stage
*/
remove: function() {
var stage = this.getStage(), canvas = this.canvas, element = canvas.element;
Kinetic.Node.prototype.remove.call(this);
if(stage && canvas && Kinetic.Type._isInDocument(element)) {
stage.content.removeChild(element);
}
}
};
Kinetic.Global.extend(Kinetic.Layer, Kinetic.Container);
// add getters and setters
Kinetic.Node.addGettersSetters(Kinetic.Layer, ['clearBeforeDraw']);
/**
* set flag which determines if the layer is cleared or not
* before drawing
* @name setClearBeforeDraw
* @methodOf Kinetic.Layer.prototype
* @param {Boolean} clearBeforeDraw
*/
/**
* get flag which determines if the layer is cleared or not
* before drawing
* @name getClearBeforeDraw
* @methodOf Kinetic.Layer.prototype
*/
})();