'use strict';
exports.__esModule = true;
var _Container2 = require('../display/Container');
var _Container3 = _interopRequireDefault(_Container2);
var _RenderTexture = require('../textures/RenderTexture');
var _RenderTexture2 = _interopRequireDefault(_RenderTexture);
var _Texture = require('../textures/Texture');
var _Texture2 = _interopRequireDefault(_Texture);
var _GraphicsData = require('./GraphicsData');
var _GraphicsData2 = _interopRequireDefault(_GraphicsData);
var _Sprite = require('../sprites/Sprite');
var _Sprite2 = _interopRequireDefault(_Sprite);
var _math = require('../math');
var _utils = require('../utils');
var _const = require('../const');
var _Bounds = require('../display/Bounds');
var _Bounds2 = _interopRequireDefault(_Bounds);
var _bezierCurveTo2 = require('./utils/bezierCurveTo');
var _bezierCurveTo3 = _interopRequireDefault(_bezierCurveTo2);
var _CanvasRenderer = require('../renderers/canvas/CanvasRenderer');
var _CanvasRenderer2 = _interopRequireDefault(_CanvasRenderer);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var canvasRenderer = void 0;
var tempMatrix = new _math.Matrix();
var tempPoint = new _math.Point();
var tempColor1 = new Float32Array(4);
var tempColor2 = new Float32Array(4);
/**
* The Graphics class contains methods used to draw primitive shapes such as lines, circles and
* rectangles to the display, and to color and fill them.
*
* @class
* @extends PIXI.Container
* @memberof PIXI
*/
var Graphics = function (_Container) {
_inherits(Graphics, _Container);
/**
*
*/
function Graphics() {
_classCallCheck(this, Graphics);
/**
* The alpha value used when filling the Graphics object.
*
* @member {number}
* @default 1
*/
var _this = _possibleConstructorReturn(this, _Container.call(this));
_this.fillAlpha = 1;
/**
* The width (thickness) of any lines drawn.
*
* @member {number}
* @default 0
*/
_this.lineWidth = 0;
/**
* The color of any lines drawn.
*
* @member {string}
* @default 0
*/
_this.lineColor = 0;
/**
* Graphics data
*
* @member {PIXI.GraphicsData[]}
* @private
*/
_this.graphicsData = [];
/**
* The tint applied to the graphic shape. This is a hex value. Apply a value of 0xFFFFFF to
* reset the tint.
*
* @member {number}
* @default 0xFFFFFF
*/
_this.tint = 0xFFFFFF;
/**
* The previous tint applied to the graphic shape. Used to compare to the current tint and
* check if theres change.
*
* @member {number}
* @private
* @default 0xFFFFFF
*/
_this._prevTint = 0xFFFFFF;
/**
* The blend mode to be applied to the graphic shape. Apply a value of
* `PIXI.BLEND_MODES.NORMAL` to reset the blend mode.
*
* @member {number}
* @default PIXI.BLEND_MODES.NORMAL;
* @see PIXI.BLEND_MODES
*/
_this.blendMode = _const.BLEND_MODES.NORMAL;
/**
* Current path
*
* @member {PIXI.GraphicsData}
* @private
*/
_this.currentPath = null;
/**
* Array containing some WebGL-related properties used by the WebGL renderer.
*
* @member {object<number, object>}
* @private
*/
// TODO - _webgl should use a prototype object, not a random undocumented object...
_this._webGL = {};
/**
* Whether this shape is being used as a mask.
*
* @member {boolean}
*/
_this.isMask = false;
/**
* The bounds' padding used for bounds calculation.
*
* @member {number}
*/
_this.boundsPadding = 0;
/**
* A cache of the local bounds to prevent recalculation.
*
* @member {PIXI.Rectangle}
* @private
*/
_this._localBounds = new _Bounds2.default();
/**
* Used to detect if the graphics object has changed. If this is set to true then the graphics
* object will be recalculated.
*
* @member {boolean}
* @private
*/
_this.dirty = 0;
/**
* Used to detect if we need to do a fast rect check using the id compare method
* @type {Number}
*/
_this.fastRectDirty = -1;
/**
* Used to detect if we clear the graphics webGL data
* @type {Number}
*/
_this.clearDirty = 0;
/**
* Used to detect if we we need to recalculate local bounds
* @type {Number}
*/
_this.boundsDirty = -1;
/**
* Used to detect if the cached sprite object needs to be updated.
*
* @member {boolean}
* @private
*/
_this.cachedSpriteDirty = false;
_this._spriteRect = null;
_this._fastRect = false;
/**
* When cacheAsBitmap is set to true the graphics object will be rendered as if it was a sprite.
* This is useful if your graphics element does not change often, as it will speed up the rendering
* of the object in exchange for taking up texture memory. It is also useful if you need the graphics
* object to be anti-aliased, because it will be rendered using canvas. This is not recommended if
* you are constantly redrawing the graphics element.
*
* @name cacheAsBitmap
* @member {boolean}
* @memberof PIXI.Graphics#
* @default false
*/
return _this;
}
/**
* Creates a new Graphics object with the same values as this one.
* Note that the only the properties of the object are cloned, not its transform (position,scale,etc)
*
* @return {PIXI.Graphics} A clone of the graphics object
*/
Graphics.prototype.clone = function clone() {
var clone = new Graphics();
clone.renderable = this.renderable;
clone.fillAlpha = this.fillAlpha;
clone.lineWidth = this.lineWidth;
clone.lineColor = this.lineColor;
clone.tint = this.tint;
clone.blendMode = this.blendMode;
clone.isMask = this.isMask;
clone.boundsPadding = this.boundsPadding;
clone.dirty = 0;
clone.cachedSpriteDirty = this.cachedSpriteDirty;
// copy graphics data
for (var i = 0; i < this.graphicsData.length; ++i) {
clone.graphicsData.push(this.graphicsData[i].clone());
}
clone.currentPath = clone.graphicsData[clone.graphicsData.length - 1];
clone.updateLocalBounds();
return clone;
};
/**
* Specifies the line style used for subsequent calls to Graphics methods such as the lineTo()
* method or the drawCircle() method.
*
* @param {number} [lineWidth=0] - width of the line to draw, will update the objects stored style
* @param {number} [color=0] - color of the line to draw, will update the objects stored style
* @param {number} [alpha=1] - alpha of the line to draw, will update the objects stored style
* @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
*/
Graphics.prototype.lineStyle = function lineStyle() {
var lineWidth = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
var color = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
var alpha = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
this.lineWidth = lineWidth;
this.lineColor = color;
this.lineAlpha = alpha;
if (this.currentPath) {
if (this.currentPath.shape.points.length) {
// halfway through a line? start a new one!
var shape = new _math.Polygon(this.currentPath.shape.points.slice(-2));
shape.closed = false;
this.drawShape(shape);
} else {
// otherwise its empty so lets just set the line properties
this.currentPath.lineWidth = this.lineWidth;
this.currentPath.lineColor = this.lineColor;
this.currentPath.lineAlpha = this.lineAlpha;
}
}
return this;
};
/**
* Moves the current drawing position to x, y.
*
* @param {number} x - the X coordinate to move to
* @param {number} y - the Y coordinate to move to
* @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
*/
Graphics.prototype.moveTo = function moveTo(x, y) {
var shape = new _math.Polygon([x, y]);
shape.closed = false;
this.drawShape(shape);
return this;
};
/**
* Draws a line using the current line style from the current drawing position to (x, y);
* The current drawing position is then set to (x, y).
*
* @param {number} x - the X coordinate to draw to
* @param {number} y - the Y coordinate to draw to
* @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
*/
Graphics.prototype.lineTo = function lineTo(x, y) {
this.currentPath.shape.points.push(x, y);
this.dirty++;
return this;
};
/**
* Calculate the points for a quadratic bezier curve and then draws it.
* Based on: https://stackoverflow.com/questions/785097/how-do-i-implement-a-bezier-curve-in-c
*
* @param {number} cpX - Control point x
* @param {number} cpY - Control point y
* @param {number} toX - Destination point x
* @param {number} toY - Destination point y
* @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
*/
Graphics.prototype.quadraticCurveTo = function quadraticCurveTo(cpX, cpY, toX, toY) {
if (this.currentPath) {
if (this.currentPath.shape.points.length === 0) {
this.currentPath.shape.points = [0, 0];
}
} else {
this.moveTo(0, 0);
}
var n = 20;
var points = this.currentPath.shape.points;
var xa = 0;
var ya = 0;
if (points.length === 0) {
this.moveTo(0, 0);
}
var fromX = points[points.length - 2];
var fromY = points[points.length - 1];
for (var i = 1; i <= n; ++i) {
var j = i / n;
xa = fromX + (cpX - fromX) * j;
ya = fromY + (cpY - fromY) * j;
points.push(xa + (cpX + (toX - cpX) * j - xa) * j, ya + (cpY + (toY - cpY) * j - ya) * j);
}
this.dirty++;
return this;
};
/**
* Calculate the points for a bezier curve and then draws it.
*
* @param {number} cpX - Control point x
* @param {number} cpY - Control point y
* @param {number} cpX2 - Second Control point x
* @param {number} cpY2 - Second Control point y
* @param {number} toX - Destination point x
* @param {number} toY - Destination point y
* @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
*/
Graphics.prototype.bezierCurveTo = function bezierCurveTo(cpX, cpY, cpX2, cpY2, toX, toY) {
if (this.currentPath) {
if (this.currentPath.shape.points.length === 0) {
this.currentPath.shape.points = [0, 0];
}
} else {
this.moveTo(0, 0);
}
var points = this.currentPath.shape.points;
var fromX = points[points.length - 2];
var fromY = points[points.length - 1];
points.length -= 2;
(0, _bezierCurveTo3.default)(fromX, fromY, cpX, cpY, cpX2, cpY2, toX, toY, points);
this.dirty++;
return this;
};
/**
* The arcTo() method creates an arc/curve between two tangents on the canvas.
*
* "borrowed" from https://code.google.com/p/fxcanvas/ - thanks google!
*
* @param {number} x1 - The x-coordinate of the beginning of the arc
* @param {number} y1 - The y-coordinate of the beginning of the arc
* @param {number} x2 - The x-coordinate of the end of the arc
* @param {number} y2 - The y-coordinate of the end of the arc
* @param {number} radius - The radius of the arc
* @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
*/
Graphics.prototype.arcTo = function arcTo(x1, y1, x2, y2, radius) {
if (this.currentPath) {
if (this.currentPath.shape.points.length === 0) {
this.currentPath.shape.points.push(x1, y1);
}
} else {
this.moveTo(x1, y1);
}
var points = this.currentPath.shape.points;
var fromX = points[points.length - 2];
var fromY = points[points.length - 1];
var a1 = fromY - y1;
var b1 = fromX - x1;
var a2 = y2 - y1;
var b2 = x2 - x1;
var mm = Math.abs(a1 * b2 - b1 * a2);
if (mm < 1.0e-8 || radius === 0) {
if (points[points.length - 2] !== x1 || points[points.length - 1] !== y1) {
points.push(x1, y1);
}
} else {
var dd = a1 * a1 + b1 * b1;
var cc = a2 * a2 + b2 * b2;
var tt = a1 * a2 + b1 * b2;
var k1 = radius * Math.sqrt(dd) / mm;
var k2 = radius * Math.sqrt(cc) / mm;
var j1 = k1 * tt / dd;
var j2 = k2 * tt / cc;
var cx = k1 * b2 + k2 * b1;
var cy = k1 * a2 + k2 * a1;
var px = b1 * (k2 + j1);
var py = a1 * (k2 + j1);
var qx = b2 * (k1 + j2);
var qy = a2 * (k1 + j2);
var startAngle = Math.atan2(py - cy, px - cx);
var endAngle = Math.atan2(qy - cy, qx - cx);
this.arc(cx + x1, cy + y1, radius, startAngle, endAngle, b1 * a2 > b2 * a1);
}
this.dirty++;
return this;
};
/**
* The arc method creates an arc/curve (used to create circles, or parts of circles).
*
* @param {number} cx - The x-coordinate of the center of the circle
* @param {number} cy - The y-coordinate of the center of the circle
* @param {number} radius - The radius of the circle
* @param {number} startAngle - The starting angle, in radians (0 is at the 3 o'clock position
* of the arc's circle)
* @param {number} endAngle - The ending angle, in radians
* @param {boolean} [anticlockwise=false] - Specifies whether the drawing should be
* counter-clockwise or clockwise. False is default, and indicates clockwise, while true
* indicates counter-clockwise.
* @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
*/
Graphics.prototype.arc = function arc(cx, cy, radius, startAngle, endAngle) {
var anticlockwise = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
if (startAngle === endAngle) {
return this;
}
if (!anticlockwise && endAngle <= startAngle) {
endAngle += Math.PI * 2;
} else if (anticlockwise && startAngle <= endAngle) {
startAngle += Math.PI * 2;
}
var sweep = endAngle - startAngle;
var segs = Math.ceil(Math.abs(sweep) / (Math.PI * 2)) * 40;
if (sweep === 0) {
return this;
}
var startX = cx + Math.cos(startAngle) * radius;
var startY = cy + Math.sin(startAngle) * radius;
var points = this.currentPath.shape.points;
if (this.currentPath) {
if (points[points.length - 2] !== startX || points[points.length - 1] !== startY) {
points.push(startX, startY);
}
} else {
this.moveTo(startX, startY);
}
var theta = sweep / (segs * 2);
var theta2 = theta * 2;
var cTheta = Math.cos(theta);
var sTheta = Math.sin(theta);
var segMinus = segs - 1;
var remainder = segMinus % 1 / segMinus;
for (var i = 0; i <= segMinus; ++i) {
var real = i + remainder * i;
var angle = theta + startAngle + theta2 * real;
var c = Math.cos(angle);
var s = -Math.sin(angle);
points.push((cTheta * c + sTheta * s) * radius + cx, (cTheta * -s + sTheta * c) * radius + cy);
}
this.dirty++;
return this;
};
/**
* Specifies a simple one-color fill that subsequent calls to other Graphics methods
* (such as lineTo() or drawCircle()) use when drawing.
*
* @param {number} [color=0] - the color of the fill
* @param {number} [alpha=1] - the alpha of the fill
* @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
*/
Graphics.prototype.beginFill = function beginFill() {
var color = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
var alpha = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
this.filling = true;
this.fillColor = color;
this.fillAlpha = alpha;
if (this.currentPath) {
if (this.currentPath.shape.points.length <= 2) {
this.currentPath.fill = this.filling;
this.currentPath.fillColor = this.fillColor;
this.currentPath.fillAlpha = this.fillAlpha;
}
}
return this;
};
/**
* Applies a fill to the lines and shapes that were added since the last call to the beginFill() method.
*
* @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
*/
Graphics.prototype.endFill = function endFill() {
this.filling = false;
this.fillColor = null;
this.fillAlpha = 1;
return this;
};
/**
*
* @param {number} x - The X coord of the top-left of the rectangle
* @param {number} y - The Y coord of the top-left of the rectangle
* @param {number} width - The width of the rectangle
* @param {number} height - The height of the rectangle
* @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
*/
Graphics.prototype.drawRect = function drawRect(x, y, width, height) {
this.drawShape(new _math.Rectangle(x, y, width, height));
return this;
};
/**
*
* @param {number} x - The X coord of the top-left of the rectangle
* @param {number} y - The Y coord of the top-left of the rectangle
* @param {number} width - The width of the rectangle
* @param {number} height - The height of the rectangle
* @param {number} radius - Radius of the rectangle corners
* @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
*/
Graphics.prototype.drawRoundedRect = function drawRoundedRect(x, y, width, height, radius) {
this.drawShape(new _math.RoundedRectangle(x, y, width, height, radius));
return this;
};
/**
* Draws a circle.
*
* @param {number} x - The X coordinate of the center of the circle
* @param {number} y - The Y coordinate of the center of the circle
* @param {number} radius - The radius of the circle
* @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
*/
Graphics.prototype.drawCircle = function drawCircle(x, y, radius) {
this.drawShape(new _math.Circle(x, y, radius));
return this;
};
/**
* Draws an ellipse.
*
* @param {number} x - The X coordinate of the center of the ellipse
* @param {number} y - The Y coordinate of the center of the ellipse
* @param {number} width - The half width of the ellipse
* @param {number} height - The half height of the ellipse
* @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
*/
Graphics.prototype.drawEllipse = function drawEllipse(x, y, width, height) {
this.drawShape(new _math.Ellipse(x, y, width, height));
return this;
};
/**
* Draws a polygon using the given path.
*
* @param {number[]|PIXI.Point[]} path - The path data used to construct the polygon.
* @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
*/
Graphics.prototype.drawPolygon = function drawPolygon(path) {
// prevents an argument assignment deopt
// see section 3.1: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments
var points = path;
var closed = true;
if (points instanceof _math.Polygon) {
closed = points.closed;
points = points.points;
}
if (!Array.isArray(points)) {
// prevents an argument leak deopt
// see section 3.2: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments
points = new Array(arguments.length);
for (var i = 0; i < points.length; ++i) {
points[i] = arguments[i]; // eslint-disable-line prefer-rest-params
}
}
var shape = new _math.Polygon(points);
shape.closed = closed;
this.drawShape(shape);
return this;
};
/**
* Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings.
*
* @return {PIXI.Graphics} This Graphics object. Good for chaining method calls
*/
Graphics.prototype.clear = function clear() {
if (this.lineWidth || this.filling || this.graphicsData.length > 0) {
this.lineWidth = 0;
this.filling = false;
this.dirty++;
this.clearDirty++;
this.graphicsData.length = 0;
}
return this;
};
/**
* True if graphics consists of one rectangle, and thus, can be drawn like a Sprite and
* masked with gl.scissor.
*
* @returns {boolean} True if only 1 rect.
*/
Graphics.prototype.isFastRect = function isFastRect() {
return this.graphicsData.length === 1 && this.graphicsData[0].shape.type === _const.SHAPES.RECT && !this.graphicsData[0].lineWidth;
};
/**
* Renders the object using the WebGL renderer
*
* @private
* @param {PIXI.WebGLRenderer} renderer - The renderer
*/
Graphics.prototype._renderWebGL = function _renderWebGL(renderer) {
// if the sprite is not visible or the alpha is 0 then no need to render this element
if (this.dirty !== this.fastRectDirty) {
this.fastRectDirty = this.dirty;
this._fastRect = this.isFastRect();
}
// TODO this check can be moved to dirty?
if (this._fastRect) {
this._renderSpriteRect(renderer);
} else {
renderer.setObjectRenderer(renderer.plugins.graphics);
renderer.plugins.graphics.render(this);
}
};
/**
* Renders a sprite rectangle.
*
* @private
* @param {PIXI.WebGLRenderer} renderer - The renderer
*/
Graphics.prototype._renderSpriteRect = function _renderSpriteRect(renderer) {
var rect = this.graphicsData[0].shape;
if (!this._spriteRect) {
if (!Graphics._SPRITE_TEXTURE) {
Graphics._SPRITE_TEXTURE = _RenderTexture2.default.create(10, 10);
var canvas = document.createElement('canvas');
canvas.width = 10;
canvas.height = 10;
var context = canvas.getContext('2d');
context.fillStyle = 'white';
context.fillRect(0, 0, 10, 10);
Graphics._SPRITE_TEXTURE = _Texture2.default.fromCanvas(canvas);
}
this._spriteRect = new _Sprite2.default(Graphics._SPRITE_TEXTURE);
}
if (this.tint === 0xffffff) {
this._spriteRect.tint = this.graphicsData[0].fillColor;
} else {
var t1 = tempColor1;
var t2 = tempColor2;
(0, _utils.hex2rgb)(this.graphicsData[0].fillColor, t1);
(0, _utils.hex2rgb)(this.tint, t2);
t1[0] *= t2[0];
t1[1] *= t2[1];
t1[2] *= t2[2];
this._spriteRect.tint = (0, _utils.rgb2hex)(t1);
}
this._spriteRect.alpha = this.graphicsData[0].fillAlpha;
this._spriteRect.worldAlpha = this.worldAlpha * this._spriteRect.alpha;
Graphics._SPRITE_TEXTURE._frame.width = rect.width;
Graphics._SPRITE_TEXTURE._frame.height = rect.height;
this._spriteRect.transform.worldTransform = this.transform.worldTransform;
this._spriteRect.anchor.set(-rect.x / rect.width, -rect.y / rect.height);
this._spriteRect._onAnchorUpdate();
this._spriteRect._renderWebGL(renderer);
};
/**
* Renders the object using the Canvas renderer
*
* @private
* @param {PIXI.CanvasRenderer} renderer - The renderer
*/
Graphics.prototype._renderCanvas = function _renderCanvas(renderer) {
if (this.isMask === true) {
return;
}
renderer.plugins.graphics.render(this);
};
/**
* Retrieves the bounds of the graphic shape as a rectangle object
*
* @private
*/
Graphics.prototype._calculateBounds = function _calculateBounds() {
if (this.boundsDirty !== this.dirty) {
this.boundsDirty = this.dirty;
this.updateLocalBounds();
this.dirty++;
this.cachedSpriteDirty = true;
}
var lb = this._localBounds;
this._bounds.addFrame(this.transform, lb.minX, lb.minY, lb.maxX, lb.maxY);
};
/**
* Tests if a point is inside this graphics object
*
* @param {PIXI.Point} point - the point to test
* @return {boolean} the result of the test
*/
Graphics.prototype.containsPoint = function containsPoint(point) {
this.worldTransform.applyInverse(point, tempPoint);
var graphicsData = this.graphicsData;
for (var i = 0; i < graphicsData.length; ++i) {
var data = graphicsData[i];
if (!data.fill) {
continue;
}
// only deal with fills..
if (data.shape) {
if (data.shape.contains(tempPoint.x, tempPoint.y)) {
return true;
}
}
}
return false;
};
/**
* Update the bounds of the object
*
*/
Graphics.prototype.updateLocalBounds = function updateLocalBounds() {
var minX = Infinity;
var maxX = -Infinity;
var minY = Infinity;
var maxY = -Infinity;
if (this.graphicsData.length) {
var shape = 0;
var x = 0;
var y = 0;
var w = 0;
var h = 0;
for (var i = 0; i < this.graphicsData.length; i++) {
var data = this.graphicsData[i];
var type = data.type;
var lineWidth = data.lineWidth;
shape = data.shape;
if (type === _const.SHAPES.RECT || type === _const.SHAPES.RREC) {
x = shape.x - lineWidth / 2;
y = shape.y - lineWidth / 2;
w = shape.width + lineWidth;
h = shape.height + lineWidth;
minX = x < minX ? x : minX;
maxX = x + w > maxX ? x + w : maxX;
minY = y < minY ? y : minY;
maxY = y + h > maxY ? y + h : maxY;
} else if (type === _const.SHAPES.CIRC) {
x = shape.x;
y = shape.y;
w = shape.radius + lineWidth / 2;
h = shape.radius + lineWidth / 2;
minX = x - w < minX ? x - w : minX;
maxX = x + w > maxX ? x + w : maxX;
minY = y - h < minY ? y - h : minY;
maxY = y + h > maxY ? y + h : maxY;
} else if (type === _const.SHAPES.ELIP) {
x = shape.x;
y = shape.y;
w = shape.width + lineWidth / 2;
h = shape.height + lineWidth / 2;
minX = x - w < minX ? x - w : minX;
maxX = x + w > maxX ? x + w : maxX;
minY = y - h < minY ? y - h : minY;
maxY = y + h > maxY ? y + h : maxY;
} else {
// POLY
var points = shape.points;
var x2 = 0;
var y2 = 0;
var dx = 0;
var dy = 0;
var rw = 0;
var rh = 0;
var cx = 0;
var cy = 0;
for (var j = 0; j + 2 < points.length; j += 2) {
x = points[j];
y = points[j + 1];
x2 = points[j + 2];
y2 = points[j + 3];
dx = Math.abs(x2 - x);
dy = Math.abs(y2 - y);
h = lineWidth;
w = Math.sqrt(dx * dx + dy * dy);
if (w < 1e-9) {
continue;
}
rw = (h / w * dy + dx) / 2;
rh = (h / w * dx + dy) / 2;
cx = (x2 + x) / 2;
cy = (y2 + y) / 2;
minX = cx - rw < minX ? cx - rw : minX;
maxX = cx + rw > maxX ? cx + rw : maxX;
minY = cy - rh < minY ? cy - rh : minY;
maxY = cy + rh > maxY ? cy + rh : maxY;
}
}
}
} else {
minX = 0;
maxX = 0;
minY = 0;
maxY = 0;
}
var padding = this.boundsPadding;
this._localBounds.minX = minX - padding;
this._localBounds.maxX = maxX + padding * 2;
this._localBounds.minY = minY - padding;
this._localBounds.maxY = maxY + padding * 2;
};
/**
* Draws the given shape to this Graphics object. Can be any of Circle, Rectangle, Ellipse, Line or Polygon.
*
* @param {PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.Rectangle|PIXI.RoundedRectangle} shape - The shape object to draw.
* @return {PIXI.GraphicsData} The generated GraphicsData object.
*/
Graphics.prototype.drawShape = function drawShape(shape) {
if (this.currentPath) {
// check current path!
if (this.currentPath.shape.points.length <= 2) {
this.graphicsData.pop();
}
}
this.currentPath = null;
var data = new _GraphicsData2.default(this.lineWidth, this.lineColor, this.lineAlpha, this.fillColor, this.fillAlpha, this.filling, shape);
this.graphicsData.push(data);
if (data.type === _const.SHAPES.POLY) {
data.shape.closed = data.shape.closed || this.filling;
this.currentPath = data;
}
this.dirty++;
return data;
};
/**
* Generates a canvas texture.
*
* @param {number} scaleMode - The scale mode of the texture.
* @param {number} resolution - The resolution of the texture.
* @return {PIXI.Texture} The new texture.
*/
Graphics.prototype.generateCanvasTexture = function generateCanvasTexture(scaleMode) {
var resolution = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
var bounds = this.getLocalBounds();
var canvasBuffer = _RenderTexture2.default.create(bounds.width, bounds.height, scaleMode, resolution);
if (!canvasRenderer) {
canvasRenderer = new _CanvasRenderer2.default();
}
tempMatrix.tx = -bounds.x;
tempMatrix.ty = -bounds.y;
canvasRenderer.render(this, canvasBuffer, false, tempMatrix);
var texture = _Texture2.default.fromCanvas(canvasBuffer.baseTexture._canvasRenderTarget.canvas, scaleMode);
texture.baseTexture.resolution = resolution;
texture.baseTexture.update();
return texture;
};
/**
* Closes the current path.
*
* @return {PIXI.Graphics} Returns itself.
*/
Graphics.prototype.closePath = function closePath() {
// ok so close path assumes next one is a hole!
var currentPath = this.currentPath;
if (currentPath && currentPath.shape) {
currentPath.shape.close();
}
return this;
};
/**
* Adds a hole in the current path.
*
* @return {PIXI.Graphics} Returns itself.
*/
Graphics.prototype.addHole = function addHole() {
// this is a hole!
var hole = this.graphicsData.pop();
this.currentPath = this.graphicsData[this.graphicsData.length - 1];
this.currentPath.addHole(hole.shape);
this.currentPath = null;
return this;
};
/**
* Destroys the Graphics object.
*
* @param {object|boolean} [options] - Options parameter. A boolean will act as if all
* options have been set to that value
* @param {boolean} [options.children=false] - if set to true, all the children will have
* their destroy method called as well. 'options' will be passed on to those calls.
*/
Graphics.prototype.destroy = function destroy(options) {
_Container.prototype.destroy.call(this, options);
// destroy each of the GraphicsData objects
for (var i = 0; i < this.graphicsData.length; ++i) {
this.graphicsData[i].destroy();
}
// for each webgl data entry, destroy the WebGLGraphicsData
for (var id in this._webgl) {
for (var j = 0; j < this._webgl[id].data.length; ++j) {
this._webgl[id].data[j].destroy();
}
}
if (this._spriteRect) {
this._spriteRect.destroy();
}
this.graphicsData = null;
this.currentPath = null;
this._webgl = null;
this._localBounds = null;
};
return Graphics;
}(_Container3.default);
exports.default = Graphics;
Graphics._SPRITE_TEXTURE = null;
//# sourceMappingURL=Graphics.js.map