konva/src/Global.js

389 lines
13 KiB
JavaScript
Raw Normal View History

2014-02-27 08:49:18 +08:00
/*
* KineticJS JavaScript Framework v@@version
* http://www.kineticjs.com/
* Copyright 2013, Eric Rowell
* Licensed under the MIT or GPL Version 2 licenses.
* Date: @@date
*
* Copyright (C) 2011 - 2013 by Eric Rowell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* @namespace Kinetic
2013-03-26 16:09:21 +08:00
*/
2014-02-27 08:49:18 +08:00
/*jshint -W079, -W020*/
var Kinetic = {};
2014-02-27 19:55:39 +08:00
(function(root) {
var PI_OVER_180 = Math.PI / 180;
Kinetic = {
// public
version: '@@version',
// private
stages: [],
idCounter: 0,
ids: {},
names: {},
shapes: {},
listenClickTap: false,
inDblClickWindow: false,
// configurations
enableTrace: false,
traceArrMax: 100,
dblClickWindow: 400,
2014-04-14 09:49:10 +08:00
/**
* Global pixel ratio configuration. KineticJS automatically detect pixel ratio of current device.
* But you may override such property, if you want to use your value.
* @property
* @default undefined
* @memberof Kinetic
* @example
* Kinetic.pixelRatio = 1;
*/
pixelRatio: undefined,
2014-04-14 09:49:10 +08:00
/**
* Drag distance property. If you start to drag a node you may want to wait until pointer is moved to some distance from start point,
* only then start dragging.
* @property
* @default 0
* @memberof Kinetic
* @example
* Kinetic.dragDistance = 10;
*/
2014-03-11 23:14:03 +08:00
dragDistance : 0,
2014-04-14 09:49:10 +08:00
/**
* Use degree values for angle properties. You may set this property to false if you want to use radiant values.
* @property
* @default true
* @memberof Kinetic
* @example
* node.rotation(45); // 45 degrees
* Kinetic.angleDeg = false;
* node.rotation(Math.PI / 2); // PI/2 radian
*/
angleDeg: true,
// user agent
UA: (function() {
2014-02-27 19:55:39 +08:00
var userAgent = (root.navigator && root.navigator.userAgent) || '';
var ua = userAgent.toLowerCase(),
// jQuery UA regex
match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
/(webkit)[ \/]([\w.]+)/.exec( ua ) ||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
/(msie) ([\w.]+)/.exec( ua ) ||
2014-02-27 08:49:18 +08:00
ua.indexOf('compatible') < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
[],
// adding mobile flag as well
2014-02-27 19:55:39 +08:00
mobile = !!(userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i));
return {
browser: match[ 1 ] || '',
version: match[ 2 ] || '0',
// adding mobile flab
mobile: mobile
};
})(),
/**
* @namespace Filters
* @memberof Kinetic
*/
Filters: {},
/**
* Node constructor. Nodes are entities that can be transformed, layered,
* and have bound events. The stage, layers, groups, and shapes all extend Node.
* @constructor
* @memberof Kinetic
* @abstract
* @param {Object} config
* @@nodeParams
*/
Node: function(config) {
this._init(config);
},
/**
* Shape constructor. Shapes are primitive objects such as rectangles,
* circles, text, lines, etc.
* @constructor
* @memberof Kinetic
* @augments Kinetic.Node
* @param {Object} config
* @@shapeParams
* @@nodeParams
* @example
2014-04-04 11:17:09 +08:00
* var customShape = new Kinetic.Shape({
* x: 5,
* y: 10,
* fill: 'red',
* // a Kinetic.Canvas renderer is passed into the drawFunc function
* drawFunc: function(context) {
* context.beginPath();
* context.moveTo(200, 50);
* context.lineTo(420, 80);
* context.quadraticCurveTo(300, 100, 260, 170);
* context.closePath();
* context.fillStrokeShape(this);
* }
*});
*/
Shape: function(config) {
this.__init(config);
},
/**
* Container constructor.&nbsp; Containers are used to contain nodes or other containers
* @constructor
* @memberof Kinetic
* @augments Kinetic.Node
* @abstract
* @param {Object} config
* @@nodeParams
* @@containerParams
*/
Container: function(config) {
this.__init(config);
},
/**
* Stage constructor. A stage is used to contain multiple layers
* @constructor
* @memberof Kinetic
* @augments Kinetic.Container
* @param {Object} config
* @param {String|DomElement} config.container Container id or DOM element
* @@nodeParams
* @@containerParams
* @example
2014-04-04 11:17:09 +08:00
* var stage = new Kinetic.Stage({
* width: 500,
* height: 800,
* container: 'containerId'
* });
*/
Stage: function(config) {
this.___init(config);
},
/**
* BaseLayer constructor.
* @constructor
* @memberof Kinetic
* @augments Kinetic.Container
* @param {Object} config
* @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want
* to clear the canvas before each layer draw. The default value is true.
* @@nodeParams
* @@containerParams
* @example
* var layer = new Kinetic.Layer();
*/
BaseLayer: function(config) {
this.___init(config);
},
/**
* Layer constructor. Layers are tied to their own canvas element and are used
* to contain groups or shapes.
* @constructor
* @memberof Kinetic
* @augments Kinetic.Container
* @param {Object} config
* @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want
* to clear the canvas before each layer draw. The default value is true.
* @@nodeParams
* @@containerParams
* @example
* var layer = new Kinetic.Layer();
*/
Layer: function(config) {
this.____init(config);
},
/**
* FastLayer constructor. Layers are tied to their own canvas element and are used
* to contain shapes only. If you don't need node nesting, mouse and touch interactions,
* or event pub/sub, you should use FastLayer instead of Layer to create your layers.
* It renders about 2x faster than normal layers.
* @constructor
* @memberof Kinetic
* @augments Kinetic.Container
* @param {Object} config
* @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want
* to clear the canvas before each layer draw. The default value is true.
* @@containerParams
* @example
* var layer = new Kinetic.FastLayer();
*/
FastLayer: function(config) {
this.____init(config);
},
/**
* Group constructor. Groups are used to contain shapes or other groups.
* @constructor
* @memberof Kinetic
* @augments Kinetic.Container
* @param {Object} config
* @@nodeParams
* @@containerParams
* @example
* var group = new Kinetic.Group();
*/
Group: function(config) {
this.___init(config);
},
2013-03-26 16:09:21 +08:00
/**
* returns whether or not drag and drop is currently active
* @method
* @memberof Kinetic
2013-03-26 16:09:21 +08:00
*/
isDragging: function() {
var dd = Kinetic.DD;
2013-04-03 13:29:56 +08:00
// if DD is not included with the build, then
// drag and drop is not even possible
if (!dd) {
return false;
}
2013-04-03 13:29:56 +08:00
// if DD is included with the build
else {
return dd.isDragging;
}
},
/**
* returns whether or not a drag and drop operation is ready, but may
2013-04-03 13:29:56 +08:00
* not necessarily have started
* @method
* @memberof Kinetic
2013-04-03 13:29:56 +08:00
*/
isDragReady: function() {
var dd = Kinetic.DD;
2013-04-03 13:29:56 +08:00
// if DD is not included with the build, then
// drag and drop is not even possible
if (!dd) {
return false;
}
2013-04-03 13:29:56 +08:00
// if DD is included with the build
else {
return !!dd.node;
}
},
_addId: function(node, id) {
if(id !== undefined) {
this.ids[id] = node;
}
},
_removeId: function(id) {
if(id !== undefined) {
delete this.ids[id];
}
},
_addName: function(node, name) {
if(name !== undefined) {
if(this.names[name] === undefined) {
this.names[name] = [];
}
this.names[name].push(node);
}
},
_removeName: function(name, _id) {
if(name !== undefined) {
var nodes = this.names[name];
if(nodes !== undefined) {
for(var n = 0; n < nodes.length; n++) {
var no = nodes[n];
if(no._id === _id) {
nodes.splice(n, 1);
}
}
if(nodes.length === 0) {
delete this.names[name];
}
}
}
},
getAngle: function(angle) {
return this.angleDeg ? angle * PI_OVER_180 : angle;
}
};
2014-02-27 19:55:39 +08:00
})(this);
// Uses Node, AMD or browser globals to create a module.
// If you want something that will work in other stricter CommonJS environments,
// or if you need to create a circular dependency, see commonJsStrict.js
// Defines a module "returnExports" that depends another module called "b".
// Note that the name of the module is implied by the file name. It is best
// if the file name and the exported global have matching names.
// If the 'b' module also uses this type of boilerplate, then
// in the browser, it will create a global .b that is used below.
// If you do not want to support the browser global path, then you
// can remove the `root` use and the passing `this` as the first arg to
// the top function.
// if the module has no dependencies, the above pattern can be simplified to
( function(root, factory) {
if( typeof exports === 'object') {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like enviroments that support module.exports,
// like Node.
2014-02-27 19:55:39 +08:00
var Canvas = require('canvas');
var jsdom = require('jsdom').jsdom;
2014-03-01 18:09:27 +08:00
var doc = jsdom('<!DOCTYPE html><html><head></head><body></body></html>');
2014-02-27 19:55:39 +08:00
var KineticJS = factory();
Kinetic.document = doc;
Kinetic.window = Kinetic.document.createWindow();
Kinetic.window.Image = Canvas.Image;
Kinetic.root = root;
2014-02-27 19:55:39 +08:00
Kinetic._nodeCanvas = Canvas;
module.exports = KineticJS;
return;
}
else if( typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(factory);
}
Kinetic.document = document;
Kinetic.window = window;
Kinetic.root = root;
}((1, eval)('this'), function() {
// Just return a value to define the module export.
// This example returns an object, but the module
// can return a function as the exported value.
return Kinetic;
}));