UNPKG

phaser3-rex-plugins

Version:
902 lines (878 loc) 27.2 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.rexroundrectangle = factory()); })(this, (function () { 'use strict'; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); } var GetValue$1 = Phaser.Utils.Objects.GetValue; var RoundRectangle$1 = /*#__PURE__*/function () { function RoundRectangle(x, y, width, height, radiusConfig) { _classCallCheck(this, RoundRectangle); if (x === undefined) { x = 0; } if (y === undefined) { y = x; } if (width === undefined) { width = 0; } if (height === undefined) { height = 0; } if (radiusConfig === undefined) { radiusConfig = 0; } this.cornerRadius = {}; this._width = 0; this._height = 0; this.setTo(x, y, width, height, radiusConfig); } _createClass(RoundRectangle, [{ key: "setTo", value: function setTo(x, y, width, height, radiusConfig) { this.setPosition(x, y); this.setRadius(radiusConfig); this.setSize(width, height); return this; } }, { key: "setPosition", value: function setPosition(x, y) { this.x = x; this.y = y; return this; } }, { key: "setRadius", value: function setRadius(value) { if (value === undefined) { value = 0; } this.radius = value; return this; } }, { key: "setSize", value: function setSize(width, height) { this.width = width; this.height = height; return this; } }, { key: "minWidth", get: function get() { var radius = this.cornerRadius; return Math.max(radius.tl.x + radius.tr.x, radius.bl.x + radius.br.x); } }, { key: "minHeight", get: function get() { var radius = this.cornerRadius; return Math.max(radius.tl.y + radius.bl.y, radius.tr.y + radius.br.y); } }, { key: "width", get: function get() { return this._width; }, set: function set(value) { if (value == null) { value = 0; } this._width = Math.max(value, this.minWidth); } }, { key: "height", get: function get() { return this._height; }, set: function set(value) { if (value == null) { value = 0; } this._height = Math.max(value, this.minHeight); } }, { key: "radius", get: function get() { var radius = this.cornerRadius; return Math.max(radius.tl.x, radius.tl.y, radius.tr.x, radius.tr.y, radius.bl.x, radius.bl.y, radius.br.x, radius.br.y); }, set: function set(value) { var defaultRadiusX, defaultRadiusY; if (typeof value === 'number') { defaultRadiusX = value; defaultRadiusY = value; } else { defaultRadiusX = GetValue$1(value, 'x', 0); defaultRadiusY = GetValue$1(value, 'y', 0); } var radius = this.cornerRadius; radius.tl = GetRadius(GetValue$1(value, 'tl', undefined), defaultRadiusX, defaultRadiusY); radius.tr = GetRadius(GetValue$1(value, 'tr', undefined), defaultRadiusX, defaultRadiusY); radius.bl = GetRadius(GetValue$1(value, 'bl', undefined), defaultRadiusX, defaultRadiusY); radius.br = GetRadius(GetValue$1(value, 'br', undefined), defaultRadiusX, defaultRadiusY); } }, { key: "radiusTL", get: function get() { var radius = this.cornerRadius.tl; return Math.max(radius.x, radius.y); }, set: function set(value) { SetRadius(this.cornerRadius.tl, value); } }, { key: "radiusTR", get: function get() { var radius = this.cornerRadius.tr; return Math.max(radius.x, radius.y); }, set: function set(value) { SetRadius(this.cornerRadius.tr, value); } }, { key: "radiusBL", get: function get() { var radius = this.cornerRadius.bl; return Math.max(radius.x, radius.y); }, set: function set(value) { SetRadius(this.cornerRadius.bl, value); } }, { key: "radiusBR", get: function get() { var radius = this.cornerRadius.br; return Math.max(radius.x, radius.y); }, set: function set(value) { SetRadius(this.cornerRadius.br, value); } }]); return RoundRectangle; }(); var GetRadius = function GetRadius(radius, defaultRadiusX, defaultRadiusY) { if (radius === undefined) { radius = { x: defaultRadiusX, y: defaultRadiusY }; } else if (typeof radius === 'number') { radius = { x: radius, y: radius }; } SetConvex(radius); return radius; }; var SetRadius = function SetRadius(radius, value) { if (typeof value === 'number') { radius.x = value; radius.y = value; } else { radius.x = GetValue$1(value, 'x', 0); radius.y = GetValue$1(value, 'y', 0); } SetConvex(radius); }; var SetConvex = function SetConvex(radius) { radius.convex = radius.x >= 0 || radius.y >= 0; radius.x = Math.abs(radius.x); radius.y = Math.abs(radius.y); }; var LineTo = function LineTo(x, y, pathData) { var cnt = pathData.length; if (cnt >= 2) { var lastX = pathData[cnt - 2]; var lastY = pathData[cnt - 1]; if (x === lastX && y === lastY) { return pathData; } } pathData.push(x, y); return pathData; }; var DegToRad = Phaser.Math.DegToRad; var ArcTo = function ArcTo(centerX, centerY, radiusX, radiusY, startAngle, endAngle, antiClockWise, iteration, pathData) { // startAngle, endAngle: 0 ~ 360 if (antiClockWise && endAngle > startAngle) { endAngle -= 360; } else if (!antiClockWise && endAngle < startAngle) { endAngle += 360; } var deltaAngle = endAngle - startAngle; var step = DegToRad(deltaAngle) / iteration; startAngle = DegToRad(startAngle); for (var i = 0; i <= iteration; i++) { var angle = startAngle + step * i; var x = centerX + radiusX * Math.cos(angle); var y = centerY + radiusY * Math.sin(angle); LineTo(x, y, pathData); } return pathData; }; /* src: { fillColor, fillAlpha, pathData, pathIndexes // Earcut(pathData) } */ var Utils$1 = Phaser.Renderer.WebGL.Utils; var FillPathWebGL = function FillPathWebGL(pipeline, calcMatrix, src, alpha, dx, dy) { var fillTintColor = Utils$1.getTintAppendFloatAlpha(src.fillColor, src.fillAlpha * alpha); var path = src.pathData; var pathIndexes = src.pathIndexes; for (var i = 0; i < pathIndexes.length; i += 3) { var p0 = pathIndexes[i] * 2; var p1 = pathIndexes[i + 1] * 2; var p2 = pathIndexes[i + 2] * 2; var x0 = path[p0 + 0] - dx; var y0 = path[p0 + 1] - dy; var x1 = path[p1 + 0] - dx; var y1 = path[p1 + 1] - dy; var x2 = path[p2 + 0] - dx; var y2 = path[p2 + 1] - dy; var tx0 = calcMatrix.getX(x0, y0); var ty0 = calcMatrix.getY(x0, y0); var tx1 = calcMatrix.getX(x1, y1); var ty1 = calcMatrix.getY(x1, y1); var tx2 = calcMatrix.getX(x2, y2); var ty2 = calcMatrix.getY(x2, y2); pipeline.batchTri(src, tx0, ty0, tx1, ty1, tx2, ty2, 0, 0, 1, 1, fillTintColor, fillTintColor, fillTintColor, 2); } }; /* src: { strokeColor, strokeAlpha, pathData, lineWidth, closePath } */ var Utils = Phaser.Renderer.WebGL.Utils; var StrokePathWebGL = function StrokePathWebGL(pipeline, src, alpha, dx, dy) { var strokeTint = pipeline.strokeTint; var strokeTintColor = Utils.getTintAppendFloatAlpha(src.strokeColor, src.strokeAlpha * alpha); strokeTint.TL = strokeTintColor; strokeTint.TR = strokeTintColor; strokeTint.BL = strokeTintColor; strokeTint.BR = strokeTintColor; var path = src.pathData; var pathLength = path.length - 1; var lineWidth = src.lineWidth; var halfLineWidth = lineWidth / 2; var px1 = path[0] - dx; var py1 = path[1] - dy; if (!src.closePath) { pathLength -= 2; } for (var i = 2; i < pathLength; i += 2) { var px2 = path[i] - dx; var py2 = path[i + 1] - dy; pipeline.batchLine(px1, py1, px2, py2, halfLineWidth, halfLineWidth, lineWidth, i - 2, src.closePath ? i === pathLength - 1 : false); px1 = px2; py1 = py2; } }; var GetCalcMatrix = Phaser.GameObjects.GetCalcMatrix; var PolygonWebGLRenderer = function PolygonWebGLRenderer(renderer, src, camera, parentMatrix) { if (src.dirty) { src.updateData(); src.dirty = false; } camera.addToRenderList(src); var pipeline = renderer.pipelines.set(src.pipeline); var result = GetCalcMatrix(src, camera, parentMatrix); var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc); var dx = src._displayOriginX; var dy = src._displayOriginY; var alpha = camera.alpha * src.alpha; renderer.pipelines.preBatch(src); if (src.isFilled) { FillPathWebGL(pipeline, calcMatrix, src, alpha, dx, dy); } if (src.isStroked) { StrokePathWebGL(pipeline, src, alpha, dx, dy); } renderer.pipelines.postBatch(src); }; var FillStyleCanvas = function FillStyleCanvas(ctx, src, altColor, altAlpha) { var fillColor = altColor ? altColor : src.fillColor; var fillAlpha = altAlpha ? altAlpha : src.fillAlpha; var red = (fillColor & 0xFF0000) >>> 16; var green = (fillColor & 0xFF00) >>> 8; var blue = fillColor & 0xFF; ctx.fillStyle = 'rgba(' + red + ',' + green + ',' + blue + ',' + fillAlpha + ')'; }; var LineStyleCanvas = function LineStyleCanvas(ctx, src, altColor, altAlpha) { var strokeColor = altColor ? altColor : src.strokeColor; var strokeAlpha = altAlpha ? altAlpha : src.strokeAlpha; var red = (strokeColor & 0xFF0000) >>> 16; var green = (strokeColor & 0xFF00) >>> 8; var blue = strokeColor & 0xFF; ctx.strokeStyle = 'rgba(' + red + ',' + green + ',' + blue + ',' + strokeAlpha + ')'; ctx.lineWidth = src.lineWidth; }; var SetTransform = Phaser.Renderer.Canvas.SetTransform; var PolygonCanvasRenderer = function PolygonCanvasRenderer(renderer, src, camera, parentMatrix) { if (src.dirty) { src.updateData(); src.dirty = false; } camera.addToRenderList(src); var ctx = renderer.currentContext; if (SetTransform(renderer, ctx, src, camera, parentMatrix)) { var dx = src._displayOriginX; var dy = src._displayOriginY; var path = src.pathData; var pathLength = path.length - 1; var px1 = path[0] - dx; var py1 = path[1] - dy; ctx.beginPath(); ctx.moveTo(px1, py1); if (!src.closePath) { pathLength -= 2; } for (var i = 2; i < pathLength; i += 2) { var px2 = path[i] - dx; var py2 = path[i + 1] - dy; ctx.lineTo(px2, py2); } ctx.closePath(); if (src.isFilled) { FillStyleCanvas(ctx, src); ctx.fill(); } if (src.isStroked) { LineStyleCanvas(ctx, src); ctx.stroke(); } // Restore the context saved in SetTransform ctx.restore(); } }; var Render = { renderWebGL: PolygonWebGLRenderer, renderCanvas: PolygonCanvasRenderer }; var Shape = Phaser.GameObjects.Shape; var IsPlainObject = Phaser.Utils.Objects.IsPlainObject; var GetValue = Phaser.Utils.Objects.GetValue; var Earcut = Phaser.Geom.Polygon.Earcut; var RoundRectangle = /*#__PURE__*/function (_Shape) { _inherits(RoundRectangle, _Shape); var _super = _createSuper(RoundRectangle); function RoundRectangle(scene, x, y, width, height, radiusConfig, fillColor, fillAlpha) { var _this; _classCallCheck(this, RoundRectangle); var strokeColor, strokeAlpha, strokeWidth, shapeType; if (IsPlainObject(x)) { var config = x; x = config.x; y = config.y; width = config.width; height = config.height; radiusConfig = config.radius; fillColor = config.color; fillAlpha = config.alpha; strokeColor = config.strokeColor; strokeAlpha = config.strokeAlpha; strokeWidth = config.strokeWidth; shapeType = config.shape; } if (x === undefined) { x = 0; } if (y === undefined) { y = 0; } if (width === undefined) { width = 1; } if (height === undefined) { height = width; } if (radiusConfig === undefined) { radiusConfig = 0; } if (shapeType === undefined) { shapeType = 0; } var geom = new RoundRectangle$1(); // Configurate it later _this = _super.call(this, scene, 'rexRoundRectangleShape', geom); _this.setShapeType(shapeType); if (_this.shapeType === 0) { var radius = GetValue(radiusConfig, 'radius', radiusConfig); geom.setTo(0, 0, width, height, radius); } else { var radius = { x: width / 2, y: height / 2 }; geom.setTo(0, 0, width, height, radius); } var iteration = GetValue(radiusConfig, 'iteration', undefined); _this.setIteration(iteration); _this.setPosition(x, y); _this.setFillStyle(fillColor, fillAlpha); if (strokeColor !== undefined && strokeWidth === undefined) { strokeWidth = 2; } _this.setStrokeStyle(strokeWidth, strokeColor, strokeAlpha); _this.updateDisplayOrigin(); _this.dirty = true; return _this; } _createClass(RoundRectangle, [{ key: "fillColor", get: function get() { return this._fillColor; }, set: function set(value) { this._fillColor = value; this.isFilled = value != null && this._fillAlpha > 0; } }, { key: "fillAlpha", get: function get() { return this._fillAlpha; }, set: function set(value) { this._fillAlpha = value; this.isFilled = value > 0 && this._fillColor != null; } // Fully override setFillStyle method }, { key: "setFillStyle", value: function setFillStyle(color, alpha) { if (alpha === undefined) { alpha = 1; } this.fillColor = color; this.fillAlpha = alpha; return this; } }, { key: "strokeColor", get: function get() { return this._strokeColor; }, set: function set(value) { this._strokeColor = value; this.isStroked = value != null && this._strokeAlpha > 0 && this._lineWidth > 0; } }, { key: "strokeAlpha", get: function get() { return this._strokeAlpha; }, set: function set(value) { this._strokeAlpha = value; this.isStroked = value > 0 && this._strokeColor != null && this._lineWidth > 0; } }, { key: "lineWidth", get: function get() { return this._lineWidth; }, set: function set(value) { this._lineWidth = value; this.isStroked = value > 0 && this._strokeColor != null; } // Fully override setStrokeStyle method }, { key: "setStrokeStyle", value: function setStrokeStyle(lineWidth, color, alpha) { if (alpha === undefined) { alpha = 1; } this.lineWidth = lineWidth; this.strokeColor = color; this.strokeAlpha = alpha; return this; } }, { key: "updateData", value: function updateData() { var geom = this.geom; var pathData = this.pathData; pathData.length = 0; var width = geom.width, height = geom.height, cornerRadius = geom.cornerRadius, radius, iteration = this.iteration + 1; // Top-left radius = cornerRadius.tl; if (IsArcCorner(radius)) { if (radius.convex) { var centerX = radius.x; var centerY = radius.y; ArcTo(centerX, centerY, radius.x, radius.y, 180, 270, false, iteration, pathData); } else { var centerX = 0; var centerY = 0; ArcTo(centerX, centerY, radius.x, radius.y, 90, 0, true, iteration, pathData); } } else { LineTo(0, 0, pathData); } // Top-right radius = cornerRadius.tr; if (IsArcCorner(radius)) { if (radius.convex) { var centerX = width - radius.x; var centerY = radius.y; ArcTo(centerX, centerY, radius.x, radius.y, 270, 360, false, iteration, pathData); } else { var centerX = width; var centerY = 0; ArcTo(centerX, centerY, radius.x, radius.y, 180, 90, true, iteration, pathData); } } else { LineTo(width, 0, pathData); } // Bottom-right radius = cornerRadius.br; if (IsArcCorner(radius)) { if (radius.convex) { var centerX = width - radius.x; var centerY = height - radius.y; ArcTo(centerX, centerY, radius.x, radius.y, 0, 90, false, iteration, pathData); } else { var centerX = width; var centerY = height; ArcTo(centerX, centerY, radius.x, radius.y, 270, 180, true, iteration, pathData); } } else { LineTo(width, height, pathData); } // Bottom-left radius = cornerRadius.bl; if (IsArcCorner(radius)) { if (radius.convex) { var centerX = radius.x; var centerY = height - radius.y; ArcTo(centerX, centerY, radius.x, radius.y, 90, 180, false, iteration, pathData); } else { var centerX = 0; var centerY = height; ArcTo(centerX, centerY, radius.x, radius.y, 360, 270, true, iteration, pathData); } } else { LineTo(0, height, pathData); } pathData.push(pathData[0], pathData[1]); // Repeat first point to close curve this.pathIndexes = Earcut(pathData); return this; } }, { key: "setShapeType", value: function setShapeType(shapeType) { if (typeof shapeType === 'string') { shapeType = ShapeTypeMap[shapeType]; } this.shapeType = shapeType; return this; } }, { key: "width", get: function get() { return this.geom.width; }, set: function set(value) { this.resize(value, this.height); } }, { key: "height", get: function get() { return this.geom.height; }, set: function set(value) { this.resize(this.width, value); } }, { key: "setSize", value: function setSize(width, height) { // Override Shape's setSize method if (height === undefined) { height = width; } if (this.geom.width === width && this.geom.height === height) { return this; } this.geom.setSize(width, height); if (this.shapeType === 1) { this.setRadius({ x: width / 2, y: height / 2 }); } this.updateDisplayOrigin(); this.dirty = true; var input = this.input; if (input && !input.customHitArea) { input.hitArea.width = width; input.hitArea.height = height; } return this; } }, { key: "resize", value: function resize(width, height) { this.setSize(width, height); return this; } }, { key: "radius", get: function get() { return this.geom.radius; }, set: function set(value) { this.geom.setRadius(value); this.updateDisplayOrigin(); this.dirty = true; } }, { key: "radiusTL", get: function get() { return this.geom.radiusTL; }, set: function set(value) { this.geom.radiusTL = value; this.dirty = true; } }, { key: "radiusTR", get: function get() { return this.geom.radiusTR; }, set: function set(value) { this.geom.radiusTR = value; this.dirty = true; } }, { key: "radiusBL", get: function get() { return this.geom.radiusBL; }, set: function set(value) { this.geom.radiusBL = value; this.dirty = true; } }, { key: "radiusBR", get: function get() { return this.geom.radiusBR; }, set: function set(value) { this.geom.radiusBR = value; this.dirty = true; } }, { key: "setRadius", value: function setRadius(value) { if (value === undefined) { value = 0; } this.radius = value; return this; } }, { key: "setRadiusTL", value: function setRadiusTL(value) { if (value === undefined) { value = 0; } this.radiusTL = value; return this; } }, { key: "setRadiusTR", value: function setRadiusTR(value) { if (value === undefined) { value = 0; } this.radiusTR = value; return this; } }, { key: "setRadiusBL", value: function setRadiusBL(value) { if (value === undefined) { value = 0; } this.radiusBL = value; return this; } }, { key: "setRadiusBR", value: function setRadiusBR(value) { if (value === undefined) { value = 0; } this.radiusBR = value; return this; } }, { key: "cornerRadius", get: function get() { return this.geom.cornerRadius; }, set: function set(value) { this.radius = value; } }, { key: "setCornerRadius", value: function setCornerRadius(value) { return this.setRadius(value); } }, { key: "iteration", get: function get() { return this._iteration; }, set: function set(value) { // Set iteration first time if (this._iteration === undefined) { this._iteration = value; return; } // Change iteration value if (this._iteration === value) { return; } this._iteration = value; this.dirty = true; } }, { key: "setIteration", value: function setIteration(iteration) { if (iteration === undefined) { iteration = 6; } this.iteration = iteration; return this; } }]); return RoundRectangle; }(Shape); var IsArcCorner = function IsArcCorner(radius) { return radius.x > 0 && radius.y > 0; }; var ShapeTypeMap = { rectangle: 0, circle: 1 }; Object.assign(RoundRectangle.prototype, Render); return RoundRectangle; }));