'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); /** * * @param {boolean} [nativeLines=false] - If true the lines will be draw using LINES instead of TRIANGLE_STRIP */ function Graphics() { var nativeLines = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; _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; /** * If true the lines will be draw using LINES instead of TRIANGLE_STRIP * * @member {boolean} */ _this.nativeLines = nativeLines; /** * 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; // If the currentPath exists, take its points. Otherwise call `moveTo` to start a path. var points = this.currentPath ? this.currentPath.shape.points : null; if (points) { if (points[points.length - 2] !== startX || points[points.length - 1] !== startY) { points.push(startX, startY); } } else { this.moveTo(startX, startY); points = this.currentPath.shape.points; } 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.boundsDirty = -1; this.dirty++; this.clearDirty++; this.graphicsData.length = 0; } this.currentPath = null; this._spriteRect = null; 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) { this._spriteRect = new _Sprite2.default(new _Texture2.default(_Texture2.default.WHITE)); } var sprite = this._spriteRect; if (this.tint === 0xffffff) { sprite.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]; sprite.tint = (0, _utils.rgb2hex)(t1); } sprite.alpha = this.graphicsData[0].fillAlpha; sprite.worldAlpha = this.worldAlpha * sprite.alpha; sprite.blendMode = this.blendMode; sprite._texture._frame.width = rect.width; sprite._texture._frame.height = rect.height; sprite.transform.worldTransform = this.transform.worldTransform; sprite.anchor.set(-rect.x / rect.width, -rect.y / rect.height); sprite._onAnchorUpdate(); sprite._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.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, this.nativeLines, 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(); } this.transform.updateLocalTransform(); this.transform.localTransform.copy(tempMatrix); tempMatrix.invert(); tempMatrix.tx -= bounds.x; tempMatrix.ty -= bounds.y; canvasRenderer.render(this, canvasBuffer, true, tempMatrix); var texture = _Texture2.default.fromCanvas(canvasBuffer.baseTexture._canvasRenderTarget.canvas, scaleMode, 'graphics'); 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. * @param {boolean} [options.texture=false] - Only used for child Sprites if options.children is set to true * Should it destroy the texture of the child sprite * @param {boolean} [options.baseTexture=false] - Only used for child Sprites if options.children is set to true * Should it destroy the base texture of the child sprite */ 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