konva/src/Shape.js

629 lines
17 KiB
JavaScript
Raw Normal View History

(function() {
/**
* Shape constructor. Shapes are primitive objects such as rectangles,
* circles, text, lines, etc.
* @constructor
* @augments Kinetic.Node
* @param {Object} config
* {{ShapeParams}}
* {{NodeParams}}
2012-04-29 12:12:01 +08:00
*/
Kinetic.Shape = function(config) {
this._initShape(config);
};
function _fillFunc(context) {
context.fill();
}
function _strokeFunc(context) {
context.stroke();
}
2013-02-12 14:55:24 +08:00
function _fillFuncHit(context) {
context.fill();
}
function _strokeFuncHit(context) {
context.stroke();
}
2012-04-29 12:12:01 +08:00
Kinetic.Shape.prototype = {
_initShape: function(config) {
this.nodeType = 'Shape';
this._fillFunc = _fillFunc;
this._strokeFunc = _strokeFunc;
2013-02-12 14:55:24 +08:00
this._fillFuncHit = _fillFuncHit;
this._strokeFuncHit = _strokeFuncHit;
// set colorKey
var shapes = Kinetic.Global.shapes;
var key;
while(true) {
key = Kinetic.Type._getRandomColorKey();
if(key && !( key in shapes)) {
break;
}
}
this.colorKey = key;
shapes[key] = this;
this.createAttrs();
// call super constructor
Kinetic.Node.call(this, config);
},
/**
* get canvas context tied to the layer
* @name getContext
* @methodOf Kinetic.Shape.prototype
*/
getContext: function() {
return this.getLayer().getContext();
},
/**
2012-12-17 04:56:30 +08:00
* get canvas renderer tied to the layer. Note that this returns a canvas renderer, not a canvas element
* @name getCanvas
* @methodOf Kinetic.Shape.prototype
*/
getCanvas: function() {
return this.getLayer().getCanvas();
},
/**
* returns whether or not a shadow will be rendered
* @name hasShadow
* @methodOf Kinetic.Shape.prototype
*/
hasShadow: function() {
return !!(this.getShadowColor() || this.getShadowBlur() || this.getShadowOffset());
},
/**
* returns whether or not a fill will be rendered
* @name hasFill
* @methodOf Kinetic.Shape.prototype
*/
hasFill: function() {
return !!(this.getFill() || this.getFillPatternImage() || this.getFillLinearGradientStartPoint() || this.getFillRadialGradientStartPoint());
},
_get: function(selector) {
return this.nodeType === selector || this.shapeType === selector ? [this] : [];
},
/**
* determines if point is in the shape
2012-12-17 04:56:30 +08:00
* @name intersects
* @methodOf Kinetic.Shape.prototype
* @param {Object} point point can be an object containing
* an x and y property, or it can be an array with two elements
* in which the first element is the x component and the second
* element is the y component
*/
intersects: function() {
var pos = Kinetic.Type._getXY(Array.prototype.slice.call(arguments));
var stage = this.getStage();
var hitCanvas = stage.hitCanvas;
hitCanvas.clear();
this.drawScene(hitCanvas);
var p = hitCanvas.context.getImageData(Math.round(pos.x), Math.round(pos.y), 1, 1).data;
return p[3] > 0;
},
2013-01-31 02:05:58 +08:00
/**
* enable fill
*/
enableFill: function() {
this.setAttr('fillEnabled', true);
},
2013-01-31 02:05:58 +08:00
/**
* disable fill
*/
disableFill: function() {
this.setAttr('fillEnabled', false);
},
2013-01-31 02:05:58 +08:00
/**
* enable stroke
*/
enableStroke: function() {
this.setAttr('strokeEnabled', true);
},
2013-01-31 02:05:58 +08:00
/**
* disable stroke
*/
disableStroke: function() {
this.setAttr('strokeEnabled', false);
},
/**
* enable stroke scale
*/
enableStrokeScale: function() {
this.setAttr('strokeScaleEnabled', true);
},
/**
* disable stroke scale
*/
disableStrokeScale: function() {
this.setAttr('strokeScaleEnabled', false);
},
2013-01-31 02:05:58 +08:00
/**
* enable shadow
*/
enableShadow: function() {
this.setAttr('shadowEnabled', true);
},
2013-01-31 02:05:58 +08:00
/**
* disable shadow
*/
disableShadow: function() {
this.setAttr('shadowEnabled', false);
},
2013-01-31 02:05:58 +08:00
/**
* enable dash array
*/
enableDashArray: function() {
this.setAttr('dashArrayEnabled', true);
},
2013-01-31 02:05:58 +08:00
/**
* disable dash array
*/
disableDashArray: function() {
this.setAttr('dashArrayEnabled', false);
},
remove: function() {
Kinetic.Node.prototype.remove.call(this);
delete Kinetic.Global.shapes[this.colorKey];
},
drawScene: function(canvas) {
var attrs = this.attrs, drawFunc = attrs.drawFunc, canvas = canvas || this.getLayer().getCanvas(), context = canvas.getContext();
if(drawFunc && this.isVisible()) {
context.save();
canvas._applyOpacity(this);
canvas._applyLineJoin(this);
canvas._applyAncestorTransforms(this);
drawFunc.call(this, canvas);
context.restore();
}
},
drawHit: function() {
var attrs = this.attrs, drawFunc = attrs.drawHitFunc || attrs.drawFunc, canvas = this.getLayer().hitCanvas, context = canvas.getContext();
if(drawFunc && this.isVisible() && this.isListening()) {
context.save();
canvas._applyLineJoin(this);
canvas._applyAncestorTransforms(this);
drawFunc.call(this, canvas);
context.restore();
}
},
_setDrawFuncs: function() {
if(!this.attrs.drawFunc && this.drawFunc) {
this.setDrawFunc(this.drawFunc);
}
if(!this.attrs.drawHitFunc && this.drawHitFunc) {
this.setDrawHitFunc(this.drawHitFunc);
}
}
};
Kinetic.Global.extend(Kinetic.Shape, Kinetic.Node);
// add getters and setters
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'stroke');
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'lineJoin');
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'lineCap');
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'strokeWidth');
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'drawFunc');
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'drawHitFunc');
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'dashArray');
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'shadowColor');
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'shadowBlur');
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'shadowOpacity');
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'fillPatternImage');
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'fill');
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'fillPatternX');
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'fillPatternY');
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'fillLinearGradientColorStops');
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'fillRadialGradientStartRadius');
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'fillRadialGradientEndRadius');
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'fillRadialGradientColorStops');
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'fillPatternRepeat');
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'fillEnabled', true);
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'strokeEnabled', true);
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'shadowEnabled', true);
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'dashArrayEnabled', true);
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'fillPriority', 'color');
Kinetic.Node.addGetterSetter(Kinetic.Shape, 'strokeScaleEnabled', true);
/**
* set stroke color
* @name setStroke
* @methodOf Kinetic.Shape.prototype
* @param {String} stroke
*/
/**
* set line join
* @name setLineJoin
* @methodOf Kinetic.Shape.prototype
* @param {String} lineJoin. Can be miter, round, or bevel. The
* default is miter
*/
2013-01-03 13:35:51 +08:00
/**
* set line cap. Can be butt, round, or square
* @name setLineCap
* @methodOf Kinetic.Shape.prototype
* @param {String} lineCap
*/
/**
* set stroke width
* @name setStrokeWidth
* @methodOf Kinetic.Shape.prototype
* @param {Number} strokeWidth
*/
/**
* set draw function
* @name setDrawFunc
* @methodOf Kinetic.Shape.prototype
* @param {Function} drawFunc drawing function
*/
/**
* set draw hit function used for hit detection
* @name setDrawHitFunc
* @methodOf Kinetic.Shape.prototype
* @param {Function} drawHitFunc drawing function used for hit detection
*/
/**
* set dash array.
* @name setDashArray
2013-01-07 01:04:10 +08:00
* @methodOf Kinetic.Shape.prototype
* @param {Array} dashArray
* examples:<br>
* [10, 5] dashes are 10px long and 5 pixels apart
2012-12-17 04:56:30 +08:00
* [10, 20, 0.001, 20] if using a round lineCap, the line will
* be made up of alternating dashed lines that are 10px long
2012-12-17 04:56:30 +08:00
* and 20px apart, and dots that have a radius of 5px and are 20px
* apart
*/
/**
* set shadow color
* @name setShadowColor
* @methodOf Kinetic.Shape.prototype
* @param {String} color
*/
/**
* set shadow blur
* @name setShadowBlur
* @methodOf Kinetic.Shape.prototype
* @param {Number} blur
*/
/**
* set shadow opacity
* @name setShadowOpacity
* @methodOf Kinetic.Shape.prototype
* @param {Number} opacity must be a value between 0 and 1
*/
/**
2013-01-03 13:35:51 +08:00
* set fill pattern image
* @name setFillPatternImage
* @methodOf Kinetic.Shape.prototype
2013-01-03 13:35:51 +08:00
* @param {Image} image object
*/
/**
* set fill color
* @name setFill
* @methodOf Kinetic.Shape.prototype
* @param {String} color
*/
/**
* set fill pattern x
* @name setFillPatternX
* @methodOf Kinetic.Shape.prototype
* @param {Number} x
*/
/**
* set fill pattern y
* @name setFillPatternY
* @methodOf Kinetic.Shape.prototype
* @param {Number} y
*/
/**
* set fill linear gradient color stops
* @name setFillLinearGradientColorStops
* @methodOf Kinetic.Shape.prototype
* @param {Array} colorStops
*/
/**
* set fill radial gradient start radius
* @name setFillRadialGradientStartRadius
* @methodOf Kinetic.Shape.prototype
* @param {Number} radius
*/
/**
* set fill radial gradient end radius
* @name setFillRadialGradientEndRadius
* @methodOf Kinetic.Shape.prototype
* @param {Number} radius
*/
/**
* set fill radial gradient color stops
* @name setFillRadialGradientColorStops
* @methodOf Kinetic.Shape.prototype
* @param {Number} colorStops
*/
/**
* set fill pattern repeat
* @name setFillPatternRepeat
* @methodOf Kinetic.Shape.prototype
* @param {Number} repeat can be 'repeat', 'repeat-x', 'repeat-y', or 'no-repeat'. The default is 'no-repeat'
*/
/**
* set fill priority
* @name setFillPriority
* @methodOf Kinetic.Shape.prototype
* @param {Number} priority can be color, pattern, linear-gradient, or radial-gradient
* The default is color.
*/
/**
* get stroke color
* @name getStroke
* @methodOf Kinetic.Shape.prototype
*/
/**
* get line join
* @name getLineJoin
* @methodOf Kinetic.Shape.prototype
*/
2013-01-03 13:35:51 +08:00
/**
* get line cap
* @name getLineCap
* @methodOf Kinetic.Shape.prototype
*/
/**
* get stroke width
* @name getStrokeWidth
* @methodOf Kinetic.Shape.prototype
*/
/**
* get draw function
* @name getDrawFunc
* @methodOf Kinetic.Shape.prototype
*/
/**
* get draw hit function
* @name getDrawHitFunc
* @methodOf Kinetic.Shape.prototype
*/
2013-01-03 13:35:51 +08:00
/**
* get dash array
* @name getDashArray
2013-01-07 01:04:10 +08:00
* @methodOf Kinetic.Shape.prototype
2013-01-03 13:35:51 +08:00
*/
/**
* get shadow color
* @name getShadowColor
* @methodOf Kinetic.Shape.prototype
*/
/**
* get shadow blur
* @name getShadowBlur
* @methodOf Kinetic.Shape.prototype
*/
/**
* get shadow opacity
* @name getShadowOpacity
* @methodOf Kinetic.Shape.prototype
*/
2013-01-03 13:35:51 +08:00
/**
* get fill pattern image
* @name getFillPatternImage
* @methodOf Kinetic.Shape.prototype
*/
/**
* get fill color
* @name getFill
* @methodOf Kinetic.Shape.prototype
*/
/**
* get fill pattern x
* @name getFillPatternX
* @methodOf Kinetic.Shape.prototype
*/
/**
* get fill pattern y
* @name getFillPatternY
* @methodOf Kinetic.Shape.prototype
*/
/**
* get fill linear gradient color stops
* @name getFillLinearGradientColorStops
* @methodOf Kinetic.Shape.prototype
* @param {Array} colorStops
*/
/**
* get fill radial gradient start radius
* @name getFillRadialGradientStartRadius
* @methodOf Kinetic.Shape.prototype
*/
/**
* get fill radial gradient end radius
* @name getFillRadialGradientEndRadius
* @methodOf Kinetic.Shape.prototype
*/
/**
* get fill radial gradient color stops
* @name getFillRadialGradientColorStops
* @methodOf Kinetic.Shape.prototype
*/
/**
* get fill pattern repeat
* @name getFillPatternRepeat
* @methodOf Kinetic.Shape.prototype
*/
/**
* get fill priority
* @name getFillPriority
* @methodOf Kinetic.Shape.prototype
*/
Kinetic.Node.addPointGetterSetter(Kinetic.Shape, 'fillPatternOffset');
Kinetic.Node.addPointGetterSetter(Kinetic.Shape, 'fillPatternScale');
Kinetic.Node.addPointGetterSetter(Kinetic.Shape, 'fillLinearGradientStartPoint');
Kinetic.Node.addPointGetterSetter(Kinetic.Shape, 'fillLinearGradientEndPoint');
Kinetic.Node.addPointGetterSetter(Kinetic.Shape, 'fillRadialGradientStartPoint');
Kinetic.Node.addPointGetterSetter(Kinetic.Shape, 'fillRadialGradientEndPoint');
Kinetic.Node.addPointGetterSetter(Kinetic.Shape, 'shadowOffset');
2013-01-03 13:35:51 +08:00
/**
* set fill pattern offset
* @name setFillPatternOffset
* @methodOf Kinetic.Shape.prototype
* @param {Number|Array|Object} offset
*/
/**
* set fill pattern scale
* @name setFillPatternScale
* @methodOf Kinetic.Shape.prototype
* @param {Number|Array|Object} scale
*/
/**
* set fill linear gradient start point
* @name setFillLinearGradientStartPoint
* @methodOf Kinetic.Shape.prototype
* @param {Number|Array|Object} startPoint
*/
/**
* set fill linear gradient end point
* @name setFillLinearGradientEndPoint
* @methodOf Kinetic.Shape.prototype
* @param {Number|Array|Object} endPoint
*/
/**
* set fill radial gradient start point
* @name setFillRadialGradientStartPoint
* @methodOf Kinetic.Shape.prototype
* @param {Number|Array|Object} startPoint
*/
/**
* set fill radial gradient end point
* @name setFillRadialGradientEndPoint
* @methodOf Kinetic.Shape.prototype
* @param {Number|Array|Object} endPoint
*/
/**
* set shadow offset
* @name setShadowOffset
* @methodOf Kinetic.Shape.prototype
* @param {Number|Array|Object} offset
*/
/**
* get fill pattern offset
* @name getFillPatternOffset
* @methodOf Kinetic.Shape.prototype
*/
/**
* get fill pattern scale
* @name getFillPatternScale
* @methodOf Kinetic.Shape.prototype
*/
/**
* get fill linear gradient start point
* @name getFillLinearGradientStartPoint
* @methodOf Kinetic.Shape.prototype
*/
/**
* get fill linear gradient end point
* @name getFillLinearGradientEndPoint
* @methodOf Kinetic.Shape.prototype
*/
/**
* get fill radial gradient start point
* @name getFillRadialGradientStartPoint
* @methodOf Kinetic.Shape.prototype
*/
/**
* get fill radial gradient end point
* @name getFillRadialGradientEndPoint
* @methodOf Kinetic.Shape.prototype
*/
/**
* get shadow offset
* @name getShadowOffset
* @methodOf Kinetic.Shape.prototype
*/
Kinetic.Node.addRotationGetterSetter(Kinetic.Shape, 'fillPatternRotation', 0);
2013-01-03 13:35:51 +08:00
/**
2013-01-03 13:35:51 +08:00
* set fill pattern rotation in radians
* @name setFillPatternRotation
* @methodOf Kinetic.Shape.prototype
2013-01-03 13:35:51 +08:00
* @param {Number} rotation
*/
/**
2013-01-03 13:35:51 +08:00
* set fill pattern rotation in degrees
* @name setFillPatternRotationDeg
* @methodOf Kinetic.Shape.prototype
2013-01-03 13:35:51 +08:00
* @param {Number} rotationDeg
*/
/**
2013-01-03 13:35:51 +08:00
* get fill pattern rotation in radians
* @name getFillPatternRotation
* @methodOf Kinetic.Shape.prototype
*/
2013-01-03 13:35:51 +08:00
/**
* get fill pattern rotation in degrees
* @name getFillPatternRotationDeg
* @methodOf Kinetic.Shape.prototype
*/
})();