mirror of
https://github.com/konvajs/konva.git
synced 2025-06-27 22:51:29 +08:00
added Matrix.js and started integration
This commit is contained in:
parent
afad713df3
commit
0da8adfb6e
3
Thorfile
3
Thorfile
@ -5,7 +5,8 @@ class Build < Thor
|
|||||||
FILES = [
|
FILES = [
|
||||||
"license.js", "src/GlobalObject.js", "src/Node.js", "src/Container.js", "src/Stage.js",
|
"license.js", "src/GlobalObject.js", "src/Node.js", "src/Container.js", "src/Stage.js",
|
||||||
"src/Layer.js", "src/Group.js", "src/Shape.js", "src/shapes/Rect.js", "src/shapes/Circle.js", "src/shapes/Image.js",
|
"src/Layer.js", "src/Group.js", "src/Shape.js", "src/shapes/Rect.js", "src/shapes/Circle.js", "src/shapes/Image.js",
|
||||||
"src/shapes/Polygon.js", "src/shapes/RegularPolygon.js", "src/shapes/Star.js", "src/shapes/Text.js"
|
"src/shapes/Polygon.js", "src/shapes/RegularPolygon.js", "src/shapes/Star.js", "src/shapes/Text.js",
|
||||||
|
"src/Matrix.js"
|
||||||
]
|
]
|
||||||
|
|
||||||
desc "dev", "Concatenate all the js files into /dist/kinetic-VERSION.js."
|
desc "dev", "Concatenate all the js files into /dist/kinetic-VERSION.js."
|
||||||
|
211
dist/kinetic-core.js
vendored
211
dist/kinetic-core.js
vendored
@ -3,7 +3,7 @@
|
|||||||
* http://www.kineticjs.com/
|
* http://www.kineticjs.com/
|
||||||
* Copyright 2012, Eric Rowell
|
* Copyright 2012, Eric Rowell
|
||||||
* Licensed under the MIT or GPL Version 2 licenses.
|
* Licensed under the MIT or GPL Version 2 licenses.
|
||||||
* Date: Mar 21 2012
|
* Date: Mar 22 2012
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 - 2012 by Eric Rowell
|
* Copyright (C) 2011 - 2012 by Eric Rowell
|
||||||
*
|
*
|
||||||
@ -762,6 +762,24 @@ Kinetic.Node.prototype = {
|
|||||||
getDragBounds: function() {
|
getDragBounds: function() {
|
||||||
return this.dragBounds;
|
return this.dragBounds;
|
||||||
},
|
},
|
||||||
|
getMatrix: function() {
|
||||||
|
var m = new Kinetic.Matrix();
|
||||||
|
|
||||||
|
if(this.x !== 0 || this.y !== 0) {
|
||||||
|
m.translate(this.x, this.y);
|
||||||
|
}
|
||||||
|
if(this.rotation !== 0) {
|
||||||
|
m.rotate(this.rotation);
|
||||||
|
}
|
||||||
|
if(this.scale.x !== 1 || this.scale.y !== 1) {
|
||||||
|
m.scale(this.scale.x, this.scale.y);
|
||||||
|
}
|
||||||
|
if(this.centerOffset.x !== 0 || this.centerOffset.y !== 0) {
|
||||||
|
m.translate(-1 * this.centerOffset.x, -1 * this.centerOffset.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
return m;
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* initialize drag and drop
|
* initialize drag and drop
|
||||||
*/
|
*/
|
||||||
@ -945,6 +963,7 @@ Kinetic.Container.prototype = {
|
|||||||
* animations
|
* animations
|
||||||
* @constructor
|
* @constructor
|
||||||
* @augments Kinetic.Container
|
* @augments Kinetic.Container
|
||||||
|
* @augments Kinetic.Node
|
||||||
* @param {String|DomElement} cont Container id or DOM element
|
* @param {String|DomElement} cont Container id or DOM element
|
||||||
* @param {int} width
|
* @param {int} width
|
||||||
* @param {int} height
|
* @param {int} height
|
||||||
@ -991,8 +1010,9 @@ Kinetic.Stage = function(cont, width, height) {
|
|||||||
// add stage to global object
|
// add stage to global object
|
||||||
Kinetic.GlobalObject.stages.push(this);
|
Kinetic.GlobalObject.stages.push(this);
|
||||||
|
|
||||||
// call super constructor
|
// call super constructors
|
||||||
Kinetic.Container.apply(this, []);
|
Kinetic.Container.apply(this, []);
|
||||||
|
Kinetic.Node.apply(this, []);
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
* Stage methods
|
* Stage methods
|
||||||
@ -1049,48 +1069,6 @@ Kinetic.Stage.prototype = {
|
|||||||
this.backstageLayer.getCanvas().width = width;
|
this.backstageLayer.getCanvas().width = width;
|
||||||
this.backstageLayer.getCanvas().height = height;
|
this.backstageLayer.getCanvas().height = height;
|
||||||
},
|
},
|
||||||
/**
|
|
||||||
* set stage scale. If only one parameter is passed in, then
|
|
||||||
* both scaleX and scaleY are set to the parameter
|
|
||||||
* @param {int} scaleX
|
|
||||||
* @param {int} scaleY
|
|
||||||
*/
|
|
||||||
setScale: function(scaleX, scaleY) {
|
|
||||||
var oldScaleX = this.scale.x;
|
|
||||||
var oldScaleY = this.scale.y;
|
|
||||||
|
|
||||||
if(scaleY) {
|
|
||||||
this.scale.x = scaleX;
|
|
||||||
this.scale.y = scaleY;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.scale.x = scaleX;
|
|
||||||
this.scale.y = scaleX;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* scale all shape positions
|
|
||||||
*/
|
|
||||||
var layers = this.children;
|
|
||||||
var that = this;
|
|
||||||
function scaleChildren(children) {
|
|
||||||
for(var i = 0; i < children.length; i++) {
|
|
||||||
var child = children[i];
|
|
||||||
child.x *= that.scale.x / oldScaleX;
|
|
||||||
child.y *= that.scale.y / oldScaleY;
|
|
||||||
if(child.children) {
|
|
||||||
scaleChildren(child.children);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scaleChildren(layers);
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* get scale
|
|
||||||
*/
|
|
||||||
getScale: function() {
|
|
||||||
return this.scale;
|
|
||||||
},
|
|
||||||
/**
|
/**
|
||||||
* clear all layers
|
* clear all layers
|
||||||
*/
|
*/
|
||||||
@ -1135,16 +1113,14 @@ Kinetic.Stage.prototype = {
|
|||||||
remove: function(layer) {
|
remove: function(layer) {
|
||||||
// remove layer canvas from dom
|
// remove layer canvas from dom
|
||||||
this.content.removeChild(layer.canvas);
|
this.content.removeChild(layer.canvas);
|
||||||
|
|
||||||
this._remove(layer);
|
this._remove(layer);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* bind event listener to stage (which is essentially
|
* bind event listener to container DOM element
|
||||||
* the container DOM)
|
|
||||||
* @param {String} typesStr
|
* @param {String} typesStr
|
||||||
* @param {function} handler
|
* @param {function} handler
|
||||||
*/
|
*/
|
||||||
on: function(typesStr, handler) {
|
onContainer: function(typesStr, handler) {
|
||||||
var types = typesStr.split(' ');
|
var types = typesStr.split(' ');
|
||||||
for(var n = 0; n < types.length; n++) {
|
for(var n = 0; n < types.length; n++) {
|
||||||
var baseEvent = types[n];
|
var baseEvent = types[n];
|
||||||
@ -1376,7 +1352,7 @@ Kinetic.Stage.prototype = {
|
|||||||
* handle incoming event
|
* handle incoming event
|
||||||
* @param {Event} evt
|
* @param {Event} evt
|
||||||
*/
|
*/
|
||||||
_handleEvent: function(evt) {
|
_handleStageEvent: function(evt) {
|
||||||
var go = Kinetic.GlobalObject;
|
var go = Kinetic.GlobalObject;
|
||||||
if(!evt) {
|
if(!evt) {
|
||||||
evt = window.event;
|
evt = window.event;
|
||||||
@ -1425,25 +1401,25 @@ Kinetic.Stage.prototype = {
|
|||||||
// desktop events
|
// desktop events
|
||||||
this.container.addEventListener('mousedown', function(evt) {
|
this.container.addEventListener('mousedown', function(evt) {
|
||||||
that.mouseDown = true;
|
that.mouseDown = true;
|
||||||
that._handleEvent(evt);
|
that._handleStageEvent(evt);
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
this.container.addEventListener('mousemove', function(evt) {
|
this.container.addEventListener('mousemove', function(evt) {
|
||||||
that.mouseUp = false;
|
that.mouseUp = false;
|
||||||
that.mouseDown = false;
|
that.mouseDown = false;
|
||||||
that._handleEvent(evt);
|
that._handleStageEvent(evt);
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
this.container.addEventListener('mouseup', function(evt) {
|
this.container.addEventListener('mouseup', function(evt) {
|
||||||
that.mouseUp = true;
|
that.mouseUp = true;
|
||||||
that.mouseDown = false;
|
that.mouseDown = false;
|
||||||
that._handleEvent(evt);
|
that._handleStageEvent(evt);
|
||||||
|
|
||||||
that.clickStart = false;
|
that.clickStart = false;
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
this.container.addEventListener('mouseover', function(evt) {
|
this.container.addEventListener('mouseover', function(evt) {
|
||||||
that._handleEvent(evt);
|
that._handleStageEvent(evt);
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
this.container.addEventListener('mouseout', function(evt) {
|
this.container.addEventListener('mouseout', function(evt) {
|
||||||
@ -1453,18 +1429,18 @@ Kinetic.Stage.prototype = {
|
|||||||
this.container.addEventListener('touchstart', function(evt) {
|
this.container.addEventListener('touchstart', function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
that.touchStart = true;
|
that.touchStart = true;
|
||||||
that._handleEvent(evt);
|
that._handleStageEvent(evt);
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
this.container.addEventListener('touchmove', function(evt) {
|
this.container.addEventListener('touchmove', function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
that._handleEvent(evt);
|
that._handleStageEvent(evt);
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
this.container.addEventListener('touchend', function(evt) {
|
this.container.addEventListener('touchend', function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
that.touchEnd = true;
|
that.touchEnd = true;
|
||||||
that._handleEvent(evt);
|
that._handleStageEvent(evt);
|
||||||
}, false);
|
}, false);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@ -1555,7 +1531,7 @@ Kinetic.Stage.prototype = {
|
|||||||
_prepareDrag: function() {
|
_prepareDrag: function() {
|
||||||
var that = this;
|
var that = this;
|
||||||
|
|
||||||
this.on('mousemove touchmove', function(evt) {
|
this.onContainer('mousemove touchmove', function(evt) {
|
||||||
var go = Kinetic.GlobalObject;
|
var go = Kinetic.GlobalObject;
|
||||||
var node = go.drag.node;
|
var node = go.drag.node;
|
||||||
if(node) {
|
if(node) {
|
||||||
@ -1586,7 +1562,7 @@ Kinetic.Stage.prototype = {
|
|||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
this.on('mouseup touchend mouseout', function(evt) {
|
this.onContainer('mouseup touchend mouseout', function(evt) {
|
||||||
that._endDrag(evt);
|
that._endDrag(evt);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -1626,8 +1602,9 @@ Kinetic.Stage.prototype = {
|
|||||||
this.content.appendChild(this.backstageLayer.canvas);
|
this.content.appendChild(this.backstageLayer.canvas);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// extend Container
|
// Extend Container and Node
|
||||||
Kinetic.GlobalObject.extend(Kinetic.Stage, Kinetic.Container);
|
Kinetic.GlobalObject.extend(Kinetic.Stage, Kinetic.Container);
|
||||||
|
Kinetic.GlobalObject.extend(Kinetic.Stage, Kinetic.Node);
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
// Layer
|
// Layer
|
||||||
@ -1874,56 +1851,26 @@ Kinetic.Shape.prototype = {
|
|||||||
if(this.visible) {
|
if(this.visible) {
|
||||||
var stage = layer.getStage();
|
var stage = layer.getStage();
|
||||||
var context = layer.getContext();
|
var context = layer.getContext();
|
||||||
|
|
||||||
var family = [];
|
var family = [];
|
||||||
|
var parent = this.parent;
|
||||||
|
|
||||||
family.unshift(this);
|
family.unshift(this);
|
||||||
var parent = this.parent;
|
while(parent) {
|
||||||
while(parent.className !== 'Stage') {
|
|
||||||
family.unshift(parent);
|
family.unshift(parent);
|
||||||
parent = parent.parent;
|
parent = parent.parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
// children transforms
|
context.save();
|
||||||
for(var n = 0; n < family.length; n++) {
|
for(var n = 0; n < family.length; n++) {
|
||||||
var obj = family[n];
|
var node = family[n];
|
||||||
|
var m = node.getMatrix();
|
||||||
context.save();
|
m.transformContext(context);
|
||||||
if(obj.x !== 0 || obj.y !== 0) {
|
if(node.getAbsoluteAlpha() !== 1) {
|
||||||
context.translate(obj.x, obj.y);
|
context.globalAlpha = node.getAbsoluteAlpha();
|
||||||
}
|
|
||||||
if(obj.centerOffset.x !== 0 || obj.centerOffset.y !== 0) {
|
|
||||||
context.translate(obj.centerOffset.x, obj.centerOffset.y);
|
|
||||||
}
|
|
||||||
if(obj.rotation !== 0) {
|
|
||||||
context.rotate(obj.rotation);
|
|
||||||
}
|
|
||||||
if(obj.scale.x !== 1 || obj.scale.y !== 1) {
|
|
||||||
context.scale(obj.scale.x, obj.scale.y);
|
|
||||||
}
|
|
||||||
if(obj.centerOffset.x !== 0 || obj.centerOffset.y !== 0) {
|
|
||||||
context.translate(-1 * obj.centerOffset.x, -1 * obj.centerOffset.y);
|
|
||||||
}
|
|
||||||
if(obj.getAbsoluteAlpha() !== 1) {
|
|
||||||
context.globalAlpha = obj.getAbsoluteAlpha();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// stage transform
|
|
||||||
context.save();
|
|
||||||
if(stage && (stage.scale.x !== 1 || stage.scale.y !== 1)) {
|
|
||||||
context.scale(stage.scale.x, stage.scale.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.tempLayer = layer;
|
this.tempLayer = layer;
|
||||||
this.drawFunc.call(this);
|
this.drawFunc.call(this);
|
||||||
|
|
||||||
// children restore
|
|
||||||
for(var i = 0; i < family.length; i++) {
|
|
||||||
context.restore();
|
|
||||||
}
|
|
||||||
|
|
||||||
// stage restore
|
|
||||||
context.restore();
|
context.restore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2534,3 +2481,73 @@ Kinetic.Text.prototype = {
|
|||||||
// extend Shape
|
// extend Shape
|
||||||
Kinetic.GlobalObject.extend(Kinetic.Text, Kinetic.Shape);
|
Kinetic.GlobalObject.extend(Kinetic.Text, Kinetic.Shape);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Last updated November 2011
|
||||||
|
* By Simon Sarris
|
||||||
|
* www.simonsarris.com
|
||||||
|
* sarris@acm.org
|
||||||
|
*
|
||||||
|
* Free to use and distribute at will
|
||||||
|
* So long as you are nice to people, etc
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The usage of this class was inspired by some of the work done by a forked
|
||||||
|
* project, KineticJS-Ext by Wappworks, which is based on Simon's Transform
|
||||||
|
* class. KineticJS has slightly modified the original class and added new methods
|
||||||
|
* specific for canvas.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matrix object
|
||||||
|
*/
|
||||||
|
Kinetic.Matrix = function() {
|
||||||
|
this.m = [1, 0, 0, 1, 0, 0];
|
||||||
|
}
|
||||||
|
|
||||||
|
Kinetic.Matrix.prototype = {
|
||||||
|
/**
|
||||||
|
* Apply translation
|
||||||
|
* @param {Number} x
|
||||||
|
* @param {Number} y
|
||||||
|
*/
|
||||||
|
translate: function(x, y) {
|
||||||
|
this.m[4] += this.m[0] * x + this.m[2] * y;
|
||||||
|
this.m[5] += this.m[1] * x + this.m[3] * y;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Apply scale
|
||||||
|
* @param {Number} sx
|
||||||
|
* @param {Number} sy
|
||||||
|
*/
|
||||||
|
scale: function(sx, sy) {
|
||||||
|
this.m[0] *= sx;
|
||||||
|
this.m[1] *= sx;
|
||||||
|
this.m[2] *= sy;
|
||||||
|
this.m[3] *= sy;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Apply rotation
|
||||||
|
* @param {Number} rad Angle in radians
|
||||||
|
*/
|
||||||
|
rotate: function(rad) {
|
||||||
|
var c = Math.cos(rad);
|
||||||
|
var s = Math.sin(rad);
|
||||||
|
var m11 = this.m[0] * c + this.m[2] * s;
|
||||||
|
var m12 = this.m[1] * c + this.m[3] * s;
|
||||||
|
var m21 = this.m[0] * -s + this.m[2] * c;
|
||||||
|
var m22 = this.m[1] * -s + this.m[3] * c;
|
||||||
|
this.m[0] = m11;
|
||||||
|
this.m[1] = m12;
|
||||||
|
this.m[2] = m21;
|
||||||
|
this.m[3] = m22;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* transform canvas context
|
||||||
|
*/
|
||||||
|
transformContext: function(context) {
|
||||||
|
var m = this.m;
|
||||||
|
context.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
4
dist/kinetic-core.min.js
vendored
4
dist/kinetic-core.min.js
vendored
File diff suppressed because one or more lines are too long
69
src/Matrix.js
Normal file
69
src/Matrix.js
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Last updated November 2011
|
||||||
|
* By Simon Sarris
|
||||||
|
* www.simonsarris.com
|
||||||
|
* sarris@acm.org
|
||||||
|
*
|
||||||
|
* Free to use and distribute at will
|
||||||
|
* So long as you are nice to people, etc
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The usage of this class was inspired by some of the work done by a forked
|
||||||
|
* project, KineticJS-Ext by Wappworks, which is based on Simon's Transform
|
||||||
|
* class. KineticJS has slightly modified the original class and added new methods
|
||||||
|
* specific for canvas.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matrix object
|
||||||
|
*/
|
||||||
|
Kinetic.Matrix = function() {
|
||||||
|
this.m = [1, 0, 0, 1, 0, 0];
|
||||||
|
}
|
||||||
|
|
||||||
|
Kinetic.Matrix.prototype = {
|
||||||
|
/**
|
||||||
|
* Apply translation
|
||||||
|
* @param {Number} x
|
||||||
|
* @param {Number} y
|
||||||
|
*/
|
||||||
|
translate: function(x, y) {
|
||||||
|
this.m[4] += this.m[0] * x + this.m[2] * y;
|
||||||
|
this.m[5] += this.m[1] * x + this.m[3] * y;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Apply scale
|
||||||
|
* @param {Number} sx
|
||||||
|
* @param {Number} sy
|
||||||
|
*/
|
||||||
|
scale: function(sx, sy) {
|
||||||
|
this.m[0] *= sx;
|
||||||
|
this.m[1] *= sx;
|
||||||
|
this.m[2] *= sy;
|
||||||
|
this.m[3] *= sy;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Apply rotation
|
||||||
|
* @param {Number} rad Angle in radians
|
||||||
|
*/
|
||||||
|
rotate: function(rad) {
|
||||||
|
var c = Math.cos(rad);
|
||||||
|
var s = Math.sin(rad);
|
||||||
|
var m11 = this.m[0] * c + this.m[2] * s;
|
||||||
|
var m12 = this.m[1] * c + this.m[3] * s;
|
||||||
|
var m21 = this.m[0] * -s + this.m[2] * c;
|
||||||
|
var m22 = this.m[1] * -s + this.m[3] * c;
|
||||||
|
this.m[0] = m11;
|
||||||
|
this.m[1] = m12;
|
||||||
|
this.m[2] = m21;
|
||||||
|
this.m[3] = m22;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* transform canvas context
|
||||||
|
*/
|
||||||
|
transformContext: function(context) {
|
||||||
|
var m = this.m;
|
||||||
|
context.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
|
||||||
|
}
|
||||||
|
};
|
18
src/Node.js
18
src/Node.js
@ -515,6 +515,24 @@ Kinetic.Node.prototype = {
|
|||||||
getDragBounds: function() {
|
getDragBounds: function() {
|
||||||
return this.dragBounds;
|
return this.dragBounds;
|
||||||
},
|
},
|
||||||
|
getMatrix: function() {
|
||||||
|
var m = new Kinetic.Matrix();
|
||||||
|
|
||||||
|
if(this.x !== 0 || this.y !== 0) {
|
||||||
|
m.translate(this.x, this.y);
|
||||||
|
}
|
||||||
|
if(this.rotation !== 0) {
|
||||||
|
m.rotate(this.rotation);
|
||||||
|
}
|
||||||
|
if(this.scale.x !== 1 || this.scale.y !== 1) {
|
||||||
|
m.scale(this.scale.x, this.scale.y);
|
||||||
|
}
|
||||||
|
if(this.centerOffset.x !== 0 || this.centerOffset.y !== 0) {
|
||||||
|
m.translate(-1 * this.centerOffset.x, -1 * this.centerOffset.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
return m;
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* initialize drag and drop
|
* initialize drag and drop
|
||||||
*/
|
*/
|
||||||
|
46
src/Shape.js
46
src/Shape.js
@ -112,56 +112,26 @@ Kinetic.Shape.prototype = {
|
|||||||
if(this.visible) {
|
if(this.visible) {
|
||||||
var stage = layer.getStage();
|
var stage = layer.getStage();
|
||||||
var context = layer.getContext();
|
var context = layer.getContext();
|
||||||
|
|
||||||
var family = [];
|
var family = [];
|
||||||
|
var parent = this.parent;
|
||||||
|
|
||||||
family.unshift(this);
|
family.unshift(this);
|
||||||
var parent = this.parent;
|
while(parent) {
|
||||||
while(parent.className !== 'Stage') {
|
|
||||||
family.unshift(parent);
|
family.unshift(parent);
|
||||||
parent = parent.parent;
|
parent = parent.parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
// children transforms
|
context.save();
|
||||||
for(var n = 0; n < family.length; n++) {
|
for(var n = 0; n < family.length; n++) {
|
||||||
var obj = family[n];
|
var node = family[n];
|
||||||
|
var m = node.getMatrix();
|
||||||
context.save();
|
m.transformContext(context);
|
||||||
if(obj.x !== 0 || obj.y !== 0) {
|
if(node.getAbsoluteAlpha() !== 1) {
|
||||||
context.translate(obj.x, obj.y);
|
context.globalAlpha = node.getAbsoluteAlpha();
|
||||||
}
|
|
||||||
if(obj.centerOffset.x !== 0 || obj.centerOffset.y !== 0) {
|
|
||||||
context.translate(obj.centerOffset.x, obj.centerOffset.y);
|
|
||||||
}
|
|
||||||
if(obj.rotation !== 0) {
|
|
||||||
context.rotate(obj.rotation);
|
|
||||||
}
|
|
||||||
if(obj.scale.x !== 1 || obj.scale.y !== 1) {
|
|
||||||
context.scale(obj.scale.x, obj.scale.y);
|
|
||||||
}
|
|
||||||
if(obj.centerOffset.x !== 0 || obj.centerOffset.y !== 0) {
|
|
||||||
context.translate(-1 * obj.centerOffset.x, -1 * obj.centerOffset.y);
|
|
||||||
}
|
|
||||||
if(obj.getAbsoluteAlpha() !== 1) {
|
|
||||||
context.globalAlpha = obj.getAbsoluteAlpha();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// stage transform
|
|
||||||
context.save();
|
|
||||||
if(stage && (stage.scale.x !== 1 || stage.scale.y !== 1)) {
|
|
||||||
context.scale(stage.scale.x, stage.scale.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.tempLayer = layer;
|
this.tempLayer = layer;
|
||||||
this.drawFunc.call(this);
|
this.drawFunc.call(this);
|
||||||
|
|
||||||
// children restore
|
|
||||||
for(var i = 0; i < family.length; i++) {
|
|
||||||
context.restore();
|
|
||||||
}
|
|
||||||
|
|
||||||
// stage restore
|
|
||||||
context.restore();
|
context.restore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
75
src/Stage.js
75
src/Stage.js
@ -6,6 +6,7 @@
|
|||||||
* animations
|
* animations
|
||||||
* @constructor
|
* @constructor
|
||||||
* @augments Kinetic.Container
|
* @augments Kinetic.Container
|
||||||
|
* @augments Kinetic.Node
|
||||||
* @param {String|DomElement} cont Container id or DOM element
|
* @param {String|DomElement} cont Container id or DOM element
|
||||||
* @param {int} width
|
* @param {int} width
|
||||||
* @param {int} height
|
* @param {int} height
|
||||||
@ -52,8 +53,9 @@ Kinetic.Stage = function(cont, width, height) {
|
|||||||
// add stage to global object
|
// add stage to global object
|
||||||
Kinetic.GlobalObject.stages.push(this);
|
Kinetic.GlobalObject.stages.push(this);
|
||||||
|
|
||||||
// call super constructor
|
// call super constructors
|
||||||
Kinetic.Container.apply(this, []);
|
Kinetic.Container.apply(this, []);
|
||||||
|
Kinetic.Node.apply(this, []);
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
* Stage methods
|
* Stage methods
|
||||||
@ -110,48 +112,6 @@ Kinetic.Stage.prototype = {
|
|||||||
this.backstageLayer.getCanvas().width = width;
|
this.backstageLayer.getCanvas().width = width;
|
||||||
this.backstageLayer.getCanvas().height = height;
|
this.backstageLayer.getCanvas().height = height;
|
||||||
},
|
},
|
||||||
/**
|
|
||||||
* set stage scale. If only one parameter is passed in, then
|
|
||||||
* both scaleX and scaleY are set to the parameter
|
|
||||||
* @param {int} scaleX
|
|
||||||
* @param {int} scaleY
|
|
||||||
*/
|
|
||||||
setScale: function(scaleX, scaleY) {
|
|
||||||
var oldScaleX = this.scale.x;
|
|
||||||
var oldScaleY = this.scale.y;
|
|
||||||
|
|
||||||
if(scaleY) {
|
|
||||||
this.scale.x = scaleX;
|
|
||||||
this.scale.y = scaleY;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.scale.x = scaleX;
|
|
||||||
this.scale.y = scaleX;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* scale all shape positions
|
|
||||||
*/
|
|
||||||
var layers = this.children;
|
|
||||||
var that = this;
|
|
||||||
function scaleChildren(children) {
|
|
||||||
for(var i = 0; i < children.length; i++) {
|
|
||||||
var child = children[i];
|
|
||||||
child.x *= that.scale.x / oldScaleX;
|
|
||||||
child.y *= that.scale.y / oldScaleY;
|
|
||||||
if(child.children) {
|
|
||||||
scaleChildren(child.children);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scaleChildren(layers);
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* get scale
|
|
||||||
*/
|
|
||||||
getScale: function() {
|
|
||||||
return this.scale;
|
|
||||||
},
|
|
||||||
/**
|
/**
|
||||||
* clear all layers
|
* clear all layers
|
||||||
*/
|
*/
|
||||||
@ -196,16 +156,14 @@ Kinetic.Stage.prototype = {
|
|||||||
remove: function(layer) {
|
remove: function(layer) {
|
||||||
// remove layer canvas from dom
|
// remove layer canvas from dom
|
||||||
this.content.removeChild(layer.canvas);
|
this.content.removeChild(layer.canvas);
|
||||||
|
|
||||||
this._remove(layer);
|
this._remove(layer);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* bind event listener to stage (which is essentially
|
* bind event listener to container DOM element
|
||||||
* the container DOM)
|
|
||||||
* @param {String} typesStr
|
* @param {String} typesStr
|
||||||
* @param {function} handler
|
* @param {function} handler
|
||||||
*/
|
*/
|
||||||
on: function(typesStr, handler) {
|
onContainer: function(typesStr, handler) {
|
||||||
var types = typesStr.split(' ');
|
var types = typesStr.split(' ');
|
||||||
for(var n = 0; n < types.length; n++) {
|
for(var n = 0; n < types.length; n++) {
|
||||||
var baseEvent = types[n];
|
var baseEvent = types[n];
|
||||||
@ -437,7 +395,7 @@ Kinetic.Stage.prototype = {
|
|||||||
* handle incoming event
|
* handle incoming event
|
||||||
* @param {Event} evt
|
* @param {Event} evt
|
||||||
*/
|
*/
|
||||||
_handleEvent: function(evt) {
|
_handleStageEvent: function(evt) {
|
||||||
var go = Kinetic.GlobalObject;
|
var go = Kinetic.GlobalObject;
|
||||||
if(!evt) {
|
if(!evt) {
|
||||||
evt = window.event;
|
evt = window.event;
|
||||||
@ -486,25 +444,25 @@ Kinetic.Stage.prototype = {
|
|||||||
// desktop events
|
// desktop events
|
||||||
this.container.addEventListener('mousedown', function(evt) {
|
this.container.addEventListener('mousedown', function(evt) {
|
||||||
that.mouseDown = true;
|
that.mouseDown = true;
|
||||||
that._handleEvent(evt);
|
that._handleStageEvent(evt);
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
this.container.addEventListener('mousemove', function(evt) {
|
this.container.addEventListener('mousemove', function(evt) {
|
||||||
that.mouseUp = false;
|
that.mouseUp = false;
|
||||||
that.mouseDown = false;
|
that.mouseDown = false;
|
||||||
that._handleEvent(evt);
|
that._handleStageEvent(evt);
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
this.container.addEventListener('mouseup', function(evt) {
|
this.container.addEventListener('mouseup', function(evt) {
|
||||||
that.mouseUp = true;
|
that.mouseUp = true;
|
||||||
that.mouseDown = false;
|
that.mouseDown = false;
|
||||||
that._handleEvent(evt);
|
that._handleStageEvent(evt);
|
||||||
|
|
||||||
that.clickStart = false;
|
that.clickStart = false;
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
this.container.addEventListener('mouseover', function(evt) {
|
this.container.addEventListener('mouseover', function(evt) {
|
||||||
that._handleEvent(evt);
|
that._handleStageEvent(evt);
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
this.container.addEventListener('mouseout', function(evt) {
|
this.container.addEventListener('mouseout', function(evt) {
|
||||||
@ -514,18 +472,18 @@ Kinetic.Stage.prototype = {
|
|||||||
this.container.addEventListener('touchstart', function(evt) {
|
this.container.addEventListener('touchstart', function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
that.touchStart = true;
|
that.touchStart = true;
|
||||||
that._handleEvent(evt);
|
that._handleStageEvent(evt);
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
this.container.addEventListener('touchmove', function(evt) {
|
this.container.addEventListener('touchmove', function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
that._handleEvent(evt);
|
that._handleStageEvent(evt);
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
this.container.addEventListener('touchend', function(evt) {
|
this.container.addEventListener('touchend', function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
that.touchEnd = true;
|
that.touchEnd = true;
|
||||||
that._handleEvent(evt);
|
that._handleStageEvent(evt);
|
||||||
}, false);
|
}, false);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@ -616,7 +574,7 @@ Kinetic.Stage.prototype = {
|
|||||||
_prepareDrag: function() {
|
_prepareDrag: function() {
|
||||||
var that = this;
|
var that = this;
|
||||||
|
|
||||||
this.on('mousemove touchmove', function(evt) {
|
this.onContainer('mousemove touchmove', function(evt) {
|
||||||
var go = Kinetic.GlobalObject;
|
var go = Kinetic.GlobalObject;
|
||||||
var node = go.drag.node;
|
var node = go.drag.node;
|
||||||
if(node) {
|
if(node) {
|
||||||
@ -647,7 +605,7 @@ Kinetic.Stage.prototype = {
|
|||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
this.on('mouseup touchend mouseout', function(evt) {
|
this.onContainer('mouseup touchend mouseout', function(evt) {
|
||||||
that._endDrag(evt);
|
that._endDrag(evt);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -687,5 +645,6 @@ Kinetic.Stage.prototype = {
|
|||||||
this.content.appendChild(this.backstageLayer.canvas);
|
this.content.appendChild(this.backstageLayer.canvas);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// extend Container
|
// Extend Container and Node
|
||||||
Kinetic.GlobalObject.extend(Kinetic.Stage, Kinetic.Container);
|
Kinetic.GlobalObject.extend(Kinetic.Stage, Kinetic.Container);
|
||||||
|
Kinetic.GlobalObject.extend(Kinetic.Stage, Kinetic.Node);
|
||||||
|
@ -1163,4 +1163,28 @@ Test.prototype.tests = {
|
|||||||
layer.add(circle);
|
layer.add(circle);
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
},
|
},
|
||||||
|
'DRAG AND DROP - drag and drop shape inside scaled group': function(containerId) {
|
||||||
|
var stage = new Kinetic.Stage(containerId, 578, 200);
|
||||||
|
var layer = new Kinetic.Layer();
|
||||||
|
var group = new Kinetic.Group({
|
||||||
|
scale: {
|
||||||
|
x: 1.5,
|
||||||
|
y: 1.5
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var circle = new Kinetic.Circle({
|
||||||
|
x: stage.width / 2,
|
||||||
|
y: stage.height / 2,
|
||||||
|
radius: 70,
|
||||||
|
fill: 'red',
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 4,
|
||||||
|
draggable: true
|
||||||
|
});
|
||||||
|
|
||||||
|
group.add(circle);
|
||||||
|
layer.add(group);
|
||||||
|
stage.add(layer);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
@ -830,6 +830,39 @@ Test.prototype.tests = {
|
|||||||
test(circle.getDragConstraint() === 'vertical', 'drag constraint should be vertical');
|
test(circle.getDragConstraint() === 'vertical', 'drag constraint should be vertical');
|
||||||
test(circle.getDragBounds().bottom === 200, 'drag bottom should be 200');
|
test(circle.getDragBounds().bottom === 200, 'drag bottom should be 200');
|
||||||
},
|
},
|
||||||
|
'NODE - translate, rotate, scale shape': function(containerId) {
|
||||||
|
var stage = new Kinetic.Stage(containerId, 578, 200);
|
||||||
|
var layer = new Kinetic.Layer();
|
||||||
|
var circle = new Kinetic.Rect({
|
||||||
|
x: 100,
|
||||||
|
y: 100,
|
||||||
|
rotationDeg: 20,
|
||||||
|
width: 100,
|
||||||
|
height: 50,
|
||||||
|
fill: 'green',
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 4,
|
||||||
|
scale: {
|
||||||
|
x: 2,
|
||||||
|
y: 1
|
||||||
|
},
|
||||||
|
centerOffset: {
|
||||||
|
x: 50,
|
||||||
|
y: 25
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
layer.add(circle);
|
||||||
|
stage.add(layer);
|
||||||
|
|
||||||
|
stage.onFrame(function(frame) {
|
||||||
|
circle.rotation += .1;
|
||||||
|
layer.draw();
|
||||||
|
});
|
||||||
|
|
||||||
|
//stage.start();
|
||||||
|
|
||||||
|
},
|
||||||
'STAGE - add layer then shape': function(containerId) {
|
'STAGE - add layer then shape': function(containerId) {
|
||||||
var stage = new Kinetic.Stage(containerId, 578, 200);
|
var stage = new Kinetic.Stage(containerId, 578, 200);
|
||||||
var layer = new Kinetic.Layer();
|
var layer = new Kinetic.Layer();
|
||||||
|
Loading…
Reference in New Issue
Block a user