Merge github.com:ericdrowell/KineticJS

This commit is contained in:
Louis Jolibois
2013-03-27 18:55:52 +01:00
46 changed files with 1263 additions and 882 deletions

View File

@@ -135,7 +135,7 @@
})();
Kinetic.Animation.requestAnimFrame = function(callback) {
var raf = Kinetic.DD && Kinetic.DD.moving ? this.fixedRequestAnimFrame : RAF;
var raf = Kinetic.DD && Kinetic.DD.isDragging ? this.fixedRequestAnimFrame : RAF;
raf(callback);
};

View File

@@ -204,11 +204,7 @@
if (!canvas && layer) {
canvas = layer.getCanvas();
}
if(layer && layer.getClearBeforeDraw()) {
canvas.clear();
}
}
if(this.isVisible()) {
if (clip) {
@@ -229,20 +225,21 @@
},
drawHit: function() {
var clip = !!this.getClipFunc() && this.nodeType !== 'Stage',
dd = Kinetic.DD,
hitCanvas;
if (clip) {
hitCanvas = this.getLayer().hitCanvas;
hitCanvas._clip(this);
}
if(this.isVisible() && this.isListening()) {
if(this.shouldDrawHit()) {
if (clip) {
hitCanvas = this.getLayer().hitCanvas;
hitCanvas._clip(this);
}
var children = this.children, len = children.length;
for(var n = 0; n < len; n++) {
children[n].drawHit();
}
}
if (clip) {
hitCanvas.getContext().restore();
if (clip) {
hitCanvas.getContext().restore();
}
}
}
};

View File

@@ -1,127 +1,122 @@
(function() {
Kinetic.DD = {
// properties
anim: new Kinetic.Animation(),
moving: false,
isDragging: false,
offset: {
x: 0,
y: 0
}
};
Kinetic.getNodeDragging = function() {
return Kinetic.DD.node;
};
Kinetic.DD._initDragLayer = function(stage) {
stage.dragLayer = new Kinetic.Layer();
stage.dragLayer.getCanvas().getElement().className = 'kinetic-drag-and-drop-layer';
};
Kinetic.DD._drag = function(evt) {
var dd = Kinetic.DD, node = dd.node;
if(node) {
var pos = node.getStage().getUserPosition();
var dbf = node.attrs.dragBoundFunc;
var newNodePos = {
x: pos.x - dd.offset.x,
y: pos.y - dd.offset.y
};
if(dbf !== undefined) {
newNodePos = dbf.call(node, newNodePos, evt);
}
node.setAbsolutePosition(newNodePos);
if(!dd.moving) {
dd.moving = true;
node.setListening(false);
// execute dragstart events if defined
node._handleEvent('dragstart', evt);
}
// execute ondragmove if defined
node._handleEvent('dragmove', evt);
}
};
Kinetic.DD._endDrag = function(evt) {
var dd = Kinetic.DD, node = dd.node;
if(node) {
var nodeType = node.nodeType, stage = node.getStage();
node.setListening(true);
if(nodeType === 'Stage') {
node.draw();
}
// else if group, shape, or layer
else {
if((nodeType === 'Group' || nodeType === 'Shape') && node.getDragOnTop()) {
node.getStage().dragLayer.remove();
},
node: null,
// methods
_drag: function(evt) {
var dd = Kinetic.DD,
node = dd.node;
if(node) {
var pos = node.getStage().getPointerPosition();
var dbf = node.getDragBoundFunc();
var newNodePos = {
x: pos.x - dd.offset.x,
y: pos.y - dd.offset.y
};
if(dbf !== undefined) {
newNodePos = dbf.call(node, newNodePos, evt);
}
node.moveToTop();
node.getLayer().draw();
node.setAbsolutePosition(newNodePos);
if(!dd.isDragging) {
dd.isDragging = true;
node._handleEvent('dragstart', evt);
}
// execute ondragmove if defined
node._handleEvent('dragmove', evt);
}
delete dd.node;
dd.anim.stop();
// only fire dragend event if the drag and drop
// operation actually started. This can be detected by
// checking dd.moving
if(dd.moving) {
dd.moving = false;
node._handleEvent('dragend', evt);
},
_endDragBefore: function(evt) {
var dd = Kinetic.DD,
evt = evt || {},
node = dd.node,
nodeType, layer;
if(node) {
nodeType = node.nodeType,
layer = node.getLayer();
dd.anim.stop();
// only fire dragend event if the drag and drop
// operation actually started.
if(dd.isDragging) {
dd.isDragging = false;
evt.dragEndNode = node;
}
delete dd.node;
if (layer) {
layer.draw();
}
else {
node.draw();
}
}
},
_endDragAfter: function(evt) {
var evt = evt || {},
dragEndNode = evt.dragEndNode;
if (evt && dragEndNode) {
dragEndNode._handleEvent('dragend', evt);
}
}
};
Kinetic.Node.prototype._startDrag = function(evt) {
// Node extenders
/**
* initiate drag and drop
* @name startDrag
* @methodOf Kinetic.Node.prototype
*/
Kinetic.Node.prototype.startDrag = function() {
var dd = Kinetic.DD,
that = this,
stage = this.getStage(),
layer = this.getLayer(),
pos = stage.getUserPosition();
pos = stage.getPointerPosition(),
m = this.getTransform().getTranslation(),
ap = this.getAbsolutePosition(),
animNode = layer || this;
if(pos) {
var m = this.getTransform().getTranslation(), ap = this.getAbsolutePosition(), nodeType = this.nodeType, container;
if (dd.node) {
dd.node.stopDrag();
}
dd.node = this;
dd.offset.x = pos.x - ap.x;
dd.offset.y = pos.y - ap.y;
dd.anim.node = this;
// Stage and Layer node types
if(nodeType === 'Stage' || nodeType === 'Layer') {
dd.anim.start();
}
// Group or Shape node types
else {
if(this.getDragOnTop()) {
// WARNING: it's important to delay the moveTo operation,
// layer redraws, and anim.start() until after the method execution
// has completed or else there will be a flicker on mobile devices
// due to the time it takes to append the dd canvas to the DOM
//setTimeout(function() {
//if(dd.node) {
// clear shape from layer canvas
that.setVisible(false);
layer.draw();
that.setVisible(true);
stage.add(stage.dragLayer);
dd.anim.start();
//}
//}, 0);
}
else {
dd.anim.start();
}
}
dd.anim.node = animNode;
dd.anim.start();
}
};
/**
* stop drag and drop
* @name stopDrag
* @methodOf Kinetic.Node.prototype
*/
Kinetic.Node.prototype.stopDrag = function() {
var dd = Kinetic.DD;
dd._endDragBefore();
dd._endDragAfter();
};
/**
* set draggable
* @name setDraggable
@@ -140,15 +135,15 @@
*/
Kinetic.Node.prototype.isDragging = function() {
var dd = Kinetic.DD;
return dd.node && dd.node._id === this._id && dd.moving;
return dd.node && dd.node._id === this._id && dd.isDragging;
};
Kinetic.Node.prototype._listenDrag = function() {
this._dragCleanup();
var that = this;
this.on('mousedown.kinetic touchstart.kinetic', function(evt) {
if(!Kinetic.getNodeDragging()) {
that._startDrag(evt);
if(!Kinetic.DD.node) {
that.startDrag(evt);
}
});
};
@@ -169,10 +164,11 @@
var stage = this.getStage();
var dd = Kinetic.DD;
if(stage && dd.node && dd.node._id === this._id) {
dd._endDrag();
dd.node.stopDrag();
}
}
};
Kinetic.Node.prototype._dragCleanup = function() {
this.off('mousedown.kinetic');
this.off('touchstart.kinetic');
@@ -224,11 +220,15 @@
* @methodOf Kinetic.Node.prototype
*/
Kinetic.Node.prototype.isDraggable = Kinetic.Node.prototype.getDraggable;
// listen for capturing phase so that the _endDrag method is
// listen for capturing phase so that the _endDrag* methods are
// called before the stage mouseup event is triggered in order
// to render the hit graph just in time to pick up the event
var html = document.getElementsByTagName('html')[0];
html.addEventListener('mouseup', Kinetic.DD._endDrag, true);
html.addEventListener('touchend', Kinetic.DD._endDrag, true);
html.addEventListener('mouseup', Kinetic.DD._endDragBefore, true);
html.addEventListener('touchend', Kinetic.DD._endDragBefore, true);
html.addEventListener('mouseup', Kinetic.DD._endDragAfter, false);
html.addEventListener('touchend', Kinetic.DD._endDragAfter, false);
})();

View File

@@ -25,16 +25,22 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* @namespace
/**
* @namespace
*/
var Kinetic = {}; (function() {
var Kinetic = {};
(function() {
Kinetic.version = '{{version}}';
/**
* @namespace
/**
* @namespace
*/
Kinetic.Filters = {};
Kinetic.Plugins = {};
Kinetic.DD = {};
/**
* @namespace
*/
Kinetic.Global = {
stages: [],
idCounter: 0,
@@ -42,6 +48,15 @@ var Kinetic = {}; (function() {
names: {},
//shapes hash. rgb keys and shape values
shapes: {},
/**
* @method isDragging returns whether or not drag and drop
* is currently active
* @methodOf Kinetic.Global
*/
isDragging: function() {
var dd = Kinetic.DD;
return (!dd || dd.isDragging);
},
warn: function(str) {
/*
* IE9 on Windows7 64bit will throw a JS error

View File

@@ -27,49 +27,6 @@
// 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() {
// 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.getClearBeforeDraw()) {
canvas.clear();
}
Kinetic.Container.prototype.drawScene.call(this, canvas);
},
toDataURL: function(config) {
config = config || {};
var mimeType = config.mimeType || null,
@@ -114,8 +71,15 @@
* @methodOf Kinetic.Layer.prototype
*/
getCanvas: function() {
var stage = this.getStage();
return (stage && stage._isTempDDLayerActive()) ? stage.dragLayer.canvas : this.canvas;
return this.canvas;
},
/**
* get layer hit canvas
* @name getHitCanvas
* @methodOf Kinetic.Layer.prototype
*/
getHitCanvas: function() {
return this.hitCanvas;
},
/**
* get layer canvas context

View File

@@ -1,4 +1,27 @@
(function() {
// CONSTANTS
var SPACE = ' ',
EMPTY_STRING = '',
DOT = '.',
GET = 'get',
SET = 'set',
SHAPE = 'Shape',
STAGE = 'Stage',
X = 'x',
Y = 'y',
KINETIC = 'kinetic',
BEFORE = 'before',
CHANGE = 'Change',
ID = 'id',
NAME = 'name',
MOUSEENTER = 'mouseenter',
MOUSELEAVE = 'mouseleave',
DEG = 'Deg',
ON = 'on',
OFF = 'off',
BEFORE_DRAW = 'beforeDraw',
DRAW = 'draw';
/**
* Node constructor. Nodes are entities that can be transformed, layered,
* and have bound events. The stage, layers, groups, and shapes all extend Node.
@@ -29,19 +52,21 @@
* @param {Function} handler The handler function is passed an event object
*/
on: function(typesStr, handler) {
var types = typesStr.split(' ');
/*
var types = typesStr.split(SPACE),
len = types.length,
n, type, event, parts, baseEvent, name;
/*
* loop through types and attach event listeners to
* each one. eg. 'click mouseover.namespace mouseout'
* will create three event bindings
*/
var len = types.length;
for(var n = 0; n < len; n++) {
var type = types[n];
var event = type;
var parts = event.split('.');
var baseEvent = parts[0];
var name = parts.length > 1 ? parts[1] : '';
for(n = 0; n < len; n++) {
type = types[n];
event = type;
parts = event.split(DOT);
baseEvent = parts[0];
name = parts.length > 1 ? parts[1] : EMPTY_STRING;
if(!this.eventListeners[baseEvent]) {
this.eventListeners[baseEvent] = [];
@@ -66,13 +91,15 @@
* @param {String} typesStr e.g. 'click', 'mousedown touchstart', '.foobar'
*/
off: function(typesStr) {
var types = typesStr.split(' ');
var len = types.length;
for(var n = 0; n < len; n++) {
var type = types[n];
var event = type;
var parts = event.split('.');
var baseEvent = parts[0];
var types = typesStr.split(SPACE),
len = types.length,
n, type, event, parts, baseEvent;
for(n = 0; n < len; n++) {
type = types[n];
event = type;
parts = event.split(DOT);
baseEvent = parts[0];
if(parts.length > 1) {
if(baseEvent) {
@@ -99,6 +126,7 @@
*/
remove: function() {
var parent = this.getParent();
if(parent && parent.children) {
parent.children.splice(this.index, 1);
parent._setChildrenIndices();
@@ -111,7 +139,10 @@
* @methodOf Kinetic.Node.prototype
*/
destroy: function() {
var parent = this.getParent(), stage = this.getStage(), dd = Kinetic.DD, go = Kinetic.Global;
var parent = this.getParent(),
stage = this.getStage(),
dd = Kinetic.DD,
go = Kinetic.Global;
// destroy children
while(this.children && this.children.length > 0) {
@@ -141,7 +172,7 @@
* @param {String} attr
*/
getAttr: function(attr) {
var method = 'get' + Kinetic.Type._capitalize(attr);
var method = GET + Kinetic.Type._capitalize(attr);
return this[method]();
},
/**
@@ -169,9 +200,11 @@
* @param {Object} config object containing key value pairs
*/
setAttrs: function(config) {
var key, method;
if(config) {
for(var key in config) {
var method = 'set' + Kinetic.Type._capitalize(key);
for(key in config) {
method = SET + Kinetic.Type._capitalize(key);
// use setter if available
if(Kinetic.Type._isFunction(this[method])) {
this[method](config[key]);
@@ -256,18 +289,20 @@
* @methodOf Kinetic.Node.prototype
*/
getAbsoluteZIndex: function() {
var level = this.getLevel();
var stage = this.getStage();
var that = this;
var index = 0;
var level = this.getLevel(),
stage = this.getStage(),
that = this,
index = 0,
nodes, len, n, child;
function addChildren(children) {
var nodes = [];
var len = children.length;
for(var n = 0; n < len; n++) {
var child = children[n];
nodes = [];
len = children.length;
for(n = 0; n < len; n++) {
child = children[n];
index++;
if(child.nodeType !== 'Shape') {
if(child.nodeType !== SHAPE) {
nodes = nodes.concat(child.getChildren());
}
@@ -280,7 +315,7 @@
addChildren(nodes);
}
}
if(that.nodeType !== 'Stage') {
if(that.nodeType !== STAGE) {
addChildren(that.getStage().getChildren());
}
@@ -294,8 +329,9 @@
* @methodOf Kinetic.Node.prototype
*/
getLevel: function() {
var level = 0;
var parent = this.parent;
var level = 0,
parent = this.parent;
while(parent) {
level++;
parent = parent.parent;
@@ -311,8 +347,8 @@
*/
setPosition: function() {
var pos = Kinetic.Type._getXY([].slice.call(arguments));
this.setAttr('x', pos.x);
this.setAttr('y', pos.y);
this.setAttr(X, pos.x);
this.setAttr(Y, pos.y);
},
/**
* get node position relative to parent
@@ -331,8 +367,9 @@
* @methodOf Kinetic.Node.prototype
*/
getAbsolutePosition: function() {
var trans = this.getAbsoluteTransform();
var o = this.getOffset();
var trans = this.getAbsoluteTransform(),
o = this.getOffset();
trans.translate(o.x, o.y);
return trans.getTranslation();
},
@@ -344,8 +381,10 @@
* @param {Number} y
*/
setAbsolutePosition: function() {
var pos = Kinetic.Type._getXY([].slice.call(arguments));
var trans = this._clearTransform();
var pos = Kinetic.Type._getXY([].slice.call(arguments)),
trans = this._clearTransform(),
it;
// don't clear translation
this.attrs.x = trans.x;
this.attrs.y = trans.y;
@@ -353,7 +392,7 @@
delete trans.y;
// unravel transform
var it = this.getAbsoluteTransform();
it = this.getAbsoluteTransform();
it.invert();
it.translate(pos.x, pos.y);
@@ -373,9 +412,9 @@
* @param {Number} y
*/
move: function() {
var pos = Kinetic.Type._getXY([].slice.call(arguments));
var x = this.getX();
var y = this.getY();
var pos = Kinetic.Type._getXY([].slice.call(arguments)),
x = this.getX(),
y = this.getY();
if(pos.x !== undefined) {
x += pos.x;
@@ -388,7 +427,9 @@
this.setPosition(x, y);
},
_eachAncestorReverse: function(func, includeSelf) {
var family = [], parent = this.getParent();
var family = [],
parent = this.getParent(),
len, n;
// build family by traversing ancestors
if(includeSelf) {
@@ -399,8 +440,8 @@
parent = parent.parent;
}
var len = family.length;
for(var n = 0; n < len; n++) {
len = family.length;
for(n = 0; n < len; n++) {
func(family[n]);
}
},
@@ -440,8 +481,8 @@
* @methodOf Kinetic.Node.prototype
*/
moveUp: function() {
var index = this.index;
var len = this.parent.getChildren().length;
var index = this.index,
len = this.parent.getChildren().length;
if(index < len - 1) {
this.parent.children.splice(index, 1);
this.parent.children.splice(index + 1, 0, this);
@@ -517,13 +558,16 @@
* @methodOf Kinetic.Node.prototype
*/
toObject: function() {
var type = Kinetic.Type, obj = {}, attrs = this.attrs;
var type = Kinetic.Type,
obj = {},
attrs = this.getAttrs(),
key, val;
obj.attrs = {};
// serialize only attributes that are not function, image, DOM, or objects with methods
for(var key in attrs) {
var val = attrs[key];
for(key in attrs) {
val = attrs[key];
if(!type._isFunction(val) && !type._isElement(val) && !(type._isObject(val) && type._hasMethods(val))) {
obj.attrs[key] = val;
}
@@ -597,10 +641,11 @@
*/
getAbsoluteTransform: function() {
// absolute transform
var am = new Kinetic.Transform();
var am = new Kinetic.Transform(),
m;
this._eachAncestorReverse(function(node) {
var m = node.getTransform();
m = node.getTransform();
am.multiply(m);
}, true);
return am;
@@ -645,20 +690,21 @@
*/
clone: function(obj) {
// instantiate new node
var classType = this.shapeType || this.nodeType;
var node = new Kinetic[classType](this.attrs);
var classType = this.shapeType || this.nodeType,
node = new Kinetic[classType](this.attrs),
key, allListeners, len, n, listener;
// copy over user listeners
for(var key in this.eventListeners) {
var allListeners = this.eventListeners[key];
var len = allListeners.length;
for(var n = 0; n < len; n++) {
var listener = allListeners[n];
// copy over listeners
for(key in this.eventListeners) {
allListeners = this.eventListeners[key];
len = allListeners.length;
for(n = 0; n < len; n++) {
listener = allListeners[n];
/*
* don't include kinetic namespaced listeners because
* these are generated by the constructors
*/
if(listener.name.indexOf('kinetic') < 0) {
if(listener.name.indexOf(KINETIC) < 0) {
// if listeners array doesn't exist, then create it
if(!node.eventListeners[key]) {
node.eventListeners[key] = [];
@@ -691,8 +737,12 @@
* is very high quality
*/
toDataURL: function(config) {
config = config || {};
var mimeType = config.mimeType || null, quality = config.quality || null, canvas, context, x = config.x || 0, y = config.y || 0;
var config = config || {},
mimeType = config.mimeType || null,
quality = config.quality || null,
x = config.x || 0,
y = config.y || 0,
canvas, context;
//if width and height are defined, create new canvas to draw on, else reuse stage buffer canvas
if(config.width && config.height) {
@@ -784,10 +834,13 @@
return this.nodeType === selector ? [this] : [];
},
_off: function(type, name) {
for(var i = 0; i < this.eventListeners[type].length; i++) {
if(this.eventListeners[type][i].name === name) {
this.eventListeners[type].splice(i, 1);
if(this.eventListeners[type].length === 0) {
var evtListeners = this.eventListeners[type],
i;
for(i = 0; i < evtListeners.length; i++) {
if(evtListeners[i].name === name) {
evtListeners.splice(i, 1);
if(evtListeners.length === 0) {
delete this.eventListeners[type];
break;
}
@@ -827,18 +880,20 @@
return trans;
},
_setTransform: function(trans) {
for(var key in trans) {
var key;
for(key in trans) {
this.attrs[key] = trans[key];
}
},
_fireBeforeChangeEvent: function(attr, oldVal, newVal) {
this._handleEvent('before' + Kinetic.Type._capitalize(attr) + 'Change', {
this._handleEvent(BEFORE + Kinetic.Type._capitalize(attr) + CHANGE, {
oldVal: oldVal,
newVal: newVal
});
},
_fireChangeEvent: function(attr, oldVal, newVal) {
this._handleEvent(attr + 'Change', {
this._handleEvent(attr + CHANGE, {
oldVal: oldVal,
newVal: newVal
});
@@ -850,10 +905,13 @@
* @param {String} id
*/
setId: function(id) {
var oldId = this.getId(), stage = this.getStage(), go = Kinetic.Global;
var oldId = this.getId(),
stage = this.getStage(),
go = Kinetic.Global;
go._removeId(oldId);
go._addId(this, id);
this.setAttr('id', id);
this.setAttr(ID, id);
},
/**
* set name
@@ -862,31 +920,43 @@
* @param {String} name
*/
setName: function(name) {
var oldName = this.getName(), stage = this.getStage(), go = Kinetic.Global;
var oldName = this.getName(),
stage = this.getStage(),
go = Kinetic.Global;
go._removeName(oldName, this._id);
go._addName(this, name);
this.setAttr('name', name);
this.setAttr(NAME, name);
},
/**
* get node type. Returns 'Stage', 'Layer', 'Group', or 'Shape'
* @name getNodeType
* @methodOf Kinetic.Node.prototype
*/
getNodeType: function() {
return this.nodeType;
},
setAttr: function(key, val) {
var oldVal;
if(val !== undefined) {
var oldVal = this.attrs[key];
oldVal = this.attrs[key];
this._fireBeforeChangeEvent(key, oldVal, val);
this.attrs[key] = val;
this._fireChangeEvent(key, oldVal, val);
}
},
_handleEvent: function(eventType, evt, compareShape) {
if(evt && this.nodeType === 'Shape') {
evt.shape = this;
if(evt && this.nodeType === SHAPE) {
evt.targetNode = this;
}
var stage = this.getStage();
var el = this.eventListeners;
var okayToRun = true;
if(eventType === 'mouseenter' && compareShape && this._id === compareShape._id) {
if(eventType === MOUSEENTER && compareShape && this._id === compareShape._id) {
okayToRun = false;
}
else if(eventType === 'mouseleave' && compareShape && this._id === compareShape._id) {
else if(eventType === MOUSELEAVE && compareShape && this._id === compareShape._id) {
okayToRun = false;
}
@@ -916,20 +986,29 @@
}
},
/*
* draw both scene and hit graphs.
* draw both scene and hit graphs. If the node being drawn is the stage, all of the layers will be cleared and redra
* @name draw
* @methodOf Kinetic.Node.prototype
* the scene renderer
*/
draw: function() {
var layer = this.getLayer();
var layer = this.getLayer(),
evt = {
node: this
};
if(layer && layer.getClearBeforeDraw()) {
layer.getCanvas().clear();
layer.getHitCanvas().clear();
}
this.fire(BEFORE_DRAW, evt);
this.drawScene();
this.drawHit();
this.fire(DRAW, evt);
},
shouldDrawHit: function() {
return this.isVisible() && this.isListening() && !Kinetic.Global.isDragging();
}
};
@@ -948,15 +1027,17 @@
this.addRotationSetter(constructor, arr);
};
Kinetic.Node.addSetter = function(constructor, attr) {
var that = this;
var method = 'set' + Kinetic.Type._capitalize(attr);
var that = this,
method = SET + Kinetic.Type._capitalize(attr);
constructor.prototype[method] = function(val) {
this.setAttr(attr, val);
};
};
Kinetic.Node.addPointSetter = function(constructor, attr) {
var that = this;
var method = 'set' + Kinetic.Type._capitalize(attr);
var that = this,
method = SET + Kinetic.Type._capitalize(attr);
constructor.prototype[method] = function() {
var pos = Kinetic.Type._getXY([].slice.call(arguments));
@@ -975,20 +1056,22 @@
};
};
Kinetic.Node.addRotationSetter = function(constructor, attr) {
var that = this;
var method = 'set' + Kinetic.Type._capitalize(attr);
var that = this,
method = SET + Kinetic.Type._capitalize(attr);
// radians
constructor.prototype[method] = function(val) {
this.setAttr(attr, val);
};
// degrees
constructor.prototype[method + 'Deg'] = function(deg) {
constructor.prototype[method + DEG] = function(deg) {
this.setAttr(attr, Kinetic.Type._degToRad(deg));
};
};
Kinetic.Node.addGetter = function(constructor, attr, def) {
var that = this;
var method = 'get' + Kinetic.Type._capitalize(attr);
var that = this,
method = GET + Kinetic.Type._capitalize(attr);
constructor.prototype[method] = function(arg) {
var val = this.attrs[attr];
if (val === undefined) {
@@ -998,8 +1081,9 @@
};
};
Kinetic.Node.addRotationGetter = function(constructor, attr, def) {
var that = this;
var method = 'get' + Kinetic.Type._capitalize(attr);
var that = this,
method = GET + Kinetic.Type._capitalize(attr);
// radians
constructor.prototype[method] = function() {
var val = this.attrs[attr];
@@ -1009,7 +1093,7 @@
return val;
};
// degrees
constructor.prototype[method + 'Deg'] = function() {
constructor.prototype[method + DEG] = function() {
var val = this.attrs[attr];
if (val === undefined) {
val = def;
@@ -1034,13 +1118,13 @@
return this._createNode(JSON.parse(json), container);
};
Kinetic.Node._createNode = function(obj, container) {
var type;
var type, no, len, n;
// determine type
if(obj.nodeType === 'Shape') {
if(obj.nodeType === SHAPE) {
// add custom shape
if(obj.shapeType === undefined) {
type = 'Shape';
type = SHAPE;
}
// add standard shape
else {
@@ -1056,10 +1140,10 @@
obj.attrs.container = container;
}
var no = new Kinetic[type](obj.attrs);
no = new Kinetic[type](obj.attrs);
if(obj.children) {
var len = obj.children.length;
for(var n = 0; n < len; n++) {
len = obj.children.length;
for(n = 0; n < len; n++) {
no.add(this._createNode(obj.children[n]));
}
}
@@ -1232,18 +1316,6 @@
* @methodOf Kinetic.Node.prototype
*/
Kinetic.Node.prototype.isVisible = Kinetic.Node.prototype.getVisible;
// collection mappings
var collectionMappings = ['on', 'off'];
for(var n = 0; n < 2; n++) {
// induce scope
(function(i) {
var method = collectionMappings[i];
Kinetic.Collection.prototype[method] = function() {
var args = [].slice.call(arguments);
args.unshift(method);
this.apply.apply(this, args);
};
})(n);
}
Kinetic.Collection.mapMethods(['on', 'off']);
})();

View File

@@ -163,6 +163,14 @@
disableDashArray: function() {
this.setAttr('dashArrayEnabled', false);
},
/**
* get shape type. Ex. 'Circle', 'Rect', 'Text', etc.
* @name getShapeType
* @methodOf Kinetic.Shape.prototype
*/
getShapeType: function() {
return this.shapeType;
},
remove: function() {
Kinetic.Node.prototype.remove.call(this);
delete Kinetic.Global.shapes[this.colorKey];
@@ -188,7 +196,7 @@
canvas = this.getLayer().hitCanvas,
context = canvas.getContext();
if(drawFunc && this.isVisible() && this.isListening()) {
if(drawFunc && this.shouldDrawHit()) {
context.save();
canvas._applyLineJoin(this);
canvas._applyAncestorTransforms(this);

View File

@@ -1,7 +1,31 @@
(function() {
// CONSTANTS
var EVENTS = ['mousedown', 'mousemove', 'mouseup', 'mouseout', 'touchstart', 'touchmove', 'touchend'],
var STAGE = 'Stage',
STRING = 'string',
PX = 'px',
MOUSEOUT = 'mouseout',
MOUSELEAVE = 'mouseleave',
MOUSEOUT = 'mouseout',
MOUSEOVER = 'mouseover',
MOUSEENTER = 'mouseenter',
MOUSEMOVE = 'mousemove',
MOUSEDOWN = 'mousedown',
MOUSEUP = 'mouseup',
CLICK = 'click',
DBL_CLICK = 'dblclick',
TOUCHSTART = 'touchstart'
TOUCHEND = 'touchend'
TAP = 'tap',
DBL_TAP = 'dbltap',
TOUCHMOVE = 'touchmove',
DIV = 'div',
RELATIVE = 'relative',
INLINE_BLOCK = 'inline-block',
KINETICJS_CONTENT = 'kineticjs-content',
SPACE = ' ',
CONTAINER = 'container',
EVENTS = [MOUSEDOWN, MOUSEMOVE, MOUSEUP, MOUSEOUT, TOUCHSTART, TOUCHMOVE, TOUCHEND],
// cached variables
eventsLength = EVENTS.length;
@@ -20,20 +44,15 @@
Kinetic.Stage.prototype = {
_initStage: function(config) {
var dd = Kinetic.DD;
this.createAttrs();
// call super constructor
Kinetic.Container.call(this, config);
this._setStageDefaultProperties();
this.nodeType = STAGE;
this.dblClickWindow = 400;
this._id = Kinetic.Global.idCounter++;
this._buildDOM();
this._bindContentEvents();
Kinetic.Global.stages.push(this);
if(dd) {
dd._initDragLayer(this);
}
},
/**
* set container dom element which contains the stage wrapper div element
@@ -42,14 +61,26 @@
* @param {DomElement} container can pass in a dom element or id string
*/
setContainer: function(container) {
/*
* if container is a string, assume it's an id for
* a DOM element
*/
if( typeof container === 'string') {
if( typeof container === STRING) {
container = document.getElementById(container);
}
this.setAttr('container', container);
this.setAttr(CONTAINER, container);
},
draw: function() {
// clear children layers
var children = this.getChildren(),
len = children.length,
n, layer;
for(n = 0; n < len; n++) {
layer = children[n];
if (layer.getClearBeforeDraw()) {
layer.getCanvas().clear();
layer.getHitCanvas().clear();
}
}
Kinetic.Node.prototype.draw.call(this);
},
/**
* draw layer scene graphs
@@ -89,8 +120,11 @@
* @methodOf Kinetic.Stage.prototype
*/
clear: function() {
var layers = this.children;
for(var n = 0; n < layers.length; n++) {
var layers = this.children,
len = length,
n;
for(n = 0; n < len; n++) {
layers[n].clear();
}
},
@@ -102,7 +136,7 @@
Kinetic.Node.prototype.remove.call(this);
if(content && Kinetic.Type._isInDocument(content)) {
this.attrs.container.removeChild(content);
this.getContainer().removeChild(content);
}
},
/**
@@ -122,11 +156,11 @@
return this.touchPos;
},
/**
* get user position which can be a touc position or mouse position
* @name getUserPosition
* get pointer position which can be a touc position or mouse position
* @name getPointerPosition
* @methodOf Kinetic.Stage.prototype
*/
getUserPosition: function() {
getPointerPosition: function() {
return this.getTouchPosition() || this.getMousePosition();
},
getStage: function() {
@@ -158,8 +192,8 @@
* is very high quality
*/
toDataURL: function(config) {
config = config || {};
var mimeType = config.mimeType || null,
var config = config || {},
mimeType = config.mimeType || null,
quality = config.quality || null,
x = config.x || 0,
y = config.y || 0,
@@ -175,9 +209,10 @@
}
function drawLayer(n) {
var layer = layers[n];
var layerUrl = layer.toDataURL();
var imageObj = new Image();
var layer = layers[n],
layerUrl = layer.toDataURL(),
imageObj = new Image();
imageObj.onload = function() {
context.drawImage(imageObj, 0, 0);
@@ -225,20 +260,22 @@
* @param {Object} pos point object
*/
getIntersection: function(pos) {
var shape;
var layers = this.getChildren();
var layers = this.getChildren(),
len = layers.length,
end = len - 1,
n, layer, p, colorKey, shape;
/*
* traverse through layers from top to bottom and look
* for hit detection
*/
for(var n = layers.length - 1; n >= 0; n--) {
var layer = layers[n];
for(n = end; n >= 0; n--) {
layer = layers[n];
if(layer.isVisible() && layer.isListening()) {
var p = layer.hitCanvas.context.getImageData(Math.round(pos.x), Math.round(pos.y), 1, 1).data;
p = layer.hitCanvas.context.getImageData(Math.round(pos.x), Math.round(pos.y), 1, 1).data;
// this indicates that a hit pixel may have been found
if(p[3] === 255) {
var colorKey = Kinetic.Type._rgbToHex(p[0], p[1], p[2]);
colorKey = Kinetic.Type._rgbToHex(p[0], p[1], p[2]);
shape = Kinetic.Global.shapes[colorKey];
return {
shape: shape,
@@ -258,19 +295,22 @@
},
_resizeDOM: function() {
if(this.content) {
var width = this.attrs.width;
var height = this.attrs.height;
var width = this.getWidth(),
height = this.getHeight(),
layers = this.getChildren(),
len = layers.length,
n;
// set content dimensions
this.content.style.width = width + 'px';
this.content.style.height = height + 'px';
this.content.style.width = width + PX;
this.content.style.height = height + PX;
this.bufferCanvas.setSize(width, height, 1);
this.hitCanvas.setSize(width, height);
// set user defined layer dimensions
var layers = this.children;
for(var n = 0; n < layers.length; n++) {
var layer = layers[n];
// set pointer defined layer dimensions
for(n = 0; n < len; n++) {
layer = layers[n];
layer.getCanvas().setSize(width, height);
layer.hitCanvas.setSize(width, height);
layer.draw();
@@ -293,23 +333,13 @@
// chainable
return this;
},
/**
* get drag and drop layer
*/
getDragLayer: function() {
return this.dragLayer;
},
getParent: function() {
return null;
},
getLayer: function() {
return null;
},
_isTempDDLayerActive: function() {
var dragLayer = this.dragLayer;
return dragLayer && dragLayer.getStage();
},
_setUserPosition: function(evt) {
_setPointerPosition: function(evt) {
if(!evt) {
evt = window.event;
}
@@ -324,43 +354,45 @@
var that = this,
n, pubEvent, f;
for (var n = 0; n < eventsLength; n++) {
for (n = 0; n < eventsLength; n++) {
pubEvent = EVENTS[n];
f = that['_' + pubEvent];
that.content.addEventListener(pubEvent, f.bind(that), false);
}
},
_mouseout: function(evt) {
this._setUserPosition(evt);
var dd = Kinetic.DD;
// if there's a current target shape, run mouseout handlers
var targetShape = this.targetShape;
if(targetShape && (!dd || !dd.moving)) {
targetShape._handleEvent('mouseout', evt);
targetShape._handleEvent('mouseleave', evt);
this._setPointerPosition(evt);
var go = Kinetic.Global,
targetShape = this.targetShape;
if(targetShape && !go.isDragging()) {
targetShape._handleEvent(MOUSEOUT, evt);
targetShape._handleEvent(MOUSELEAVE, evt);
this.targetShape = null;
}
this.mousePos = undefined;
},
_mousemove: function(evt) {
this._setUserPosition(evt);
var dd = Kinetic.DD;
var obj = this.getIntersection(this.getUserPosition());
this._setPointerPosition(evt);
var go = Kinetic.Global,
dd = Kinetic.DD,
obj = this.getIntersection(this.getPointerPosition()),
shape;
if(obj) {
var shape = obj.shape;
shape = obj.shape;
if(shape) {
if((!dd || !dd.moving) && obj.pixel[3] === 255 && (!this.targetShape || this.targetShape._id !== shape._id)) {
if(!go.isDragging() && obj.pixel[3] === 255 && (!this.targetShape || this.targetShape._id !== shape._id)) {
if(this.targetShape) {
this.targetShape._handleEvent('mouseout', evt, shape);
this.targetShape._handleEvent('mouseleave', evt, shape);
this.targetShape._handleEvent(MOUSEOUT, evt, shape);
this.targetShape._handleEvent(MOUSELEAVE, evt, shape);
}
shape._handleEvent('mouseover', evt, this.targetShape);
shape._handleEvent('mouseenter', evt, this.targetShape);
shape._handleEvent(MOUSEOVER, evt, this.targetShape);
shape._handleEvent(MOUSEENTER, evt, this.targetShape);
this.targetShape = shape;
}
else {
shape._handleEvent('mousemove', evt);
shape._handleEvent(MOUSEMOVE, evt);
}
}
}
@@ -368,51 +400,57 @@
* if no shape was detected, clear target shape and try
* to run mouseout from previous target shape
*/
else if(this.targetShape && (!dd || !dd.moving)) {
this.targetShape._handleEvent('mouseout', evt);
this.targetShape._handleEvent('mouseleave', evt);
else if(this.targetShape && !go.isDragging()) {
this.targetShape._handleEvent(MOUSEOUT, evt);
this.targetShape._handleEvent(MOUSELEAVE, evt);
this.targetShape = null;
}
// start drag and drop
if(dd) {
dd._drag(evt);
}
},
_mousedown: function(evt) {
var obj, dd = Kinetic.DD;
this._setUserPosition(evt);
obj = this.getIntersection(this.getUserPosition());
this._setPointerPosition(evt);
var dd = Kinetic.DD,
go = Kinetic.Global,
obj = this.getIntersection(this.getPointerPosition()),
shape;
if(obj && obj.shape) {
var shape = obj.shape;
shape = obj.shape;
this.clickStart = true;
shape._handleEvent('mousedown', evt);
this.clickStartShape = shape;
shape._handleEvent(MOUSEDOWN, evt);
}
//init stage drag and drop
if(dd && this.attrs.draggable && !dd.node) {
this._startDrag(evt);
if(this.isDraggable() && !dd.node) {
this.startDrag(evt);
}
},
_mouseup: function(evt) {
this._setUserPosition(evt);
var that = this, dd = Kinetic.DD, obj = this.getIntersection(this.getUserPosition());
this._setPointerPosition(evt);
var that = this,
go = Kinetic.Global,
obj = this.getIntersection(this.getPointerPosition()),
shape;
if(obj && obj.shape) {
var shape = obj.shape;
shape._handleEvent('mouseup', evt);
shape = obj.shape;
shape._handleEvent(MOUSEUP, evt);
// detect if click or double click occurred
if(this.clickStart) {
/*
* if dragging and dropping, don't fire click or dbl click
* event
* if dragging and dropping, or if click doesn't map to
* the correct shape, don't fire click or dbl click event
*/
if(!dd || !dd.moving || !dd.node) {
shape._handleEvent('click', evt);
if(!go.isDragging() && shape._id === this.clickStartShape._id) {
shape._handleEvent(CLICK, evt);
if(this.inDoubleClickWindow) {
shape._handleEvent('dblclick', evt);
shape._handleEvent(DBL_CLICK, evt);
}
this.inDoubleClickWindow = true;
setTimeout(function() {
@@ -424,30 +462,37 @@
this.clickStart = false;
},
_touchstart: function(evt) {
var obj, dd = Kinetic.DD;
this._setPointerPosition(evt);
var dd = Kinetic.DD,
go = Kinetic.Global,
obj = this.getIntersection(this.getPointerPosition()),
shape;
this._setUserPosition(evt);
evt.preventDefault();
obj = this.getIntersection(this.getUserPosition());
if(obj && obj.shape) {
var shape = obj.shape;
shape = obj.shape;
this.tapStart = true;
shape._handleEvent('touchstart', evt);
this.tapStartShape = shape;
shape._handleEvent(TOUCHSTART, evt);
}
// init stage drag and drop
if(dd && this.attrs.draggable && !dd.node) {
this._startDrag(evt);
if(dd && !go.isDragging() && this.isDraggable()) {
this.startDrag(evt);
}
},
_touchend: function(evt) {
this._setUserPosition(evt);
var that = this, dd = Kinetic.DD, obj = this.getIntersection(this.getUserPosition());
this._setPointerPosition(evt);
var that = this,
go = Kinetic.Global,
obj = this.getIntersection(this.getPointerPosition()),
shape;
if(obj && obj.shape) {
var shape = obj.shape;
shape._handleEvent('touchend', evt);
shape = obj.shape;
shape._handleEvent(TOUCHEND, evt);
// detect if tap or double tap occurred
if(this.tapStart) {
@@ -455,11 +500,11 @@
* if dragging and dropping, don't fire tap or dbltap
* event
*/
if(!dd || !dd.moving || !dd.node) {
shape._handleEvent('tap', evt);
if(!go.isDragging() && shape._id === this.tapStartShape._id) {
shape._handleEvent(TAP, evt);
if(this.inDoubleClickWindow) {
shape._handleEvent('dbltap', evt);
shape._handleEvent(DBL_TAP, evt);
}
this.inDoubleClickWindow = true;
setTimeout(function() {
@@ -472,13 +517,16 @@
this.tapStart = false;
},
_touchmove: function(evt) {
this._setUserPosition(evt);
var dd = Kinetic.DD;
this._setPointerPosition(evt);
var dd = Kinetic.DD,
obj = this.getIntersection(this.getPointerPosition()),
shape;
evt.preventDefault();
var obj = this.getIntersection(this.getUserPosition());
if(obj && obj.shape) {
var shape = obj.shape;
shape._handleEvent('touchmove', evt);
shape = obj.shape;
shape._handleEvent(TOUCHMOVE, evt);
}
// start drag and drop
@@ -491,8 +539,9 @@
* @param {Event} evt
*/
_setMousePosition: function(evt) {
var mouseX = evt.clientX - this._getContentPosition().left;
var mouseY = evt.clientY - this._getContentPosition().top;
var mouseX = evt.clientX - this._getContentPosition().left,
mouseY = evt.clientY - this._getContentPosition().top;
this.mousePos = {
x: mouseX,
y: mouseY
@@ -503,12 +552,15 @@
* @param {Event} evt
*/
_setTouchPosition: function(evt) {
var touch, touchX, touchY;
if(evt.touches !== undefined && evt.touches.length === 1) {
// one finger
var touch = evt.touches[0];
// Get the information for finger #1
var touchX = touch.clientX - this._getContentPosition().left;
var touchY = touch.clientY - this._getContentPosition().top;
touch = evt.touches[0];
// get the information for finger #1
touchX = touch.clientX - this._getContentPosition().left;
touchY = touch.clientY - this._getContentPosition().top;
this.touchPos = {
x: touchX,
@@ -531,10 +583,10 @@
*/
_buildDOM: function() {
// content
this.content = document.createElement('div');
this.content.style.position = 'relative';
this.content.style.display = 'inline-block';
this.content.className = 'kineticjs-content';
this.content = document.createElement(DIV);
this.content.style.position = RELATIVE;
this.content.style.display = INLINE_BLOCK;
this.content.className = KINETICJS_CONTENT;
this.attrs.container.appendChild(this.content);
this.bufferCanvas = new Kinetic.SceneCanvas();
@@ -548,23 +600,14 @@
* @param {function} handler
*/
_onContent: function(typesStr, handler) {
var types = typesStr.split(' ');
for(var n = 0; n < types.length; n++) {
var baseEvent = types[n];
var types = typesStr.split(SPACE),
len = types.length,
n, baseEvent;
for(n = 0; n < len; n++) {
baseEvent = types[n];
this.content.addEventListener(baseEvent, handler, false);
}
},
/**
* set defaults
*/
_setStageDefaultProperties: function() {
this.nodeType = 'Stage';
this.dblClickWindow = 400;
this.targetShape = null;
this.mousePos = undefined;
this.clickStart = false;
this.touchPos = undefined;
this.tapStart = false;
}
};
Kinetic.Global.extend(Kinetic.Stage, Kinetic.Container);

View File

@@ -31,11 +31,11 @@
* @param {Number} [config.text.lineHeight] default is 1
* {{NodeParams}}
*/
Kinetic.Plugins.Label = function(config) {
Kinetic.Label = function(config) {
this._initLabel(config);
};
Kinetic.Plugins.Label.prototype = {
Kinetic.Label.prototype = {
_initLabel: function(config) {
var that = this,
text = null;
@@ -45,7 +45,7 @@
Kinetic.Group.call(this, config);
text = new Kinetic.Text(config.text);
this.setText(text);
this.setRect(new Kinetic.Plugins.LabelRect(config.rect));
this.setRect(new Kinetic.LabelRect(config.rect));
this.innerGroup.add(this.getRect());
this.innerGroup.add(text);
this.add(this.innerGroup);
@@ -102,15 +102,15 @@
}
};
Kinetic.Global.extend(Kinetic.Plugins.Label, Kinetic.Group);
Kinetic.Node.addGetterSetter(Kinetic.Plugins.Label, 'text');
Kinetic.Node.addGetterSetter(Kinetic.Plugins.Label, 'rect');
Kinetic.Global.extend(Kinetic.Label, Kinetic.Group);
Kinetic.Node.addGetterSetter(Kinetic.Label, 'text');
Kinetic.Node.addGetterSetter(Kinetic.Label, 'rect');
Kinetic.Plugins.LabelRect = function(config) {
Kinetic.LabelRect = function(config) {
this._initLabelRect(config);
};
Kinetic.Plugins.LabelRect.prototype = {
Kinetic.LabelRect.prototype = {
_initLabelRect: function(config) {
this.createAttrs();
Kinetic.Shape.call(this, config);
@@ -165,9 +165,9 @@
}
};
Kinetic.Global.extend(Kinetic.Plugins.LabelRect, Kinetic.Shape);
Kinetic.Node.addGetterSetter(Kinetic.Plugins.LabelRect, 'pointerDirection', NONE);
Kinetic.Node.addGetterSetter(Kinetic.Plugins.LabelRect, 'pointerWidth', 0);
Kinetic.Node.addGetterSetter(Kinetic.Plugins.LabelRect, 'pointerHeight', 0);
Kinetic.Node.addGetterSetter(Kinetic.Plugins.LabelRect, 'cornerRadius', 0);
Kinetic.Global.extend(Kinetic.LabelRect, Kinetic.Shape);
Kinetic.Node.addGetterSetter(Kinetic.LabelRect, 'pointerDirection', NONE);
Kinetic.Node.addGetterSetter(Kinetic.LabelRect, 'pointerWidth', 0);
Kinetic.Node.addGetterSetter(Kinetic.LabelRect, 'pointerHeight', 0);
Kinetic.Node.addGetterSetter(Kinetic.LabelRect, 'cornerRadius', 0);
})();

View File

@@ -9,11 +9,11 @@
* {{ShapeParams}}
* {{NodeParams}}
*/
Kinetic.Plugins.Path = function(config) {
Kinetic.Path = function(config) {
this._initPath(config);
};
Kinetic.Plugins.Path.prototype = {
Kinetic.Path.prototype = {
_initPath: function(config) {
this.dataArray = [];
var that = this;
@@ -23,9 +23,9 @@
this.shapeType = 'Path';
this._setDrawFuncs();
this.dataArray = Kinetic.Plugins.Path.parsePathData(this.attrs.data);
this.dataArray = Kinetic.Path.parsePathData(this.attrs.data);
this.on('dataChange', function() {
that.dataArray = Kinetic.Plugins.Path.parsePathData(that.attrs.data);
that.dataArray = Kinetic.Path.parsePathData(that.attrs.data);
});
},
drawFunc: function(canvas) {
@@ -72,16 +72,16 @@
canvas.fillStroke(this);
}
};
Kinetic.Global.extend(Kinetic.Plugins.Path, Kinetic.Shape);
Kinetic.Global.extend(Kinetic.Path, Kinetic.Shape);
/*
* Utility methods written by jfollas to
* handle length and point measurements
*/
Kinetic.Plugins.Path.getLineLength = function(x1, y1, x2, y2) {
Kinetic.Path.getLineLength = function(x1, y1, x2, y2) {
return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
};
Kinetic.Plugins.Path.getPointOnLine = function(dist, P1x, P1y, P2x, P2y, fromX, fromY) {
Kinetic.Path.getPointOnLine = function(dist, P1x, P1y, P2x, P2y, fromX, fromY) {
if(fromX === undefined) {
fromX = P1x;
}
@@ -129,7 +129,7 @@
return pt;
};
Kinetic.Plugins.Path.getPointOnCubicBezier = function(pct, P1x, P1y, P2x, P2y, P3x, P3y, P4x, P4y) {
Kinetic.Path.getPointOnCubicBezier = function(pct, P1x, P1y, P2x, P2y, P3x, P3y, P4x, P4y) {
function CB1(t) {
return t * t * t;
}
@@ -150,7 +150,7 @@
y: y
};
};
Kinetic.Plugins.Path.getPointOnQuadraticBezier = function(pct, P1x, P1y, P2x, P2y, P3x, P3y) {
Kinetic.Path.getPointOnQuadraticBezier = function(pct, P1x, P1y, P2x, P2y, P3x, P3y) {
function QB1(t) {
return t * t;
}
@@ -168,7 +168,7 @@
y: y
};
};
Kinetic.Plugins.Path.getPointOnEllipticalArc = function(cx, cy, rx, ry, theta, psi) {
Kinetic.Path.getPointOnEllipticalArc = function(cx, cy, rx, ry, theta, psi) {
var cosPsi = Math.cos(psi), sinPsi = Math.sin(psi);
var pt = {
x: rx * Math.cos(theta),
@@ -185,7 +185,7 @@
* L data for the purpose of high performance Path
* rendering
*/
Kinetic.Plugins.Path.parsePathData = function(data) {
Kinetic.Path.parsePathData = function(data) {
// Path Data Segment must begin with a moveTo
//m (x y)+ Relative moveTo (subsequent points are treated as lineTo)
//M (x y)+ Absolute moveTo (subsequent points are treated as lineTo)
@@ -422,9 +422,9 @@
return ca;
};
Kinetic.Plugins.Path.calcLength = function(x, y, cmd, points) {
Kinetic.Path.calcLength = function(x, y, cmd, points) {
var len, p1, p2;
var path = Kinetic.Plugins.Path;
var path = Kinetic.Path;
switch (cmd) {
case 'L':
@@ -486,7 +486,7 @@
return 0;
};
Kinetic.Plugins.Path.convertEndpointToCenterParameterization = function(x1, y1, x2, y2, fa, fs, rx, ry, psiDeg) {
Kinetic.Path.convertEndpointToCenterParameterization = function(x1, y1, x2, y2, fa, fs, rx, ry, psiDeg) {
// Derived from: http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
var psi = psiDeg * (Math.PI / 180.0);
var xp = Math.cos(psi) * (x1 - x2) / 2.0 + Math.sin(psi) * (y1 - y2) / 2.0;
@@ -543,7 +543,7 @@
return [cx, cy, rx, ry, theta, dTheta, psi, fs];
};
// add getters setters
Kinetic.Node.addGetterSetter(Kinetic.Plugins.Path, 'data');
Kinetic.Node.addGetterSetter(Kinetic.Path, 'data');
/**
* set SVG path data string. This method
@@ -551,13 +551,13 @@
* into a data array. Currently supported SVG data:
* M, m, L, l, H, h, V, v, Q, q, T, t, C, c, S, s, A, a, Z, z
* @name setData
* @methodOf Kinetic.Plugins.Path.prototype
* @methodOf Kinetic.Path.prototype
* @param {String} SVG path command string
*/
/**
* get SVG path data string
* @name getData
* @methodOf Kinetic.Plugins.Path.prototype
* @methodOf Kinetic.Path.prototype
*/
})();

View File

@@ -9,11 +9,11 @@
* {{ShapeParams}}
* {{NodeParams}}
*/
Kinetic.Plugins.RegularPolygon = function(config) {
Kinetic.RegularPolygon = function(config) {
this._initRegularPolygon(config);
};
Kinetic.Plugins.RegularPolygon.prototype = {
Kinetic.RegularPolygon.prototype = {
_initRegularPolygon: function(config) {
this.createAttrs();
@@ -36,35 +36,35 @@
canvas.fillStroke(this);
}
};
Kinetic.Global.extend(Kinetic.Plugins.RegularPolygon, Kinetic.Shape);
Kinetic.Global.extend(Kinetic.RegularPolygon, Kinetic.Shape);
// add getters setters
Kinetic.Node.addGetterSetter(Kinetic.Plugins.RegularPolygon, 'radius', 0);
Kinetic.Node.addGetterSetter(Kinetic.Plugins.RegularPolygon, 'sides', 0);
Kinetic.Node.addGetterSetter(Kinetic.RegularPolygon, 'radius', 0);
Kinetic.Node.addGetterSetter(Kinetic.RegularPolygon, 'sides', 0);
/**
* set radius
* @name setRadius
* @methodOf Kinetic.Plugins.RegularPolygon.prototype
* @methodOf Kinetic.RegularPolygon.prototype
* @param {Number} radius
*/
/**
* set number of sides
* @name setSides
* @methodOf Kinetic.Plugins.RegularPolygon.prototype
* @methodOf Kinetic.RegularPolygon.prototype
* @param {int} sides
*/
/**
* get radius
* @name getRadius
* @methodOf Kinetic.Plugins.RegularPolygon.prototype
* @methodOf Kinetic.RegularPolygon.prototype
*/
/**
* get number of sides
* @name getSides
* @methodOf Kinetic.Plugins.RegularPolygon.prototype
* @methodOf Kinetic.RegularPolygon.prototype
*/
})();

View File

@@ -10,11 +10,11 @@
* {{ShapeParams}}
* {{NodeParams}}
*/
Kinetic.Plugins.Star = function(config) {
Kinetic.Star = function(config) {
this._initStar(config);
};
Kinetic.Plugins.Star.prototype = {
Kinetic.Star.prototype = {
_initStar: function(config) {
this.createAttrs();
@@ -40,49 +40,49 @@
canvas.fillStroke(this);
}
};
Kinetic.Global.extend(Kinetic.Plugins.Star, Kinetic.Shape);
Kinetic.Global.extend(Kinetic.Star, Kinetic.Shape);
// add getters setters
Kinetic.Node.addGetterSetter(Kinetic.Plugins.Star, 'numPoints', 0);
Kinetic.Node.addGetterSetter(Kinetic.Plugins.Star, 'innerRadius', 0);
Kinetic.Node.addGetterSetter(Kinetic.Plugins.Star, 'outerRadius', 0);
Kinetic.Node.addGetterSetter(Kinetic.Star, 'numPoints', 0);
Kinetic.Node.addGetterSetter(Kinetic.Star, 'innerRadius', 0);
Kinetic.Node.addGetterSetter(Kinetic.Star, 'outerRadius', 0);
/**
* set number of points
* @name setNumPoints
* @methodOf Kinetic.Plugins.Star.prototype
* @methodOf Kinetic.Star.prototype
* @param {Integer} points
*/
/**
* set outer radius
* @name setOuterRadius
* @methodOf Kinetic.Plugins.Star.prototype
* @methodOf Kinetic.Star.prototype
* @param {Number} radius
*/
/**
* set inner radius
* @name setInnerRadius
* @methodOf Kinetic.Plugins.Star.prototype
* @methodOf Kinetic.Star.prototype
* @param {Number} radius
*/
/**
* get number of points
* @name getNumPoints
* @methodOf Kinetic.Plugins.Star.prototype
* @methodOf Kinetic.Star.prototype
*/
/**
* get outer radius
* @name getOuterRadius
* @methodOf Kinetic.Plugins.Star.prototype
* @methodOf Kinetic.Star.prototype
*/
/**
* get inner radius
* @name getInnerRadius
* @methodOf Kinetic.Plugins.Star.prototype
* @methodOf Kinetic.Star.prototype
*/
})();

View File

@@ -16,7 +16,7 @@
* {{ShapeParams}}
* {{NodeParams}}
*/
Kinetic.Plugins.TextPath = function(config) {
Kinetic.TextPath = function(config) {
this._initTextPath(config);
};
@@ -27,7 +27,7 @@
context.strokeText(this.partialText, 0, 0);
}
Kinetic.Plugins.TextPath.prototype = {
Kinetic.TextPath.prototype = {
_initTextPath: function(config) {
var that = this;
@@ -46,9 +46,9 @@
this.shapeType = 'TextPath';
this._setDrawFuncs();
this.dataArray = Kinetic.Plugins.Path.parsePathData(this.attrs.data);
this.dataArray = Kinetic.Path.parsePathData(this.attrs.data);
this.on('dataChange', function() {
that.dataArray = Kinetic.Plugins.Path.parsePathData(this.attrs.data);
that.dataArray = Kinetic.Path.parsePathData(this.attrs.data);
});
// update text data for certain attr changes
var attrs = ['text', 'textStroke', 'textStrokeWidth'];
@@ -97,7 +97,7 @@
/**
* get text width in pixels
* @name getTextWidth
* @methodOf Kinetic.Plugins.TextPath.prototype
* @methodOf Kinetic.TextPath.prototype
*/
getTextWidth: function() {
return this.textWidth;
@@ -105,7 +105,7 @@
/**
* get text height in pixels
* @name getTextHeight
* @methodOf Kinetic.Plugins.TextPath.prototype
* @methodOf Kinetic.TextPath.prototype
*/
getTextHeight: function() {
return this.textHeight;
@@ -113,7 +113,7 @@
/**
* set text
* @name setText
* @methodOf Kinetic.Plugins.TextPath.prototype
* @methodOf Kinetic.TextPath.prototype
* @param {String} text
*/
setText: function(text) {
@@ -201,8 +201,8 @@
switch (pathCmd.command) {
case 'L':
if(Kinetic.Plugins.Path.getLineLength(p0.x, p0.y, pathCmd.points[0], pathCmd.points[1]) > glyphWidth) {
p1 = Kinetic.Plugins.Path.getPointOnLine(glyphWidth, p0.x, p0.y, pathCmd.points[0], pathCmd.points[1], p0.x, p0.y);
if(Kinetic.Path.getLineLength(p0.x, p0.y, pathCmd.points[0], pathCmd.points[1]) > glyphWidth) {
p1 = Kinetic.Path.getPointOnLine(glyphWidth, p0.x, p0.y, pathCmd.points[0], pathCmd.points[1], p0.x, p0.y);
}
else
pathCmd = undefined;
@@ -227,7 +227,7 @@
currentT = end;
needNewSegment = true;
}
p1 = Kinetic.Plugins.Path.getPointOnEllipticalArc(pathCmd.points[0], pathCmd.points[1], pathCmd.points[2], pathCmd.points[3], currentT, pathCmd.points[6]);
p1 = Kinetic.Path.getPointOnEllipticalArc(pathCmd.points[0], pathCmd.points[1], pathCmd.points[2], pathCmd.points[3], currentT, pathCmd.points[6]);
break;
case 'C':
if(currentT === 0) {
@@ -245,7 +245,7 @@
currentT = 1.0;
needNewSegment = true;
}
p1 = Kinetic.Plugins.Path.getPointOnCubicBezier(currentT, pathCmd.start.x, pathCmd.start.y, pathCmd.points[0], pathCmd.points[1], pathCmd.points[2], pathCmd.points[3], pathCmd.points[4], pathCmd.points[5]);
p1 = Kinetic.Path.getPointOnCubicBezier(currentT, pathCmd.start.x, pathCmd.start.y, pathCmd.points[0], pathCmd.points[1], pathCmd.points[2], pathCmd.points[3], pathCmd.points[4], pathCmd.points[5]);
break;
case 'Q':
if(currentT === 0)
@@ -259,13 +259,13 @@
currentT = 1.0;
needNewSegment = true;
}
p1 = Kinetic.Plugins.Path.getPointOnQuadraticBezier(currentT, pathCmd.start.x, pathCmd.start.y, pathCmd.points[0], pathCmd.points[1], pathCmd.points[2], pathCmd.points[3]);
p1 = Kinetic.Path.getPointOnQuadraticBezier(currentT, pathCmd.start.x, pathCmd.start.y, pathCmd.points[0], pathCmd.points[1], pathCmd.points[2], pathCmd.points[3]);
break;
}
if(p1 !== undefined) {
currLen = Kinetic.Plugins.Path.getLineLength(p0.x, p0.y, p1.x, p1.y);
currLen = Kinetic.Path.getLineLength(p0.x, p0.y, p1.x, p1.y);
}
if(needNewSegment) {
@@ -282,7 +282,7 @@
if(p0 === undefined || p1 === undefined)
break;
var width = Kinetic.Plugins.Path.getLineLength(p0.x, p0.y, p1.x, p1.y);
var width = Kinetic.Path.getLineLength(p0.x, p0.y, p1.x, p1.y);
// Note: Since glyphs are rendered one at a time, any kerning pair data built into the font will not be used.
// Can foresee having a rough pair table built in that the developer can override as needed.
@@ -290,7 +290,7 @@
var kern = 0;
// placeholder for future implementation
var midpoint = Kinetic.Plugins.Path.getPointOnLine(kern + width / 2.0, p0.x, p0.y, p1.x, p1.y);
var midpoint = Kinetic.Path.getPointOnLine(kern + width / 2.0, p0.x, p0.y, p1.x, p1.y);
var rotation = Math.atan2((p1.y - p0.y), (p1.x - p0.x));
this.glyphInfo.push({
@@ -307,59 +307,59 @@
};
// map TextPath methods to Text
Kinetic.Plugins.TextPath.prototype._getContextFont = Kinetic.Text.prototype._getContextFont;
Kinetic.TextPath.prototype._getContextFont = Kinetic.Text.prototype._getContextFont;
Kinetic.Global.extend(Kinetic.Plugins.TextPath, Kinetic.Shape);
Kinetic.Global.extend(Kinetic.TextPath, Kinetic.Shape);
// add setters and getters
Kinetic.Node.addGetterSetter(Kinetic.Plugins.TextPath, 'fontFamily', CALIBRI);
Kinetic.Node.addGetterSetter(Kinetic.Plugins.TextPath, 'fontSize', 12);
Kinetic.Node.addGetterSetter(Kinetic.Plugins.TextPath, 'fontStyle', NORMAL);
Kinetic.Node.addGetterSetter(Kinetic.TextPath, 'fontFamily', CALIBRI);
Kinetic.Node.addGetterSetter(Kinetic.TextPath, 'fontSize', 12);
Kinetic.Node.addGetterSetter(Kinetic.TextPath, 'fontStyle', NORMAL);
Kinetic.Node.addGetter(Kinetic.Plugins.TextPath, 'text', EMPTY_STRING);
Kinetic.Node.addGetter(Kinetic.TextPath, 'text', EMPTY_STRING);
/**
* set font family
* @name setFontFamily
* @methodOf Kinetic.Plugins.TextPath.prototype
* @methodOf Kinetic.TextPath.prototype
* @param {String} fontFamily
*/
/**
* set font size
* @name setFontSize
* @methodOf Kinetic.Plugins.TextPath.prototype
* @methodOf Kinetic.TextPath.prototype
* @param {int} fontSize
*/
/**
* set font style. Can be 'normal', 'italic', or 'bold'. 'normal' is the default.
* @name setFontStyle
* @methodOf Kinetic.Plugins.TextPath.prototype
* @methodOf Kinetic.TextPath.prototype
* @param {String} fontStyle
*/
/**
* get font family
* @name getFontFamily
* @methodOf Kinetic.Plugins.TextPath.prototype
* @methodOf Kinetic.TextPath.prototype
*/
/**
* get font size
* @name getFontSize
* @methodOf Kinetic.Plugins.TextPath.prototype
* @methodOf Kinetic.TextPath.prototype
*/
/**
* get font style
* @name getFontStyle
* @methodOf Kinetic.Plugins.TextPath.prototype
* @methodOf Kinetic.TextPath.prototype
*/
/**
* get text
* @name getText
* @methodOf Kinetic.Plugins.TextPath.prototype
* @methodOf Kinetic.TextPath.prototype
*/
})();

View File

@@ -1,4 +1,8 @@
(function() {
// CONSTANTS
var IMAGE = 'Image',
CROP = 'crop';
/**
* Image constructor
* @constructor
@@ -15,38 +19,40 @@
Kinetic.Image.prototype = {
_initImage: function(config) {
var that = this;
// call super constructor
Kinetic.Shape.call(this, config);
this.shapeType = 'Image';
this.shapeType = IMAGE;
this._setDrawFuncs();
var that = this;
this.on('imageChange', function(evt) {
that._syncSize();
});
this._syncSize();
},
drawFunc: function(canvas) {
var width = this.getWidth(), height = this.getHeight(), params, that = this, context = canvas.getContext();
var width = this.getWidth(),
height = this.getHeight(),
params,
that = this,
context = canvas.getContext(),
image = this.getImage(),
crop = this.getCrop(),
cropX, cropY, cropWidth, cropHeight;
context.beginPath();
context.rect(0, 0, width, height);
context.closePath();
canvas.fillStroke(this);
if(this.attrs.image) {
if(image) {
// if cropping
if(this.attrs.crop && this.attrs.crop.width && this.attrs.crop.height) {
var cropX = this.attrs.crop.x || 0;
var cropY = this.attrs.crop.y || 0;
var cropWidth = this.attrs.crop.width;
var cropHeight = this.attrs.crop.height;
params = [this.attrs.image, cropX, cropY, cropWidth, cropHeight, 0, 0, width, height];
if(crop) {
cropX = crop.x || 0;
cropY = crop.y || 0;
cropWidth = crop.width || 0;
cropHeight = crop.height || 0;
params = [image, cropX, cropY, cropWidth, cropHeight, 0, 0, width, height];
}
// no cropping
else {
params = [this.attrs.image, 0, 0, width, height];
params = [image, 0, 0, width, height];
}
if(this.hasShadow()) {
@@ -57,12 +63,13 @@
else {
this._drawImage(context, params);
}
}
},
drawHitFunc: function(canvas) {
var width = this.getWidth(), height = this.getHeight(), imageHitRegion = this.imageHitRegion, appliedShadow = false, context = canvas.getContext();
var width = this.getWidth(),
height = this.getHeight(),
imageHitRegion = this.imageHitRegion,
context = canvas.getContext();
if(imageHitRegion) {
context.drawImage(imageHitRegion, 0, 0, width, height);
@@ -89,16 +96,20 @@
* filter has been applied
*/
applyFilter: function(filter, config, callback) {
var canvas = new Kinetic.Canvas(this.attrs.image.width, this.attrs.image.height);
var context = canvas.getContext();
context.drawImage(this.attrs.image, 0, 0);
var image = this.getImage(),
canvas = new Kinetic.Canvas({
width: image.width,
height: image.height
}),
context = canvas.getContext(),
that = this;
context.drawImage(image, 0, 0);
try {
var imageData = context.getImageData(0, 0, canvas.getWidth(), canvas.getHeight());
filter(imageData, config);
var that = this;
Kinetic.Type._getImage(imageData, function(imageObj) {
that.setImage(imageObj);
if(callback) {
callback();
}
@@ -119,11 +130,12 @@
* @param {Number} config.height
*/
setCrop: function() {
var config = [].slice.call(arguments);
var pos = Kinetic.Type._getXY(config);
var size = Kinetic.Type._getSize(config);
var both = Kinetic.Type._merge(pos, size);
this.setAttr('crop', Kinetic.Type._merge(both, this.getCrop()));
var config = [].slice.call(arguments),
pos = Kinetic.Type._getXY(config),
size = Kinetic.Type._getSize(config),
both = Kinetic.Type._merge(pos, size);
this.setAttr(CROP, Kinetic.Type._merge(both, this.getCrop()));
},
/**
* create image hit region which enables more accurate hit detection mapping of the image
@@ -134,22 +146,33 @@
* the image hit region has been created
*/
createImageHitRegion: function(callback) {
var canvas = new Kinetic.Canvas(this.attrs.width, this.attrs.height);
var context = canvas.getContext();
context.drawImage(this.attrs.image, 0, 0);
var that = this,
width = this.getWidth(),
height = this.getHeight(),
canvas = new Kinetic.Canvas({
width: width,
height: height
}),
context = canvas.getContext(),
image = this.getImage(),
imageData, data, rgbColorKey, i, n;
context.drawImage(image, 0, 0);
try {
var imageData = context.getImageData(0, 0, canvas.getWidth(), canvas.getHeight());
var data = imageData.data;
var rgbColorKey = Kinetic.Type._hexToRgb(this.colorKey);
imageData = context.getImageData(0, 0, width, height);
data = imageData.data;
rgbColorKey = Kinetic.Type._hexToRgb(this.colorKey);
// replace non transparent pixels with color key
for(var i = 0, n = data.length; i < n; i += 4) {
data[i] = rgbColorKey.r;
data[i + 1] = rgbColorKey.g;
data[i + 2] = rgbColorKey.b;
// i+3 is alpha (the fourth element)
for(i = 0, n = data.length; i < n; i += 4) {
if (data[i + 3] > 0) {
data[i] = rgbColorKey.r;
data[i + 1] = rgbColorKey.g;
data[i + 2] = rgbColorKey.b;
}
}
var that = this;
Kinetic.Type._getImage(imageData, function(imageObj) {
that.imageHitRegion = imageObj;
if(callback) {
@@ -169,15 +192,13 @@
clearImageHitRegion: function() {
delete this.imageHitRegion;
},
_syncSize: function() {
if(this.attrs.image) {
if(!this.attrs.width) {
this.setWidth(this.attrs.image.width);
}
if(!this.attrs.height) {
this.setHeight(this.attrs.image.height);
}
}
getWidth: function() {
var image = this.getImage();
return this.attrs.width || (image ? image.width : 0);
},
getHeight: function() {
var image = this.getImage();
return this.attrs.height || (image ? image.height : 0);
},
_drawImage: function(context, a) {
if(a.length === 5) {

View File

@@ -318,7 +318,7 @@
Kinetic.Node.addGetterSetter(Kinetic.Text, 'padding', 0);
Kinetic.Node.addGetterSetter(Kinetic.Text, 'align', LEFT);
Kinetic.Node.addGetterSetter(Kinetic.Text, 'lineHeight', 1);
Kinetic.Node.addGetterSetter(Kinetic.Text, 'wrap', NONE);
Kinetic.Node.addGetterSetter(Kinetic.Text, 'wrap', WORD);
Kinetic.Node.addGetter(Kinetic.Text, TEXT, EMPTY_STRING);

View File

@@ -32,20 +32,9 @@
context.closePath();
canvas.fillStroke(this);
},
/**
* set angle in degrees
* @name setAngleDeg
* @methodOf Kinetic.Wedge.prototype
* @param {Number} deg
*/
setAngleDeg: function(deg) {
this.setAngle(Kinetic.Type._degToRad(deg));
},
/**
* set angle in degrees
* @name getAngleDeg
* @methodOf Kinetic.Wedge.prototype
*/
getAngleDeg: function() {
return Kinetic.Type._radToDeg(this.getAngle());
}

View File

@@ -14,22 +14,6 @@
return this;
}
Kinetic.Collection.prototype = new Array();
/**
* apply a method to all nodes in the array
* @name apply
* @methodOf Kinetic.Collection.prototype
* @param {String} method
* @param val
*/
Kinetic.Collection.prototype.apply = function(method) {
args = [].slice.call(arguments);
args.shift();
for(var n = 0; n < this.length; n++) {
if(Kinetic.Type._isFunction(this[n][method])) {
this[n][method].apply(this[n], args);
}
}
};
/**
* iterate through node array
* @name each
@@ -38,7 +22,28 @@
*/
Kinetic.Collection.prototype.each = function(func) {
for(var n = 0; n < this.length; n++) {
func.call(this[n], n, this[n]);
func(this[n], n);
}
};
Kinetic.Collection.mapMethods = function(arr) {
var leng = arr.length,
n;
for(n = 0; n < leng; n++) {
// induce scope
(function(i) {
var method = arr[i];
Kinetic.Collection.prototype[method] = function() {
var len = this.length,
i;
args = [].slice.call(arguments);
for(i = 0; i < len; i++) {
this[i][method].apply(this[i], args);
}
};
})(n);
}
};
})();

View File

@@ -1,4 +1,13 @@
(function() {
// CONSTANTS
var CANVAS = 'canvas',
CONTEXT_2D = '2d',
OBJECT_ARRAY = '[object Array]',
OBJECT_NUMBER = '[object Number]',
OBJECT_STRING = '[object String]',
PI_OVER_DEG180 = Math.PI / 180,
DEG180_OVER_PI = 180 / Math.PI;
/*
* utilities that handle data type detection, conversion, and manipulation
*/
@@ -16,27 +25,30 @@
return (!!obj && obj.constructor == Object);
},
_isArray: function(obj) {
return Object.prototype.toString.call(obj) == '[object Array]';
return Object.prototype.toString.call(obj) == OBJECT_ARRAY;
},
_isNumber: function(obj) {
return Object.prototype.toString.call(obj) == '[object Number]';
return Object.prototype.toString.call(obj) == OBJECT_NUMBER;
},
_isString: function(obj) {
return Object.prototype.toString.call(obj) == '[object String]';
return Object.prototype.toString.call(obj) == OBJECT_STRING;
},
/*
* other utils
*/
_hasMethods: function(obj) {
var names = [];
for(var key in obj) {
if(this._isFunction(obj[key]))
var names = [],
key;
for(key in obj) {
if(this._isFunction(obj[key])) {
names.push(key);
}
}
return names.length > 0;
},
_isInDocument: function(el) {
while( el = el.parentNode) {
while(el = el.parentNode) {
if(el == document) {
return true;
}
@@ -229,6 +241,8 @@
* arg can be an image object or image data
*/
_getImage: function(arg, callback) {
var imageObj, canvas, context, dataUrl;
// if arg is null or undefined
if(!arg) {
callback(null);
@@ -241,8 +255,7 @@
// if arg is a string, then it's a data url
else if(this._isString(arg)) {
var imageObj = new Image();
/** @ignore */
imageObj = new Image();
imageObj.onload = function() {
callback(imageObj);
}
@@ -251,14 +264,13 @@
//if arg is an object that contains the data property, it's an image object
else if(arg.data) {
var canvas = document.createElement('canvas');
canvas = document.createElement(CANVAS);
canvas.width = arg.width;
canvas.height = arg.height;
var context = canvas.getContext('2d');
context = canvas.getContext(CONTEXT_2D);
context.putImageData(arg, 0, 0);
var dataUrl = canvas.toDataURL();
var imageObj = new Image();
/** @ignore */
dataUrl = canvas.toDataURL();
imageObj = new Image();
imageObj.onload = function() {
callback(imageObj);
}
@@ -280,9 +292,10 @@
};
},
_getRandomColorKey: function() {
var r = (Math.random() * 255) | 0;
var g = (Math.random() * 255) | 0;
var b = (Math.random() * 255) | 0;
var r = (Math.random() * 255) | 0,
g = (Math.random() * 255) | 0,
b = (Math.random() * 255) | 0;
return this._rgbToHex(r, g, b);
},
// o1 takes precedence over o2
@@ -312,10 +325,10 @@
return retObj;
},
_degToRad: function(deg) {
return deg * Math.PI / 180;
return deg * PI_OVER_DEG180;
},
_radToDeg: function(rad) {
return rad * 180 / Math.PI;
return rad * DEG180_OVER_PI;
},
_capitalize: function(str) {
return str.charAt(0).toUpperCase() + str.slice(1);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -12,29 +12,64 @@ function endTimer(str) {
var diff = after - before;
console.log(str + ': ' + diff + 'ms');
}
function warn(condition, message) {
test(condition, message, true);
}
function test(condition, message, warn) {
if(!condition) {
if(warn) {
if(testCounter.style.backgroundColor != 'red') {
testCounter.style.backgroundColor = 'orange';
testCounter.style.color = 'black';
}
console.warn(message + ' (NOTE: use Google Chrome for data url comparisons, run on web server for caching and filtering)');
}
else {
testCounter.style.backgroundColor = 'red';
testCounter.style.color = 'black';
throw new Error(message);
}
testCounter.style.backgroundColor = 'red';
testCounter.style.color = 'black';
throw new Error(message);
}
numTests++;
testCounter.innerHTML = numTests;
}
function warn(condition, message) {
if(!condition) {
if(testCounter.style.backgroundColor != 'red') {
testCounter.style.backgroundColor = 'orange';
testCounter.style.color = 'black';
}
console.warn(message);
}
numTests++;
testCounter.innerHTML = numTests;
}
function testDataUrl(actual, key, message) {
var expected = dataUrls[key];
if(actual !== expected) {
if(testCounter.style.backgroundColor != 'red') {
testCounter.style.backgroundColor = 'orange';
testCounter.style.color = 'black';
}
console.warn(message + ' (NOTE: use Google Chrome for data url comparisons, run on web server for caching and filtering)');
console.log('key: ' + key);
console.log('actual:');
console.log(actual);
console.log('expected:');
console.log(expected);
}
numTests++;
testCounter.innerHTML = numTests;
}
function testJSON(actual, expected, message) {
if(actual !== expected) {
if(testCounter.style.backgroundColor != 'red') {
testCounter.style.backgroundColor = 'orange';
testCounter.style.color = 'black';
}
console.warn(message + ' (NOTE: use Google Chrome for data url comparisons, run on web server for caching and filtering)');
console.log('actual:');
console.log(actual);
console.log('expected:');
console.log(expected);
}
numTests++;
testCounter.innerHTML = numTests;
}
function log(message) {
console.log('LOG: ' + message);
}

View File

@@ -1,3 +1,4 @@
Test.Modules.DD = {
'remove shape with onclick': function(containerId) {
var stage = new Kinetic.Stage({
@@ -27,7 +28,7 @@ Test.Modules.DD = {
function remove() {
circle.remove();
layer.draw();
warn(layer.toDataURL() === dataUrls['cleared'], 'canvas should be cleared after removing shape onclick');
testDataUrl(layer.toDataURL(), 'cleared', 'canvas should be cleared after removing shape onclick');
}
circle.on('click', function() {
@@ -38,13 +39,13 @@ Test.Modules.DD = {
clientX: 291,
clientY: 112 + top
});
Kinetic.DD._endDragBefore();
stage._mouseup({
clientX: 291,
clientY: 112 + top
});
// end drag is tied to document mouseup and touchend event
// which can't be simulated. call _endDrag manually
Kinetic.DD._endDrag();
Kinetic.DD._endDragAfter({dragEndNode:circle});
},
'test dragstart, dragmove, dragend': function(containerId) {
var stage = new Kinetic.Stage({
@@ -89,16 +90,17 @@ Test.Modules.DD = {
var dragEnd = false;
var mouseup = false;
var layerDragMove = false;
var events = [];
circle.on('dragstart', function() {
dragStart = true;
});
/*
circle.on('dragmove', function() {
dragMove = true;
});
*/
layer.on('dragmove', function() {
//console.log('move');
@@ -106,14 +108,18 @@ Test.Modules.DD = {
circle.on('dragend', function() {
dragEnd = true;
// test set draggable false after drag end
//this.setDraggable(false);
console.log('dragend');
events.push('dragend');
});
circle.on('mouseup', function() {
//console.log('mousup')
console.log('mouseup');
events.push('mouseup');
});
warn(layer.toDataURL() === dataUrls['drag circle before'], 'start data url is incorrect');
testDataUrl(layer.toDataURL(), 'drag circle before', 'start data url is incorrect');
/*
* simulate drag and drop
*/
@@ -136,23 +142,23 @@ Test.Modules.DD = {
//test(dragMove, 'dragmove event was not triggered');
test(!dragEnd, 'dragend event should not have been triggered');
Kinetic.DD._endDragBefore();
stage._mouseup({
clientX: 100,
clientY: 98 + top
});
// end drag is tied to document mouseup and touchend event
// which can't be simulated. call _endDrag manually
Kinetic.DD._endDrag();
Kinetic.DD._endDragAfter({dragEndNode:circle});
test(dragStart, 'dragstart event was not triggered');
//test(dragMove, 'dragmove event was not triggered');
test(dragMove, 'dragmove event was not triggered');
test(dragEnd, 'dragend event was not triggered');
test(events.toString() === 'mouseup,dragend', 'mouseup should occur before dragend');
warn(layer.toDataURL() === dataUrls['drag circle after'], 'end data url is incorrect');
testDataUrl(layer.toDataURL(), 'drag circle after', 'end data url is incorrect');
console.log(layer);
showHit(layer);
console.log(layer.eventListeners['dragmove']);
},
'cancel drag and drop by setting draggable to false': function(containerId) {
var stage = new Kinetic.Stage({
@@ -210,13 +216,12 @@ Test.Modules.DD = {
clientY: 100 + top
});
Kinetic.DD._endDragBefore();
stage._mouseup({
clientX: 100,
clientY: 100 + top
});
// end drag is tied to document mouseup and touchend event
// which can't be simulated. call _endDrag manually
Kinetic.DD._endDrag();
Kinetic.DD._endDragAfter({dragEndNode:circle});
test(circle.getPosition().x === 380, 'circle x should be 380');
test(circle.getPosition().y === 100, 'circle y should be 100');
@@ -264,7 +269,7 @@ Test.Modules.DD = {
var top = stage.content.getBoundingClientRect().top;
//console.log(layer.toDataURL())
warn(layer.toDataURL() === dataUrls['drag layer before'], 'start data url is incorrect');
testDataUrl(layer.toDataURL(), 'drag layer before', 'start data url is incorrect');
/*
* simulate drag and drop
@@ -279,21 +284,176 @@ Test.Modules.DD = {
clientY: 109 + top
});
Kinetic.DD._endDragBefore();
stage._mouseup({
clientX: 210,
clientY: 109 + top
});
// end drag is tied to document mouseup and touchend event
// which can't be simulated. call _endDrag manually
Kinetic.DD._endDrag();
Kinetic.DD._endDragAfter({dragEndNode:circle2});
//console.log(layer.toDataURL())
warn(layer.toDataURL() === dataUrls['drag layer after'], 'end data url is incorrect');
testDataUrl(layer.toDataURL(), 'drag layer after', 'end data url is incorrect');
}
};
Test.Modules.EVENT = {
'draw events': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
height: 200,
throttle: 999
});
var layer = new Kinetic.Layer();
var circle = new Kinetic.Circle({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
radius: 70,
fill: 'red'
});
var eventNodes = [];
var savedEvt;
var order = [];
layer.on('draw', function(evt) {
savedEvt = evt;
eventNodes.push(this.getNodeType());
order.push('layer draw');
});
stage.on('draw', function(evt) {
eventNodes.push(this.getNodeType());
order.push('stage draw');
});
layer.on('beforeDraw', function(evt) {
order.push('layer beforeDraw');
});
stage.on('beforeDraw', function(evt) {
order.push('stage beforeDraw');
});
layer.add(circle);
stage.add(layer);
test(eventNodes.toString() === 'Layer,Stage', 'layer draw event should have fired followed by stage draw event');
test(savedEvt.node.getNodeType() === 'Layer', 'event object should contain a node property which is Layer');
test(order.toString() === 'layer beforeDraw,stage beforeDraw,layer draw,stage draw', 'order should be: layer beforeDraw,stage beforeDraw,layer draw,stage draw');
},
'click mapping': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
height: 200,
throttle: 999
});
var layer = new Kinetic.Layer({
drawFunc: function() {
var context = this.getContext();
context.beginPath();
context.moveTo(200, 50);
context.lineTo(420, 80);
context.quadraticCurveTo(300, 100, 260, 170);
context.closePath();
context.fillStyle = 'blue';
context.fill(context);
}
});
var redCircle = new Kinetic.Circle({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
radius: 70,
fill: 'red'
});
var greenCircle = new Kinetic.Circle({
x: 400,
y: stage.getHeight() / 2,
radius: 70,
fill: 'green'
});
var redClicks = 0;
var greenClicks = 0;
redCircle.on('click', function() {
console.log('clicked redCircle');
redClicks++;
});
greenCircle.on('click', function() {
console.log('clicked greenCircle');
greenClicks++;
});
layer.add(redCircle);
layer.add(greenCircle);
stage.add(layer);
var top = stage.content.getBoundingClientRect().top;
showHit(layer);
// mousedown and mouseup on red circle
stage._mousedown({
clientX: 284,
clientY: 113 + top
});
Kinetic.DD._endDragBefore();
stage._mouseup({
clientX: 284,
clientY: 113 + top
});
Kinetic.DD._endDragAfter({dragEndNode:redCircle});
test(redClicks === 1, 'red circle should have 1 click');
test(greenClicks === 0, 'green circle should have 0 clicks');
// mousedown and mouseup on green circle
stage._mousedown({
clientX: 397,
clientY: 108 + top
});
Kinetic.DD._endDragBefore();
stage._mouseup({
clientX: 397,
clientY: 108 + top
});
Kinetic.DD._endDragAfter({dragEndNode:redCircle});
test(redClicks === 1, 'red circle should have 1 click');
test(greenClicks === 1, 'green circle should have 1 click');
// mousedown red circle and mouseup on green circle
stage._mousedown({
clientX: 284,
clientY: 113 + top
});
Kinetic.DD._endDragBefore();
stage._mouseup({
clientX: 397,
clientY: 108 + top
});
Kinetic.DD._endDragAfter({dragEndNode:redCircle});
test(redClicks === 1, 'red circle should still have 1 click');
test(greenClicks === 1, 'green circle should still have 1 click');
},
'text events': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
@@ -315,6 +475,7 @@ Test.Modules.EVENT = {
var click = false
text.on('click', function() {
console.log('text click');
click = true;
});
@@ -326,17 +487,18 @@ Test.Modules.EVENT = {
showHit(layer);
stage._mousedown({
clientX: 291,
clientY: 112 + top
clientX: 300,
clientY: 120 + top
});
stage._mouseup({
clientX: 291,
clientY: 112 + top
});
// end drag is tied to document mouseup and touchend event
// which can't be simulated. call _endDrag manually
Kinetic.DD._endDrag();
Kinetic.DD._endDragBefore();
stage._mouseup({
clientX: 300,
clientY: 120 + top
});
Kinetic.DD._endDragAfter({dragEndNode:text});
//TODO: can't get this to pass
test(click, 'click event should have been fired when mousing down and then up on text');
},
@@ -380,14 +542,14 @@ Test.Modules.EVENT = {
var top = stage.content.getBoundingClientRect().top;
warn(layer.toDataURL() === dataUrls['modify fill and stroke before'], 'start data url is incorrect');
testDataUrl(layer.toDataURL(), 'modify fill and stroke before', 'start data url is incorrect');
stage._mousemove({
clientX: 377,
clientY: 101 + top
});
warn(layer.toDataURL() === dataUrls['modify fill and stroke after'], 'mid data url is incorrect');
testDataUrl(layer.toDataURL(), 'modify fill and stroke after', 'mid data url is incorrect');
// move mouse back out of circle
stage._mousemove({
@@ -399,7 +561,7 @@ Test.Modules.EVENT = {
clientY: 138 + top
});
warn(layer.toDataURL() === dataUrls['modify fill and stroke before'], 'end data url is incorrect');
testDataUrl(layer.toDataURL(), 'modify fill and stroke before', 'end data url is incorrect');
},
'mousedown mouseup mouseover mouseout mousemove click dblclick / touchstart touchend touchmove tap dbltap': function(containerId) {
var stage = new Kinetic.Stage({
@@ -544,13 +706,12 @@ Test.Modules.EVENT = {
test(!mouseout, '3) mouseout should be false');
// mouseup inside circle
Kinetic.DD._endDragBefore();
stage._mouseup({
clientX: 290,
clientY: 100 + top
});
// end drag is tied to document mouseup and touchend event
// which can't be simulated. call _endDrag manually
Kinetic.DD._endDrag();
Kinetic.DD._endDragAfter({dragEndNode:circle});
test(mouseover, '4) mouseover should be true');
test(mousemove, '4) mousemove should be true');
@@ -575,13 +736,12 @@ Test.Modules.EVENT = {
test(!mouseout, '5) mouseout should be false');
// mouseup inside circle to trigger double click
Kinetic.DD._endDragBefore();
stage._mouseup({
clientX: 290,
clientY: 100 + top
});
// end drag is tied to document mouseup and touchend event
// which can't be simulated. call _endDrag manually
Kinetic.DD._endDrag();
Kinetic.DD._endDragAfter({dragEndNode:circle});
test(mouseover, '6) mouseover should be true');
test(mousemove, '6) mousemove should be true');
@@ -638,7 +798,7 @@ Test.Modules.EVENT = {
});
// end drag is tied to document mouseup and touchend event
// which can't be simulated. call _endDrag manually
Kinetic.DD._endDrag();
//Kinetic.DD._endDrag();
test(touchstart, '9) touchstart should be true');
test(!touchmove, '9) touchmove should be false');
@@ -669,7 +829,7 @@ Test.Modules.EVENT = {
});
// end drag is tied to document mouseup and touchend event
// which can't be simulated. call _endDrag manually
Kinetic.DD._endDrag();
//Kinetic.DD._endDrag();
test(touchstart, '11) touchstart should be true');
test(!touchmove, '11) touchmove should be false');
@@ -990,13 +1150,12 @@ Test.Modules.EVENT = {
clientX: 374,
clientY: 114 + top
});
Kinetic.DD._endDragBefore();
stage._mouseup({
clientX: 374,
clientY: 114 + top
});
// end drag is tied to document mouseup and touchend event
// which can't be simulated. call _endDrag manually
Kinetic.DD._endDrag();
Kinetic.DD._endDragAfter({dragEndNode:circle});
test(e.toString() === 'circle,group1,group2,layer,stage', 'problem with event bubbling');
}
@@ -1051,25 +1210,28 @@ Test.Modules['HIT FUNCS'] = {
clientY: 112 + top
});
test(mouseovers === 0, 'mouseovers should be 0');
test(mouseouts === 0, 'mouseouts should be 0');
test(mouseovers === 0, '1) mouseovers should be 0');
test(mouseouts === 0, '1) mouseouts should be 0');
stage._mousemove({
clientX: 286,
clientY: 118 + top
});
test(mouseovers === 1, 'mouseovers should be 1');
test(mouseouts === 0, 'mouseouts should be 0');
test(mouseovers === 1, '2) mouseovers should be 1');
test(mouseouts === 0, '2)mouseouts should be 0');
stage._mousemove({
clientX: 113,
clientY: 112 + top
});
test(mouseovers === 1, 'mouseovers should be 1');
test(mouseouts === 1, 'mouseouts should be 1');
test(mouseovers === 1, '3) mouseovers should be 1');
test(mouseouts === 1, '3) mouseouts should be 1');
showHit(layer);
// set drawBufferFunc with setter
circle.setDrawHitFunc(function(canvas) {
@@ -1081,32 +1243,34 @@ Test.Modules['HIT FUNCS'] = {
canvas.stroke(this);
});
layer.getHitCanvas().clear();
layer.drawHit();
// move mouse far outside circle
stage._mousemove({
clientX: 113,
clientY: 112 + top
});
test(mouseovers === 1, 'mouseovers should be 1');
test(mouseouts === 1, 'mouseouts should be 1');
test(mouseovers === 1, '4) mouseovers should be 1');
test(mouseouts === 1, '4) mouseouts should be 1');
stage._mousemove({
clientX: 286,
clientY: 118 + top
});
test(mouseovers === 1, 'mouseovers should be 1');
test(mouseouts === 1, 'mouseouts should be 1');
test(mouseovers === 1, '5) mouseovers should be 1');
test(mouseouts === 1, '5) mouseouts should be 1');
stage._mousemove({
clientX: 321,
clientY: 112 + top
});
test(mouseovers === 1, 'mouseovers should be 1');
test(mouseouts === 1, 'mouseouts should be 1');
test(mouseovers === 1, '6) mouseovers should be 1');
test(mouseouts === 1, '6) mouseouts should be 1');
// move to center of circle
stage._mousemove({
@@ -1114,7 +1278,8 @@ Test.Modules['HIT FUNCS'] = {
clientY: 112 + top
});
test(mouseovers === 2, 'mouseovers should be 2');
test(mouseouts === 1, 'mouseouts should be 1');
test(mouseovers === 2, '7) mouseovers should be 2');
test(mouseouts === 1, '7) mouseouts should be 1');
}
};

View File

@@ -331,7 +331,7 @@ Test.Modules.EVENTS = {
});
var layer = new Kinetic.Layer();
var star = new Kinetic.Plugins.Star({
var star = new Kinetic.Star({
x: 200,
y: 100,
numPoints: 10,
@@ -404,7 +404,7 @@ Test.Modules.EVENTS = {
var layer = new Kinetic.Layer({
rotationDeg: 20
});
var star = new Kinetic.Plugins.Star({
var star = new Kinetic.Star({
x: 200,
y: 100,
numPoints: 10,
@@ -788,7 +788,7 @@ Test.Modules.DRAG_AND_DROP = {
});
var layer = new Kinetic.Layer();
var star = new Kinetic.Plugins.Star({
var star = new Kinetic.Star({
x: 200,
y: 100,
numPoints: 5,
@@ -1355,12 +1355,13 @@ Test.Modules.DRAG_AND_DROP = {
'stage and shape draggable': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
draggable: true,
width: 578,
height: 200,
draggable: true
height: 200
});
var layer = new Kinetic.Layer({
draggable: true
});
var layer = new Kinetic.Layer();
var group = new Kinetic.Group();
var rect = new Kinetic.Rect({
x: 150,
@@ -1369,8 +1370,7 @@ Test.Modules.DRAG_AND_DROP = {
height: 50,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
draggable: true,
strokeWidth: 4
});
var rect2 = new Kinetic.Rect({

View File

@@ -528,7 +528,7 @@ Test.Modules.PERFORMANCE = {
startTimer();
for(var n = 0; n < 1000; n++) {
var star = new Kinetic.Plugins.Star({
var star = new Kinetic.Star({
innerRadius: 20,
outerRadius: 50,
fill: 'yellow',
@@ -560,7 +560,7 @@ Test.Modules.PERFORMANCE = {
});
var layer = new Kinetic.Layer();
var star = new Kinetic.Plugins.Star({
var star = new Kinetic.Star({
innerRadius: 20,
outerRadius: 50,
fill: 'yellow',

View File

@@ -156,12 +156,14 @@ Test.Modules.CONTAINER = {
test(shapes.length === 2, 'shapes array should have 2 elements');
shapes.apply('setX', 200);
shapes.each(function(node) {
node.setX(200);
});
layer.draw();
shapes.each(function() {
test(this.getX() === 200, 'shape x should be 200');
shapes.each(function(node) {
test(node.getX() === 200, 'shape x should be 200');
});
},
'set fill on array by Shape-selector': function(containerId) {
@@ -200,12 +202,14 @@ Test.Modules.CONTAINER = {
test(shapes.length === 2, 'shapes array should have 2 elements');
shapes.apply('setFill', 'gray');
shapes.each(function(node) {
node.setFill('gray');
});
layer.draw();
shapes.each(function() {
test(this.getFill() === 'gray', 'shape x should be 200');
shapes.each(function(node) {
test(node.getFill() === 'gray', 'shape x should be 200');
});
},
'add listener to an array of nodes': function(containerId) {
@@ -517,7 +521,7 @@ Test.Modules.CONTAINER = {
fill: 'red'
});
var textpath = new Kinetic.Plugins.TextPath({
var textpath = new Kinetic.TextPath({
y: 35,
stroke: 'black',
strokeWidth: 1,
@@ -528,7 +532,7 @@ Test.Modules.CONTAINER = {
data: "M 10,10 300,150 550,150"
});
var path = new Kinetic.Plugins.Path({
var path = new Kinetic.Path({
x: 200,
y: -75,
data: 'M200,100h100v50z',
@@ -541,7 +545,7 @@ Test.Modules.CONTAINER = {
shadowOpacity: 0.5
});
var poly = new Kinetic.Plugins.RegularPolygon({
var poly = new Kinetic.RegularPolygon({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
sides: 5,
@@ -606,7 +610,7 @@ Test.Modules.CONTAINER = {
stage.toDataURL({
callback: function(dataUrl) {
//console.log(dataUrl)
warn(dataUrl === dataUrls['node shape type selector'], 'problem with node and shape type selector render.');
testDataUrl(dataUrl,'node shape type selector', 'problem with node and shape type selector render.');
}
});
},
@@ -856,7 +860,7 @@ Test.Modules.CONTAINER = {
blueLayer.setZIndex(1);
console.log(greenLayer.getZIndex());
//console.log(greenLayer.getZIndex());
test(greenLayer.getZIndex() === 0, 'green layer should have z index of 0');
test(blueLayer.getZIndex() === 1, 'blue layer should have z index of 1');
@@ -864,7 +868,7 @@ Test.Modules.CONTAINER = {
stage.toDataURL({
callback: function(dataUrl) {
//console.log(dataUrl)
warn(dataUrls['blue on top of green'] === dataUrl, 'layer setZIndex is not working');
testDataUrl(dataUrl, 'blue on top of green', 'layer setZIndex is not working');
}
});
},
@@ -905,7 +909,7 @@ Test.Modules.CONTAINER = {
stage.toDataURL({
callback: function(dataUrl) {
warn(dataUrls['blue on top of green'] === dataUrl, 'layer moveToTop is not working');
testDataUrl(dataUrl, 'blue on top of green', 'layer moveToTop is not working');
}
});
},
@@ -946,7 +950,7 @@ Test.Modules.CONTAINER = {
stage.toDataURL({
callback: function(dataUrl) {
warn(dataUrls['blue on top of green'] === dataUrl, 'layer moveToBottom is not working');
testDataUrl(dataUrl, 'blue on top of green', 'layer moveToBottom is not working');
}
});
},
@@ -986,7 +990,7 @@ Test.Modules.CONTAINER = {
stage.toDataURL({
callback: function(dataUrl) {
warn(dataUrls['blue on top of green'] === dataUrl, 'layer moveDown is not working');
testDataUrl(dataUrl, 'blue on top of green', 'layer moveDown is not working');
}
});
},
@@ -1026,7 +1030,7 @@ Test.Modules.CONTAINER = {
stage.toDataURL({
callback: function(dataUrl) {
warn(dataUrls['blue on top of green'] === dataUrl, 'layer moveUp is not working');
testDataUrl(dataUrl, 'blue on top of green', 'layer moveUp is not working');
}
});
},

View File

@@ -22,8 +22,6 @@ Test.Modules.LAYER = {
var style = layer.getCanvas().getElement().style;
console.log('--' + style.display);
test(style.position === 'absolute', 'canvas position style should be absolute');
test(style.border === '0px', 'canvas border style should be 0px');
test(style.margin === '0px', 'canvas margin style should be 0px');
@@ -104,6 +102,7 @@ Test.Modules.LAYER = {
warn(dataUrls['stacked green circles'] === dataUrl, 'stacked green circles stage data url is incorrect');
}
});
warn(dataUrls['stacked green circles'] === layer.toDataURL(), 'stacked green circles layer data url is incorrect');
},

View File

@@ -124,7 +124,7 @@ Test.Modules.NODE = {
var dataUrl = layer.toDataURL();
warn(dataUrl === dataUrls['group to image'], 'group to image data url is incorrect');
testDataUrl(dataUrl, 'group to image', 'group to image data url is incorrect');
}
});
@@ -367,7 +367,7 @@ Test.Modules.NODE = {
//console.log(layer.toDataURL());
warn(layer.toDataURL() === dataUrls['clone group'], 'problem cloning group');
testDataUrl(layer.toDataURL(), 'clone group', 'problem cloning group');
},
'test on attr change': function(containerId) {
@@ -736,7 +736,7 @@ Test.Modules.NODE = {
layer.draw();
//console.log(layer.toDataURL());
warn(dataUrls['regular and cached polygon'] === layer.toDataURL(), 'regular and cached polygon layer data url is incorrect');
testDataUrl(layer.toDataURL(), 'regular and cached polygon', 'regular and cached polygon layer data url is incorrect');
});
}
@@ -839,7 +839,7 @@ Test.Modules.NODE = {
var dataUrl = layer.toDataURL();
//console.log(dataUrl);
warn(dataUrl === dataUrls['cache shape, group, layer, and stage'], 'problem caching shape, group, layer, and stage');
testDataUrl(dataUrl, 'cache shape, group, layer, and stage', 'problem caching shape, group, layer, and stage');
}
});
@@ -2013,12 +2013,11 @@ Test.Modules.NODE = {
group.add(circle);
layer.draw();
var expectedJson = '{"attrs":{"width":578,"height":200,"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false},"nodeType":"Stage","children":[{"attrs":{"clearBeforeDraw":true,"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false},"nodeType":"Layer","children":[{"attrs":{"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false},"nodeType":"Group","children":[{"attrs":{"radius":70,"visible":true,"listening":true,"name":"myCircle","opacity":1,"x":289,"y":100,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":true,"fill":"green","stroke":"black","strokeWidth":4},"nodeType":"Shape","shapeType":"Circle"}]}]}]}';
var expectedJson = '{"attrs":{"width":578,"height":200},"nodeType":"Stage","children":[{"attrs":{},"nodeType":"Layer","children":[{"attrs":{},"nodeType":"Group","children":[{"attrs":{"x":289,"y":100,"radius":70,"fill":"green","stroke":"black","strokeWidth":4,"name":"myCircle","draggable":true},"nodeType":"Shape","shapeType":"Circle"}]}]}]}';
//console.log(stage.toJSON())
//console.log(expectedJson);
//test(stage.toJSON() === expectedJson, 'problem with serialization');
testJSON(stage.toJSON(), expectedJson, 'problem with serialization');
},
'serialize shape': function(containerId) {
var stage = new Kinetic.Stage({
@@ -2044,18 +2043,16 @@ Test.Modules.NODE = {
group.add(circle);
layer.draw();
var expectedJson = '{"attrs":{"radius":70,"visible":true,"listening":true,"name":"myCircle","opacity":1,"x":289,"y":100,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":true,"fill":"green","stroke":"black","strokeWidth":4},"nodeType":"Shape","shapeType":"Circle"}';
var expectedJson = '{"attrs":{"x":289,"y":100,"radius":70,"fill":"green","stroke":"black","strokeWidth":4,"name":"myCircle","draggable":true},"nodeType":"Shape","shapeType":"Circle"}';
//console.log(circle.toJSON())
//console.log(expectedJson);
//test(circle.toJSON() === expectedJson, 'problem with serialization');
testJSON(circle.toJSON(), expectedJson, 'problem with serialization');
},
'load stage using json': function(containerId) {
var json = '{"attrs":{"width":578,"height":200,"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false},"nodeType":"Stage","children":[{"attrs":{"clearBeforeDraw":true,"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false},"nodeType":"Layer","children":[{"attrs":{"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false},"nodeType":"Group","children":[{"attrs":{"radius":70,"visible":true,"listening":true,"name":"myCircle","opacity":1,"x":289,"y":100,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":true,"fill":"green","stroke":"black","strokeWidth":4},"nodeType":"Shape","shapeType":"Circle"}]}]}]}';
var json = '{"attrs":{"width":578,"height":200},"nodeType":"Stage","children":[{"attrs":{},"nodeType":"Layer","children":[{"attrs":{},"nodeType":"Group","children":[{"attrs":{"x":289,"y":100,"radius":70,"fill":"green","stroke":"black","strokeWidth":4,"name":"myCircle","draggable":true},"nodeType":"Shape","shapeType":"Circle"}]}]}]}';
var stage = Kinetic.Node.create(json, containerId);
//test(stage.toJSON() === json, "problem loading stage with json");
testJSON(stage.toJSON(), json, 'problem loading stage with json');
},
'serialize stage with custom shape': function(containerId) {
var stage = new Kinetic.Stage({
@@ -2090,23 +2087,18 @@ Test.Modules.NODE = {
var startDataUrl = layer.toDataURL();
warn(startDataUrl === dataUrls['serialize stage with custom shape'], 'start data url is incorrect');
//test(triangle.getId() === 'myTriangle', 'triangle id should be myTriangle');
testDataUrl(startDataUrl, 'serialize stage with custom shape', 'start data url is incorrect');
test(triangle.getId() === 'myTriangle', 'triangle id should be myTriangle');
//console.log(stage.toJSON());
var expectedJson = '{"attrs":{"width":578,"height":200,"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false},"nodeType":"Stage","children":[{"attrs":{"clearBeforeDraw":true,"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false},"nodeType":"Layer","children":[{"attrs":{"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false},"nodeType":"Group","children":[{"attrs":{"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false,"fill":"#00D2FF","stroke":"black","strokeWidth":4,"id":"myTriangle"},"nodeType":"Shape"}]}]}]}';
var expectedJson = '{"attrs":{"width":578,"height":200},"nodeType":"Stage","children":[{"attrs":{},"nodeType":"Layer","children":[{"attrs":{},"nodeType":"Group","children":[{"attrs":{"fill":"#00D2FF","stroke":"black","strokeWidth":4,"id":"myTriangle"},"nodeType":"Shape"}]}]}]}';
//console.log(stage.toJSON())
//test(stage.toJSON() === expectedJson, "problem serializing stage with custom shape");
testJSON(stage.toJSON(), expectedJson, 'problem serializing stage with custom shape');
/*
* test redrawing layer after serialization
* drawing should be the same
*/
layer.draw();
var endDataUrl = layer.toDataURL();
warn(endDataUrl === dataUrls['serialize stage with custom shape'], 'end data url is incorrect');
testDataUrl(endDataUrl,'serialize stage with custom shape', 'end data url is incorrect');
},
'load stage with custom shape using json': function(containerId) {
@@ -2120,15 +2112,17 @@ Test.Modules.NODE = {
canvas.fill(this);
canvas.stroke(this);
};
var json = '{"attrs":{"width":578,"height":200,"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false},"nodeType":"Stage","children":[{"attrs":{"clearBeforeDraw":true,"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false},"nodeType":"Layer","children":[{"attrs":{"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false},"nodeType":"Group","children":[{"attrs":{"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false,"fill":"#00D2FF","stroke":"black","strokeWidth":4,"id":"myTriangle"},"nodeType":"Shape"}]}]}]}';
var json = '{"attrs":{"width":578,"height":200},"nodeType":"Stage","children":[{"attrs":{},"nodeType":"Layer","children":[{"attrs":{},"nodeType":"Group","children":[{"attrs":{"fill":"#00D2FF","stroke":"black","strokeWidth":4,"id":"myTriangle"},"nodeType":"Shape"}]}]}]}';
var stage = Kinetic.Node.create(json, containerId);
stage.get('#myTriangle').apply('setDrawFunc', drawTriangle);
stage.get('#myTriangle').each(function(node) {
node.setDrawFunc(drawTriangle);
});
stage.draw();
//console.log(stage.toJSON());
//test(stage.toJSON() === json, "problem loading stage with custom shape json");
testJSON(stage.toJSON(), json, 'problem loading stage with custom shape json');
},
'serialize stage with an image': function(containerId) {
var imageObj = new Image();
@@ -2152,20 +2146,22 @@ Test.Modules.NODE = {
layer.add(darth);
stage.add(layer);
var expectedJson = '{"attrs":{"width":578,"height":200,"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false},"nodeType":"Stage","children":[{"attrs":{"clearBeforeDraw":true,"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false},"nodeType":"Layer","children":[{"attrs":{"visible":true,"listening":true,"opacity":1,"x":200,"y":60,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":50,"y":150},"draggable":false,"id":"darth","width":438,"height":300},"nodeType":"Shape","shapeType":"Image"}]}]}';
//console.log(stage.toJSON())
//test(stage.toJSON() === expectedJson, 'problem with serializing stage with image');
var expectedJson = '{"attrs":{"width":578,"height":200},"nodeType":"Stage","children":[{"attrs":{},"nodeType":"Layer","children":[{"attrs":{"x":200,"y":60,"offset":{"x":50,"y":150},"id":"darth"},"nodeType":"Shape","shapeType":"Image"}]}]}';
testJSON(stage.toJSON(), expectedJson, 'problem with serializing stage with image');
};
imageObj.src = '../assets/darth-vader.jpg';
},
'load stage with an image': function(containerId) {
var imageObj = new Image();
imageObj.onload = function() {
var json = '{"attrs":{"width":578,"height":200,"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false},"nodeType":"Stage","children":[{"attrs":{"clearBeforeDraw":true,"visible":true,"listening":true,"opacity":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":0,"y":0},"draggable":false},"nodeType":"Layer","children":[{"attrs":{"visible":true,"listening":true,"opacity":1,"x":200,"y":60,"scale":{"x":1,"y":1},"rotation":0,"offset":{"x":50,"y":150},"draggable":false,"id":"darth","width":438,"height":300},"nodeType":"Shape","shapeType":"Image"}]}]}';
var json = '{"attrs":{"width":578,"height":200},"nodeType":"Stage","children":[{"attrs":{},"nodeType":"Layer","children":[{"attrs":{"x":200,"y":60,"offset":{"x":50,"y":150},"id":"darth"},"nodeType":"Shape","shapeType":"Image"}]}]}';
var stage = Kinetic.Node.create(json, containerId);
//test(stage.toJSON(), json, 'problem loading stage json with image');
stage.get('#darth').apply('setImage', imageObj);
testJSON(stage.toJSON(), json, 'problem loading stage json with image');
stage.get('#darth').each(function(node) {
node.setImage(imageObj);
});
stage.draw();
};
imageObj.src = '../assets/darth-vader.jpg';
@@ -2547,7 +2543,7 @@ Test.Modules.NODE = {
rect.destroy();
//test(!rect.transAnim.isRunning(), 'rect trans should not be running after destroying it');
layer.draw();
warn(layer.toDataURL() === dataUrls['cleared'], 'transitioning rectangle should have been destroyed and removed from the screen');
testDataUrl(layer.toDataURL(), 'cleared', 'transitioning rectangle should have been destroyed and removed from the screen');
}, 1000);
},
'hide stage': function(containerId) {
@@ -2617,7 +2613,7 @@ Test.Modules.NODE = {
layer.hide();
layer.draw();
console.log(layer.toDataURL());
//console.log(layer.toDataURL());
test(layer.toDataURL() === dataUrls['cleared'], 'layer is still visible');
},
@@ -2654,5 +2650,40 @@ Test.Modules.NODE = {
layer.draw();
test(layer.toDataURL() === dataUrls['cleared'], 'group is still visible');
},
'test getNodeType()': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var group = new Kinetic.Group();
var rect = new Kinetic.Rect({
x: 200,
y: 100,
width: 100,
height: 50,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
draggable: true,
rotationDeg: 60,
scale: {
x: 2,
y: 1
}
});
group.add(rect);
layer.add(group);
stage.add(layer);
test(stage.getNodeType() === 'Stage', 'node type should be Stage');
test(layer.getNodeType() === 'Layer', 'node type should be Layer');
test(group.getNodeType() === 'Group', 'node type should be Group');
test(rect.getNodeType() === 'Shape', 'node type should be Shape');
}
};

View File

@@ -7,7 +7,7 @@ Test.Modules.LABEL = {
});
var layer = new Kinetic.Layer();
var label = new Kinetic.Plugins.Label({
var label = new Kinetic.Label({
x: 100,
y: 100,
draggable: true,
@@ -51,5 +51,7 @@ Test.Modules.LABEL = {
label.getText().setText('Hello big world');
layer.draw();
test(label.getNodeType() === 'Group', 'label should be a group');
}
};

File diff suppressed because one or more lines are too long

View File

@@ -7,7 +7,7 @@ Test.Modules.REGULAR_POLYGON = {
});
var layer = new Kinetic.Layer();
var poly = new Kinetic.Plugins.RegularPolygon({
var poly = new Kinetic.RegularPolygon({
x: 200,
y: 100,
sides: 3,
@@ -24,6 +24,8 @@ Test.Modules.REGULAR_POLYGON = {
layer.add(poly);
stage.add(layer);
test(poly.getShapeType() === 'RegularPolygon', 'shape type should be RegularPolygon');
},
'add regular polygon square': function(containerId) {
@@ -34,7 +36,7 @@ Test.Modules.REGULAR_POLYGON = {
});
var layer = new Kinetic.Layer();
var poly = new Kinetic.Plugins.RegularPolygon({
var poly = new Kinetic.RegularPolygon({
x: 200,
y: 100,
sides: 4,
@@ -56,7 +58,7 @@ Test.Modules.REGULAR_POLYGON = {
});
var layer = new Kinetic.Layer();
var poly = new Kinetic.Plugins.RegularPolygon({
var poly = new Kinetic.RegularPolygon({
x: 200,
y: 100,
sides: 5,
@@ -78,7 +80,7 @@ Test.Modules.REGULAR_POLYGON = {
});
var layer = new Kinetic.Layer();
var poly = new Kinetic.Plugins.RegularPolygon({
var poly = new Kinetic.RegularPolygon({
x: 200,
y: 100,
sides: 8,

View File

@@ -7,7 +7,7 @@ Test.Modules.STAR = {
});
var layer = new Kinetic.Layer();
var star = new Kinetic.Plugins.Star({
var star = new Kinetic.Star({
x: 200,
y: 100,
numPoints: 5,
@@ -29,6 +29,8 @@ Test.Modules.STAR = {
layer.add(star);
stage.add(layer);
test(star.getShapeType() === 'Star', 'shape type should be Star');
},
'add five point star with line join and shadow': function(containerId) {
var stage = new Kinetic.Stage({
@@ -46,7 +48,7 @@ Test.Modules.STAR = {
fill: 'red'
});
var star = new Kinetic.Plugins.Star({
var star = new Kinetic.Star({
x: 200,
y: 100,
numPoints: 5,

File diff suppressed because one or more lines are too long

View File

@@ -24,7 +24,7 @@ Test.Modules.SHAPE = {
//console.log(layer.toDataURL());
warn(layer.toDataURL() === dataUrls['scaled rect with disabled stroke scale'], 'probem with stroke scale disabling');
testDataUrl(layer.toDataURL(), 'scaled rect with disabled stroke scale', 'probem with stroke scale disabling');
},
'test intersects()': function(containerId) {
var stage = new Kinetic.Stage({
@@ -113,7 +113,7 @@ Test.Modules.SHAPE = {
var dataUrl = layer.toDataURL();
//console.log(dataUrl);
warn(dataUrl === dataUrls['custom shape with two fills and strokes'], 'problem with custom shape with two fills');
testDataUrl(dataUrl, 'custom shape with two fills and strokes', 'problem with custom shape with two fills');
},
'custom shape with fill, stroke, and strokeWidth': function(containerId) {
@@ -208,7 +208,7 @@ Test.Modules.SHAPE = {
var dataUrl = layer.toDataURL();
//console.log(dataUrl);
warn(dataUrls['change custom shape draw func'] === dataUrl, 'problem with setDrawFunc');
testDataUrl(dataUrl, 'change custom shape draw func', 'problem with setDrawFunc');
},
'add star with translated, scaled, rotated fill': function(containerId) {
var imageObj = new Image();
@@ -220,7 +220,7 @@ Test.Modules.SHAPE = {
});
var layer = new Kinetic.Layer();
var star = new Kinetic.Plugins.Star({
var star = new Kinetic.Star({
x: 200,
y: 100,
numPoints: 5,
@@ -415,7 +415,7 @@ Test.Modules.SHAPE = {
stage.add(layer);
//console.log(layer.toDataURL());
warn(layer.toDataURL() === dataUrls['everything enabled'], 'should be circle with green fill, dashed stroke, and shadow');
testDataUrl(layer.toDataURL(), 'everything enabled', 'should be circle with green fill, dashed stroke, and shadow');
},
'fill disabled': function(containerId) {
var stage = new Kinetic.Stage({
@@ -444,7 +444,7 @@ Test.Modules.SHAPE = {
stage.add(layer);
//console.log(layer.toDataURL());
warn(layer.toDataURL() === dataUrls['fill disabled'], 'should be circle with no fill, dashed stroke, and shadow');
testDataUrl(layer.toDataURL(), 'fill disabled', 'should be circle with no fill, dashed stroke, and shadow');
},
'stroke disabled': function(containerId) {
var stage = new Kinetic.Stage({
@@ -473,7 +473,7 @@ Test.Modules.SHAPE = {
stage.add(layer);
//console.log(layer.toDataURL());
warn(layer.toDataURL() === dataUrls['stroke disabled'], 'should be circle with green fill, no stroke, and shadow');
testDataUrl(layer.toDataURL(), 'stroke disabled', 'should be circle with green fill, no stroke, and shadow');
},
'dash array disabled': function(containerId) {
var stage = new Kinetic.Stage({
@@ -502,7 +502,7 @@ Test.Modules.SHAPE = {
stage.add(layer);
//console.log(layer.toDataURL());
warn(layer.toDataURL() === dataUrls['dash array disabled'], 'should be circle with green fill, solid stroke, and shadow');
testDataUrl(layer.toDataURL(), 'dash array disabled', 'should be circle with green fill, solid stroke, and shadow');
},
'shadow disabled': function(containerId) {
var stage = new Kinetic.Stage({
@@ -531,7 +531,7 @@ Test.Modules.SHAPE = {
stage.add(layer);
//console.log(layer.toDataURL());
warn(layer.toDataURL() === dataUrls['shadow disabled'], 'should be circle with green fill, dashed stroke, and no shadow');
testDataUrl(layer.toDataURL(), 'shadow disabled', 'should be circle with green fill, dashed stroke, and no shadow');
},
'test enablers and disablers': function(containerId) {
var stage = new Kinetic.Stage({
@@ -628,7 +628,7 @@ Test.Modules.SHAPE = {
});
var layer = new Kinetic.Layer();
var star = new Kinetic.Plugins.Star({
var star = new Kinetic.Star({
x: 200,
y: 100,
numPoints: 5,
@@ -650,17 +650,17 @@ Test.Modules.SHAPE = {
//console.log(layer.toDataURL());
warn(layer.toDataURL() === dataUrls['red star'], 'star should have red fill');
testDataUrl(layer.toDataURL(), 'red star', 'star should have red fill');
star.setFillPriority('linear-gradient');
layer.draw();
warn(layer.toDataURL() === dataUrls['star with linear gradient fill'], 'star should have linear gradient fill');
testDataUrl(layer.toDataURL(), 'star with linear gradient fill', 'star should have linear gradient fill');
star.setFillPriority('color');
layer.draw();
warn(layer.toDataURL() === dataUrls['red star'], 'star should have red fill again');
testDataUrl(layer.toDataURL(), 'red star', 'star should have red fill again');
}

View File

@@ -55,11 +55,13 @@ Test.Modules.BLOB = {
stage.add(layer);
//console.log(layer.toDataURL());
warn(layer.toDataURL() === dataUrls['blobs'], 'problem with blobs');
testDataUrl(layer.toDataURL(), 'blobs', 'problem with blobs');
test(blob1.getTension() === 0.8, 'blob1 tension should be 0.8');
test(blob2.getTension() === 1.2, 'blob2 tension should be 1.2');
test(blob1.getShapeType() === 'Blob', 'shape type should be Blob');
}
};

View File

@@ -33,7 +33,8 @@ Test.Modules.CIRCLE = {
test(attrs.strokeWidth === 4, 'strokeWidth attr should be strokeWidth');
test(attrs.name === 'myCircle', 'name attr should be myCircle');
test(attrs.draggable === true, 'draggable attr should be true');
},
test(circle.getShapeType() === 'Circle', 'shape type should be Circle');
},
'add circle with pattern fill': function(containerId) {
var imageObj = new Image();
imageObj.onload = function() {

View File

@@ -1,4 +1,4 @@
Test.Modules.ELLISPE = {
Test.Modules.ELLIPSE = {
'add ellipse': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
@@ -6,7 +6,7 @@ Test.Modules.ELLISPE = {
height: 200
});
var layer = new Kinetic.Layer();
var circle = new Kinetic.Ellipse({
var ellipse = new Kinetic.Ellipse({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
radius: [70, 35],
@@ -14,7 +14,8 @@ Test.Modules.ELLISPE = {
stroke: 'black',
strokeWidth: 8
});
layer.add(circle);
layer.add(ellipse);
stage.add(layer);
test(ellipse.getShapeType() === 'Ellipse', 'shape type should be Ellipse');
}
};

View File

@@ -117,6 +117,8 @@ Test.Modules.IMAGE = {
});
//document.body.appendChild(layer.bufferCanvas.element)
test(darth.getShapeType() === 'Image', 'shape type should be Image');
};
imageObj.src = '../assets/darth-vader.jpg';
@@ -185,7 +187,7 @@ Test.Modules.IMAGE = {
var hitDataUrl = layer.hitCanvas.toDataURL();
//console.log(hitDataUrl);
warn(hitDataUrl === dataUrls['transparent image hit render'], 'problem rendering image on hit graph');
testDataUrl(hitDataUrl,'transparent image hit render', 'problem rendering image on hit graph');
});
};
imageObj.src = '../assets/lion.png';
@@ -289,7 +291,7 @@ Test.Modules.IMAGE = {
layer.draw();
var dataUrl = layer.toDataURL();
//console.log(dataUrl);
warn(dataUrl === dataUrls['adjust image brightness'], 'problem with Brighten filter.');
testDataUrl(dataUrl, 'adjust image brightness', 'problem with Brighten filter.');
});
};
@@ -325,7 +327,7 @@ Test.Modules.IMAGE = {
layer.draw();
var dataUrl = layer.toDataURL();
//console.log(dataUrl);
warn(dataUrl === dataUrls['adjust image brightness'], 'problem with Brighten filter.');
testDataUrl(dataUrl, 'blur filter', 'problem with Blur filter.');
});
};

View File

@@ -46,6 +46,8 @@ Test.Modules.LINE = {
line.setPoints([73, 160, 340, 23]);
test(line.getPoints()[0].x === 73, 'first point x should be 73');
test(line.getShapeType() === 'Line', 'shape type should be Line');
},
'add dashed line': function(containerId) {
var stage = new Kinetic.Stage({

View File

@@ -36,6 +36,8 @@ Test.Modules.POLYGON - {
layer.add(poly);
stage.add(layer);
test(poly.getShapeType() === 'Polygon', 'shape type should be Polygon');
}
};

View File

@@ -24,6 +24,8 @@ Test.Modules.RECT = {
layer.add(rect);
stage.add(layer);
test(rect.getShapeType() === 'Rect', 'shape type should be Rect');
},
'add stroke rect': function(containerId) {
var stage = new Kinetic.Stage({

View File

@@ -77,7 +77,9 @@ Test.Modules.SPLINE = {
*/
//console.log(layer.toDataURL());
warn(layer.toDataURL() === dataUrls['curvy lines'], 'problem with curvy lines');
testDataUrl(layer.toDataURL(), 'curvy lines', 'problem with curvy lines');
test(line1.getShapeType() === 'Spline', 'shape type should be Spline');
},
'create from points represented as a flat array': function(containerId) {

View File

@@ -112,6 +112,8 @@ Test.Modules.SPRITE = {
sprite.stop();
}, 3000);
//document.body.appendChild(layer.bufferCanvas.element)
test(sprite.getShapeType() === 'Sprite', 'shape type should be Sprite');
};
imageObj.src = '../assets/scorpion-sprite.png';
}

View File

@@ -54,6 +54,8 @@ Test.Modules.Text = {
group.add(text);
layer.add(group);
stage.add(layer);
test(text.getShapeType() === 'Text', 'shape type should be Text');
},
'text getters and setters': function(containerId) {
var stage = new Kinetic.Stage({
@@ -247,7 +249,7 @@ Test.Modules.Text = {
//console.log(layer.toDataURL());
warn(layer.toDataURL() === dataUrls['multiline text with shadows'], 'multi line text with shadows data url is incorrect');
testDataUrl(layer.toDataURL(),'multiline text with shadows', 'multi line text with shadows data url is incorrect');
},
'change font size should update text data': function(containerId) {
var stage = new Kinetic.Stage({
@@ -315,7 +317,7 @@ Test.Modules.Text = {
stage.add(layer);
//console.log(layer.toDataURL());
warn(layer.toDataURL() === dataUrls['text everything enabled'], 'should be text with blue fill and red stroke');
testDataUrl(layer.toDataURL(), 'text everything enabled', 'should be text with blue fill and red stroke');
},
'text fill disabled': function(containerId) {
var stage = new Kinetic.Stage({
@@ -345,7 +347,7 @@ Test.Modules.Text = {
stage.add(layer);
//console.log(layer.toDataURL());
warn(layer.toDataURL() === dataUrls['text fill disabled'], 'should be text with no fill and red stroke');
testDataUrl(layer.toDataURL(), 'text fill disabled', 'should be text with no fill and red stroke');
},
'text stroke disabled': function(containerId) {
var stage = new Kinetic.Stage({
@@ -375,7 +377,7 @@ Test.Modules.Text = {
stage.add(layer);
//console.log(layer.toDataURL());
warn(layer.toDataURL() === dataUrls['text stroke disabled'], 'should be text with blue fill and no stroke');
testDataUrl(layer.toDataURL(),'text stroke disabled', 'should be text with blue fill and no stroke');
},
'wrapped text': function (containerId) {
var stage = new Kinetic.Stage({
@@ -401,15 +403,15 @@ Test.Modules.Text = {
layer.add(text);
stage.add(layer);
warn(layer.toDataURL() === dataUrls['wrapped text']['wrapping to words'], 'text should be wrapped to words');
testDataUrl(layer.toDataURL(),'wrapping to words', 'text should be wrapped to words');
text.setWrap('none');
layer.draw();
warn(layer.toDataURL() === dataUrls['wrapped text']['no wrapping'], 'text should not be wrapped');
testDataUrl(layer.toDataURL(),'no wrapping', 'text should not be wrapped');
text.setWrap('char');
layer.draw();
warn(layer.toDataURL() === dataUrls['wrapped text']['wrapping to chars'], 'text should be wrapped to chars');
testDataUrl(layer.toDataURL(), 'wrapping to chars', 'text should be wrapped to chars');
}
};

View File

@@ -22,7 +22,9 @@ Test.Modules.Wedge = {
stage.add(layer);
//console.log(layer.toDataURL());
warn(layer.toDataURL() === dataUrls['wedge'], 'problem rendering wedge');
testDataUrl(layer.toDataURL(), 'wedge', 'problem rendering wedge');
test(wedge.getShapeType() === 'Wedge', 'shape type should be Wedge');
},
'set wedge angle using degrees': function(containerId) {
var stage = new Kinetic.Stage({
@@ -75,6 +77,6 @@ Test.Modules.Wedge = {
layer.draw();
//console.log(layer.toDataURL());
warn(layer.toDataURL() === dataUrls['rotate wedge'], 'problem with rotated wedge rendering');
testDataUrl(layer.toDataURL(), 'rotate wedge', 'problem with rotated wedge rendering');
}
};

View File

@@ -228,16 +228,5 @@ Test.Modules.STAGE = {
test(stage.getStage() !== undefined, 'stage is undefined');
//console.log(stage.getStage());
},
'test stage.getDragLayer': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
height: 200
});
test(stage.getDragLayer().getCanvas().getElement().className === 'kinetic-drag-and-drop-layer', 'problem with stage.getDragLayer');
}
};

View File

@@ -191,6 +191,7 @@ Test.Modules.TRANSITION = {
easing: 'bounce-ease-out'
});
/*
setTimeout(function() {
test(rect.transAnim.isRunning(), 'rect trans should be running');
trans.stop();
@@ -201,5 +202,6 @@ Test.Modules.TRANSITION = {
trans.resume();
test(rect.transAnim.isRunning(), 'rect trans should be running after resume');
}, 1500);
*/
}
};