diff --git a/README.md b/README.md index 1dc0e220..7004bf0e 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ To build a development version of the library, run `thor build:dev VERSION`, whe If you add a file in the src directory, be sure to add the filename to the filename array in the Thorfile. #Tests -To run unit tests, open the `unitTests.html` file in the `tests/html` directory. To run functional tests, open the `functionalTests.html` file. The tests output the results to the console via `console.log()` so be sure to have it open. +To run tests, open `unitTests.html`, `functionalTests.html`, or `manualTests.html` in the `tests/html` directory. Unit tests and functional tests output the results to the console via `console.log()` so be sure to have it open. #Pull Requests -I'd be happy to review any pull requests that may better the KineticJS project, in particular if you have a bug fix or a new shape (see `src/shapes` for examples). Before doing so, please first make sure that all of the unit tests and functional tests pass. +I'd be happy to review any pull requests that may better the KineticJS project, in particular if you have a bug fix, enhancement, or a new shape (see `src/shapes` for examples). Before doing so, please first make sure that all of the unit tests and functional tests pass. diff --git a/dist/kinetic-core.js b/dist/kinetic-core.js index 81f4f7c9..6de42a00 100644 --- a/dist/kinetic-core.js +++ b/dist/kinetic-core.js @@ -3,7 +3,7 @@ * http://www.kineticjs.com/ * Copyright 2012, Eric Rowell * Licensed under the MIT or GPL Version 2 licenses. - * Date: Jun 14 2012 + * Date: Jun 15 2012 * * Copyright (C) 2011 - 2012 by Eric Rowell * @@ -1583,7 +1583,6 @@ Kinetic.Stage = function(config) { this._id = Kinetic.GlobalObject.idCounter++; this._buildDOM(); this._bindContentEvents(); - this._prepareDrag(); //change events this.on('widthChange.kinetic_reserved', function() { @@ -1971,7 +1970,7 @@ Kinetic.Stage.prototype = { } // handle touchstart - if(!isDragging && this.touchStart && !this.touchMove) { + else if(!isDragging && this.touchStart && !this.touchMove) { this.touchStart = false; this.tapStart = true; shape._handleEvent('touchstart', evt); @@ -2027,7 +2026,8 @@ Kinetic.Stage.prototype = { } // handle mousemove and touchmove - else if(!isDragging && this.mouseMove) { + +else if(!isDragging && this.mouseMove) { shape._handleEvent('mousemove', evt); return true; } @@ -2158,17 +2158,17 @@ else if(!isDragging && this.touchMove) { var pubEvent = events[n]; // induce scope ( function() { - var event = pubEvent; + var event = pubEvent; that.content.addEventListener(event, function(evt) { - that['_on' + event](evt); + that['_' + event](evt); }, false); }()); } }, - _onmouseover: function(evt) { + _mouseover: function(evt) { this._handleStageEvent(evt); }, - _onmouseout: function(evt) { + _mouseout: function(evt) { // if there's a current target shape, run mouseout handlers var targetShape = this.targetShape; if(targetShape) { @@ -2176,8 +2176,11 @@ else if(!isDragging && this.touchMove) { this.targetShape = undefined; } this.mousePos = undefined; + + // end drag and drop + this._endDrag(evt); }, - _onmousemove: function(evt) { + _mousemove: function(evt) { //throttle mousemove var throttle = this.attrs.throttle; var date = new Date(); @@ -2190,8 +2193,11 @@ else if(!isDragging && this.touchMove) { this.mouseUp = false; this._handleStageEvent(evt); } + + // start drag and drop + this._startDrag(evt); }, - _onmousedown: function(evt) { + _mousedown: function(evt) { this.mouseDown = true; this.mouseUp = false; this.mouseMove = false; @@ -2202,14 +2208,17 @@ else if(!isDragging && this.touchMove) { this._initDrag(); } }, - _onmouseup: function(evt) { + _mouseup: function(evt) { this.mouseDown = false; this.mouseUp = true; this.mouseMove = false; this._handleStageEvent(evt); this.clickStart = false; + + // end drag and drop + this._endDrag(evt); }, - _ontouchstart: function(evt) { + _touchstart: function(evt) { evt.preventDefault(); this.touchStart = true; this.touchEnd = false; @@ -2222,14 +2231,17 @@ else if(!isDragging && this.touchMove) { this._initDrag(); } }, - _ontouchend: function(evt) { + _touchend: function(evt) { this.touchStart = false; this.touchEnd = true; this.touchMove = false; this._handleStageEvent(evt); this.tapStart = false; + + // end drag and drop + this._endDrag(evt); }, - _ontouchmove: function(evt) { + _touchmove: function(evt) { //throttle touchmove var that = this; var throttle = this.attrs.throttle; @@ -2253,6 +2265,9 @@ else if(!isDragging && this.touchMove) { that._handleStageEvent(evt); }, 5); } + + // start drag and drop + this._startDrag(evt); }, /** * set mouse positon for desktop apps @@ -2337,80 +2352,73 @@ else if(!isDragging && this.touchMove) { go.drag.node = undefined; }, /** - * prepare drag and drop + * start drag and drop */ - _prepareDrag: function() { + _startDrag: function(evt) { var that = this; + var go = Kinetic.GlobalObject; + var node = go.drag.node; - this._onContent('mousemove touchmove', function(evt) { - var go = Kinetic.GlobalObject; - var node = go.drag.node; + if(node) { + var pos = that.getUserPosition(); + var dc = node.attrs.dragConstraint; + var db = node.attrs.dragBounds; + var lastNodePos = { + x: node.attrs.x, + y: node.attrs.y + }; - if(node) { - var pos = that.getUserPosition(); - var dc = node.attrs.dragConstraint; - var db = node.attrs.dragBounds; - var lastNodePos = { - x: node.attrs.x, - y: node.attrs.y - }; + // default + var newNodePos = { + x: pos.x - go.drag.offset.x, + y: pos.y - go.drag.offset.y + }; - // default - var newNodePos = { - x: pos.x - go.drag.offset.x, - y: pos.y - go.drag.offset.y - }; - - // bounds overrides - if(db.left !== undefined && newNodePos.x < db.left) { - newNodePos.x = db.left; - } - if(db.right !== undefined && newNodePos.x > db.right) { - newNodePos.x = db.right; - } - if(db.top !== undefined && newNodePos.y < db.top) { - newNodePos.y = db.top; - } - if(db.bottom !== undefined && newNodePos.y > db.bottom) { - newNodePos.y = db.bottom; - } - - node.setAbsolutePosition(newNodePos); - - // constraint overrides - if(dc === 'horizontal') { - node.attrs.y = lastNodePos.y; - } - else if(dc === 'vertical') { - node.attrs.x = lastNodePos.x; - } - - /* - * if dragging and dropping the stage, - * draw all of the layers - */ - if(go.drag.node.nodeType === 'Stage') { - go.drag.node.draw(); - } - - else { - go.drag.node.getLayer().draw(); - } - - if(!go.drag.moving) { - go.drag.moving = true; - // execute dragstart events if defined - go.drag.node._handleEvent('dragstart', evt); - } - - // execute user defined ondragmove if defined - go.drag.node._handleEvent('dragmove', evt); + // bounds overrides + if(db.left !== undefined && newNodePos.x < db.left) { + newNodePos.x = db.left; + } + if(db.right !== undefined && newNodePos.x > db.right) { + newNodePos.x = db.right; + } + if(db.top !== undefined && newNodePos.y < db.top) { + newNodePos.y = db.top; + } + if(db.bottom !== undefined && newNodePos.y > db.bottom) { + newNodePos.y = db.bottom; } - }, false); - this._onContent('mouseup touchend mouseout', function(evt) { - that._endDrag(evt); - }); + node.setAbsolutePosition(newNodePos); + + // constraint overrides + if(dc === 'horizontal') { + node.attrs.y = lastNodePos.y; + } + else if(dc === 'vertical') { + node.attrs.x = lastNodePos.x; + } + + /* + * if dragging and dropping the stage, + * draw all of the layers + */ + if(go.drag.node.nodeType === 'Stage') { + go.drag.node.draw(); + } + + else { + go.drag.node.getLayer().draw(); + } + + if(!go.drag.moving) { + go.drag.moving = true; + // execute dragstart events if defined + go.drag.node._handleEvent('dragstart', evt); + } + + // execute user defined ondragmove if defined + go.drag.node._handleEvent('dragmove', evt); + } }, /** * build dom diff --git a/dist/kinetic-core.min.js b/dist/kinetic-core.min.js index dd5f36da..f498d677 100644 --- a/dist/kinetic-core.min.js +++ b/dist/kinetic-core.min.js @@ -3,7 +3,7 @@ * http://www.kineticjs.com/ * Copyright 2012, Eric Rowell * Licensed under the MIT or GPL Version 2 licenses. - * Date: Jun 14 2012 + * Date: Jun 15 2012 * * Copyright (C) 2011 - 2012 by Eric Rowell * @@ -25,5 +25,5 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -var Kinetic={};Kinetic.GlobalObject={stages:[],idCounter:0,tempNodes:[],animations:[],animIdCounter:0,animRunning:!1,maxDragTimeInterval:20,frame:{time:0,timeDiff:0,lastTime:0},drag:{moving:!1,node:undefined,offset:{x:0,y:0},lastDrawTime:0},extend:function(a,b){for(var c in b.prototype)b.prototype.hasOwnProperty(c)&&a.prototype[c]===undefined&&(a.prototype[c]=b.prototype[c])},addSetters:function(constructor,a){for(var b=0;b0){this._updateFrameObject(),this._runFrames();var a=this;requestAnimFrame(function(){a._animationLoop()})}else this.animRunning=!1,this.frame.lastTime=0},_handleAnimation:function(){var a=this;this.animRunning?this.frame.lastTime=0:(this.animRunning=!0,a._animationLoop())},_isElement:function(a){return!!a&&a.nodeType==1},_isFunction:function(a){return!!(a&&a.constructor&&a.call&&a.apply)},_isArray:function(a){return a.length!==undefined},_isObject:function(a){return typeof a=="object"},_isNumber:function(a){return Object.prototype.toString.call(a)=="[object Number]"},_hasMethods:function(a){var b=[];for(var c in a)this._isFunction(a[c])&&b.push(c);return b.length>0},_getXY:function(a){if(this._isNumber(a))return{x:a,y:a};if(this._isArray(a)){if(a.length===1){var b=a[0];if(this._isNumber(b))return{x:b,y:b};if(this._isArray(b))return{x:b[0],y:b[1]};if(this._isObject(b))return b}else if(a.length>=2)return{x:a[0],y:a[1]}}else if(this._isObject(a))return a;return{x:0,y:0}},_getSize:function(a){if(this._isNumber(a))return{width:a,height:a};if(this._isArray(a))if(a.length===1){var b=a[0];if(this._isNumber(b))return{width:b,height:b};if(this._isArray(b)){if(b.length>=4)return{width:b[2],height:b[3]};if(b.length>=2)return{width:b[0],height:b[1]}}else if(this._isObject(b))return b}else{if(a.length>=4)return{width:a[2],height:a[3]};if(a.length>=2)return{width:a[0],height:a[1]}}else if(this._isObject(a))return a;return{width:0,height:0}},_getPoints:function(a){if(a===undefined)return[];if(this._isObject(a[0]))return a;var b=[];for(var c=0;c1?g[1]:"";this.eventListeners[h]||(this.eventListeners[h]=[]),this.eventListeners[h].push({name:i,handler:b})}},off:function(a){var b=a.split(" ");for(var c=0;c1){var h=f[1];for(var i=0;i0&&f[0].getLevel()<=a&&e(f)}var a=this.getLevel(),b=this.getStage(),c=this,d=0;return c.nodeType!=="Stage"&&e(c.getStage().getChildren()),d},getLevel:function(){var a=0,b=this.parent;while(b)a++,b=b.parent;return a},setScale:function(){this.setAttrs({scale:arguments})},setPosition:function(){var a=Kinetic.GlobalObject._getXY(arguments);this.setAttrs(a)},getPosition:function(){return{x:this.attrs.x,y:this.attrs.y}},getAbsolutePosition:function(){return this.getAbsoluteTransform().getTranslation()},setAbsolutePosition:function(){var a=Kinetic.GlobalObject._getXY(arguments),b=this.attrs.rotation,c={x:this.attrs.scale.x,y:this.attrs.scale.y},d={x:this.attrs.offset.x,y:this.attrs.offset.y};this.attrs.rotation=0,this.attrs.scale={x:1,y:1};var e=this.getAbsoluteTransform();e.invert(),e.translate(a.x,a.y),a={x:this.attrs.x+e.getTranslation().x,y:this.attrs.y+e.getTranslation().y},this.setPosition(a.x,a.y),this.rotate(b),this.attrs.scale={x:c.x,y:c.y}},move:function(){var a=Kinetic.GlobalObject._getXY(arguments),b=this.getX(),c=this.getY();a.x!==undefined&&(b+=a.x),a.y!==undefined&&(c+=a.y),this.setAttrs({x:b,y:c})},setRotationDeg:function(a){this.setRotation(a*Math.PI/180)},getRotationDeg:function(){return this.attrs.rotation*180/Math.PI},rotate:function(a){this.setAttrs({rotation:this.getRotation()+a})},rotateDeg:function(a){this.setAttrs({rotation:this.getRotation()+a*Math.PI/180})},listen:function(a){this.setAttrs({listen:a})},isListening:function(){return this.attrs.listen},moveToTop:function(){var a=this.index;this.parent.children.splice(a,1),this.parent.children.push(this),this.parent._setChildrenIndices()},moveUp:function(){var a=this.index;this.parent.children.splice(a,1),this.parent.children.splice(a+1,0,this),this.parent._setChildrenIndices()},moveDown:function(){var a=this.index;a>0&&(this.parent.children.splice(a,1),this.parent.children.splice(a-1,0,this),this.parent._setChildrenIndices())},moveToBottom:function(){var a=this.index;this.parent.children.splice(a,1),this.parent.children.unshift(this),this.parent._setChildrenIndices()},setZIndex:function(a){var b=this.index;this.parent.children.splice(b,1),this.parent.children.splice(a,0,this),this.parent._setChildrenIndices()},getAbsoluteAlpha:function(){var a=1,b=this;while(b.nodeType!=="Stage")a*=b.attrs.alpha,b=b.parent;return a},draggable:function(a){this.setAttrs({draggable:a})},isDragging:function(){var a=Kinetic.GlobalObject;return a.drag.node!==undefined&&a.drag.node._id===this._id&&a.drag.moving},moveTo:function(a){var b=this.parent;b.children.splice(this.index,1),b._setChildrenIndices(),a.children.push(this),this.index=a.children.length-1,this.parent=a,a._setChildrenIndices()},getParent:function(){return this.parent},getLayer:function(){return this.nodeType==="Layer"?this:this.getParent().getLayer()},getStage:function(){return this.nodeType==="Stage"?this:this.getParent()===undefined?undefined:this.getParent().getStage()},simulate:function(a){this._handleEvent(a,{})},setOffset:function(){this.setAttrs({offset:arguments})},transitionTo:function(a){var b=Kinetic.GlobalObject;this.transAnim!==undefined&&(b._removeAnimation(this.transAnim),this.transAnim=undefined);var c=this.nodeType==="Stage"?this:this.getLayer(),d=this,e=new Kinetic.Transition(this,a),f={func:function(){e._onEnterFrame()},node:c};return this.transAnim=f,b._addAnimation(f),e.onFinished=function(){b._removeAnimation(f),d.transAnim=undefined,a.callback!==undefined&&a.callback(),f.node.draw()},e.start(),b._handleAnimation(),e},getAbsoluteTransform:function(){var a=new Kinetic.Transform,b=[],c=this.parent;b.unshift(this);while(c)b.unshift(c),c=c.parent;for(var d=0;d0)this.remove(this.children[0])},add:function(a){a._id=Kinetic.GlobalObject.idCounter++,a.index=this.children.length,a.parent=this,this.children.push(a);var b=a.getStage();if(b===undefined){var c=Kinetic.GlobalObject;c.tempNodes.push(a)}else{b._addId(a),b._addName(a);var c=Kinetic.GlobalObject;c._pullNodes(b)}return this._add!==undefined&&this._add(a),this},remove:function(a){if(a&&a.index!==undefined&&this.children[a.index]._id==a._id){var b=this.getStage();b!==undefined&&(b._removeId(a),b._removeName(a));var c=Kinetic.GlobalObject;for(var d=0;d=0;d--){var e=c[d];if(e.attrs.listen)if(e.nodeType==="Shape"){var f=this._detectEvent(e,b);if(f)return!0}else{var f=this._traverseChildren(e,b);if(f)return!0}}return!1},_handleStageEvent:function(a){var b=new Date,c=b.getTime();this.lastEventTime=c;var d=Kinetic.GlobalObject;a||(a=window.event),this._setMousePosition(a),this._setTouchPosition(a),this.pathLayer.clear(),this.targetFound=!1;var e=!1;for(var f=this.children.length-1;f>=0;f--){var g=this.children[f];if(g.isVisible()&&f>=0&&g.attrs.listen&&this._traverseChildren(g,a)){e=!0;break}}!e&&this.mouseoutShape&&(this.mouseoutShape._handleEvent("mouseout",a),this.mouseoutShape=undefined)},_bindContentEvents:function(){var a=Kinetic.GlobalObject,b=this,c=["mousedown","mousemove","mouseup","mouseover","mouseout","touchstart","touchmove","touchend"];for(var d=0;d=f&&(this.mouseDown=!1,this.mouseUp=!1,this._handleStageEvent(a))},_onmousedown:function(a){this.mouseDown=!0,this.mouseUp=!1,this.mouseMove=!1,this._handleStageEvent(a),this.attrs.draggable&&this._initDrag()},_onmouseup:function(a){this.mouseDown=!1,this.mouseUp=!0,this.mouseMove=!1,this._handleStageEvent(a),this.clickStart=!1},_ontouchstart:function(a){a.preventDefault(),this.touchStart=!0,this.touchEnd=!1,this.touchMove=!1,this._handleStageEvent(a),this.attrs.draggable&&this._initDrag()},_ontouchend:function(a){this.touchStart=!1,this.touchEnd=!0,this.touchMove=!1,this._handleStageEvent(a),this.tapStart=!1},_ontouchmove:function(a){var b=this,c=this.attrs.throttle,d=new Date,e=d.getTime(),f=e-this.lastEventTime,g=1e3/c;f>=g&&setTimeout(function(){a.preventDefault(),b.touchEnd=!1,b.touchMove=!0,b._handleStageEvent(a)},5)},_setMousePosition:function(a){var b=a.offsetX||a.clientX-this._getContentPosition().left+window.pageXOffset,c=a.offsetY||a.clientY-this._getContentPosition().top+window.pageYOffset;this.mousePos={x:b,y:c}},_setTouchPosition:function(a){if(a.touches!==undefined&&a.touches.length===1){var b=a.touches[0],c=b.clientX-this._getContentPosition().left+window.pageXOffset,d=b.clientY-this._getContentPosition().top+window.pageYOffset;this.touchPos={x:c,y:d}}},_getContentPosition:function(){var a=this.content,b=0,c=0;while(a&&a.tagName!=="BODY")b+=a.offsetTop-a.scrollTop,c+=a.offsetLeft-a.scrollLeft,a=a.offsetParent;return{top:b,left:c}},_modifyPathContext:function(a){a.stroke=function(){},a.fill=function(){},a.fillRect=function(b,c,d,e){a.rect(b,c,d,e)},a.strokeRect=function(b,c,d,e){a.rect(b,c,d,e)},a.drawImage=function(){},a.fillText=function(){},a.strokeText=function(){}},_endDrag:function(a){var b=Kinetic.GlobalObject;b.drag.node&&b.drag.moving&&(b.drag.moving=!1,b.drag.node._handleEvent("dragend",a)),b.drag.node=undefined},_prepareDrag:function(){var a=this;this._onContent("mousemove touchmove",function(b){var c=Kinetic.GlobalObject,d=c.drag.node;if(d){var e=a.getUserPosition(),f=d.attrs.dragConstraint,g=d.attrs.dragBounds,h={x:d.attrs.x,y:d.attrs.y},i={x:e.x-c.drag.offset.x,y:e.y-c.drag.offset.y};g.left!==undefined&&i.xg.right&&(i.x=g.right),g.top!==undefined&&i.yg.bottom&&(i.y=g.bottom),d.setAbsolutePosition(i),f==="horizontal"?d.attrs.y=h.y:f==="vertical"&&(d.attrs.x=h.x),c.drag.node.nodeType==="Stage"?c.drag.node.draw():c.drag.node.getLayer().draw(),c.drag.moving||(c.drag.moving=!0,c.drag.node._handleEvent("dragstart",b)),c.drag.node._handleEvent("dragmove",b)}},!1),this._onContent("mouseup touchend mouseout",function(b){a._endDrag(b)})},_buildDOM:function(){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.bufferLayer=new Kinetic.Layer({name:"bufferLayer"}),this.pathLayer=new Kinetic.Layer({name:"pathLayer"}),this.bufferLayer.parent=this,this.pathLayer.parent=this,this._modifyPathContext(this.pathLayer.context),this.bufferLayer.getCanvas().style.display="none",this.pathLayer.getCanvas().style.display="none",this.bufferLayer.canvas.className="kineticjs-buffer-layer",this.content.appendChild(this.bufferLayer.canvas),this.pathLayer.canvas.className="kineticjs-path-layer",this.content.appendChild(this.pathLayer.canvas),this.setSize(this.attrs.width,this.attrs.height),this._resizeDOM()},_addId:function(a){a.attrs.id!==undefined&&(this.ids[a.attrs.id]=a)},_removeId:function(a){a.attrs.id!==undefined&&(this.ids[a.attrs.id]=undefined)},_addName:function(a){var b=a.attrs.name;b!==undefined&&(this.names[b]===undefined&&(this.names[b]=[]),this.names[b].push(a))},_removeName:function(a){if(a.attrs.name!==undefined){var b=this.names[a.attrs.name];if(b!==undefined){for(var c=0;c=e)this._draw(),this.drawTimeout!==undefined&&(clearTimeout(this.drawTimeout),this.drawTimeout=undefined);else if(this.drawTimeout===undefined){var f=this;this.drawTimeout=setTimeout(function(){f.draw()},17)}},setThrottle:function(a){this.attrs.throttle=a},getThrottle:function(){return this.attrs.throttle},beforeDraw:function(a){this.beforeDrawFunc=a},afterDraw:function(a){this.afterDrawFunc=a},clear:function(){var a=this.getContext(),b=this.getCanvas();a.clearRect(0,0,b.width,b.height)},getCanvas:function(){return this.canvas},getContext:function(){return this.context},_draw:function(){var a=new Date,b=a.getTime();this.lastDrawTime=b,this.beforeDrawFunc!==undefined&&this.beforeDrawFunc.call(this),this.clear(),this.isVisible()&&(this.attrs.drawFunc!==undefined&&this.attrs.drawFunc.call(this),this._drawChildren()),this.afterDrawFunc!==undefined&&this.afterDrawFunc.call(this)}},Kinetic.GlobalObject.extend(Kinetic.Layer,Kinetic.Container),Kinetic.GlobalObject.extend(Kinetic.Layer,Kinetic.Node),Kinetic.Group=function(a){this.nodeType="Group",Kinetic.Container.apply(this,[]),Kinetic.Node.apply(this,[a])},Kinetic.Group.prototype={draw:function(){this.attrs.visible&&this._drawChildren()}},Kinetic.GlobalObject.extend(Kinetic.Group,Kinetic.Container),Kinetic.GlobalObject.extend(Kinetic.Group,Kinetic.Node),Kinetic.Shape=function(a){this.setDefaultAttrs({fill:undefined,stroke:undefined,strokeWidth:undefined,lineJoin:undefined,detectionType:"path",shadow:{blur:10,alpha:1,offset:{x:0,y:0}}}),this.data=[],this.nodeType="Shape",this.appliedShadow=!1,Kinetic.Node.apply(this,[a])},Kinetic.Shape.prototype={getContext:function(){return this.tempLayer===undefined?null:this.tempLayer.getContext()},getCanvas:function(){return this.tempLayer.getCanvas()},stroke:function(){var a=!1,b=this.getContext();b.save();if(!!this.attrs.stroke||!!this.attrs.strokeWidth){this.appliedShadow||(a=this._applyShadow());var c=this.attrs.stroke?this.attrs.stroke:"black",d=this.attrs.strokeWidth?this.attrs.strokeWidth:2;b.lineWidth=d,b.strokeStyle=c,b.stroke()}b.restore(),a&&this.stroke()},fill:function(){var a=!1,b=this.getContext();b.save();var c=this.attrs.fill;if(!!c){this.appliedShadow||(a=this._applyShadow());var d=c.start,e=c.end,f=null;if(typeof c=="string")f=this.attrs.fill,b.fillStyle=f,b.fill();else if(c.image!==undefined){var g=c.repeat===undefined?"repeat":c.repeat;f=b.createPattern(c.image,g),b.save(),c.offset!==undefined&&b.translate(c.offset.x,c.offset.y),b.fillStyle=f,b.fill(),b.restore()}else if(d.radius===undefined&&e.radius===undefined){var b=this.getContext(),h=b.createLinearGradient(d.x,d.y,e.x,e.y),i=c.colorStops;for(var j=0;j0){var f=this.attrs.points[c-1].x,g=this.attrs.points[c-1].y;this._dashedLine(f,g,d,e,this.attrs.dashArray)}else a.lineTo(d,e)}!this.attrs.lineCap||(a.lineCap=this.attrs.lineCap),this.stroke()},Kinetic.Shape.apply(this,[a])},Kinetic.Line.prototype={setPoints:function(a){this.setAttrs({points:a})},_dashedLine:function(a,b,c,d,e){var f=this.getContext(),g=e.length,h=c-a,i=d-b,j=h>i,k=j?i/h:h/i;k>9999?k=9999:k<-9999&&(k=-9999);var l=Math.sqrt(h*h+i*i),m=0,n=!0;while(l>=.1&&m<1e4){var o=e[m++%g];o===0&&(o=.001),o>l&&(o=l);var p=Math.sqrt(o*o/(1+k*k));j?(a+=h<0&&i<0?p*-1:p,b+=h<0&&i<0?k*p*-1:k*p):(a+=h<0&&i<0?k*p*-1:k*p,b+=h<0&&i<0?p*-1:p),f[n?"lineTo":"moveTo"](a,b),l-=o,n=!n}f.moveTo(c,d)}},Kinetic.GlobalObject.extend(Kinetic.Line,Kinetic.Shape),Kinetic.GlobalObject.addSetters(Kinetic.Line,["dashArray","lineCap"]),Kinetic.GlobalObject.addGetters(Kinetic.Line,["dashArray","lineCap","points"]),Kinetic.Path=function(a){this.shapeType="Path",this.dataArray=[];var b=this;a.drawFunc=function(){var a=this.getContext(),b=this.dataArray;a.beginPath();for(var c=0;ci?h:i,o=h>i?1:h/i,p=h>i?i/h:1;a.translate(f,g),a.rotate(l),a.scale(o,p),a.arc(0,0,n,j,j+k,1-m),a.scale(1/o,1/p),a.rotate(-l),a.translate(-f,-g);break;case"z":a.closePath()}}this.fill(),this.stroke()},Kinetic.Shape.apply(this,[a]),this.dataArray=this.getDataArray(),this.on("dataArrayChange",function(){b.dataArray=b.getDataArray()})},Kinetic.Path.prototype={getDataArray:function(){var a=this.attrs.data,b=["m","M","l","L","v","V","h","H","z","Z","c","C","q","Q","t","T","s","S","a","A"];a=a.replace(new RegExp(" ","g"),",");for(var c=0;c0&&j[0]===""&&j.shift();for(var k=0;k0){if(isNaN(j[0]))break;var l=undefined,m=[];switch(i){case"l":f+=j.shift(),g+=j.shift(),l="L",m.push(f,g);break;case"L":f=j.shift(),g=j.shift(),m.push(f,g);break;case"m":f+=j.shift(),g+=j.shift(),l="M",m.push(f,g),i="l";break;case"M":f=j.shift(),g=j.shift(),l="M",m.push(f,g),i="L";break;case"h":f+=j.shift(),l="L",m.push(f,g);break;case"H":f=j.shift(),l="L",m.push(f,g);break;case"v":g+=j.shift(),l="L",m.push(f,g);break;case"V":g=j.shift(),l="L",m.push(f,g);break;case"C":m.push(j.shift(),j.shift(),j.shift(),j.shift()),f=j.shift(),g=j.shift(),m.push(f,g);break;case"c":m.push(f+j.shift(),g+j.shift(),f+j.shift(),g+j.shift()),f+=j.shift(),g+=j.shift(),l="C",m.push(f,g);break;case"S":var n=f,o=g,p=e[e.length-1];p.command==="C"&&(n=f+(f-p.points[2]),o=g+(g-p.points[3])),m.push(n,o,j.shift(),j.shift()),f=j.shift(),g=j.shift(),l="C",m.push(f,g);break;case"s":var n=f,o=g,p=e[e.length-1];p.command==="C"&&(n=f+(f-p.points[2]),o=g+(g-p.points[3])),m.push(n,o,f+j.shift(),g+j.shift()),f+=j.shift(),g+=j.shift(),l="C",m.push(f,g);break;case"Q":m.push(j.shift(),j.shift()),f=j.shift(),g=j.shift(),m.push(f,g);break;case"q":m.push(f+j.shift(),g+j.shift()),f+=j.shift(),g+=j.shift(),l="Q",m.push(f,g);break;case"T":var n=f,o=g,p=e[e.length-1];p.command==="Q"&&(n=f+(f-p.points[0]),o=g+(g-p.points[1])),f=j.shift(),g=j.shift(),l="Q",m.push(n,o,f,g);break;case"t":var n=f,o=g,p=e[e.length-1];p.command==="Q"&&(n=f+(f-p.points[0]),o=g+(g-p.points[1])),f+=j.shift(),g+=j.shift(),l="Q",m.push(n,o,f,g);break;case"A":var q=j.shift(),r=j.shift(),s=j.shift(),t=j.shift(),u=j.shift(),v=f,w=g;f=j.shift(),g=j.shift(),l="A",m=this._convertEndpointToCenterParameterization(v,w,f,g,t,u,q,r,s);break;case"a":var q=j.shift(),r=j.shift(),s=j.shift(),t=j.shift(),u=j.shift(),v=f,w=g;f+=j.shift(),g+=j.shift(),l="A",m=this._convertEndpointToCenterParameterization(v,w,f,g,t,u,q,r,s)}e.push({command:l||i,points:m})}(i==="z"||i==="Z")&&e.push({command:"z",points:[]})}return e},_convertEndpointToCenterParameterization:function(a,b,c,d,e,f,g,h,i){var j=i*(Math.PI/180),k=Math.cos(j)*(a-c)/2+Math.sin(j)*(b-d)/2,l=-1*Math.sin(j)*(a-c)/2+Math.cos(j)*(b-d)/2,m=k*k/(g*g)+l*l/(h*h);m>1&&(g*=Math.sqrt(m),h*=Math.sqrt(m));var n=Math.sqrt((g*g*h*h-g*g*l*l-h*h*k*k)/(g*g*l*l+h*h*k*k));e==f&&(n*=-1),isNaN(n)&&(n=0);var o=n*g*l/h,p=n*-h*k/g,q=(a+c)/2+Math.cos(j)*o-Math.sin(j)*p,r=(b+d)/2+Math.sin(j)*o+Math.cos(j)*p,s=function(a){return Math.sqrt(a[0]*a[0]+a[1]*a[1])},t=function(a,b){return(a[0]*b[0]+a[1]*b[1])/(s(a)*s(b))},u=function(a,b){return(a[0]*b[1]=1&&(y=0),f==0&&y>0&&(y-=2*Math.PI),f==1&&y<0&&(y+=2*Math.PI),[q,r,g,h,v,y,j,f]}},Kinetic.GlobalObject.extend(Kinetic.Path,Kinetic.Shape),Kinetic.GlobalObject.addSetters(Kinetic.Path,["data"]),Kinetic.GlobalObject.addGetters(Kinetic.Path,["data"]),Kinetic.Transform=function(){this.m=[1,0,0,1,0,0]},Kinetic.Transform.prototype={translate:function(a,b){this.m[4]+=this.m[0]*a+this.m[2]*b,this.m[5]+=this.m[1]*a+this.m[3]*b},scale:function(a,b){this.m[0]*=a,this.m[1]*=a,this.m[2]*=b,this.m[3]*=b},rotate:function(a){var b=Math.cos(a),c=Math.sin(a),d=this.m[0]*b+this.m[2]*c,e=this.m[1]*b+this.m[3]*c,f=this.m[0]*-c+this.m[2]*b,g=this.m[1]*-c+this.m[3]*b;this.m[0]=d,this.m[1]=e,this.m[2]=f,this.m[3]=g},getTranslation:function(){return{x:this.m[4],y:this.m[5]}},multiply:function(a){var b=this.m[0]*a.m[0]+this.m[2]*a.m[1],c=this.m[1]*a.m[0]+this.m[3]*a.m[1],d=this.m[0]*a.m[2]+this.m[2]*a.m[3],e=this.m[1]*a.m[2]+this.m[3]*a.m[3],f=this.m[0]*a.m[4]+this.m[2]*a.m[5]+this.m[4],g=this.m[1]*a.m[4]+this.m[3]*a.m[5]+this.m[5];this.m[0]=b,this.m[1]=c,this.m[2]=d,this.m[3]=e,this.m[4]=f,this.m[5]=g},invert:function(){var a=1/(this.m[0]*this.m[3]-this.m[1]*this.m[2]),b=this.m[3]*a,c=-this.m[1]*a,d=-this.m[2]*a,e=this.m[0]*a,f=a*(this.m[2]*this.m[5]-this.m[3]*this.m[4]),g=a*(this.m[1]*this.m[4]-this.m[0]*this.m[5]);this.m[0]=b,this.m[1]=c,this.m[2]=d,this.m[3]=e,this.m[4]=f,this.m[5]=g},getMatrix:function(){return this.m}},Kinetic.Transition=function(a,b){function d(a,b){for(var e in a)e!=="duration"&&e!=="easing"&&e!=="callback"&&(Kinetic.GlobalObject._isObject(a[e])?d(a[e],b[e]):c._add(c._getTween(b,e,a[e])))}this.node=a,this.config=b,this.tweens=[];var c=this;d(b,a.attrs);var e=0;for(var f=0;f=c.tweens.length&&c.onFinished()}}},Kinetic.Transition.prototype={start:function(){for(var a=0;athis.getDuration()?this.looping?(this.rewind(a-this._duration),this.update(),this.broadcastMessage("onLooped",{target:this,type:"onLooped"})):(this._time=this._duration,this.update(),this.stop(),this.broadcastMessage("onFinished",{target:this,type:"onFinished"})):a<0?(this.rewind(),this.update()):(this._time=a,this.update())},getTime:function(){return this._time},setDuration:function(a){this._duration=a===null||a<=0?1e5:a},getDuration:function(){return this._duration},setPosition:function(a){this.prevPos=this._pos,this.propFunc(a),this._pos=a,this.broadcastMessage("onChanged",{target:this,type:"onChanged"})},getPosition:function(a){return a===undefined&&(a=this._time),this.func(a,this.begin,this._change,this._duration)},setFinish:function(a){this._change=a-this.begin},getFinish:function(){return this.begin+this._change},start:function(){this.rewind(),this.startEnterFrame(),this.broadcastMessage("onStarted",{target:this,type:"onStarted"})},rewind:function(a){this.stop(),this._time=a===undefined?0:a,this.fixTime(),this.update()},fforward:function(){this._time=this._duration,this.fixTime(),this.update()},update:function(){this.setPosition(this.getPosition(this._time))},startEnterFrame:function(){this.stopEnterFrame(),this.isPlaying=!0,this.onEnterFrame()},onEnterFrame:function(){this.isPlaying&&this.nextFrame()},nextFrame:function(){this.setTime((this.getTimer()-this._startTime)/1e3)},stop:function(){this.stopEnterFrame(),this.broadcastMessage("onStopped",{target:this,type:"onStopped"})},stopEnterFrame:function(){this.isPlaying=!1},continueTo:function(a,b){this.begin=this._pos,this.setFinish(a),this._duration!==undefined&&this.setDuration(b),this.start()},resume:function(){this.fixTime(),this.startEnterFrame(),this.broadcastMessage("onResumed",{target:this,type:"onResumed"})},yoyo:function(){this.continueTo(this.begin,this._time)},addListener:function(a){return this.removeListener(a),this._listeners.push(a)},removeListener:function(a){var b=this._listeners,c=b.length;while(c--)if(b[c]==a)return b.splice(c,1),!0;return!1},broadcastMessage:function(){var a=[];for(var b=0;b0){this._updateFrameObject(),this._runFrames();var a=this;requestAnimFrame(function(){a._animationLoop()})}else this.animRunning=!1,this.frame.lastTime=0},_handleAnimation:function(){var a=this;this.animRunning?this.frame.lastTime=0:(this.animRunning=!0,a._animationLoop())},_isElement:function(a){return!!a&&a.nodeType==1},_isFunction:function(a){return!!(a&&a.constructor&&a.call&&a.apply)},_isArray:function(a){return a.length!==undefined},_isObject:function(a){return typeof a=="object"},_isNumber:function(a){return Object.prototype.toString.call(a)=="[object Number]"},_hasMethods:function(a){var b=[];for(var c in a)this._isFunction(a[c])&&b.push(c);return b.length>0},_getXY:function(a){if(this._isNumber(a))return{x:a,y:a};if(this._isArray(a)){if(a.length===1){var b=a[0];if(this._isNumber(b))return{x:b,y:b};if(this._isArray(b))return{x:b[0],y:b[1]};if(this._isObject(b))return b}else if(a.length>=2)return{x:a[0],y:a[1]}}else if(this._isObject(a))return a;return{x:0,y:0}},_getSize:function(a){if(this._isNumber(a))return{width:a,height:a};if(this._isArray(a))if(a.length===1){var b=a[0];if(this._isNumber(b))return{width:b,height:b};if(this._isArray(b)){if(b.length>=4)return{width:b[2],height:b[3]};if(b.length>=2)return{width:b[0],height:b[1]}}else if(this._isObject(b))return b}else{if(a.length>=4)return{width:a[2],height:a[3]};if(a.length>=2)return{width:a[0],height:a[1]}}else if(this._isObject(a))return a;return{width:0,height:0}},_getPoints:function(a){if(a===undefined)return[];if(this._isObject(a[0]))return a;var b=[];for(var c=0;c1?g[1]:"";this.eventListeners[h]||(this.eventListeners[h]=[]),this.eventListeners[h].push({name:i,handler:b})}},off:function(a){var b=a.split(" ");for(var c=0;c1){var h=f[1];for(var i=0;i0&&f[0].getLevel()<=a&&e(f)}var a=this.getLevel(),b=this.getStage(),c=this,d=0;return c.nodeType!=="Stage"&&e(c.getStage().getChildren()),d},getLevel:function(){var a=0,b=this.parent;while(b)a++,b=b.parent;return a},setScale:function(){this.setAttrs({scale:arguments})},setPosition:function(){var a=Kinetic.GlobalObject._getXY(arguments);this.setAttrs(a)},getPosition:function(){return{x:this.attrs.x,y:this.attrs.y}},getAbsolutePosition:function(){return this.getAbsoluteTransform().getTranslation()},setAbsolutePosition:function(){var a=Kinetic.GlobalObject._getXY(arguments),b=this.attrs.rotation,c={x:this.attrs.scale.x,y:this.attrs.scale.y},d={x:this.attrs.offset.x,y:this.attrs.offset.y};this.attrs.rotation=0,this.attrs.scale={x:1,y:1};var e=this.getAbsoluteTransform();e.invert(),e.translate(a.x,a.y),a={x:this.attrs.x+e.getTranslation().x,y:this.attrs.y+e.getTranslation().y},this.setPosition(a.x,a.y),this.rotate(b),this.attrs.scale={x:c.x,y:c.y}},move:function(){var a=Kinetic.GlobalObject._getXY(arguments),b=this.getX(),c=this.getY();a.x!==undefined&&(b+=a.x),a.y!==undefined&&(c+=a.y),this.setAttrs({x:b,y:c})},setRotationDeg:function(a){this.setRotation(a*Math.PI/180)},getRotationDeg:function(){return this.attrs.rotation*180/Math.PI},rotate:function(a){this.setAttrs({rotation:this.getRotation()+a})},rotateDeg:function(a){this.setAttrs({rotation:this.getRotation()+a*Math.PI/180})},listen:function(a){this.setAttrs({listen:a})},isListening:function(){return this.attrs.listen},moveToTop:function(){var a=this.index;this.parent.children.splice(a,1),this.parent.children.push(this),this.parent._setChildrenIndices()},moveUp:function(){var a=this.index;this.parent.children.splice(a,1),this.parent.children.splice(a+1,0,this),this.parent._setChildrenIndices()},moveDown:function(){var a=this.index;a>0&&(this.parent.children.splice(a,1),this.parent.children.splice(a-1,0,this),this.parent._setChildrenIndices())},moveToBottom:function(){var a=this.index;this.parent.children.splice(a,1),this.parent.children.unshift(this),this.parent._setChildrenIndices()},setZIndex:function(a){var b=this.index;this.parent.children.splice(b,1),this.parent.children.splice(a,0,this),this.parent._setChildrenIndices()},getAbsoluteAlpha:function(){var a=1,b=this;while(b.nodeType!=="Stage")a*=b.attrs.alpha,b=b.parent;return a},draggable:function(a){this.setAttrs({draggable:a})},isDragging:function(){var a=Kinetic.GlobalObject;return a.drag.node!==undefined&&a.drag.node._id===this._id&&a.drag.moving},moveTo:function(a){var b=this.parent;b.children.splice(this.index,1),b._setChildrenIndices(),a.children.push(this),this.index=a.children.length-1,this.parent=a,a._setChildrenIndices()},getParent:function(){return this.parent},getLayer:function(){return this.nodeType==="Layer"?this:this.getParent().getLayer()},getStage:function(){return this.nodeType==="Stage"?this:this.getParent()===undefined?undefined:this.getParent().getStage()},simulate:function(a){this._handleEvent(a,{})},setOffset:function(){this.setAttrs({offset:arguments})},transitionTo:function(a){var b=Kinetic.GlobalObject;this.transAnim!==undefined&&(b._removeAnimation(this.transAnim),this.transAnim=undefined);var c=this.nodeType==="Stage"?this:this.getLayer(),d=this,e=new Kinetic.Transition(this,a),f={func:function(){e._onEnterFrame()},node:c};return this.transAnim=f,b._addAnimation(f),e.onFinished=function(){b._removeAnimation(f),d.transAnim=undefined,a.callback!==undefined&&a.callback(),f.node.draw()},e.start(),b._handleAnimation(),e},getAbsoluteTransform:function(){var a=new Kinetic.Transform,b=[],c=this.parent;b.unshift(this);while(c)b.unshift(c),c=c.parent;for(var d=0;d0)this.remove(this.children[0])},add:function(a){a._id=Kinetic.GlobalObject.idCounter++,a.index=this.children.length,a.parent=this,this.children.push(a);var b=a.getStage();if(b===undefined){var c=Kinetic.GlobalObject;c.tempNodes.push(a)}else{b._addId(a),b._addName(a);var c=Kinetic.GlobalObject;c._pullNodes(b)}return this._add!==undefined&&this._add(a),this},remove:function(a){if(a&&a.index!==undefined&&this.children[a.index]._id==a._id){var b=this.getStage();b!==undefined&&(b._removeId(a),b._removeName(a));var c=Kinetic.GlobalObject;for(var d=0;d=0;d--){var e=c[d];if(e.attrs.listen)if(e.nodeType==="Shape"){var f=this._detectEvent(e,b);if(f)return!0}else{var f=this._traverseChildren(e,b);if(f)return!0}}return!1},_handleStageEvent:function(a){var b=new Date,c=b.getTime();this.lastEventTime=c;var d=Kinetic.GlobalObject;a||(a=window.event),this._setMousePosition(a),this._setTouchPosition(a),this.pathLayer.clear(),this.targetFound=!1;var e=!1;for(var f=this.children.length-1;f>=0;f--){var g=this.children[f];if(g.isVisible()&&f>=0&&g.attrs.listen&&this._traverseChildren(g,a)){e=!0;break}}!e&&this.mouseoutShape&&(this.mouseoutShape._handleEvent("mouseout",a),this.mouseoutShape=undefined)},_bindContentEvents:function(){var a=Kinetic.GlobalObject,b=this,c=["mousedown","mousemove","mouseup","mouseover","mouseout","touchstart","touchmove","touchend"];for(var d=0;d=f&&(this.mouseDown=!1,this.mouseUp=!1,this._handleStageEvent(a)),this._startDrag(a)},_mousedown:function(a){this.mouseDown=!0,this.mouseUp=!1,this.mouseMove=!1,this._handleStageEvent(a),this.attrs.draggable&&this._initDrag()},_mouseup:function(a){this.mouseDown=!1,this.mouseUp=!0,this.mouseMove=!1,this._handleStageEvent(a),this.clickStart=!1,this._endDrag(a)},_touchstart:function(a){a.preventDefault(),this.touchStart=!0,this.touchEnd=!1,this.touchMove=!1,this._handleStageEvent(a),this.attrs.draggable&&this._initDrag()},_touchend:function(a){this.touchStart=!1,this.touchEnd=!0,this.touchMove=!1,this._handleStageEvent(a),this.tapStart=!1,this._endDrag(a)},_touchmove:function(a){var b=this,c=this.attrs.throttle,d=new Date,e=d.getTime(),f=e-this.lastEventTime,g=1e3/c;f>=g&&setTimeout(function(){a.preventDefault(),b.touchEnd=!1,b.touchMove=!0,b._handleStageEvent(a)},5),this._startDrag(a)},_setMousePosition:function(a){var b=a.offsetX||a.clientX-this._getContentPosition().left+window.pageXOffset,c=a.offsetY||a.clientY-this._getContentPosition().top+window.pageYOffset;this.mousePos={x:b,y:c}},_setTouchPosition:function(a){if(a.touches!==undefined&&a.touches.length===1){var b=a.touches[0],c=b.clientX-this._getContentPosition().left+window.pageXOffset,d=b.clientY-this._getContentPosition().top+window.pageYOffset;this.touchPos={x:c,y:d}}},_getContentPosition:function(){var a=this.content,b=0,c=0;while(a&&a.tagName!=="BODY")b+=a.offsetTop-a.scrollTop,c+=a.offsetLeft-a.scrollLeft,a=a.offsetParent;return{top:b,left:c}},_modifyPathContext:function(a){a.stroke=function(){},a.fill=function(){},a.fillRect=function(b,c,d,e){a.rect(b,c,d,e)},a.strokeRect=function(b,c,d,e){a.rect(b,c,d,e)},a.drawImage=function(){},a.fillText=function(){},a.strokeText=function(){}},_endDrag:function(a){var b=Kinetic.GlobalObject;b.drag.node&&b.drag.moving&&(b.drag.moving=!1,b.drag.node._handleEvent("dragend",a)),b.drag.node=undefined},_startDrag:function(a){var b=this,c=Kinetic.GlobalObject,d=c.drag.node;if(d){var e=b.getUserPosition(),f=d.attrs.dragConstraint,g=d.attrs.dragBounds,h={x:d.attrs.x,y:d.attrs.y},i={x:e.x-c.drag.offset.x,y:e.y-c.drag.offset.y};g.left!==undefined&&i.xg.right&&(i.x=g.right),g.top!==undefined&&i.yg.bottom&&(i.y=g.bottom),d.setAbsolutePosition(i),f==="horizontal"?d.attrs.y=h.y:f==="vertical"&&(d.attrs.x=h.x),c.drag.node.nodeType==="Stage"?c.drag.node.draw():c.drag.node.getLayer().draw(),c.drag.moving||(c.drag.moving=!0,c.drag.node._handleEvent("dragstart",a)),c.drag.node._handleEvent("dragmove",a)}},_buildDOM:function(){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.bufferLayer=new Kinetic.Layer({name:"bufferLayer"}),this.pathLayer=new Kinetic.Layer({name:"pathLayer"}),this.bufferLayer.parent=this,this.pathLayer.parent=this,this._modifyPathContext(this.pathLayer.context),this.bufferLayer.getCanvas().style.display="none",this.pathLayer.getCanvas().style.display="none",this.bufferLayer.canvas.className="kineticjs-buffer-layer",this.content.appendChild(this.bufferLayer.canvas),this.pathLayer.canvas.className="kineticjs-path-layer",this.content.appendChild(this.pathLayer.canvas),this.setSize(this.attrs.width,this.attrs.height),this._resizeDOM()},_addId:function(a){a.attrs.id!==undefined&&(this.ids[a.attrs.id]=a)},_removeId:function(a){a.attrs.id!==undefined&&(this.ids[a.attrs.id]=undefined)},_addName:function(a){var b=a.attrs.name;b!==undefined&&(this.names[b]===undefined&&(this.names[b]=[]),this.names[b].push(a))},_removeName:function(a){if(a.attrs.name!==undefined){var b=this.names[a.attrs.name];if(b!==undefined){for(var c=0;c=e)this._draw(),this.drawTimeout!==undefined&&(clearTimeout(this.drawTimeout),this.drawTimeout=undefined);else if(this.drawTimeout===undefined){var f=this;this.drawTimeout=setTimeout(function(){f.draw()},17)}},setThrottle:function(a){this.attrs.throttle=a},getThrottle:function(){return this.attrs.throttle},beforeDraw:function(a){this.beforeDrawFunc=a},afterDraw:function(a){this.afterDrawFunc=a},clear:function(){var a=this.getContext(),b=this.getCanvas();a.clearRect(0,0,b.width,b.height)},getCanvas:function(){return this.canvas},getContext:function(){return this.context},_draw:function(){var a=new Date,b=a.getTime();this.lastDrawTime=b,this.beforeDrawFunc!==undefined&&this.beforeDrawFunc.call(this),this.clear(),this.isVisible()&&(this.attrs.drawFunc!==undefined&&this.attrs.drawFunc.call(this),this._drawChildren()),this.afterDrawFunc!==undefined&&this.afterDrawFunc.call(this)}},Kinetic.GlobalObject.extend(Kinetic.Layer,Kinetic.Container),Kinetic.GlobalObject.extend(Kinetic.Layer,Kinetic.Node),Kinetic.Group=function(a){this.nodeType="Group",Kinetic.Container.apply(this,[]),Kinetic.Node.apply(this,[a])},Kinetic.Group.prototype={draw:function(){this.attrs.visible&&this._drawChildren()}},Kinetic.GlobalObject.extend(Kinetic.Group,Kinetic.Container),Kinetic.GlobalObject.extend(Kinetic.Group,Kinetic.Node),Kinetic.Shape=function(a){this.setDefaultAttrs({fill:undefined,stroke:undefined,strokeWidth:undefined,lineJoin:undefined,detectionType:"path",shadow:{blur:10,alpha:1,offset:{x:0,y:0}}}),this.data=[],this.nodeType="Shape",this.appliedShadow=!1,Kinetic.Node.apply(this,[a])},Kinetic.Shape.prototype={getContext:function(){return this.tempLayer===undefined?null:this.tempLayer.getContext()},getCanvas:function(){return this.tempLayer.getCanvas()},stroke:function(){var a=!1,b=this.getContext();b.save();if(!!this.attrs.stroke||!!this.attrs.strokeWidth){this.appliedShadow||(a=this._applyShadow());var c=this.attrs.stroke?this.attrs.stroke:"black",d=this.attrs.strokeWidth?this.attrs.strokeWidth:2;b.lineWidth=d,b.strokeStyle=c,b.stroke()}b.restore(),a&&this.stroke()},fill:function(){var a=!1,b=this.getContext();b.save();var c=this.attrs.fill;if(!!c){this.appliedShadow||(a=this._applyShadow());var d=c.start,e=c.end,f=null;if(typeof c=="string")f=this.attrs.fill,b.fillStyle=f,b.fill();else if(c.image!==undefined){var g=c.repeat===undefined?"repeat":c.repeat;f=b.createPattern(c.image,g),b.save(),c.offset!==undefined&&b.translate(c.offset.x,c.offset.y),b.fillStyle=f,b.fill(),b.restore()}else if(d.radius===undefined&&e.radius===undefined){var b=this.getContext(),h=b.createLinearGradient(d.x,d.y,e.x,e.y),i=c.colorStops;for(var j=0;j0){var f=this.attrs.points[c-1].x,g=this.attrs.points[c-1].y;this._dashedLine(f,g,d,e,this.attrs.dashArray)}else a.lineTo(d,e)}!this.attrs.lineCap||(a.lineCap=this.attrs.lineCap),this.stroke()},Kinetic.Shape.apply(this,[a])},Kinetic.Line.prototype={setPoints:function(a){this.setAttrs({points:a})},_dashedLine:function(a,b,c,d,e){var f=this.getContext(),g=e.length,h=c-a,i=d-b,j=h>i,k=j?i/h:h/i;k>9999?k=9999:k<-9999&&(k=-9999);var l=Math.sqrt(h*h+i*i),m=0,n=!0;while(l>=.1&&m<1e4){var o=e[m++%g];o===0&&(o=.001),o>l&&(o=l);var p=Math.sqrt(o*o/(1+k*k));j?(a+=h<0&&i<0?p*-1:p,b+=h<0&&i<0?k*p*-1:k*p):(a+=h<0&&i<0?k*p*-1:k*p,b+=h<0&&i<0?p*-1:p),f[n?"lineTo":"moveTo"](a,b),l-=o,n=!n}f.moveTo(c,d)}},Kinetic.GlobalObject.extend(Kinetic.Line,Kinetic.Shape),Kinetic.GlobalObject.addSetters(Kinetic.Line,["dashArray","lineCap"]),Kinetic.GlobalObject.addGetters(Kinetic.Line,["dashArray","lineCap","points"]),Kinetic.Path=function(a){this.shapeType="Path",this.dataArray=[];var b=this;a.drawFunc=function(){var a=this.getContext(),b=this.dataArray;a.beginPath();for(var c=0;ci?h:i,o=h>i?1:h/i,p=h>i?i/h:1;a.translate(f,g),a.rotate(l),a.scale(o,p),a.arc(0,0,n,j,j+k,1-m),a.scale(1/o,1/p),a.rotate(-l),a.translate(-f,-g);break;case"z":a.closePath()}}this.fill(),this.stroke()},Kinetic.Shape.apply(this,[a]),this.dataArray=this.getDataArray(),this.on("dataArrayChange",function(){b.dataArray=b.getDataArray()})},Kinetic.Path.prototype={getDataArray:function(){var a=this.attrs.data,b=["m","M","l","L","v","V","h","H","z","Z","c","C","q","Q","t","T","s","S","a","A"];a=a.replace(new RegExp(" ","g"),",");for(var c=0;c0&&j[0]===""&&j.shift();for(var k=0;k0){if(isNaN(j[0]))break;var l=undefined,m=[];switch(i){case"l":f+=j.shift(),g+=j.shift(),l="L",m.push(f,g);break;case"L":f=j.shift(),g=j.shift(),m.push(f,g);break;case"m":f+=j.shift(),g+=j.shift(),l="M",m.push(f,g),i="l";break;case"M":f=j.shift(),g=j.shift(),l="M",m.push(f,g),i="L";break;case"h":f+=j.shift(),l="L",m.push(f,g);break;case"H":f=j.shift(),l="L",m.push(f,g);break;case"v":g+=j.shift(),l="L",m.push(f,g);break;case"V":g=j.shift(),l="L",m.push(f,g);break;case"C":m.push(j.shift(),j.shift(),j.shift(),j.shift()),f=j.shift(),g=j.shift(),m.push(f,g);break;case"c":m.push(f+j.shift(),g+j.shift(),f+j.shift(),g+j.shift()),f+=j.shift(),g+=j.shift(),l="C",m.push(f,g);break;case"S":var n=f,o=g,p=e[e.length-1];p.command==="C"&&(n=f+(f-p.points[2]),o=g+(g-p.points[3])),m.push(n,o,j.shift(),j.shift()),f=j.shift(),g=j.shift(),l="C",m.push(f,g);break;case"s":var n=f,o=g,p=e[e.length-1];p.command==="C"&&(n=f+(f-p.points[2]),o=g+(g-p.points[3])),m.push(n,o,f+j.shift(),g+j.shift()),f+=j.shift(),g+=j.shift(),l="C",m.push(f,g);break;case"Q":m.push(j.shift(),j.shift()),f=j.shift(),g=j.shift(),m.push(f,g);break;case"q":m.push(f+j.shift(),g+j.shift()),f+=j.shift(),g+=j.shift(),l="Q",m.push(f,g);break;case"T":var n=f,o=g,p=e[e.length-1];p.command==="Q"&&(n=f+(f-p.points[0]),o=g+(g-p.points[1])),f=j.shift(),g=j.shift(),l="Q",m.push(n,o,f,g);break;case"t":var n=f,o=g,p=e[e.length-1];p.command==="Q"&&(n=f+(f-p.points[0]),o=g+(g-p.points[1])),f+=j.shift(),g+=j.shift(),l="Q",m.push(n,o,f,g);break;case"A":var q=j.shift(),r=j.shift(),s=j.shift(),t=j.shift(),u=j.shift(),v=f,w=g;f=j.shift(),g=j.shift(),l="A",m=this._convertEndpointToCenterParameterization(v,w,f,g,t,u,q,r,s);break;case"a":var q=j.shift(),r=j.shift(),s=j.shift(),t=j.shift(),u=j.shift(),v=f,w=g;f+=j.shift(),g+=j.shift(),l="A",m=this._convertEndpointToCenterParameterization(v,w,f,g,t,u,q,r,s)}e.push({command:l||i,points:m})}(i==="z"||i==="Z")&&e.push({command:"z",points:[]})}return e},_convertEndpointToCenterParameterization:function(a,b,c,d,e,f,g,h,i){var j=i*(Math.PI/180),k=Math.cos(j)*(a-c)/2+Math.sin(j)*(b-d)/2,l=-1*Math.sin(j)*(a-c)/2+Math.cos(j)*(b-d)/2,m=k*k/(g*g)+l*l/(h*h);m>1&&(g*=Math.sqrt(m),h*=Math.sqrt(m));var n=Math.sqrt((g*g*h*h-g*g*l*l-h*h*k*k)/(g*g*l*l+h*h*k*k));e==f&&(n*=-1),isNaN(n)&&(n=0);var o=n*g*l/h,p=n*-h*k/g,q=(a+c)/2+Math.cos(j)*o-Math.sin(j)*p,r=(b+d)/2+Math.sin(j)*o+Math.cos(j)*p,s=function(a){return Math.sqrt(a[0]*a[0]+a[1]*a[1])},t=function(a,b){return(a[0]*b[0]+a[1]*b[1])/(s(a)*s(b))},u=function(a,b){return(a[0]*b[1]=1&&(y=0),f==0&&y>0&&(y-=2*Math.PI),f==1&&y<0&&(y+=2*Math.PI),[q,r,g,h,v,y,j,f]}},Kinetic.GlobalObject.extend(Kinetic.Path,Kinetic.Shape),Kinetic.GlobalObject.addSetters(Kinetic.Path,["data"]),Kinetic.GlobalObject.addGetters(Kinetic.Path,["data"]),Kinetic.Transform=function(){this.m=[1,0,0,1,0,0]},Kinetic.Transform.prototype={translate:function(a,b){this.m[4]+=this.m[0]*a+this.m[2]*b,this.m[5]+=this.m[1]*a+this.m[3]*b},scale:function(a,b){this.m[0]*=a,this.m[1]*=a,this.m[2]*=b,this.m[3]*=b},rotate:function(a){var b=Math.cos(a),c=Math.sin(a),d=this.m[0]*b+this.m[2]*c,e=this.m[1]*b+this.m[3]*c,f=this.m[0]*-c+this.m[2]*b,g=this.m[1]*-c+this.m[3]*b;this.m[0]=d,this.m[1]=e,this.m[2]=f,this.m[3]=g},getTranslation:function(){return{x:this.m[4],y:this.m[5]}},multiply:function(a){var b=this.m[0]*a.m[0]+this.m[2]*a.m[1],c=this.m[1]*a.m[0]+this.m[3]*a.m[1],d=this.m[0]*a.m[2]+this.m[2]*a.m[3],e=this.m[1]*a.m[2]+this.m[3]*a.m[3],f=this.m[0]*a.m[4]+this.m[2]*a.m[5]+this.m[4],g=this.m[1]*a.m[4]+this.m[3]*a.m[5]+this.m[5];this.m[0]=b,this.m[1]=c,this.m[2]=d,this.m[3]=e,this.m[4]=f,this.m[5]=g},invert:function(){var a=1/(this.m[0]*this.m[3]-this.m[1]*this.m[2]),b=this.m[3]*a,c=-this.m[1]*a,d=-this.m[2]*a,e=this.m[0]*a,f=a*(this.m[2]*this.m[5]-this.m[3]*this.m[4]),g=a*(this.m[1]*this.m[4]-this.m[0]*this.m[5]);this.m[0]=b,this.m[1]=c,this.m[2]=d,this.m[3]=e,this.m[4]=f,this.m[5]=g},getMatrix:function(){return this.m}},Kinetic.Transition=function(a,b){function d(a,b){for(var e in a)e!=="duration"&&e!=="easing"&&e!=="callback"&&(Kinetic.GlobalObject._isObject(a[e])?d(a[e],b[e]):c._add(c._getTween(b,e,a[e])))}this.node=a,this.config=b,this.tweens=[];var c=this;d(b,a.attrs);var e=0;for(var f=0;f=c.tweens.length&&c.onFinished()}}},Kinetic.Transition.prototype={start:function(){for(var a=0;athis.getDuration()?this.looping?(this.rewind(a-this._duration),this.update(),this.broadcastMessage("onLooped",{target:this,type:"onLooped"})):(this._time=this._duration,this.update(),this.stop(),this.broadcastMessage("onFinished",{target:this,type:"onFinished"})):a<0?(this.rewind(),this.update()):(this._time=a,this.update())},getTime:function(){return this._time},setDuration:function(a){this._duration=a===null||a<=0?1e5:a},getDuration:function(){return this._duration},setPosition:function(a){this.prevPos=this._pos,this.propFunc(a),this._pos=a,this.broadcastMessage("onChanged",{target:this,type:"onChanged"})},getPosition:function(a){return a===undefined&&(a=this._time),this.func(a,this.begin,this._change,this._duration)},setFinish:function(a){this._change=a-this.begin},getFinish:function(){return this.begin+this._change},start:function(){this.rewind(),this.startEnterFrame(),this.broadcastMessage("onStarted",{target:this,type:"onStarted"})},rewind:function(a){this.stop(),this._time=a===undefined?0:a,this.fixTime(),this.update()},fforward:function(){this._time=this._duration,this.fixTime(),this.update()},update:function(){this.setPosition(this.getPosition(this._time))},startEnterFrame:function(){this.stopEnterFrame(),this.isPlaying=!0,this.onEnterFrame()},onEnterFrame:function(){this.isPlaying&&this.nextFrame()},nextFrame:function(){this.setTime((this.getTimer()-this._startTime)/1e3)},stop:function(){this.stopEnterFrame(),this.broadcastMessage("onStopped",{target:this,type:"onStopped"})},stopEnterFrame:function(){this.isPlaying=!1},continueTo:function(a,b){this.begin=this._pos,this.setFinish(a),this._duration!==undefined&&this.setDuration(b),this.start()},resume:function(){this.fixTime(),this.startEnterFrame(),this.broadcastMessage("onResumed",{target:this,type:"onResumed"})},yoyo:function(){this.continueTo(this.begin,this._time)},addListener:function(a){return this.removeListener(a),this._listeners.push(a)},removeListener:function(a){var b=this._listeners,c=b.length;while(c--)if(b[c]==a)return b.splice(c,1),!0;return!1},broadcastMessage:function(){var a=[];for(var b=0;b db.right) { - newNodePos.x = db.right; - } - if(db.top !== undefined && newNodePos.y < db.top) { - newNodePos.y = db.top; - } - if(db.bottom !== undefined && newNodePos.y > db.bottom) { - newNodePos.y = db.bottom; - } - - node.setAbsolutePosition(newNodePos); - - // constraint overrides - if(dc === 'horizontal') { - node.attrs.y = lastNodePos.y; - } - else if(dc === 'vertical') { - node.attrs.x = lastNodePos.x; - } - - /* - * if dragging and dropping the stage, - * draw all of the layers - */ - if(go.drag.node.nodeType === 'Stage') { - go.drag.node.draw(); - } - - else { - go.drag.node.getLayer().draw(); - } - - if(!go.drag.moving) { - go.drag.moving = true; - // execute dragstart events if defined - go.drag.node._handleEvent('dragstart', evt); - } - - // execute user defined ondragmove if defined - go.drag.node._handleEvent('dragmove', evt); + // bounds overrides + if(db.left !== undefined && newNodePos.x < db.left) { + newNodePos.x = db.left; + } + if(db.right !== undefined && newNodePos.x > db.right) { + newNodePos.x = db.right; + } + if(db.top !== undefined && newNodePos.y < db.top) { + newNodePos.y = db.top; + } + if(db.bottom !== undefined && newNodePos.y > db.bottom) { + newNodePos.y = db.bottom; } - }, false); - this._onContent('mouseup touchend mouseout', function(evt) { - that._endDrag(evt); - }); + node.setAbsolutePosition(newNodePos); + + // constraint overrides + if(dc === 'horizontal') { + node.attrs.y = lastNodePos.y; + } + else if(dc === 'vertical') { + node.attrs.x = lastNodePos.x; + } + + /* + * if dragging and dropping the stage, + * draw all of the layers + */ + if(go.drag.node.nodeType === 'Stage') { + go.drag.node.draw(); + } + + else { + go.drag.node.getLayer().draw(); + } + + if(!go.drag.moving) { + go.drag.moving = true; + // execute dragstart events if defined + go.drag.node._handleEvent('dragstart', evt); + } + + // execute user defined ondragmove if defined + go.drag.node._handleEvent('dragmove', evt); + } }, /** * build dom diff --git a/tests/html/manualTests.html b/tests/html/manualTests.html new file mode 100644 index 00000000..e9e81145 --- /dev/null +++ b/tests/html/manualTests.html @@ -0,0 +1,16 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/tests/js/functionalTests.js b/tests/js/functionalTests.js index 8f506aa4..69780cc7 100644 --- a/tests/js/functionalTests.js +++ b/tests/js/functionalTests.js @@ -1,743 +1,5 @@ Test.prototype.tests = { - 'TRANSITION - transition position and rotation': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var rect = new Kinetic.Rect({ - x: 100, - y: 100, - width: 100, - height: 50, - fill: 'green', - stroke: 'black', - strokeWidth: 4 - }); - - layer.add(rect); - stage.add(layer); - - rect.transitionTo({ - duration: 2, - x: 400, - y: 30, - rotation: Math.PI * 2, - easing: 'bounce-ease-out' - }); - }, - 'TRANSITION - all transition types': function(containerId) { - document.getElementById(containerId).style.height = '300px'; - - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 300 - }); - var layer = new Kinetic.Layer(); - - var easings = ['linear', 'ease-in', 'ease-out', 'ease-in-out', 'back-ease-in', 'back-ease-out', 'back-ease-in-out', 'elastic-ease-in', 'elastic-ease-out', 'elastic-ease-in-out', 'bounce-ease-out', 'bounce-ease-in', 'bounce-ease-in-out', 'strong-ease-in', 'strong-ease-out', 'strong-ease-in-out']; - for(var n = 0; n < easings.length; n++) { - var rect = new Kinetic.Rect({ - x: 10, - y: 10 + (n * 200 / easings.length), - width: 100, - height: 10, - fill: 'green', - stroke: 'black', - strokeWidth: 2 - }); - - layer.add(rect); - - rect.transitionTo({ - duration: 2, - width: 500, - easing: easings[n] - }); - } - - stage.add(layer); - }, - 'TRANSITION - transition callback': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var rect = new Kinetic.Rect({ - x: 100, - y: 100, - width: 100, - height: 50, - fill: 'green', - stroke: 'black', - strokeWidth: 4 - }); - - layer.add(rect); - stage.add(layer); - - rect.transitionTo({ - duration: 2, - x: 400, - y: 30, - rotation: Math.PI * 2, - easing: 'bounce-ease-out', - callback: function() { - console.log('transition done!'); - } - }); - }, - 'TRANSITION - stop and resume transition': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var rect = new Kinetic.Rect({ - x: 100, - y: 100, - width: 100, - height: 50, - fill: 'green', - stroke: 'black', - strokeWidth: 4 - }); - - layer.add(rect); - stage.add(layer); - - var trans = rect.transitionTo({ - duration: 2, - x: 400, - y: 30, - rotation: Math.PI * 2, - easing: 'bounce-ease-out' - }); - - setTimeout(function() { - trans.stop(); - }, 1000); - setTimeout(function() { - trans.resume(); - }, 2000); - }, - 'TRANSITION - transition stage': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var rect = new Kinetic.Rect({ - x: 100, - y: 100, - width: 100, - height: 50, - fill: 'green', - stroke: 'black', - strokeWidth: 4 - }); - - layer.add(rect); - stage.add(layer); - - var trans = stage.transitionTo({ - duration: 2, - x: 400, - y: 30, - rotation: Math.PI * 2, - easing: 'bounce-ease-out' - }); - }, - 'TRANSITION - transition position and rotation with two transitions': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var rect = new Kinetic.Rect({ - x: 100, - y: 100, - width: 100, - height: 50, - fill: 'green', - stroke: 'black', - strokeWidth: 4 - }); - - layer.add(rect); - stage.add(layer); - - rect.transitionTo({ - x: 400, - y: 30, - duration: 1 - }); - - rect.transitionTo({ - rotation: Math.PI * 2, - duration: 2 - }); - }, - 'ANIMATION - run animation': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var rect = new Kinetic.Rect({ - x: 200, - y: 100, - width: 100, - height: 50, - fill: 'green', - stroke: 'black', - strokeWidth: 4 - }); - - layer.add(rect); - stage.add(layer); - - var amplitude = 150; - var period = 1000; - // in ms - var centerX = stage.getWidth() / 2 - 100 / 2; - - stage.onFrame(function(frame) { - rect.attrs.x = amplitude * Math.sin(frame.time * 2 * Math.PI / period) + centerX; - layer.draw(); - }); - - stage.start(); - - setTimeout(function() { - stage.stop(); - }, 3000); - }, - 'TRANSITION - hover linear transition': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var rect = new Kinetic.Rect({ - x: stage.getWidth() / 2 - 50, - y: stage.getHeight() / 2 - 25, - width: 100, - height: 50, - fill: 'green', - stroke: 'black', - strokeWidth: 4, - offset: { - x: 50, - y: 25 - } - }); - - rect.on("mouseover", function() { - this.transitionTo({ - scale: { - x: 1.5, - y: 1.5 - }, - duration: 1 - }); - }); - - rect.on("mouseout", function() { - this.transitionTo({ - scale: { - x: 1, - y: 1 - }, - duration: 1 - }); - }); - - layer.add(rect); - stage.add(layer); - - }, - 'TRANSITION - hover ease-in transition': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var rect = new Kinetic.Rect({ - x: stage.getWidth() / 2 - 50, - y: stage.getHeight() / 2 - 25, - width: 100, - height: 50, - fill: 'green', - stroke: 'black', - strokeWidth: 4, - offset: { - x: 50, - y: 25 - } - }); - - rect.on("mouseover", function() { - this.transitionTo({ - scale: { - x: 1.5, - y: 1.5 - }, - duration: 1, - easing: "ease-in" - }); - }); - - rect.on("mouseout", function() { - this.transitionTo({ - scale: { - x: 1, - y: 1 - }, - duration: 1, - easing: "ease-in" - }); - }); - - layer.add(rect); - stage.add(layer); - - }, - 'TRANSITION - hover ease-out transition': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var rect = new Kinetic.Rect({ - x: stage.getWidth() / 2 - 50, - y: stage.getHeight() / 2 - 25, - width: 100, - height: 50, - fill: 'green', - stroke: 'black', - strokeWidth: 4, - offset: { - x: 50, - y: 25 - } - }); - - rect.on("mouseover", function() { - this.transitionTo({ - scale: { - x: 1.5, - y: 1.5 - }, - duration: 1, - easing: "ease-out" - }); - }); - - rect.on("mouseout", function() { - this.transitionTo({ - scale: { - x: 1, - y: 1 - }, - duration: 1, - easing: "ease-out" - }); - }); - - layer.add(rect); - stage.add(layer); - - }, - 'TRANSITION - hover ease-in-out transition': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var rect = new Kinetic.Rect({ - x: stage.getWidth() / 2 - 50, - y: stage.getHeight(0) / 2 - 25, - width: 100, - height: 50, - fill: 'green', - stroke: 'black', - strokeWidth: 4, - offset: { - x: 50, - y: 25 - } - }); - - rect.on("mouseover", function() { - this.transitionTo({ - scale: { - x: 1.5, - y: 1.5 - }, - duration: 1, - easing: "ease-in-out" - }); - }); - - rect.on("mouseout", function() { - this.transitionTo({ - scale: { - x: 1, - y: 1 - }, - duration: 1, - easing: "ease-in-out" - }); - }); - - layer.add(rect); - stage.add(layer); - - }, - 'TRANSITION - ease-in, ease-out, ease-in-out hovers': function(containerId) { - function addHovers(shape, easing) { - shape.on("mouseover", function() { - this.transitionTo({ - scale: { - x: 1.5, - y: 1.5 - }, - duration: 1, - easing: easing - }); - }); - shape.on("mouseout", function() { - this.transitionTo({ - scale: { - x: 1, - y: 1 - }, - duration: 1, - easing: easing - }); - }); - } - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var greenBox = new Kinetic.Rect({ - x: 50, - y: stage.getHeight() / 2 - 25, - width: 100, - height: 50, - fill: 'green', - stroke: 'black', - strokeWidth: 4, - offset: { - x: 50, - y: 25 - } - }); - - var blueBox = new Kinetic.Rect({ - x: stage.getWidth() / 2 - 50, - y: stage.getHeight() / 2 - 25, - width: 100, - height: 50, - fill: 'blue', - stroke: 'black', - strokeWidth: 4, - offset: { - x: 50, - y: 25 - } - }); - - var redBox = new Kinetic.Rect({ - x: 428, - y: stage.getHeight() / 2 - 25, - width: 100, - height: 50, - fill: 'red', - stroke: 'black', - strokeWidth: 4, - offset: { - x: 50, - y: 25 - } - }); - - addHovers(greenBox, "ease-in"); - addHovers(blueBox, "ease-out"); - addHovers(redBox, "ease-in-out"); - - layer.add(greenBox); - layer.add(blueBox); - layer.add(redBox); - stage.add(layer); - }, - 'EVENTS - mousedown mouseup mouseover mouseout mousemove click dblclick / touchstart touchend touchmove tap dbltap': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var circle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 70, - fill: 'red', - stroke: 'black', - strokeWidth: 4 - }); - - circle.on('mousedown', function() { - log('mousedown'); - }); - - circle.on('mouseup', function() { - log('mouseup'); - }); - - circle.on('mouseover', function() { - log('mouseover'); - }); - - circle.on('mouseout', function() { - log('mouseout'); - }); - - circle.on('mousemove', function() { - log('mousemove'); - }); - - circle.on('click', function() { - log('click'); - }); - - circle.on('dblclick', function() { - log('dblclick'); - }); - /* - * mobile - */ - circle.on('touchstart', function() { - log('touchstart'); - }); - - circle.on('touchend', function() { - log('touchend'); - }); - - circle.on('touchmove', function() { - log('touchmove'); - }); - - circle.on('tap', function(evt) { - log('tap'); - }); - - circle.on('dbltap', function() { - log('dbltap'); - }); - - layer.add(circle); - stage.add(layer); - }, - 'EVENTS - modify fill stroke and stroke width on hover with circle': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var circle = new Kinetic.Circle({ - x: 380, - y: stage.getHeight() / 2, - radius: 70, - strokeWidth: 4, - fill: 'red', - stroke: 'black' - }); - - circle.on('mouseover', function() { - this.setFill('yellow'); - this.setStroke('purple'); - this.setStrokeWidth(20); - layer.draw(); - }); - - circle.on('mouseout', function() { - this.setFill('red'); - this.setStroke('black'); - this.setStrokeWidth(4); - layer.draw(); - }); - - layer.add(circle); - stage.add(layer); - }, - 'EVENTS - modify fill stroke and stroke width on hover with star': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - - var star = new Kinetic.Star({ - x: 200, - y: 100, - numPoints: 10, - innerRadius: 40, - outerRadius: 70, - fill: 'green', - stroke: 'blue', - strokeWidth: 5, - name: 'foobar' - }); - - star.on('mouseover', function() { - this.setFill('yellow'); - this.setStroke('purple'); - this.setStrokeWidth(20); - layer.draw(); - }); - - star.on('mouseout', function() { - this.setFill('green'); - this.setStroke('blue'); - this.setStrokeWidth(5); - layer.draw(); - }); - - layer.add(star); - stage.add(layer); - }, - 'EVENTS - modify fill stroke and stroke width on hover with image': function(containerId) { - var imageObj = new Image(); - imageObj.onload = function() { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var darth = new Kinetic.Image({ - x: 60, - y: 60, - image: imageObj - }); - - darth.on('mouseover', function() { - this.setStroke('purple'); - this.setStrokeWidth(20); - layer.draw(); - }); - - darth.on('mouseout', function() { - this.setStroke(undefined); - this.setStrokeWidth(0); - layer.draw(); - }); - - layer.add(darth); - stage.add(layer); - }; - imageObj.src = '../darth-vader.jpg'; - }, - /* - * WARNING: this functional test will only pass if it's hosted on - * a webserver due to cross domain security issues - */ - 'EVENTS - image pixel detection': function(containerId) { - var imageObj = new Image(); - imageObj.onload = function() { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var darth = new Kinetic.Image({ - x: 200, - y: 40, - image: imageObj, - detectionType: 'pixel', - draggable: true - }); - - darth.on('mouseover', function() { - log('mouseover'); - }); - - darth.on('mouseout', function() { - log('mouseout'); - }); - - darth.on('dragend', function() { - this.saveData(); - }); - - layer.add(darth); - stage.add(layer); - - //darth.save(); - }; - imageObj.src = '../lion.png'; - }, - 'EVENTS - star pixel detection': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - - var layer = new Kinetic.Layer({ - rotationDeg: 20 - }); - var star = new Kinetic.Star({ - x: 200, - y: 100, - numPoints: 10, - innerRadius: 40, - outerRadius: 70, - fill: 'green', - stroke: 'blue', - strokeWidth: 20, - detectionType: 'pixel', - draggable: true - }); - - star.on('mouseover', function() { - log('mouseover'); - }); - - star.on('mouseout', function() { - log('mouseout'); - }); - - star.on('dragend', function() { - this.saveData(); - }); - - layer.add(star); - stage.add(layer); - star.saveData(); - }, - 'EVENTS - drag events click': function(containerId) { + 'DRAG AND DROP - test dragstart, dragmove, dragend': function(containerId) { var stage = new Kinetic.Stage({ container: containerId, width: 578, @@ -755,1357 +17,59 @@ Test.prototype.tests = { circle.draggable(true); + layer.add(circle); + stage.add(layer); + + var dragStart = false; + var dragMove = false; + var dragEnd = false; + circle.on('dragstart', function() { - log('dragstart'); + dragStart = true; + }); + + circle.on('dragstart', function() { + dragStart = true; }); circle.on('dragmove', function() { - log('dragmove'); + dragMove = true; }); circle.on('dragend', function() { - log('dragend'); - }); - - circle.on('click', function() { - log('click'); - }); - - layer.add(circle); - stage.add(layer); - }, - 'EVENTS - move mouse from shape to another shape in same layer': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - - var redCircle = new Kinetic.Circle({ - x: 200, - y: stage.getHeight() / 2, - radius: 70, - strokeWidth: 4, - fill: 'red', - stroke: 'black' - }); - - redCircle.on('mouseover', function() { - log('mouseover red circle'); - }); - redCircle.on('mouseout', function() { - log('mouseout red circle'); - }); - var greenCircle = new Kinetic.Circle({ - x: 280, - y: stage.getHeight() / 2, - radius: 70, - strokeWidth: 4, - fill: 'green', - stroke: 'black' - }); - - greenCircle.on('mouseover', function() { - log('mouseover green circle'); - }); - greenCircle.on('mouseout', function() { - log('mouseout green circle'); - }); - - layer.add(redCircle); - layer.add(greenCircle); - - stage.add(layer); - }, - 'EVENTS - move mouse from shape in one group to shape in another group': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var redGroup = new Kinetic.Group(); - var greenGroup = new Kinetic.Group(); - - var redCircle = new Kinetic.Circle({ - x: 200, - y: stage.getHeight() / 2, - radius: 70, - strokeWidth: 4, - fill: 'red', - stroke: 'black' - }); - - redCircle.on('mouseover', function() { - log('mouseover red circle'); - }); - redCircle.on('mouseout', function() { - log('mouseout red circle'); - }); - var greenCircle = new Kinetic.Circle({ - x: 280, - y: stage.getHeight() / 2, - radius: 70, - strokeWidth: 4, - fill: 'green', - stroke: 'black' - }); - - greenCircle.on('mouseover', function() { - log('mouseover green circle'); - }); - greenCircle.on('mouseout', function() { - log('mouseout green circle'); - }); - - redGroup.add(redCircle); - greenGroup.add(greenCircle); - - layer.add(redGroup); - layer.add(greenGroup); - - stage.add(layer); - }, - 'EVENTS - move mouse from shape in one layer to shape in another layer': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var redLayer = new Kinetic.Layer(); - var greenLayer = new Kinetic.Layer(); - - var redCircle = new Kinetic.Circle({ - x: 200, - y: stage.getHeight() / 2, - radius: 70, - strokeWidth: 4, - fill: 'red', - stroke: 'black' - }); - - redCircle.on('mouseover', function() { - log('mouseover red circle'); - }); - redCircle.on('mouseout', function() { - log('mouseout red circle'); - }); - var greenCircle = new Kinetic.Circle({ - x: 280, - y: stage.getHeight() / 2, - radius: 70, - strokeWidth: 4, - fill: 'green', - stroke: 'black' - }); - - greenCircle.on('mouseover', function() { - log('mouseover green circle'); - }); - greenCircle.on('mouseout', function() { - log('mouseout green circle'); - }); - - redLayer.add(redCircle); - greenLayer.add(greenCircle); - - stage.add(redLayer); - stage.add(greenLayer); - }, - 'EVENTS - mousemove from shape in one group to shape in another group': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var redGroup = new Kinetic.Group(); - var greenGroup = new Kinetic.Group(); - - var redCircle = new Kinetic.Circle({ - x: 200, - y: stage.getHeight() / 2, - radius: 70, - strokeWidth: 4, - fill: 'red', - stroke: 'black' - }); - - redCircle.on('mousemove', function() { - log('mousemove red circle'); - }); - var greenCircle = new Kinetic.Circle({ - x: 280, - y: stage.getHeight() / 2, - radius: 70, - strokeWidth: 4, - fill: 'green', - stroke: 'black' - }); - - greenCircle.on('mousemove', function() { - log('mousemove green circle'); - }); - - redGroup.add(redCircle); - greenGroup.add(greenCircle); - - layer.add(redGroup); - layer.add(greenGroup); - - stage.add(layer); - }, - 'EVENTS - group click events': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var group = new Kinetic.Group(); - - group.on('click', function() { - log('click group'); - //console.log(this); - }); - var redCircle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 80, - strokeWidth: 4, - fill: 'red', - stroke: 'black', - name: 'red' - }); - - var greenCircle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 40, - strokeWidth: 4, - fill: 'green', - stroke: 'black', - name: 'green' - }); - - group.add(redCircle); - group.add(greenCircle); - - layer.add(group); - stage.add(layer); - }, - 'EVENTS - group mousemove events': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var group = new Kinetic.Group(); - - group.on('mousemove', function() { - log('mousemove group'); - //console.log(this); - }); - var redCircle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 80, - strokeWidth: 4, - fill: 'red', - stroke: 'black' - }); - - var greenCircle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 40, - strokeWidth: 4, - fill: 'green', - stroke: 'black' - }); - - group.add(redCircle); - group.add(greenCircle); - - layer.add(group); - stage.add(layer); - }, - 'EVENTS - group mouseover events': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var group = new Kinetic.Group({ - name: 'group' - }); - - group.on('mouseover', function() { - log('mouseover group'); - }); - - group.on('mouseout', function() { - log('mouseout group'); - }); - var redCircle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 80, - strokeWidth: 4, - fill: 'red', - stroke: 'black', - name: 'red' - }); - - var greenCircle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 40, - strokeWidth: 4, - fill: 'green', - stroke: 'black', - name: 'green' - }); - - group.add(redCircle); - group.add(greenCircle); - - layer.add(group); - stage.add(layer); - }, - 'EVENTS - cancel event bubbling (only the red circle should fire click event)': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var group = new Kinetic.Group(); - - layer.on('click', function() { - log('click layer'); - //console.log(this); - }); - group.on('click', function() { - log('click group'); - //console.log(this); - }); - var redCircle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 80, - strokeWidth: 4, - fill: 'red', - stroke: 'black' - }); - - redCircle.on('click', function(evt) { - log('click red circle'); - evt.cancelBubble = true; - }); - - group.add(redCircle); - layer.add(group); - stage.add(layer); - }, - 'EVENTS - get currentTarget': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var group = new Kinetic.Group(); - - layer.on('click', function(evt) { - log(evt.shape.getName()); - - }); - var redCircle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 80, - strokeWidth: 4, - fill: 'red', - stroke: 'black', - name: 'circle' - }); - - group.add(redCircle); - layer.add(group); - stage.add(layer); - }, - 'EVENTS - shape mouseout handlers when mouse leaves stage': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - - var redCircle = new Kinetic.Circle({ - x: 550, - y: stage.getHeight() / 2, - radius: 80, - strokeWidth: 4, - fill: 'red', - stroke: 'black', - name: 'circle' - }); - - redCircle.on('mouseout', function() { - log('mouseout'); - }); - - layer.add(redCircle); - stage.add(layer); - }, - 'DRAG AND DROP - custom draw func and drag and drop layer': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - 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(); - }, - draggable: true - }); - - var circle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 70, - fill: 'red' - }); - - var circle2 = new Kinetic.Circle({ - x: 400, - y: stage.getHeight() / 2, - radius: 70, - fill: 'green' - }); - - layer.add(circle); - layer.add(circle2); - - stage.add(layer); - }, - 'DRAG AND DROP - drag and drop elastic star with shadow': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - - var star = new Kinetic.Star({ - x: 200, - y: 100, - numPoints: 5, - innerRadius: 40, - outerRadius: 70, - fill: 'green', - stroke: 'blue', - strokeWidth: 5, - lineJoin: "round", - shadow: { - color: '#aaa', - blur: 10, - offset: { - x: 5, - y: 5 - } - }, - draggable: true - }); - - layer.add(star); - stage.add(layer); - - test(star.getLineJoin() === 'round', 'lineJoin property should be round'); - star.setLineJoin('bevel'); - test(star.getLineJoin() === 'bevel', 'lineJoin property should be bevel'); - - layer.draw(); - - var trans = null; - - star.on('dragstart', function() { - if(trans) { - trans.stop(); - } - - star.setAttrs({ - shadow: { - offset: { - x: 15, - y: 15 - } - }, - offset: { - x: 10, - y: 10 - } - }); - }); - - star.on('dragend', function() { - trans = star.transitionTo({ - duration: 0.5, - easing: 'elastic-ease-out', - shadow: { - offset: { - x: 5, - y: 5 - } - }, - offset: { - x: 0, - y: 0 - } - }) + dragEnd = true; }); /* - stage.onFrame(function(frame) { - star.rotate(1 * frame.timeDiff / 1000); - layer.draw(); - }); - - stage.start(); + * simulate drag and drop */ - }, - 'DRAG AND DROP - isDragging': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var circle = new Kinetic.Circle({ - x: 380, - y: stage.getHeight() / 2, - radius: 70, - strokeWidth: 4, - fill: 'red', - stroke: 'black' - }); - - //log('not dragging yet before draggable, isDragging: ' + circle.isDragging()); - test(circle.isDragging() === false, 'isDragging() should be false'); - - circle.draggable(true); - - //log('not dragging yet after draggable, isDragging: ' + circle.isDragging()); - test(circle.isDragging() === false, 'isDragging() should be false'); - - /* - circle.on('dragstart', function() { - log('dragstart, isDragging: ' + this.isDragging()); - test(circle.isDragging() === true, 'isDragging() should be true'); - }); - - circle.on('dragmove', function() { - log('dragmove, isDragging: ' + this.isDragging()); - test(circle.isDragging() === true, 'isDragging() should be true'); - }); - - circle.on('dragend', function() { - log('dragend, isDragging: ' + this.isDragging()); - test(circle.isDragging() === false, 'isDragging() should be false'); - }); - */ - - layer.add(circle); - stage.add(layer); - }, - 'DRAG AND DROP - multiple drag and drop sets with draggable() (circle should not be draggable)': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var circle = new Kinetic.Circle({ - x: 380, - y: stage.getHeight() / 2, - radius: 70, - strokeWidth: 4, - fill: 'red', - stroke: 'black' - }); - - circle.draggable(true); - circle.draggable(true); - circle.draggable(false); - - layer.add(circle); - stage.add(layer); - - }, - 'DRAG AND DROP - two draggable shapes': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var circle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 70, - fill: 'red', - stroke: 'black', - strokeWidth: 4, - //detectionType: 'pixel' - }); - - circle.draggable(true); - - var circle2 = new Kinetic.Circle({ - x: 350, - y: stage.getHeight() / 2, - radius: 70, - fill: 'green', - stroke: 'black', - strokeWidth: 4, - draggable: true - //detectionType: 'pixel' - }); - - /* - circle.on('dragend', function() { - circle.saveData(); - }); - */ - - layer.add(circle).add(circle2); - stage.add(layer); - - //circle.saveData(); - }, - 'DRAG AND DROP - drag and drop stage': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200, - draggable: true, - //dragConstraint: 'horizontal', - /* - dragBounds: { - left: 100 - } - */ - }); - var layer = new Kinetic.Layer({ - /* - draggable: true, - dragBounds: { - left: 100 - } - */ - }); - var circle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 70, - fill: 'red', - stroke: 'black', - strokeWidth: 4, - //draggable: true, - /* - dragBounds: { - left: 100 - } - */ - }); - - //stage.draggable(false); - //layer.draggable(false); - - /* - stage.on('dragstart', function() { - console.log('dragstart'); - }); - stage.on('dragmove', function() { - //console.log('dragmove'); - }); - stage.on('dragend', function() { - console.log('dragend'); - }); - */ - - layer.add(circle); - stage.add(layer); - }, - 'DRAG AND DROP - draggable true false': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var circle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 70, - fill: 'red', - stroke: 'black', - strokeWidth: 4 + stage._mousedown({ + offsetX: 380, + offsetY: stage.getHeight() / 2 }); - circle.draggable(true); - - layer.add(circle); - stage.add(layer); - - circle.draggable(false); - }, - 'DRAG AND DROP - scale and rotate stage after add layer then drag and drop shape': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var rect = new Kinetic.Rect({ - x: 200, - y: 20, - width: 100, - height: 50, - fill: 'red', - stroke: 'black', - strokeWidth: 4, - draggable: true - //rotationDeg: 60 - //rotationDeg: Math.PI / 3 - }); - - layer.add(rect); - stage.add(layer); - - //stage.rotateDeg(20); - - //console.log(rect.getAbsoluteTransform().getTranslation()) - - stage.rotate(Math.PI / 3); - stage.setScale(0.5); - - stage.draw(); - }, - 'DRAG AND DROP - scale stage before add shape then drag and drop shape': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var circle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 70, - fill: 'red', - stroke: 'black', - strokeWidth: 4 - }); - - circle.draggable(true); - - stage.setScale(0.5); - layer.add(circle); - stage.add(layer); - }, - 'DRAG AND DROP - set stage scale to 1.5 after add layer then drag and drop shape': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var circle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 70, - fill: 'red', - stroke: 'black', - strokeWidth: 4 - }); - - circle.draggable(true); - - layer.add(circle); - stage.add(layer); - - stage.setScale(1.5); - - stage.draw(); - }, - 'DRAG AND DROP - set stage scale to 1.5 before add layer then drag and drop shape': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var circle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 70, - fill: 'red', - stroke: 'black', - strokeWidth: 4 - }); - - circle.draggable(true); - - stage.setScale(1.5); - - layer.add(circle); - stage.add(layer); - }, - 'DRAG AND DROP - check that green events are ignored when dragging red circle': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var circle1 = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 70, - fill: 'red', - stroke: 'black', - strokeWidth: 4 - }); - - var circle2 = new Kinetic.Circle({ - x: stage.getWidth() / 2 + 50, - y: stage.getHeight() / 2, - radius: 70, - fill: 'green', - stroke: 'black', - strokeWidth: 4 - }); - - circle1.draggable(true); - - circle2.on('mouseover', function() { - log('mouseover green circle'); - }); - - layer.add(circle1); - layer.add(circle2); - stage.add(layer); - }, - 'DRAG AND DROP - drag and drop constrianed horiztontally inside positioned group': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var group = new Kinetic.Group({ - x: 0, - y: 10 - }); - var circle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 70, - fill: 'red', - stroke: 'black', - strokeWidth: 4, - draggable: true, - dragConstraint: 'horizontal' - }); - - group.add(circle); - layer.add(group); - stage.add(layer); - }, - 'DRAG AND DROP - drag and drop constrianed vertically': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var circle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 70, - fill: 'red', - stroke: 'black', - strokeWidth: 4, - draggable: true, - dragConstraint: 'vertical' - }); - - layer.add(circle); - stage.add(layer); - }, - 'DRAG AND DROP - drag and drop with explicit no constraint': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var circle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 70, - fill: 'red', - stroke: 'black', - strokeWidth: 4, - draggable: true, - dragConstraint: 'none' - }); - - layer.add(circle); - stage.add(layer); - }, - 'DRAG AND DROP - drag and drop with left bounds': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var circle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 70, - fill: 'red', - stroke: 'black', - strokeWidth: 4, - draggable: true, - dragBounds: { - left: 150 - } - }); - - layer.add(circle); - stage.add(layer); - }, - 'DRAG AND DROP - drag and drop with right bounds': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var circle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 70, - fill: 'red', - stroke: 'black', - strokeWidth: 4, - draggable: true, - dragBounds: { - right: 400 - } - }); - - layer.add(circle); - stage.add(layer); - }, - 'DRAG AND DROP - drag and drop with top bounds': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var circle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 70, - fill: 'red', - stroke: 'black', - strokeWidth: 4, - draggable: true, - dragBounds: { - top: 80 - } - }); - - layer.add(circle); - stage.add(layer); - }, - 'DRAG AND DROP - drag and drop with bottom bounds': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var circle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 70, - fill: 'red', - stroke: 'black', - strokeWidth: 4, - draggable: true, - dragBounds: { - bottom: 120 - } - }); - - layer.add(circle); - stage.add(layer); - }, - 'DRAG AND DROP - drag and drop with full rect bounds': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var circle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 70, - fill: 'red', - stroke: 'black', - strokeWidth: 4, - draggable: true, - dragBounds: { - top: 80, - bottom: 120, - left: 150, - right: 578 - 150 - } - }); - - layer.add(circle); - stage.add(layer); - }, - 'DRAG AND DROP - drag and drop shape inside scrollable div': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 400 - }); - - // make container scrollable - var container = stage.getContainer(); - container.style.overflow = 'auto'; - - var layer = new Kinetic.Layer(); - var circle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: 100, - radius: 50, - fill: 'blue', - stroke: 'black', - strokeWidth: 4, - draggable: true - }); - - layer.add(circle); - stage.add(layer); - }, - 'DRAG AND DROP - drag and drop shape inside scaled group': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - var group = new Kinetic.Group({ - scale: { - x: 2, - y: 2 - } - }); - - var circle = new Kinetic.Circle({ - x: 40, - y: 40, - radius: 70, - fill: 'red', - stroke: 'black', - strokeWidth: 4, - draggable: true - }); - - group.add(circle); - layer.add(group); - stage.add(layer); - }, - 'DRAG AND DROP - translate, rotate, and scale shape, and then drag and drop': 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); - }, - 'DRAG AND DROP - translate, rotate, center offset, and scale shape, and then drag and drop': 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 - }, - offset: { - x: 50, - y: 25 - } - }); - - group.add(rect); - layer.add(group); - stage.add(layer); - - stage.onFrame(function() { - rect.rotate(0.01); - layer.draw(); - }); - //stage.start(); - - }, - 'STAGE - hide stage': 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); - - stage.hide(); - stage.draw(); - }, - 'STAGE - hide layer': 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); - - layer.hide(); - - stage.draw(); - }, - 'STAGE - hide group': 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); - - group.hide(); - - stage.draw(); - }, - 'STAGE - save image as png (click on circle to open new window)': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - - var circle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 70, - fill: 'violet', - stroke: 'black', - strokeWidth: 4 - }); + test(!dragStart, 'dragstart event should not have been triggered'); + test(!dragMove, 'dragmove event should not have been triggered'); + test(!dragEnd, 'dragend event should not have been triggered'); - circle.on('click', function() { - stage.toDataURL(function(dataUrl) { - /* - * here you can do anything you like with the data url. - * In this tutorial we'll just open the url with the browser - * so that you can see the result as an image - */ - window.open(dataUrl); + setTimeout(function() { + stage._mousemove({ + offsetX: 100, + offsetY: stage.getHeight() / 2 }); - }); - layer.add(circle); - stage.add(layer); - }, - 'STAGE - save image as low quality jpg (click on circle to open new window)': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); + test(dragStart, 'dragstart event was not triggered'); + test(dragMove, 'dragmove event was not triggered'); + test(!dragEnd, 'dragend event should not have been triggered'); + }, 50); + setTimeout(function() { + stage._mouseup({ + offsetX: 100, + offsetY: stage.getHeight() / 2 + }); - var circle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 70, - fill: 'violet', - stroke: 'black', - strokeWidth: 4 - }); - - circle.on('click', function() { - stage.toDataURL(function(dataUrl) { - /* - * here you can do anything you like with the data url. - * In this tutorial we'll just open the url with the browser - * so that you can see the result as an image - */ - window.open(dataUrl); - }, 'image/jpeg', 0); - }); - - layer.add(circle); - stage.add(layer); - }, - 'STAGE - save image as high quality jpg (click on circle to open new window)': function(containerId) { - var stage = new Kinetic.Stage({ - container: containerId, - width: 578, - height: 200 - }); - var layer = new Kinetic.Layer(); - - var circle = new Kinetic.Circle({ - x: stage.getWidth() / 2, - y: stage.getHeight() / 2, - radius: 70, - fill: 'violet', - stroke: 'black', - strokeWidth: 4 - }); - - circle.on('click', function() { - stage.toDataURL(function(dataUrl) { - /* - * here you can do anything you like with the data url. - * In this tutorial we'll just open the url with the browser - * so that you can see the result as an image - */ - window.open(dataUrl); - }, 'image/jpeg', 1); - }); - - layer.add(circle); - stage.add(layer); + test(dragStart, 'dragstart event was not triggered'); + test(dragMove, 'dragmove event was not triggered'); + test(dragEnd, 'dragend event was not triggered'); + }, 100); } }; diff --git a/tests/js/manualTests.js b/tests/js/manualTests.js new file mode 100644 index 00000000..a1e0b6c1 --- /dev/null +++ b/tests/js/manualTests.js @@ -0,0 +1,2063 @@ +Test.prototype.tests = { + 'TRANSITION - transition position and rotation': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var rect = new Kinetic.Rect({ + x: 100, + y: 100, + width: 100, + height: 50, + fill: 'green', + stroke: 'black', + strokeWidth: 4 + }); + + layer.add(rect); + stage.add(layer); + + rect.transitionTo({ + duration: 2, + x: 400, + y: 30, + rotation: Math.PI * 2, + easing: 'bounce-ease-out' + }); + }, + 'TRANSITION - all transition types': function(containerId) { + document.getElementById(containerId).style.height = '300px'; + + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 300 + }); + var layer = new Kinetic.Layer(); + + var easings = ['linear', 'ease-in', 'ease-out', 'ease-in-out', 'back-ease-in', 'back-ease-out', 'back-ease-in-out', 'elastic-ease-in', 'elastic-ease-out', 'elastic-ease-in-out', 'bounce-ease-out', 'bounce-ease-in', 'bounce-ease-in-out', 'strong-ease-in', 'strong-ease-out', 'strong-ease-in-out']; + for(var n = 0; n < easings.length; n++) { + var rect = new Kinetic.Rect({ + x: 10, + y: 10 + (n * 200 / easings.length), + width: 100, + height: 10, + fill: 'green', + stroke: 'black', + strokeWidth: 2 + }); + + layer.add(rect); + + rect.transitionTo({ + duration: 2, + width: 500, + easing: easings[n] + }); + } + + stage.add(layer); + }, + 'TRANSITION - transition callback': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var rect = new Kinetic.Rect({ + x: 100, + y: 100, + width: 100, + height: 50, + fill: 'green', + stroke: 'black', + strokeWidth: 4 + }); + + layer.add(rect); + stage.add(layer); + + rect.transitionTo({ + duration: 2, + x: 400, + y: 30, + rotation: Math.PI * 2, + easing: 'bounce-ease-out', + callback: function() { + console.log('transition done!'); + } + }); + }, + 'TRANSITION - stop and resume transition': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var rect = new Kinetic.Rect({ + x: 100, + y: 100, + width: 100, + height: 50, + fill: 'green', + stroke: 'black', + strokeWidth: 4 + }); + + layer.add(rect); + stage.add(layer); + + var trans = rect.transitionTo({ + duration: 2, + x: 400, + y: 30, + rotation: Math.PI * 2, + easing: 'bounce-ease-out' + }); + + setTimeout(function() { + trans.stop(); + }, 1000); + setTimeout(function() { + trans.resume(); + }, 2000); + }, + 'TRANSITION - transition stage': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var rect = new Kinetic.Rect({ + x: 100, + y: 100, + width: 100, + height: 50, + fill: 'green', + stroke: 'black', + strokeWidth: 4 + }); + + layer.add(rect); + stage.add(layer); + + var trans = stage.transitionTo({ + duration: 2, + x: 400, + y: 30, + rotation: Math.PI * 2, + easing: 'bounce-ease-out' + }); + }, + 'TRANSITION - transition position and rotation with two transitions': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var rect = new Kinetic.Rect({ + x: 100, + y: 100, + width: 100, + height: 50, + fill: 'green', + stroke: 'black', + strokeWidth: 4 + }); + + layer.add(rect); + stage.add(layer); + + rect.transitionTo({ + x: 400, + y: 30, + duration: 1 + }); + + rect.transitionTo({ + rotation: Math.PI * 2, + duration: 2 + }); + }, + 'ANIMATION - run animation': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var rect = new Kinetic.Rect({ + x: 200, + y: 100, + width: 100, + height: 50, + fill: 'green', + stroke: 'black', + strokeWidth: 4 + }); + + layer.add(rect); + stage.add(layer); + + var amplitude = 150; + var period = 1000; + // in ms + var centerX = stage.getWidth() / 2 - 100 / 2; + + stage.onFrame(function(frame) { + rect.attrs.x = amplitude * Math.sin(frame.time * 2 * Math.PI / period) + centerX; + layer.draw(); + }); + + stage.start(); + + setTimeout(function() { + stage.stop(); + }, 3000); + }, + 'TRANSITION - hover linear transition': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var rect = new Kinetic.Rect({ + x: stage.getWidth() / 2 - 50, + y: stage.getHeight() / 2 - 25, + width: 100, + height: 50, + fill: 'green', + stroke: 'black', + strokeWidth: 4, + offset: { + x: 50, + y: 25 + } + }); + + rect.on("mouseover", function() { + this.transitionTo({ + scale: { + x: 1.5, + y: 1.5 + }, + duration: 1 + }); + }); + + rect.on("mouseout", function() { + this.transitionTo({ + scale: { + x: 1, + y: 1 + }, + duration: 1 + }); + }); + + layer.add(rect); + stage.add(layer); + + }, + 'TRANSITION - hover ease-in transition': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var rect = new Kinetic.Rect({ + x: stage.getWidth() / 2 - 50, + y: stage.getHeight() / 2 - 25, + width: 100, + height: 50, + fill: 'green', + stroke: 'black', + strokeWidth: 4, + offset: { + x: 50, + y: 25 + } + }); + + rect.on("mouseover", function() { + this.transitionTo({ + scale: { + x: 1.5, + y: 1.5 + }, + duration: 1, + easing: "ease-in" + }); + }); + + rect.on("mouseout", function() { + this.transitionTo({ + scale: { + x: 1, + y: 1 + }, + duration: 1, + easing: "ease-in" + }); + }); + + layer.add(rect); + stage.add(layer); + + }, + 'TRANSITION - hover ease-out transition': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var rect = new Kinetic.Rect({ + x: stage.getWidth() / 2 - 50, + y: stage.getHeight() / 2 - 25, + width: 100, + height: 50, + fill: 'green', + stroke: 'black', + strokeWidth: 4, + offset: { + x: 50, + y: 25 + } + }); + + rect.on("mouseover", function() { + this.transitionTo({ + scale: { + x: 1.5, + y: 1.5 + }, + duration: 1, + easing: "ease-out" + }); + }); + + rect.on("mouseout", function() { + this.transitionTo({ + scale: { + x: 1, + y: 1 + }, + duration: 1, + easing: "ease-out" + }); + }); + + layer.add(rect); + stage.add(layer); + + }, + 'TRANSITION - hover ease-in-out transition': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var rect = new Kinetic.Rect({ + x: stage.getWidth() / 2 - 50, + y: stage.getHeight(0) / 2 - 25, + width: 100, + height: 50, + fill: 'green', + stroke: 'black', + strokeWidth: 4, + offset: { + x: 50, + y: 25 + } + }); + + rect.on("mouseover", function() { + this.transitionTo({ + scale: { + x: 1.5, + y: 1.5 + }, + duration: 1, + easing: "ease-in-out" + }); + }); + + rect.on("mouseout", function() { + this.transitionTo({ + scale: { + x: 1, + y: 1 + }, + duration: 1, + easing: "ease-in-out" + }); + }); + + layer.add(rect); + stage.add(layer); + + }, + 'TRANSITION - ease-in, ease-out, ease-in-out hovers': function(containerId) { + function addHovers(shape, easing) { + shape.on("mouseover", function() { + this.transitionTo({ + scale: { + x: 1.5, + y: 1.5 + }, + duration: 1, + easing: easing + }); + }); + shape.on("mouseout", function() { + this.transitionTo({ + scale: { + x: 1, + y: 1 + }, + duration: 1, + easing: easing + }); + }); + } + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var greenBox = new Kinetic.Rect({ + x: 50, + y: stage.getHeight() / 2 - 25, + width: 100, + height: 50, + fill: 'green', + stroke: 'black', + strokeWidth: 4, + offset: { + x: 50, + y: 25 + } + }); + + var blueBox = new Kinetic.Rect({ + x: stage.getWidth() / 2 - 50, + y: stage.getHeight() / 2 - 25, + width: 100, + height: 50, + fill: 'blue', + stroke: 'black', + strokeWidth: 4, + offset: { + x: 50, + y: 25 + } + }); + + var redBox = new Kinetic.Rect({ + x: 428, + y: stage.getHeight() / 2 - 25, + width: 100, + height: 50, + fill: 'red', + stroke: 'black', + strokeWidth: 4, + offset: { + x: 50, + y: 25 + } + }); + + addHovers(greenBox, "ease-in"); + addHovers(blueBox, "ease-out"); + addHovers(redBox, "ease-in-out"); + + layer.add(greenBox); + layer.add(blueBox); + layer.add(redBox); + stage.add(layer); + }, + 'EVENTS - mousedown mouseup mouseover mouseout mousemove click dblclick / touchstart touchend touchmove tap dbltap': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var circle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 70, + fill: 'red', + stroke: 'black', + strokeWidth: 4 + }); + + circle.on('mousedown', function() { + log('mousedown'); + }); + + circle.on('mouseup', function() { + log('mouseup'); + }); + + circle.on('mouseover', function() { + log('mouseover'); + }); + + circle.on('mouseout', function() { + log('mouseout'); + }); + + circle.on('mousemove', function() { + log('mousemove'); + }); + + circle.on('click', function() { + log('click'); + }); + + circle.on('dblclick', function() { + log('dblclick'); + }); + /* + * mobile + */ + circle.on('touchstart', function() { + log('touchstart'); + }); + + circle.on('touchend', function() { + log('touchend'); + }); + + circle.on('touchmove', function() { + log('touchmove'); + }); + + circle.on('tap', function(evt) { + log('tap'); + }); + + circle.on('dbltap', function() { + log('dbltap'); + }); + + layer.add(circle); + stage.add(layer); + }, + 'EVENTS - modify fill stroke and stroke width on hover with circle': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var circle = new Kinetic.Circle({ + x: 380, + y: stage.getHeight() / 2, + radius: 70, + strokeWidth: 4, + fill: 'red', + stroke: 'black' + }); + + circle.on('mouseover', function() { + this.setFill('yellow'); + this.setStroke('purple'); + this.setStrokeWidth(20); + layer.draw(); + }); + + circle.on('mouseout', function() { + this.setFill('red'); + this.setStroke('black'); + this.setStrokeWidth(4); + layer.draw(); + }); + + layer.add(circle); + stage.add(layer); + }, + 'EVENTS - modify fill stroke and stroke width on hover with star': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + + var star = new Kinetic.Star({ + x: 200, + y: 100, + numPoints: 10, + innerRadius: 40, + outerRadius: 70, + fill: 'green', + stroke: 'blue', + strokeWidth: 5, + name: 'foobar' + }); + + star.on('mouseover', function() { + this.setFill('yellow'); + this.setStroke('purple'); + this.setStrokeWidth(20); + layer.draw(); + }); + + star.on('mouseout', function() { + this.setFill('green'); + this.setStroke('blue'); + this.setStrokeWidth(5); + layer.draw(); + }); + + layer.add(star); + stage.add(layer); + }, + 'EVENTS - modify fill stroke and stroke width on hover with image': function(containerId) { + var imageObj = new Image(); + imageObj.onload = function() { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var darth = new Kinetic.Image({ + x: 60, + y: 60, + image: imageObj + }); + + darth.on('mouseover', function() { + this.setStroke('purple'); + this.setStrokeWidth(20); + layer.draw(); + }); + + darth.on('mouseout', function() { + this.setStroke(undefined); + this.setStrokeWidth(0); + layer.draw(); + }); + + layer.add(darth); + stage.add(layer); + }; + imageObj.src = '../darth-vader.jpg'; + }, + /* + * WARNING: this functional test will only pass if it's hosted on + * a webserver due to cross domain security issues + */ + 'EVENTS - image pixel detection': function(containerId) { + var imageObj = new Image(); + imageObj.onload = function() { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var darth = new Kinetic.Image({ + x: 200, + y: 40, + image: imageObj, + detectionType: 'pixel', + draggable: true + }); + + darth.on('mouseover', function() { + log('mouseover'); + }); + + darth.on('mouseout', function() { + log('mouseout'); + }); + + darth.on('dragend', function() { + this.saveData(); + }); + + layer.add(darth); + stage.add(layer); + + //darth.save(); + }; + imageObj.src = '../lion.png'; + }, + 'EVENTS - star pixel detection': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + + var layer = new Kinetic.Layer({ + rotationDeg: 20 + }); + var star = new Kinetic.Star({ + x: 200, + y: 100, + numPoints: 10, + innerRadius: 40, + outerRadius: 70, + fill: 'green', + stroke: 'blue', + strokeWidth: 20, + detectionType: 'pixel', + draggable: true + }); + + star.on('mouseover', function() { + log('mouseover'); + }); + + star.on('mouseout', function() { + log('mouseout'); + }); + + star.on('dragend', function() { + this.saveData(); + }); + + layer.add(star); + stage.add(layer); + star.saveData(); + }, + 'EVENTS - drag events click': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var circle = new Kinetic.Circle({ + x: 380, + y: stage.getHeight() / 2, + radius: 70, + strokeWidth: 4, + fill: 'red', + stroke: 'black' + }); + + circle.draggable(true); + + circle.on('dragstart', function() { + log('dragstart'); + }); + + circle.on('dragmove', function() { + log('dragmove'); + }); + + circle.on('dragend', function() { + log('dragend'); + }); + + circle.on('click', function() { + log('click'); + }); + + layer.add(circle); + stage.add(layer); + }, + 'EVENTS - move mouse from shape to another shape in same layer': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + + var redCircle = new Kinetic.Circle({ + x: 200, + y: stage.getHeight() / 2, + radius: 70, + strokeWidth: 4, + fill: 'red', + stroke: 'black' + }); + + redCircle.on('mouseover', function() { + log('mouseover red circle'); + }); + redCircle.on('mouseout', function() { + log('mouseout red circle'); + }); + var greenCircle = new Kinetic.Circle({ + x: 280, + y: stage.getHeight() / 2, + radius: 70, + strokeWidth: 4, + fill: 'green', + stroke: 'black' + }); + + greenCircle.on('mouseover', function() { + log('mouseover green circle'); + }); + greenCircle.on('mouseout', function() { + log('mouseout green circle'); + }); + + layer.add(redCircle); + layer.add(greenCircle); + + stage.add(layer); + }, + 'EVENTS - move mouse from shape in one group to shape in another group': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var redGroup = new Kinetic.Group(); + var greenGroup = new Kinetic.Group(); + + var redCircle = new Kinetic.Circle({ + x: 200, + y: stage.getHeight() / 2, + radius: 70, + strokeWidth: 4, + fill: 'red', + stroke: 'black' + }); + + redCircle.on('mouseover', function() { + log('mouseover red circle'); + }); + redCircle.on('mouseout', function() { + log('mouseout red circle'); + }); + var greenCircle = new Kinetic.Circle({ + x: 280, + y: stage.getHeight() / 2, + radius: 70, + strokeWidth: 4, + fill: 'green', + stroke: 'black' + }); + + greenCircle.on('mouseover', function() { + log('mouseover green circle'); + }); + greenCircle.on('mouseout', function() { + log('mouseout green circle'); + }); + + redGroup.add(redCircle); + greenGroup.add(greenCircle); + + layer.add(redGroup); + layer.add(greenGroup); + + stage.add(layer); + }, + 'EVENTS - move mouse from shape in one layer to shape in another layer': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var redLayer = new Kinetic.Layer(); + var greenLayer = new Kinetic.Layer(); + + var redCircle = new Kinetic.Circle({ + x: 200, + y: stage.getHeight() / 2, + radius: 70, + strokeWidth: 4, + fill: 'red', + stroke: 'black' + }); + + redCircle.on('mouseover', function() { + log('mouseover red circle'); + }); + redCircle.on('mouseout', function() { + log('mouseout red circle'); + }); + var greenCircle = new Kinetic.Circle({ + x: 280, + y: stage.getHeight() / 2, + radius: 70, + strokeWidth: 4, + fill: 'green', + stroke: 'black' + }); + + greenCircle.on('mouseover', function() { + log('mouseover green circle'); + }); + greenCircle.on('mouseout', function() { + log('mouseout green circle'); + }); + + redLayer.add(redCircle); + greenLayer.add(greenCircle); + + stage.add(redLayer); + stage.add(greenLayer); + }, + 'EVENTS - mousemove from shape in one group to shape in another group': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var redGroup = new Kinetic.Group(); + var greenGroup = new Kinetic.Group(); + + var redCircle = new Kinetic.Circle({ + x: 200, + y: stage.getHeight() / 2, + radius: 70, + strokeWidth: 4, + fill: 'red', + stroke: 'black' + }); + + redCircle.on('mousemove', function() { + log('mousemove red circle'); + }); + var greenCircle = new Kinetic.Circle({ + x: 280, + y: stage.getHeight() / 2, + radius: 70, + strokeWidth: 4, + fill: 'green', + stroke: 'black' + }); + + greenCircle.on('mousemove', function() { + log('mousemove green circle'); + }); + + redGroup.add(redCircle); + greenGroup.add(greenCircle); + + layer.add(redGroup); + layer.add(greenGroup); + + stage.add(layer); + }, + 'EVENTS - group click events': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var group = new Kinetic.Group(); + + group.on('click', function() { + log('click group'); + //console.log(this); + }); + var redCircle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 80, + strokeWidth: 4, + fill: 'red', + stroke: 'black', + name: 'red' + }); + + var greenCircle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 40, + strokeWidth: 4, + fill: 'green', + stroke: 'black', + name: 'green' + }); + + group.add(redCircle); + group.add(greenCircle); + + layer.add(group); + stage.add(layer); + }, + 'EVENTS - group mousemove events': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var group = new Kinetic.Group(); + + group.on('mousemove', function() { + log('mousemove group'); + //console.log(this); + }); + var redCircle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 80, + strokeWidth: 4, + fill: 'red', + stroke: 'black' + }); + + var greenCircle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 40, + strokeWidth: 4, + fill: 'green', + stroke: 'black' + }); + + group.add(redCircle); + group.add(greenCircle); + + layer.add(group); + stage.add(layer); + }, + 'EVENTS - group mouseover events': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var group = new Kinetic.Group({ + name: 'group' + }); + + group.on('mouseover', function() { + log('mouseover group'); + }); + + group.on('mouseout', function() { + log('mouseout group'); + }); + var redCircle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 80, + strokeWidth: 4, + fill: 'red', + stroke: 'black', + name: 'red' + }); + + var greenCircle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 40, + strokeWidth: 4, + fill: 'green', + stroke: 'black', + name: 'green' + }); + + group.add(redCircle); + group.add(greenCircle); + + layer.add(group); + stage.add(layer); + }, + 'EVENTS - cancel event bubbling (only the red circle should fire click event)': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var group = new Kinetic.Group(); + + layer.on('click', function() { + log('click layer'); + //console.log(this); + }); + group.on('click', function() { + log('click group'); + //console.log(this); + }); + var redCircle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 80, + strokeWidth: 4, + fill: 'red', + stroke: 'black' + }); + + redCircle.on('click', function(evt) { + log('click red circle'); + evt.cancelBubble = true; + }); + + group.add(redCircle); + layer.add(group); + stage.add(layer); + }, + 'EVENTS - get currentTarget': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var group = new Kinetic.Group(); + + layer.on('click', function(evt) { + log(evt.shape.getName()); + + }); + var redCircle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 80, + strokeWidth: 4, + fill: 'red', + stroke: 'black', + name: 'circle' + }); + + group.add(redCircle); + layer.add(group); + stage.add(layer); + }, + 'EVENTS - shape mouseout handlers when mouse leaves stage': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + + var redCircle = new Kinetic.Circle({ + x: 550, + y: stage.getHeight() / 2, + radius: 80, + strokeWidth: 4, + fill: 'red', + stroke: 'black', + name: 'circle' + }); + + redCircle.on('mouseout', function() { + log('mouseout'); + }); + + layer.add(redCircle); + stage.add(layer); + }, + 'DRAG AND DROP - custom draw func and drag and drop layer': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + 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(); + }, + draggable: true + }); + + var circle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 70, + fill: 'red' + }); + + var circle2 = new Kinetic.Circle({ + x: 400, + y: stage.getHeight() / 2, + radius: 70, + fill: 'green' + }); + + layer.add(circle); + layer.add(circle2); + + stage.add(layer); + }, + 'DRAG AND DROP - drag and drop elastic star with shadow': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + + var star = new Kinetic.Star({ + x: 200, + y: 100, + numPoints: 5, + innerRadius: 40, + outerRadius: 70, + fill: 'green', + stroke: 'blue', + strokeWidth: 5, + lineJoin: "round", + shadow: { + color: '#aaa', + blur: 10, + offset: { + x: 5, + y: 5 + } + }, + draggable: true + }); + + layer.add(star); + stage.add(layer); + star.setLineJoin('bevel'); + layer.draw(); + + var trans = null; + + star.on('dragstart', function() { + if(trans) { + trans.stop(); + } + + star.setAttrs({ + shadow: { + offset: { + x: 15, + y: 15 + } + }, + offset: { + x: 10, + y: 10 + } + }); + }); + + star.on('dragend', function() { + trans = star.transitionTo({ + duration: 0.5, + easing: 'elastic-ease-out', + shadow: { + offset: { + x: 5, + y: 5 + } + }, + offset: { + x: 0, + y: 0 + } + }) + }); + /* + stage.onFrame(function(frame) { + star.rotate(1 * frame.timeDiff / 1000); + layer.draw(); + }); + + stage.start(); + */ + }, + 'DRAG AND DROP - multiple drag and drop sets with draggable() (circle should not be draggable)': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var circle = new Kinetic.Circle({ + x: 380, + y: stage.getHeight() / 2, + radius: 70, + strokeWidth: 4, + fill: 'red', + stroke: 'black' + }); + + circle.draggable(true); + circle.draggable(true); + circle.draggable(false); + + layer.add(circle); + stage.add(layer); + + }, + 'DRAG AND DROP - two draggable shapes': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var circle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 70, + fill: 'red', + stroke: 'black', + strokeWidth: 4, + //detectionType: 'pixel' + }); + + circle.draggable(true); + + var circle2 = new Kinetic.Circle({ + x: 350, + y: stage.getHeight() / 2, + radius: 70, + fill: 'green', + stroke: 'black', + strokeWidth: 4, + draggable: true + //detectionType: 'pixel' + }); + + /* + circle.on('dragend', function() { + circle.saveData(); + }); + */ + + layer.add(circle).add(circle2); + stage.add(layer); + + //circle.saveData(); + }, + 'DRAG AND DROP - drag and drop stage': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200, + draggable: true, + //dragConstraint: 'horizontal', + /* + dragBounds: { + left: 100 + } + */ + }); + var layer = new Kinetic.Layer({ + /* + draggable: true, + dragBounds: { + left: 100 + } + */ + }); + var circle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 70, + fill: 'red', + stroke: 'black', + strokeWidth: 4, + //draggable: true, + /* + dragBounds: { + left: 100 + } + */ + }); + + //stage.draggable(false); + //layer.draggable(false); + + /* + stage.on('dragstart', function() { + console.log('dragstart'); + }); + stage.on('dragmove', function() { + //console.log('dragmove'); + }); + stage.on('dragend', function() { + console.log('dragend'); + }); + */ + + layer.add(circle); + stage.add(layer); + }, + 'DRAG AND DROP - draggable true false': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var circle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 70, + fill: 'red', + stroke: 'black', + strokeWidth: 4 + }); + + circle.draggable(true); + + layer.add(circle); + stage.add(layer); + + circle.draggable(false); + }, + 'DRAG AND DROP - scale and rotate stage after add layer then drag and drop shape': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var rect = new Kinetic.Rect({ + x: 200, + y: 20, + width: 100, + height: 50, + fill: 'red', + stroke: 'black', + strokeWidth: 4, + draggable: true + //rotationDeg: 60 + //rotationDeg: Math.PI / 3 + }); + + layer.add(rect); + stage.add(layer); + + //stage.rotateDeg(20); + + //console.log(rect.getAbsoluteTransform().getTranslation()) + + stage.rotate(Math.PI / 3); + stage.setScale(0.5); + + stage.draw(); + }, + 'DRAG AND DROP - scale stage before add shape then drag and drop shape': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var circle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 70, + fill: 'red', + stroke: 'black', + strokeWidth: 4 + }); + + circle.draggable(true); + + stage.setScale(0.5); + layer.add(circle); + stage.add(layer); + }, + 'DRAG AND DROP - set stage scale to 1.5 after add layer then drag and drop shape': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var circle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 70, + fill: 'red', + stroke: 'black', + strokeWidth: 4 + }); + + circle.draggable(true); + + layer.add(circle); + stage.add(layer); + + stage.setScale(1.5); + + stage.draw(); + }, + 'DRAG AND DROP - set stage scale to 1.5 before add layer then drag and drop shape': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var circle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 70, + fill: 'red', + stroke: 'black', + strokeWidth: 4 + }); + + circle.draggable(true); + + stage.setScale(1.5); + + layer.add(circle); + stage.add(layer); + }, + 'DRAG AND DROP - check that green events are ignored when dragging red circle': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var circle1 = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 70, + fill: 'red', + stroke: 'black', + strokeWidth: 4 + }); + + var circle2 = new Kinetic.Circle({ + x: stage.getWidth() / 2 + 50, + y: stage.getHeight() / 2, + radius: 70, + fill: 'green', + stroke: 'black', + strokeWidth: 4 + }); + + circle1.draggable(true); + + circle2.on('mouseover', function() { + log('mouseover green circle'); + }); + + layer.add(circle1); + layer.add(circle2); + stage.add(layer); + }, + 'DRAG AND DROP - drag and drop constrianed horiztontally inside positioned group': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var group = new Kinetic.Group({ + x: 0, + y: 10 + }); + var circle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 70, + fill: 'red', + stroke: 'black', + strokeWidth: 4, + draggable: true, + dragConstraint: 'horizontal' + }); + + group.add(circle); + layer.add(group); + stage.add(layer); + }, + 'DRAG AND DROP - drag and drop constrianed vertically': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var circle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 70, + fill: 'red', + stroke: 'black', + strokeWidth: 4, + draggable: true, + dragConstraint: 'vertical' + }); + + layer.add(circle); + stage.add(layer); + }, + 'DRAG AND DROP - drag and drop with explicit no constraint': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var circle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 70, + fill: 'red', + stroke: 'black', + strokeWidth: 4, + draggable: true, + dragConstraint: 'none' + }); + + layer.add(circle); + stage.add(layer); + }, + 'DRAG AND DROP - drag and drop with left bounds': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var circle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 70, + fill: 'red', + stroke: 'black', + strokeWidth: 4, + draggable: true, + dragBounds: { + left: 150 + } + }); + + layer.add(circle); + stage.add(layer); + }, + 'DRAG AND DROP - drag and drop with right bounds': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var circle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 70, + fill: 'red', + stroke: 'black', + strokeWidth: 4, + draggable: true, + dragBounds: { + right: 400 + } + }); + + layer.add(circle); + stage.add(layer); + }, + 'DRAG AND DROP - drag and drop with top bounds': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var circle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 70, + fill: 'red', + stroke: 'black', + strokeWidth: 4, + draggable: true, + dragBounds: { + top: 80 + } + }); + + layer.add(circle); + stage.add(layer); + }, + 'DRAG AND DROP - drag and drop with bottom bounds': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var circle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 70, + fill: 'red', + stroke: 'black', + strokeWidth: 4, + draggable: true, + dragBounds: { + bottom: 120 + } + }); + + layer.add(circle); + stage.add(layer); + }, + 'DRAG AND DROP - drag and drop with full rect bounds': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var circle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 70, + fill: 'red', + stroke: 'black', + strokeWidth: 4, + draggable: true, + dragBounds: { + top: 80, + bottom: 120, + left: 150, + right: 578 - 150 + } + }); + + layer.add(circle); + stage.add(layer); + }, + 'DRAG AND DROP - drag and drop shape inside scrollable div': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 400 + }); + + // make container scrollable + var container = stage.getContainer(); + container.style.overflow = 'auto'; + + var layer = new Kinetic.Layer(); + var circle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: 100, + radius: 50, + fill: 'blue', + stroke: 'black', + strokeWidth: 4, + draggable: true + }); + + layer.add(circle); + stage.add(layer); + }, + 'DRAG AND DROP - drag and drop shape inside scaled group': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + var group = new Kinetic.Group({ + scale: { + x: 2, + y: 2 + } + }); + + var circle = new Kinetic.Circle({ + x: 40, + y: 40, + radius: 70, + fill: 'red', + stroke: 'black', + strokeWidth: 4, + draggable: true + }); + + group.add(circle); + layer.add(group); + stage.add(layer); + }, + 'DRAG AND DROP - translate, rotate, and scale shape, and then drag and drop': 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); + }, + 'DRAG AND DROP - translate, rotate, center offset, and scale shape, and then drag and drop': 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 + }, + offset: { + x: 50, + y: 25 + } + }); + + group.add(rect); + layer.add(group); + stage.add(layer); + + stage.onFrame(function() { + rect.rotate(0.01); + layer.draw(); + }); + //stage.start(); + + }, + 'STAGE - hide stage': 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); + + stage.hide(); + stage.draw(); + }, + 'STAGE - hide layer': 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); + + layer.hide(); + + stage.draw(); + }, + 'STAGE - hide group': 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); + + group.hide(); + + stage.draw(); + }, + 'STAGE - save image as png (click on circle to open new window)': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + + var circle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 70, + fill: 'violet', + stroke: 'black', + strokeWidth: 4 + }); + + circle.on('click', function() { + stage.toDataURL(function(dataUrl) { + /* + * here you can do anything you like with the data url. + * In this tutorial we'll just open the url with the browser + * so that you can see the result as an image + */ + window.open(dataUrl); + }); + }); + + layer.add(circle); + stage.add(layer); + }, + 'STAGE - save image as low quality jpg (click on circle to open new window)': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + + var circle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 70, + fill: 'violet', + stroke: 'black', + strokeWidth: 4 + }); + + circle.on('click', function() { + stage.toDataURL(function(dataUrl) { + /* + * here you can do anything you like with the data url. + * In this tutorial we'll just open the url with the browser + * so that you can see the result as an image + */ + window.open(dataUrl); + }, 'image/jpeg', 0); + }); + + layer.add(circle); + stage.add(layer); + }, + 'STAGE - save image as high quality jpg (click on circle to open new window)': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + + var circle = new Kinetic.Circle({ + x: stage.getWidth() / 2, + y: stage.getHeight() / 2, + radius: 70, + fill: 'violet', + stroke: 'black', + strokeWidth: 4 + }); + + circle.on('click', function() { + stage.toDataURL(function(dataUrl) { + /* + * here you can do anything you like with the data url. + * In this tutorial we'll just open the url with the browser + * so that you can see the result as an image + */ + window.open(dataUrl); + }, 'image/jpeg', 1); + }); + + layer.add(circle); + stage.add(layer); + } +};