UNPKG

ag-grid-enterprise

Version:

AG Grid Enterprise Features

250 lines 9.71 kB
"use strict"; var __values = (this && this.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Path2D = void 0; var intersection_1 = require("./intersection"); var Command; (function (Command) { Command[Command["Move"] = 0] = "Move"; Command[Command["Line"] = 1] = "Line"; Command[Command["Arc"] = 2] = "Arc"; Command[Command["Curve"] = 3] = "Curve"; Command[Command["ClosePath"] = 4] = "ClosePath"; })(Command || (Command = {})); var Path2D = /** @class */ (function () { function Path2D() { // The methods of this class will likely be called many times per animation frame, // and any allocation can trigger a GC cycle during animation, so we attempt // to minimize the number of allocations. this.previousCommands = []; this.previousParams = []; this.previousClosedPath = false; this.commands = []; this.params = []; this._closedPath = false; } Path2D.prototype.isDirty = function () { if (this._closedPath !== this.previousClosedPath) { return true; } if (this.previousCommands.length !== this.commands.length) { return true; } if (this.previousParams.length !== this.params.length) { return true; } for (var i = 0; i < this.commands.length; i++) { if (this.commands[i] !== this.previousCommands[i]) { return true; } } for (var i = 0; i < this.params.length; i++) { if (this.params[i] !== this.previousParams[i]) { return true; } } return false; }; Path2D.prototype.draw = function (ctx) { var e_1, _a; var commands = this.commands; var params = this.params; var j = 0; ctx.beginPath(); try { for (var commands_1 = __values(commands), commands_1_1 = commands_1.next(); !commands_1_1.done; commands_1_1 = commands_1.next()) { var command = commands_1_1.value; switch (command) { case Command.Move: ctx.moveTo(params[j++], params[j++]); break; case Command.Line: ctx.lineTo(params[j++], params[j++]); break; case Command.Curve: ctx.bezierCurveTo(params[j++], params[j++], params[j++], params[j++], params[j++], params[j++]); break; case Command.Arc: ctx.arc(params[j++], params[j++], params[j++], params[j++], params[j++], params[j++] === 1); break; case Command.ClosePath: ctx.closePath(); break; } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (commands_1_1 && !commands_1_1.done && (_a = commands_1.return)) _a.call(commands_1); } finally { if (e_1) throw e_1.error; } } if (commands.length === 0) { ctx.closePath(); } }; Path2D.prototype.moveTo = function (x, y) { if (this.xy) { this.xy[0] = x; this.xy[1] = y; } else { this.xy = [x, y]; } this.commands.push(Command.Move); this.params.push(x, y); }; Path2D.prototype.lineTo = function (x, y) { if (this.xy) { this.commands.push(Command.Line); this.params.push(x, y); this.xy[0] = x; this.xy[1] = y; } else { this.moveTo(x, y); } }; Path2D.prototype.rect = function (x, y, width, height) { this.moveTo(x, y); this.lineTo(x + width, y); this.lineTo(x + width, y + height); this.lineTo(x, y + height); this.closePath(); }; Path2D.prototype.arc = function (x, y, r, sAngle, eAngle, antiClockwise) { if (antiClockwise === void 0) { antiClockwise = false; } var endX = x + r * Math.cos(eAngle); var endY = y + r * Math.sin(eAngle); if (this.xy) { this.xy[0] = endX; this.xy[1] = endY; } else { this.xy = [endX, endY]; } this.commands.push(Command.Arc); this.params.push(x, y, r, sAngle, eAngle, antiClockwise ? 1 : 0); }; Path2D.prototype.cubicCurveTo = function (cx1, cy1, cx2, cy2, x, y) { if (!this.xy) { this.moveTo(cx1, cy1); } this.commands.push(Command.Curve); this.params.push(cx1, cy1, cx2, cy2, x, y); if (this.xy) { this.xy[0] = x; this.xy[1] = y; } }; Object.defineProperty(Path2D.prototype, "closedPath", { get: function () { return this._closedPath; }, enumerable: false, configurable: true }); Path2D.prototype.closePath = function () { if (this.xy) { this.xy = undefined; this.commands.push(Command.ClosePath); this._closedPath = true; } }; Path2D.prototype.clear = function (_a) { var _b = _a === void 0 ? { trackChanges: false } : _a, trackChanges = _b.trackChanges; if (trackChanges) { this.previousCommands = this.commands; this.previousParams = this.params; this.previousClosedPath = this._closedPath; this.commands = []; this.params = []; } else { this.commands.length = 0; this.params.length = 0; } this.xy = undefined; this._closedPath = false; }; Path2D.prototype.isPointInPath = function (x, y) { var commands = this.commands; var params = this.params; var cn = commands.length; // Hit testing using ray casting method, where the ray's origin is some point // outside the path. In this case, an offscreen point that is remote enough, so that // even if the path itself is large and is partially offscreen, the ray's origin // will likely be outside the path anyway. To test if the given point is inside the // path or not, we cast a ray from the origin to the given point and check the number // of intersections of this segment with the path. If the number of intersections is // even, then the ray both entered and exited the path an equal number of times, // therefore the point is outside the path, and inside the path, if the number of // intersections is odd. Since the path is compound, we check if the ray segment // intersects with each of the path's segments, which can be either a line segment // (one or no intersection points) or a Bézier curve segment (up to 3 intersection // points). var ox = -10000; var oy = -10000; // the starting point of the current path var sx = NaN; var sy = NaN; // the previous point of the current path var px = 0; var py = 0; var intersectionCount = 0; for (var ci = 0, pi = 0; ci < cn; ci++) { switch (commands[ci]) { case Command.Move: if (!isNaN(sx)) { if (intersection_1.segmentIntersection(sx, sy, px, py, ox, oy, x, y)) { intersectionCount++; } } px = params[pi++]; sx = px; py = params[pi++]; sy = py; break; case Command.Line: if (intersection_1.segmentIntersection(px, py, params[pi++], params[pi++], ox, oy, x, y)) { intersectionCount++; } px = params[pi - 2]; py = params[pi - 1]; break; case Command.Curve: intersectionCount += intersection_1.cubicSegmentIntersections(px, py, params[pi++], params[pi++], params[pi++], params[pi++], params[pi++], params[pi++], ox, oy, x, y).length; px = params[pi - 2]; py = params[pi - 1]; break; case Command.Arc: intersectionCount += intersection_1.arcIntersections(params[pi++], params[pi++], params[pi++], params[pi++], params[pi++], Boolean(params[pi++]), ox, oy, x, y).length; px = params[pi - 2]; py = params[pi - 1]; break; case Command.ClosePath: if (!isNaN(sx)) { if (intersection_1.segmentIntersection(sx, sy, px, py, ox, oy, x, y)) { intersectionCount++; } } break; } } return intersectionCount % 2 === 1; }; return Path2D; }()); exports.Path2D = Path2D; //# sourceMappingURL=path2D.js.map