first commit
This commit is contained in:
commit
eb2f504652
32490 changed files with 5731109 additions and 0 deletions
107
node_modules/path2d-polyfill/CHANGELOG.md
generated
vendored
Normal file
107
node_modules/path2d-polyfill/CHANGELOG.md
generated
vendored
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
## [2.0.1](https://github.com/nilzona/path2d-polyfill/compare/v2.0.0...v2.0.1) (2023-01-22)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- add browser and main fields in package.json ([82e8522](https://github.com/nilzona/path2d-polyfill/commit/82e8522b17c750cc06dbade1e7022ffea312fd5d))
|
||||
|
||||
## [2.0.0](https://github.com/nilzona/path2d-polyfill/compare/v1.2.3...v2.0.0) (2023-01-22)
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
- target build now has the name `dist/path2d-polyfill.min.js`
|
||||
|
||||
- chore: null Path2D in example index.html
|
||||
|
||||
- Update tsconfig.json
|
||||
|
||||
Co-authored-by: Linus Unnebäck <linus@folkdatorn.se>
|
||||
|
||||
- chore: build for node and browsers
|
||||
|
||||
- docs: update doc example
|
||||
|
||||
Co-authored-by: Linus Unnebäck <linus@folkdatorn.se>
|
||||
|
||||
### Features
|
||||
|
||||
- node support with roundRect polyfill ([#43](https://github.com/nilzona/path2d-polyfill/issues/43)) ([2fffe15](https://github.com/nilzona/path2d-polyfill/commit/2fffe15a76e7adac50beacc0f9587d5b3cc71485))
|
||||
|
||||
## [1.2.3](https://github.com/nilzona/path2d-polyfill/compare/v1.2.2...v1.2.3) (2022-10-11)
|
||||
|
||||
## [1.2.2](https://github.com/nilzona/path2d-polyfill/compare/v1.2.1...v1.2.2) (2022-07-23)
|
||||
|
||||
undefined
|
||||
|
||||
### [1.2.1](https://github.com/nilzona/path2d-polyfill/compare/v1.2.0...v1.2.1) (2022-03-06)## [1.2.0](https://github.com/nilzona/path2d-polyfill/compare/v1.1.8...v1.2.0) (2021-10-30)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- fixup lint and build ([94be3cd](https://github.com/nilzona/path2d-polyfill/commit/94be3cd38a58f83efc403a58380ff3c23b4f18bf))
|
||||
- sync version in package.json with tags ([e12e852](https://github.com/nilzona/path2d-polyfill/commit/e12e852ffb13034fa13efd5112c59b6b13a46013))
|
||||
|
||||
### [1.1.2](https://github.com/nilzona/path2d-polyfill/compare/v1.1.8...v1.2.0) (2021-05-04)
|
||||
|
||||
### [1.1.1](https://github.com/nilzona/path2d-polyfill/compare/v1.1.8...v1.2.0) (2020-11-16)
|
||||
|
||||
### Features
|
||||
|
||||
- support for isPointInPath ([605f5d1](https://github.com/nilzona/path2d-polyfill/commit/605f5d188812e472575ccbaba351b9bbc58d3677))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- documentation readme ([5a0abaa](https://github.com/nilzona/path2d-polyfill/commit/5a0abaab6976f10c57ac83e6f6481ed425ac940e))
|
||||
|
||||
### [1.0.2](https://github.com/nilzona/path2d-polyfill/compare/v1.1.8...v1.2.0) (2020-08-27)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- remove unused css rule ([54e5174](https://github.com/nilzona/path2d-polyfill/commit/54e5174c64f6e84ef891d8830c828efc45c73b93))
|
||||
- update badge in README.md ([483afe2](https://github.com/nilzona/path2d-polyfill/commit/483afe2b3440083bbb0c3dae74510959055d0f86))
|
||||
|
||||
## [1.0.0](https://github.com/nilzona/path2d-polyfill/compare/v1.1.8...v1.2.0) (2020-05-27)
|
||||
|
||||
### [0.4.2](https://github.com/nilzona/path2d-polyfill/compare/v1.1.8...v1.2.0) (2019-08-28)
|
||||
|
||||
### [0.4.1](https://github.com/nilzona/path2d-polyfill/compare/v1.1.8...v1.2.0) (2019-04-15)
|
||||
|
||||
## [0.4.0](https://github.com/nilzona/path2d-polyfill/compare/v1.1.8...v1.2.0) (2019-04-12)
|
||||
|
||||
### Features
|
||||
|
||||
- support ellipse commands ([#7](https://github.com/nilzona/path2d-polyfill/issues/7)) ([02af6d5](https://github.com/nilzona/path2d-polyfill/commit/02af6d55365b8ef70b8eecad88b913e71ae191b2))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- move current position when a path is closed ([#9](https://github.com/nilzona/path2d-polyfill/issues/9)) ([ff6d2f7](https://github.com/nilzona/path2d-polyfill/commit/ff6d2f770f9895be2ac2e947697b8f76e488cb37))
|
||||
|
||||
### [0.3.1](https://github.com/nilzona/path2d-polyfill/compare/v1.1.8...v1.2.0) (2018-09-26)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- better checks if polyfill is needed ([bd65468](https://github.com/nilzona/path2d-polyfill/commit/bd654681662530d19a0958db22c5990424fb77f2))
|
||||
|
||||
## [0.3.0](https://github.com/nilzona/path2d-polyfill/compare/v1.1.8...v1.2.0) (2018-09-25)
|
||||
|
||||
### [0.2.2](https://github.com/nilzona/path2d-polyfill/compare/v1.1.8...v1.2.0) (2018-09-04)
|
||||
|
||||
### [0.2.1](https://github.com/nilzona/path2d-polyfill/compare/v1.1.8...v1.2.0) (2018-06-05)
|
||||
|
||||
## [0.2.0](https://github.com/nilzona/path2d-polyfill/compare/v1.1.8...v1.2.0) (2018-06-04)
|
||||
|
||||
### [0.1.3](https://github.com/nilzona/path2d-polyfill/compare/v1.1.8...v1.2.0) (2018-05-22)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Avoid reference to global window ([9d3e742](https://github.com/nilzona/path2d-polyfill/commit/9d3e74241eb0652afe22d34523f10f3a3837e179))
|
||||
- Remove wrong removeChild call ([123db85](https://github.com/nilzona/path2d-polyfill/commit/123db8571ff8b1b6c2fa917b513c74f8215acc37))
|
||||
- Update README.md ([bcb01e1](https://github.com/nilzona/path2d-polyfill/commit/bcb01e153add2dccf95adaced13646e871086a3a))
|
||||
|
||||
### [0.1.1](https://github.com/nilzona/path2d-polyfill/compare/v1.1.8...v1.2.0) (2018-05-18)
|
||||
|
||||
## [0.1.0](https://github.com/nilzona/path2d-polyfill/compare/v1.1.8...v1.2.0) (2018-05-18)
|
||||
|
||||
### Features
|
||||
|
||||
- Added examples ([261165c](https://github.com/nilzona/path2d-polyfill/commit/261165cfb0ea3a9910624f719a34a3596f1791d0))
|
||||
- First version of Path2D polyfill ([a660f19](https://github.com/nilzona/path2d-polyfill/commit/a660f194f416785a40d8d7f5ad451bb54cec15c3))
|
||||
- Implement addPath ([72d4228](https://github.com/nilzona/path2d-polyfill/commit/72d4228bd6c4dda64fa957ab80e49bd7c7677d8f))
|
||||
21
node_modules/path2d-polyfill/LICENSE
generated
vendored
Normal file
21
node_modules/path2d-polyfill/LICENSE
generated
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2018 Anders Nilsson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
107
node_modules/path2d-polyfill/README.md
generated
vendored
Normal file
107
node_modules/path2d-polyfill/README.md
generated
vendored
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
# path2d-polyfill
|
||||
|
||||
[](https://github.com/nilzona/path2d-polyfill/actions/workflows/validate.yaml)
|
||||
|
||||
Polyfills `Path2D` api and `roundRect` for CanvasRenderingContext2D
|
||||
|
||||
## Usage
|
||||
|
||||
Add this script tag to your page to enable the feature.
|
||||
|
||||
```html
|
||||
<script lang="javascript" src="https://cdn.jsdelivr.net/npm/path2d-polyfill/dist/path2d-polyfill.min.js"></script>
|
||||
```
|
||||
|
||||
or install from npm
|
||||
|
||||
```shell
|
||||
npm install --save path2d-polyfill
|
||||
```
|
||||
|
||||
and import with module bundler e.g. webpack _before_ using the feature
|
||||
|
||||
```javascript
|
||||
import "path2d-polyfill";
|
||||
```
|
||||
|
||||
This will polyfill the browser's window object with Path2D features and it will also polyfill roundRect if they are missing in both CanvasRenderingContexst and Path2D.
|
||||
|
||||
Example of usage
|
||||
|
||||
```javascript
|
||||
ctx.fill(new Path2D("M 80 80 A 45 45 0 0 0 125 125 L 125 80 Z"));
|
||||
ctx.stroke(new Path2D("M 80 80 A 45 45 0 0 0 125 125 L 125 80 Z"));
|
||||
```
|
||||
|
||||
## Usage in a node environment
|
||||
|
||||
It is possible to use this library in a node environment as well. The package exports a few functions that can be used:
|
||||
|
||||
- `Path2D` - class to create Path2D objects used by the polyfill methods
|
||||
- `polyfillPath2D` - function that adds Path2D to a "window like" object and polyfills CanvasRenderingContext2D to use Path2D
|
||||
- `polyfillRoundRect` - polyfills roundRect function on Path2D and CanvasRenderingContext2D (missing in firefox)
|
||||
- `parsePath` - function for parsing an SVG path string into canvas commands
|
||||
|
||||
use any of these functions like:
|
||||
|
||||
```js
|
||||
const { polyfillRoundRect } = require "path2d-polyfill";
|
||||
|
||||
const windowlike = { CanvasRenderingContext2D, Path2D };
|
||||
|
||||
polyfillRoundRect(windowLike);
|
||||
// roundRect functions has now been added if they were missing
|
||||
```
|
||||
|
||||
### usage with node-canvas
|
||||
|
||||
To get Path2D features with the [node-canvas library](https://github.com/Automattic/node-canvas) use the following pattern:
|
||||
|
||||
```js
|
||||
const { createCanvas, CanvasRenderingContext2D } = require("canvas");
|
||||
const { polyfillPath2D } = require("path2d-polyfill/path2d");
|
||||
|
||||
global.CanvasRenderingContext2D = CanvasRenderingContext2D;
|
||||
polyfillPath2D(global);
|
||||
// Path2D has now been added to global object
|
||||
|
||||
const canvas = createCanvas(200, 200);
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
const p = new Path2D("M10 10 l 20 0 l 0 20 Z");
|
||||
ctx.fillStyle = "green";
|
||||
ctx.fill(p);
|
||||
```
|
||||
|
||||
A working example of a node express server that serves an image drawn with canvas can be seen [here](https://gist.github.com/nilzona/e611c99336d8ea1f645bd391a459c24f)
|
||||
|
||||
## Support table
|
||||
|
||||
| Method | Supported |
|
||||
| -------------------- | :-------: |
|
||||
| constructor(SVGPath) | Yes |
|
||||
| addPath() | Yes |
|
||||
| closePath() | Yes |
|
||||
| moveTo() | Yes |
|
||||
| lineTo() | Yes |
|
||||
| bezierCurveTo() | Yes |
|
||||
| quadraticCurveTo() | Yes |
|
||||
| arc() | Yes |
|
||||
| ellipse() | Yes |
|
||||
| rect() | Yes |
|
||||
| roundRect() | Yes |
|
||||
|
||||
## See it in action
|
||||
|
||||
Clone this repo and run the following
|
||||
|
||||
```shell
|
||||
yarn
|
||||
yarn start
|
||||
```
|
||||
|
||||
open <http://localhost:10001> to see the example page.
|
||||
|
||||
## Contributing
|
||||
|
||||
Recommended to use vscode with the prettier extension to keep formatting intact.
|
||||
596
node_modules/path2d-polyfill/dist/path2d-node.cjs
generated
vendored
Normal file
596
node_modules/path2d-polyfill/dist/path2d-node.cjs
generated
vendored
Normal file
|
|
@ -0,0 +1,596 @@
|
|||
'use strict';
|
||||
|
||||
/******************************************************************************
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
***************************************************************************** */
|
||||
|
||||
function __spreadArray(to, from, pack) {
|
||||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
||||
if (ar || !(i in from)) {
|
||||
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
||||
ar[i] = from[i];
|
||||
}
|
||||
}
|
||||
return to.concat(ar || Array.prototype.slice.call(from));
|
||||
}
|
||||
|
||||
var ARG_LENGTH = {
|
||||
a: 7,
|
||||
c: 6,
|
||||
h: 1,
|
||||
l: 2,
|
||||
m: 2,
|
||||
q: 4,
|
||||
s: 4,
|
||||
t: 2,
|
||||
v: 1,
|
||||
z: 0
|
||||
};
|
||||
var SEGMENT_PATTERN = /([astvzqmhlc])([^astvzqmhlc]*)/gi;
|
||||
var NUMBER = /-?[0-9]*\.?[0-9]+(?:e[-+]?\d+)?/gi;
|
||||
function parseValues(args) {
|
||||
var numbers = args.match(NUMBER);
|
||||
return numbers ? numbers.map(Number) : [];
|
||||
}
|
||||
/**
|
||||
* parse an svg path data string. Generates an Array
|
||||
* of commands where each command is an Array of the
|
||||
* form `[command, arg1, arg2, ...]`
|
||||
*
|
||||
* https://www.w3.org/TR/SVG/paths.html#PathDataGeneralInformation
|
||||
* @ignore
|
||||
*
|
||||
* @param {string} path
|
||||
* @returns {array}
|
||||
*/
|
||||
function parsePath(path) {
|
||||
var data = [];
|
||||
var p = String(path).trim();
|
||||
// A path data segment (if there is one) must begin with a "moveto" command
|
||||
if (p[0] !== "M" && p[0] !== "m") {
|
||||
return data;
|
||||
}
|
||||
p.replace(SEGMENT_PATTERN, function (_, command, args) {
|
||||
var theArgs = parseValues(args);
|
||||
var type = command.toLowerCase();
|
||||
var theCommand = command;
|
||||
// overloaded moveTo
|
||||
if (type === "m" && theArgs.length > 2) {
|
||||
data.push(__spreadArray([theCommand], theArgs.splice(0, 2), true));
|
||||
type = "l";
|
||||
theCommand = theCommand === "m" ? "l" : "L";
|
||||
}
|
||||
// Ignore invalid commands
|
||||
if (theArgs.length < ARG_LENGTH[type]) {
|
||||
return "";
|
||||
}
|
||||
data.push(__spreadArray([theCommand], theArgs.splice(0, ARG_LENGTH[type]), true));
|
||||
// The command letter can be eliminated on subsequent commands if the
|
||||
// same command is used multiple times in a row (e.g., you can drop the
|
||||
// second "L" in "M 100 200 L 200 100 L -100 -200" and use
|
||||
// "M 100 200 L 200 100 -100 -200" instead).
|
||||
while (theArgs.length >= ARG_LENGTH[type] && theArgs.length && ARG_LENGTH[type]) {
|
||||
data.push(__spreadArray([theCommand], theArgs.splice(0, ARG_LENGTH[type]), true));
|
||||
}
|
||||
return "";
|
||||
});
|
||||
return data;
|
||||
}
|
||||
|
||||
function rotatePoint(point, angle) {
|
||||
var nx = point.x * Math.cos(angle) - point.y * Math.sin(angle);
|
||||
var ny = point.y * Math.cos(angle) + point.x * Math.sin(angle);
|
||||
point.x = nx;
|
||||
point.y = ny;
|
||||
}
|
||||
function translatePoint(point, dx, dy) {
|
||||
point.x += dx;
|
||||
point.y += dy;
|
||||
}
|
||||
function scalePoint(point, s) {
|
||||
point.x *= s;
|
||||
point.y *= s;
|
||||
}
|
||||
/**
|
||||
* Implements a browser's Path2D api
|
||||
*/
|
||||
var Path2D = /** @class */ (function () {
|
||||
function Path2D(path) {
|
||||
var _a;
|
||||
this.commands = [];
|
||||
if (path && path instanceof Path2D) {
|
||||
(_a = this.commands).push.apply(_a, path.commands);
|
||||
}
|
||||
else if (path) {
|
||||
this.commands = parsePath(path);
|
||||
}
|
||||
}
|
||||
Path2D.prototype.addPath = function (path) {
|
||||
var _a;
|
||||
if (path && path instanceof Path2D) {
|
||||
(_a = this.commands).push.apply(_a, path.commands);
|
||||
}
|
||||
};
|
||||
Path2D.prototype.moveTo = function (x, y) {
|
||||
this.commands.push(["M", x, y]);
|
||||
};
|
||||
Path2D.prototype.lineTo = function (x, y) {
|
||||
this.commands.push(["L", x, y]);
|
||||
};
|
||||
Path2D.prototype.arc = function (x, y, r, start, end, ccw) {
|
||||
this.commands.push(["AC", x, y, r, start, end, !!ccw]);
|
||||
};
|
||||
Path2D.prototype.arcTo = function (x1, y1, x2, y2, r) {
|
||||
this.commands.push(["AT", x1, y1, x2, y2, r]);
|
||||
};
|
||||
Path2D.prototype.ellipse = function (x, y, rx, ry, angle, start, end, ccw) {
|
||||
this.commands.push(["E", x, y, rx, ry, angle, start, end, !!ccw]);
|
||||
};
|
||||
Path2D.prototype.closePath = function () {
|
||||
this.commands.push(["Z"]);
|
||||
};
|
||||
Path2D.prototype.bezierCurveTo = function (cp1x, cp1y, cp2x, cp2y, x, y) {
|
||||
this.commands.push(["C", cp1x, cp1y, cp2x, cp2y, x, y]);
|
||||
};
|
||||
Path2D.prototype.quadraticCurveTo = function (cpx, cpy, x, y) {
|
||||
this.commands.push(["Q", cpx, cpy, x, y]);
|
||||
};
|
||||
Path2D.prototype.rect = function (x, y, width, height) {
|
||||
this.commands.push(["R", x, y, width, height]);
|
||||
};
|
||||
Path2D.prototype.roundRect = function (x, y, width, height, radii) {
|
||||
if (typeof radii === "undefined") {
|
||||
this.commands.push(["RR", x, y, width, height, 0]);
|
||||
}
|
||||
else {
|
||||
this.commands.push(["RR", x, y, width, height, radii]);
|
||||
}
|
||||
};
|
||||
return Path2D;
|
||||
}());
|
||||
function buildPath(ctx, commands) {
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
var endAngle;
|
||||
var startAngle;
|
||||
var largeArcFlag;
|
||||
var sweepFlag;
|
||||
var endPoint;
|
||||
var midPoint;
|
||||
var angle;
|
||||
var lambda;
|
||||
var t1;
|
||||
var t2;
|
||||
var x1;
|
||||
var y1;
|
||||
var r;
|
||||
var rx;
|
||||
var ry;
|
||||
var w;
|
||||
var h;
|
||||
var pathType;
|
||||
var centerPoint;
|
||||
var ccw;
|
||||
var radii;
|
||||
var cpx = null;
|
||||
var cpy = null;
|
||||
var qcpx = null;
|
||||
var qcpy = null;
|
||||
var startPoint = null;
|
||||
var currentPoint = null;
|
||||
ctx.beginPath();
|
||||
for (var i = 0; i < commands.length; ++i) {
|
||||
pathType = commands[i][0];
|
||||
// Reset control point if command is not cubic
|
||||
if (pathType !== "S" && pathType !== "s" && pathType !== "C" && pathType !== "c") {
|
||||
cpx = null;
|
||||
cpy = null;
|
||||
}
|
||||
if (pathType !== "T" && pathType !== "t" && pathType !== "Q" && pathType !== "q") {
|
||||
qcpx = null;
|
||||
qcpy = null;
|
||||
}
|
||||
var c = void 0;
|
||||
switch (pathType) {
|
||||
case "m":
|
||||
case "M":
|
||||
c = commands[i];
|
||||
if (pathType === "m") {
|
||||
x += c[1];
|
||||
y += c[2];
|
||||
}
|
||||
else {
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
}
|
||||
if (pathType === "M" || !startPoint) {
|
||||
startPoint = { x: x, y: y };
|
||||
}
|
||||
ctx.moveTo(x, y);
|
||||
break;
|
||||
case "l":
|
||||
c = commands[i];
|
||||
x += c[1];
|
||||
y += c[2];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "L":
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "H":
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "h":
|
||||
c = commands[i];
|
||||
x += c[1];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "V":
|
||||
c = commands[i];
|
||||
y = c[1];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "v":
|
||||
c = commands[i];
|
||||
y += c[1];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "a":
|
||||
case "A":
|
||||
c = commands[i];
|
||||
if (currentPoint === null) {
|
||||
throw new Error("This should never happen");
|
||||
}
|
||||
if (pathType === "a") {
|
||||
x += c[6];
|
||||
y += c[7];
|
||||
}
|
||||
else {
|
||||
x = c[6];
|
||||
y = c[7];
|
||||
}
|
||||
rx = c[1]; // rx
|
||||
ry = c[2]; // ry
|
||||
angle = (c[3] * Math.PI) / 180;
|
||||
largeArcFlag = !!c[4];
|
||||
sweepFlag = !!c[5];
|
||||
endPoint = { x: x, y: y };
|
||||
// https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
|
||||
midPoint = {
|
||||
x: (currentPoint.x - endPoint.x) / 2,
|
||||
y: (currentPoint.y - endPoint.y) / 2
|
||||
};
|
||||
rotatePoint(midPoint, -angle);
|
||||
// radius correction
|
||||
lambda = (midPoint.x * midPoint.x) / (rx * rx) + (midPoint.y * midPoint.y) / (ry * ry);
|
||||
if (lambda > 1) {
|
||||
lambda = Math.sqrt(lambda);
|
||||
rx *= lambda;
|
||||
ry *= lambda;
|
||||
}
|
||||
centerPoint = {
|
||||
x: (rx * midPoint.y) / ry,
|
||||
y: -(ry * midPoint.x) / rx
|
||||
};
|
||||
t1 = rx * rx * ry * ry;
|
||||
t2 = rx * rx * midPoint.y * midPoint.y + ry * ry * midPoint.x * midPoint.x;
|
||||
if (sweepFlag !== largeArcFlag) {
|
||||
scalePoint(centerPoint, Math.sqrt((t1 - t2) / t2) || 0);
|
||||
}
|
||||
else {
|
||||
scalePoint(centerPoint, -Math.sqrt((t1 - t2) / t2) || 0);
|
||||
}
|
||||
startAngle = Math.atan2((midPoint.y - centerPoint.y) / ry, (midPoint.x - centerPoint.x) / rx);
|
||||
endAngle = Math.atan2(-(midPoint.y + centerPoint.y) / ry, -(midPoint.x + centerPoint.x) / rx);
|
||||
rotatePoint(centerPoint, angle);
|
||||
translatePoint(centerPoint, (endPoint.x + currentPoint.x) / 2, (endPoint.y + currentPoint.y) / 2);
|
||||
ctx.save();
|
||||
ctx.translate(centerPoint.x, centerPoint.y);
|
||||
ctx.rotate(angle);
|
||||
ctx.scale(rx, ry);
|
||||
ctx.arc(0, 0, 1, startAngle, endAngle, !sweepFlag);
|
||||
ctx.restore();
|
||||
break;
|
||||
case "C":
|
||||
c = commands[i];
|
||||
cpx = c[3]; // Last control point
|
||||
cpy = c[4];
|
||||
x = c[5];
|
||||
y = c[6];
|
||||
ctx.bezierCurveTo(c[1], c[2], cpx, cpy, x, y);
|
||||
break;
|
||||
case "c":
|
||||
c = commands[i];
|
||||
ctx.bezierCurveTo(c[1] + x, c[2] + y, c[3] + x, c[4] + y, c[5] + x, c[6] + y);
|
||||
cpx = c[3] + x; // Last control point
|
||||
cpy = c[4] + y;
|
||||
x += c[5];
|
||||
y += c[6];
|
||||
break;
|
||||
case "S":
|
||||
c = commands[i];
|
||||
if (cpx === null || cpy === null) {
|
||||
cpx = x;
|
||||
cpy = y;
|
||||
}
|
||||
ctx.bezierCurveTo(2 * x - cpx, 2 * y - cpy, c[1], c[2], c[3], c[4]);
|
||||
cpx = c[1]; // last control point
|
||||
cpy = c[2];
|
||||
x = c[3];
|
||||
y = c[4];
|
||||
break;
|
||||
case "s":
|
||||
c = commands[i];
|
||||
if (cpx === null || cpy === null) {
|
||||
cpx = x;
|
||||
cpy = y;
|
||||
}
|
||||
ctx.bezierCurveTo(2 * x - cpx, 2 * y - cpy, c[1] + x, c[2] + y, c[3] + x, c[4] + y);
|
||||
cpx = c[1] + x; // last control point
|
||||
cpy = c[2] + y;
|
||||
x += c[3];
|
||||
y += c[4];
|
||||
break;
|
||||
case "Q":
|
||||
c = commands[i];
|
||||
qcpx = c[1]; // last control point
|
||||
qcpy = c[2];
|
||||
x = c[3];
|
||||
y = c[4];
|
||||
ctx.quadraticCurveTo(qcpx, qcpy, x, y);
|
||||
break;
|
||||
case "q":
|
||||
c = commands[i];
|
||||
qcpx = c[1] + x; // last control point
|
||||
qcpy = c[2] + y;
|
||||
x += c[3];
|
||||
y += c[4];
|
||||
ctx.quadraticCurveTo(qcpx, qcpy, x, y);
|
||||
break;
|
||||
case "T":
|
||||
c = commands[i];
|
||||
if (qcpx === null || qcpy === null) {
|
||||
qcpx = x;
|
||||
qcpy = y;
|
||||
}
|
||||
qcpx = 2 * x - qcpx; // last control point
|
||||
qcpy = 2 * y - qcpy;
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
ctx.quadraticCurveTo(qcpx, qcpy, x, y);
|
||||
break;
|
||||
case "t":
|
||||
c = commands[i];
|
||||
if (qcpx === null || qcpy === null) {
|
||||
qcpx = x;
|
||||
qcpy = y;
|
||||
}
|
||||
qcpx = 2 * x - qcpx; // last control point
|
||||
qcpy = 2 * y - qcpy;
|
||||
x += c[1];
|
||||
y += c[2];
|
||||
ctx.quadraticCurveTo(qcpx, qcpy, x, y);
|
||||
break;
|
||||
case "z":
|
||||
case "Z":
|
||||
if (startPoint) {
|
||||
x = startPoint.x;
|
||||
y = startPoint.y;
|
||||
}
|
||||
startPoint = null;
|
||||
ctx.closePath();
|
||||
break;
|
||||
case "AC": // arc
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
r = c[3];
|
||||
startAngle = c[4];
|
||||
endAngle = c[5];
|
||||
ccw = c[6];
|
||||
ctx.arc(x, y, r, startAngle, endAngle, ccw);
|
||||
break;
|
||||
case "AT": // arcTo
|
||||
c = commands[i];
|
||||
x1 = c[1];
|
||||
y1 = c[2];
|
||||
x = c[3];
|
||||
y = c[4];
|
||||
r = c[5];
|
||||
ctx.arcTo(x1, y1, x, y, r);
|
||||
break;
|
||||
case "E": // ellipse
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
rx = c[3];
|
||||
ry = c[4];
|
||||
angle = c[5];
|
||||
startAngle = c[6];
|
||||
endAngle = c[7];
|
||||
ccw = c[8];
|
||||
ctx.save();
|
||||
ctx.translate(x, y);
|
||||
ctx.rotate(angle);
|
||||
ctx.scale(rx, ry);
|
||||
ctx.arc(0, 0, 1, startAngle, endAngle, ccw);
|
||||
ctx.restore();
|
||||
break;
|
||||
case "R": // rect
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
w = c[3];
|
||||
h = c[4];
|
||||
startPoint = { x: x, y: y };
|
||||
ctx.rect(x, y, w, h);
|
||||
break;
|
||||
case "RR": // roundedRect
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
w = c[3];
|
||||
h = c[4];
|
||||
radii = c[5];
|
||||
startPoint = { x: x, y: y };
|
||||
ctx.roundRect(x, y, w, h, radii);
|
||||
break;
|
||||
}
|
||||
if (!currentPoint) {
|
||||
currentPoint = { x: x, y: y };
|
||||
}
|
||||
else {
|
||||
currentPoint.x = x;
|
||||
currentPoint.y = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Polyfills CanvasRenderingContext2D stroke, fill and isPointInPath so that they support Path2D objects.
|
||||
* @param {WindowLike} window - window like object containing a CanvasRenderingContext2D constructor
|
||||
*/
|
||||
function polyfillPath2D(window) {
|
||||
if (!window || !window.CanvasRenderingContext2D || window.Path2D)
|
||||
return;
|
||||
var CanvasRenderingContext2D = window.CanvasRenderingContext2D;
|
||||
/* eslint-disable @typescript-eslint/unbound-method */
|
||||
// setting unbound functions here. Make sure this is set in function call later
|
||||
var cFill = CanvasRenderingContext2D.prototype.fill;
|
||||
var cStroke = CanvasRenderingContext2D.prototype.stroke;
|
||||
var cIsPointInPath = CanvasRenderingContext2D.prototype.isPointInPath;
|
||||
/* eslint-enable @typescript-eslint/unbound-method */
|
||||
CanvasRenderingContext2D.prototype.fill = function fill() {
|
||||
var args = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
args[_i] = arguments[_i];
|
||||
}
|
||||
if (args[0] instanceof Path2D) {
|
||||
var path = args[0];
|
||||
var fillRule = args[1] || "nonzero";
|
||||
buildPath(this, path.commands);
|
||||
cFill.apply(this, [fillRule]);
|
||||
}
|
||||
else {
|
||||
var fillRule = args[0] || "nonzero";
|
||||
return cFill.apply(this, [fillRule]);
|
||||
}
|
||||
};
|
||||
CanvasRenderingContext2D.prototype.stroke = function stroke(path) {
|
||||
if (path) {
|
||||
buildPath(this, path.commands);
|
||||
}
|
||||
cStroke.apply(this);
|
||||
};
|
||||
CanvasRenderingContext2D.prototype.isPointInPath = function isPointInPath() {
|
||||
var args = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
args[_i] = arguments[_i];
|
||||
}
|
||||
if (args[0] instanceof Path2D) {
|
||||
// first argument is a Path2D object
|
||||
var path = args[0];
|
||||
var x = args[1];
|
||||
var y = args[2];
|
||||
var fillRule = args[3] || "nonzero";
|
||||
buildPath(this, path.commands);
|
||||
return cIsPointInPath.apply(this, [x, y, fillRule]);
|
||||
}
|
||||
else {
|
||||
return cIsPointInPath.apply(this, args);
|
||||
}
|
||||
};
|
||||
window.Path2D = Path2D;
|
||||
}
|
||||
|
||||
function roundRect(x, y, width, height, radii) {
|
||||
var _this = this;
|
||||
if (radii === void 0) { radii = 0; }
|
||||
if (typeof radii === "number") {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
radii = [radii];
|
||||
}
|
||||
// check for range error
|
||||
if (Array.isArray(radii)) {
|
||||
if (radii.length === 0 || radii.length > 4) {
|
||||
throw new RangeError("Failed to execute 'roundRect' on '".concat(this.constructor.name, "': ").concat(radii.length, " radii provided. Between one and four radii are necessary."));
|
||||
}
|
||||
radii.forEach(function (v) {
|
||||
if (v < 0) {
|
||||
throw new RangeError("Failed to execute 'roundRect' on '".concat(_this.constructor.name, "': Radius value ").concat(v, " is negative."));
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
if (radii.length === 1 && radii[0] === 0) {
|
||||
return this.rect(x, y, width, height);
|
||||
}
|
||||
// set the corners
|
||||
// tl = top left radius
|
||||
// tr = top right radius
|
||||
// br = bottom right radius
|
||||
// bl = bottom left radius
|
||||
var minRadius = Math.min(width, height) / 2;
|
||||
var tr, br, bl;
|
||||
var tl = (tr = br = bl = Math.min(minRadius, radii[0]));
|
||||
if (radii.length === 2) {
|
||||
tr = bl = Math.min(minRadius, radii[1]);
|
||||
}
|
||||
if (radii.length === 3) {
|
||||
tr = bl = Math.min(minRadius, radii[1]);
|
||||
br = Math.min(minRadius, radii[2]);
|
||||
}
|
||||
if (radii.length === 4) {
|
||||
tr = Math.min(minRadius, radii[1]);
|
||||
br = Math.min(minRadius, radii[2]);
|
||||
bl = Math.min(minRadius, radii[3]);
|
||||
}
|
||||
// begin with closing current path
|
||||
// this.closePath();
|
||||
// let's draw the rounded rectangle
|
||||
this.moveTo(x, y + height - bl);
|
||||
this.arcTo(x, y, x + tl, y, tl);
|
||||
this.arcTo(x + width, y, x + width, y + tr, tr);
|
||||
this.arcTo(x + width, y + height, x + width - br, y + height, br);
|
||||
this.arcTo(x, y + height, x, y + height - bl, bl);
|
||||
// and move to rects control point for further path drawing
|
||||
this.moveTo(x, y);
|
||||
}
|
||||
/**
|
||||
* Polyfills roundRect on CanvasRenderingContext2D and Path2D
|
||||
* @param {WindowLike} window - window like object containing both CanvasRenderingContext2D and Path2D constructor
|
||||
*/
|
||||
function polyfillRoundRect(window) {
|
||||
if (!window || !window.CanvasRenderingContext2D)
|
||||
return;
|
||||
var CanvasRenderingContext2D = window.CanvasRenderingContext2D, Path2D = window.Path2D;
|
||||
// polyfill unsupported roundRect for e.g. firefox https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/roundRect#browser_compatibility
|
||||
if (CanvasRenderingContext2D && !CanvasRenderingContext2D.prototype.roundRect) {
|
||||
CanvasRenderingContext2D.prototype.roundRect = roundRect;
|
||||
}
|
||||
if (Path2D && !Path2D.prototype.roundRect) {
|
||||
Path2D.prototype.roundRect = roundRect;
|
||||
}
|
||||
}
|
||||
|
||||
exports.Path2D = Path2D;
|
||||
exports.parsePath = parsePath;
|
||||
exports.polyfillPath2D = polyfillPath2D;
|
||||
exports.polyfillRoundRect = polyfillRoundRect;
|
||||
591
node_modules/path2d-polyfill/dist/path2d-node.mjs
generated
vendored
Normal file
591
node_modules/path2d-polyfill/dist/path2d-node.mjs
generated
vendored
Normal file
|
|
@ -0,0 +1,591 @@
|
|||
/******************************************************************************
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
***************************************************************************** */
|
||||
|
||||
function __spreadArray(to, from, pack) {
|
||||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
||||
if (ar || !(i in from)) {
|
||||
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
||||
ar[i] = from[i];
|
||||
}
|
||||
}
|
||||
return to.concat(ar || Array.prototype.slice.call(from));
|
||||
}
|
||||
|
||||
var ARG_LENGTH = {
|
||||
a: 7,
|
||||
c: 6,
|
||||
h: 1,
|
||||
l: 2,
|
||||
m: 2,
|
||||
q: 4,
|
||||
s: 4,
|
||||
t: 2,
|
||||
v: 1,
|
||||
z: 0
|
||||
};
|
||||
var SEGMENT_PATTERN = /([astvzqmhlc])([^astvzqmhlc]*)/gi;
|
||||
var NUMBER = /-?[0-9]*\.?[0-9]+(?:e[-+]?\d+)?/gi;
|
||||
function parseValues(args) {
|
||||
var numbers = args.match(NUMBER);
|
||||
return numbers ? numbers.map(Number) : [];
|
||||
}
|
||||
/**
|
||||
* parse an svg path data string. Generates an Array
|
||||
* of commands where each command is an Array of the
|
||||
* form `[command, arg1, arg2, ...]`
|
||||
*
|
||||
* https://www.w3.org/TR/SVG/paths.html#PathDataGeneralInformation
|
||||
* @ignore
|
||||
*
|
||||
* @param {string} path
|
||||
* @returns {array}
|
||||
*/
|
||||
function parsePath(path) {
|
||||
var data = [];
|
||||
var p = String(path).trim();
|
||||
// A path data segment (if there is one) must begin with a "moveto" command
|
||||
if (p[0] !== "M" && p[0] !== "m") {
|
||||
return data;
|
||||
}
|
||||
p.replace(SEGMENT_PATTERN, function (_, command, args) {
|
||||
var theArgs = parseValues(args);
|
||||
var type = command.toLowerCase();
|
||||
var theCommand = command;
|
||||
// overloaded moveTo
|
||||
if (type === "m" && theArgs.length > 2) {
|
||||
data.push(__spreadArray([theCommand], theArgs.splice(0, 2), true));
|
||||
type = "l";
|
||||
theCommand = theCommand === "m" ? "l" : "L";
|
||||
}
|
||||
// Ignore invalid commands
|
||||
if (theArgs.length < ARG_LENGTH[type]) {
|
||||
return "";
|
||||
}
|
||||
data.push(__spreadArray([theCommand], theArgs.splice(0, ARG_LENGTH[type]), true));
|
||||
// The command letter can be eliminated on subsequent commands if the
|
||||
// same command is used multiple times in a row (e.g., you can drop the
|
||||
// second "L" in "M 100 200 L 200 100 L -100 -200" and use
|
||||
// "M 100 200 L 200 100 -100 -200" instead).
|
||||
while (theArgs.length >= ARG_LENGTH[type] && theArgs.length && ARG_LENGTH[type]) {
|
||||
data.push(__spreadArray([theCommand], theArgs.splice(0, ARG_LENGTH[type]), true));
|
||||
}
|
||||
return "";
|
||||
});
|
||||
return data;
|
||||
}
|
||||
|
||||
function rotatePoint(point, angle) {
|
||||
var nx = point.x * Math.cos(angle) - point.y * Math.sin(angle);
|
||||
var ny = point.y * Math.cos(angle) + point.x * Math.sin(angle);
|
||||
point.x = nx;
|
||||
point.y = ny;
|
||||
}
|
||||
function translatePoint(point, dx, dy) {
|
||||
point.x += dx;
|
||||
point.y += dy;
|
||||
}
|
||||
function scalePoint(point, s) {
|
||||
point.x *= s;
|
||||
point.y *= s;
|
||||
}
|
||||
/**
|
||||
* Implements a browser's Path2D api
|
||||
*/
|
||||
var Path2D = /** @class */ (function () {
|
||||
function Path2D(path) {
|
||||
var _a;
|
||||
this.commands = [];
|
||||
if (path && path instanceof Path2D) {
|
||||
(_a = this.commands).push.apply(_a, path.commands);
|
||||
}
|
||||
else if (path) {
|
||||
this.commands = parsePath(path);
|
||||
}
|
||||
}
|
||||
Path2D.prototype.addPath = function (path) {
|
||||
var _a;
|
||||
if (path && path instanceof Path2D) {
|
||||
(_a = this.commands).push.apply(_a, path.commands);
|
||||
}
|
||||
};
|
||||
Path2D.prototype.moveTo = function (x, y) {
|
||||
this.commands.push(["M", x, y]);
|
||||
};
|
||||
Path2D.prototype.lineTo = function (x, y) {
|
||||
this.commands.push(["L", x, y]);
|
||||
};
|
||||
Path2D.prototype.arc = function (x, y, r, start, end, ccw) {
|
||||
this.commands.push(["AC", x, y, r, start, end, !!ccw]);
|
||||
};
|
||||
Path2D.prototype.arcTo = function (x1, y1, x2, y2, r) {
|
||||
this.commands.push(["AT", x1, y1, x2, y2, r]);
|
||||
};
|
||||
Path2D.prototype.ellipse = function (x, y, rx, ry, angle, start, end, ccw) {
|
||||
this.commands.push(["E", x, y, rx, ry, angle, start, end, !!ccw]);
|
||||
};
|
||||
Path2D.prototype.closePath = function () {
|
||||
this.commands.push(["Z"]);
|
||||
};
|
||||
Path2D.prototype.bezierCurveTo = function (cp1x, cp1y, cp2x, cp2y, x, y) {
|
||||
this.commands.push(["C", cp1x, cp1y, cp2x, cp2y, x, y]);
|
||||
};
|
||||
Path2D.prototype.quadraticCurveTo = function (cpx, cpy, x, y) {
|
||||
this.commands.push(["Q", cpx, cpy, x, y]);
|
||||
};
|
||||
Path2D.prototype.rect = function (x, y, width, height) {
|
||||
this.commands.push(["R", x, y, width, height]);
|
||||
};
|
||||
Path2D.prototype.roundRect = function (x, y, width, height, radii) {
|
||||
if (typeof radii === "undefined") {
|
||||
this.commands.push(["RR", x, y, width, height, 0]);
|
||||
}
|
||||
else {
|
||||
this.commands.push(["RR", x, y, width, height, radii]);
|
||||
}
|
||||
};
|
||||
return Path2D;
|
||||
}());
|
||||
function buildPath(ctx, commands) {
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
var endAngle;
|
||||
var startAngle;
|
||||
var largeArcFlag;
|
||||
var sweepFlag;
|
||||
var endPoint;
|
||||
var midPoint;
|
||||
var angle;
|
||||
var lambda;
|
||||
var t1;
|
||||
var t2;
|
||||
var x1;
|
||||
var y1;
|
||||
var r;
|
||||
var rx;
|
||||
var ry;
|
||||
var w;
|
||||
var h;
|
||||
var pathType;
|
||||
var centerPoint;
|
||||
var ccw;
|
||||
var radii;
|
||||
var cpx = null;
|
||||
var cpy = null;
|
||||
var qcpx = null;
|
||||
var qcpy = null;
|
||||
var startPoint = null;
|
||||
var currentPoint = null;
|
||||
ctx.beginPath();
|
||||
for (var i = 0; i < commands.length; ++i) {
|
||||
pathType = commands[i][0];
|
||||
// Reset control point if command is not cubic
|
||||
if (pathType !== "S" && pathType !== "s" && pathType !== "C" && pathType !== "c") {
|
||||
cpx = null;
|
||||
cpy = null;
|
||||
}
|
||||
if (pathType !== "T" && pathType !== "t" && pathType !== "Q" && pathType !== "q") {
|
||||
qcpx = null;
|
||||
qcpy = null;
|
||||
}
|
||||
var c = void 0;
|
||||
switch (pathType) {
|
||||
case "m":
|
||||
case "M":
|
||||
c = commands[i];
|
||||
if (pathType === "m") {
|
||||
x += c[1];
|
||||
y += c[2];
|
||||
}
|
||||
else {
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
}
|
||||
if (pathType === "M" || !startPoint) {
|
||||
startPoint = { x: x, y: y };
|
||||
}
|
||||
ctx.moveTo(x, y);
|
||||
break;
|
||||
case "l":
|
||||
c = commands[i];
|
||||
x += c[1];
|
||||
y += c[2];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "L":
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "H":
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "h":
|
||||
c = commands[i];
|
||||
x += c[1];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "V":
|
||||
c = commands[i];
|
||||
y = c[1];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "v":
|
||||
c = commands[i];
|
||||
y += c[1];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "a":
|
||||
case "A":
|
||||
c = commands[i];
|
||||
if (currentPoint === null) {
|
||||
throw new Error("This should never happen");
|
||||
}
|
||||
if (pathType === "a") {
|
||||
x += c[6];
|
||||
y += c[7];
|
||||
}
|
||||
else {
|
||||
x = c[6];
|
||||
y = c[7];
|
||||
}
|
||||
rx = c[1]; // rx
|
||||
ry = c[2]; // ry
|
||||
angle = (c[3] * Math.PI) / 180;
|
||||
largeArcFlag = !!c[4];
|
||||
sweepFlag = !!c[5];
|
||||
endPoint = { x: x, y: y };
|
||||
// https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
|
||||
midPoint = {
|
||||
x: (currentPoint.x - endPoint.x) / 2,
|
||||
y: (currentPoint.y - endPoint.y) / 2
|
||||
};
|
||||
rotatePoint(midPoint, -angle);
|
||||
// radius correction
|
||||
lambda = (midPoint.x * midPoint.x) / (rx * rx) + (midPoint.y * midPoint.y) / (ry * ry);
|
||||
if (lambda > 1) {
|
||||
lambda = Math.sqrt(lambda);
|
||||
rx *= lambda;
|
||||
ry *= lambda;
|
||||
}
|
||||
centerPoint = {
|
||||
x: (rx * midPoint.y) / ry,
|
||||
y: -(ry * midPoint.x) / rx
|
||||
};
|
||||
t1 = rx * rx * ry * ry;
|
||||
t2 = rx * rx * midPoint.y * midPoint.y + ry * ry * midPoint.x * midPoint.x;
|
||||
if (sweepFlag !== largeArcFlag) {
|
||||
scalePoint(centerPoint, Math.sqrt((t1 - t2) / t2) || 0);
|
||||
}
|
||||
else {
|
||||
scalePoint(centerPoint, -Math.sqrt((t1 - t2) / t2) || 0);
|
||||
}
|
||||
startAngle = Math.atan2((midPoint.y - centerPoint.y) / ry, (midPoint.x - centerPoint.x) / rx);
|
||||
endAngle = Math.atan2(-(midPoint.y + centerPoint.y) / ry, -(midPoint.x + centerPoint.x) / rx);
|
||||
rotatePoint(centerPoint, angle);
|
||||
translatePoint(centerPoint, (endPoint.x + currentPoint.x) / 2, (endPoint.y + currentPoint.y) / 2);
|
||||
ctx.save();
|
||||
ctx.translate(centerPoint.x, centerPoint.y);
|
||||
ctx.rotate(angle);
|
||||
ctx.scale(rx, ry);
|
||||
ctx.arc(0, 0, 1, startAngle, endAngle, !sweepFlag);
|
||||
ctx.restore();
|
||||
break;
|
||||
case "C":
|
||||
c = commands[i];
|
||||
cpx = c[3]; // Last control point
|
||||
cpy = c[4];
|
||||
x = c[5];
|
||||
y = c[6];
|
||||
ctx.bezierCurveTo(c[1], c[2], cpx, cpy, x, y);
|
||||
break;
|
||||
case "c":
|
||||
c = commands[i];
|
||||
ctx.bezierCurveTo(c[1] + x, c[2] + y, c[3] + x, c[4] + y, c[5] + x, c[6] + y);
|
||||
cpx = c[3] + x; // Last control point
|
||||
cpy = c[4] + y;
|
||||
x += c[5];
|
||||
y += c[6];
|
||||
break;
|
||||
case "S":
|
||||
c = commands[i];
|
||||
if (cpx === null || cpy === null) {
|
||||
cpx = x;
|
||||
cpy = y;
|
||||
}
|
||||
ctx.bezierCurveTo(2 * x - cpx, 2 * y - cpy, c[1], c[2], c[3], c[4]);
|
||||
cpx = c[1]; // last control point
|
||||
cpy = c[2];
|
||||
x = c[3];
|
||||
y = c[4];
|
||||
break;
|
||||
case "s":
|
||||
c = commands[i];
|
||||
if (cpx === null || cpy === null) {
|
||||
cpx = x;
|
||||
cpy = y;
|
||||
}
|
||||
ctx.bezierCurveTo(2 * x - cpx, 2 * y - cpy, c[1] + x, c[2] + y, c[3] + x, c[4] + y);
|
||||
cpx = c[1] + x; // last control point
|
||||
cpy = c[2] + y;
|
||||
x += c[3];
|
||||
y += c[4];
|
||||
break;
|
||||
case "Q":
|
||||
c = commands[i];
|
||||
qcpx = c[1]; // last control point
|
||||
qcpy = c[2];
|
||||
x = c[3];
|
||||
y = c[4];
|
||||
ctx.quadraticCurveTo(qcpx, qcpy, x, y);
|
||||
break;
|
||||
case "q":
|
||||
c = commands[i];
|
||||
qcpx = c[1] + x; // last control point
|
||||
qcpy = c[2] + y;
|
||||
x += c[3];
|
||||
y += c[4];
|
||||
ctx.quadraticCurveTo(qcpx, qcpy, x, y);
|
||||
break;
|
||||
case "T":
|
||||
c = commands[i];
|
||||
if (qcpx === null || qcpy === null) {
|
||||
qcpx = x;
|
||||
qcpy = y;
|
||||
}
|
||||
qcpx = 2 * x - qcpx; // last control point
|
||||
qcpy = 2 * y - qcpy;
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
ctx.quadraticCurveTo(qcpx, qcpy, x, y);
|
||||
break;
|
||||
case "t":
|
||||
c = commands[i];
|
||||
if (qcpx === null || qcpy === null) {
|
||||
qcpx = x;
|
||||
qcpy = y;
|
||||
}
|
||||
qcpx = 2 * x - qcpx; // last control point
|
||||
qcpy = 2 * y - qcpy;
|
||||
x += c[1];
|
||||
y += c[2];
|
||||
ctx.quadraticCurveTo(qcpx, qcpy, x, y);
|
||||
break;
|
||||
case "z":
|
||||
case "Z":
|
||||
if (startPoint) {
|
||||
x = startPoint.x;
|
||||
y = startPoint.y;
|
||||
}
|
||||
startPoint = null;
|
||||
ctx.closePath();
|
||||
break;
|
||||
case "AC": // arc
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
r = c[3];
|
||||
startAngle = c[4];
|
||||
endAngle = c[5];
|
||||
ccw = c[6];
|
||||
ctx.arc(x, y, r, startAngle, endAngle, ccw);
|
||||
break;
|
||||
case "AT": // arcTo
|
||||
c = commands[i];
|
||||
x1 = c[1];
|
||||
y1 = c[2];
|
||||
x = c[3];
|
||||
y = c[4];
|
||||
r = c[5];
|
||||
ctx.arcTo(x1, y1, x, y, r);
|
||||
break;
|
||||
case "E": // ellipse
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
rx = c[3];
|
||||
ry = c[4];
|
||||
angle = c[5];
|
||||
startAngle = c[6];
|
||||
endAngle = c[7];
|
||||
ccw = c[8];
|
||||
ctx.save();
|
||||
ctx.translate(x, y);
|
||||
ctx.rotate(angle);
|
||||
ctx.scale(rx, ry);
|
||||
ctx.arc(0, 0, 1, startAngle, endAngle, ccw);
|
||||
ctx.restore();
|
||||
break;
|
||||
case "R": // rect
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
w = c[3];
|
||||
h = c[4];
|
||||
startPoint = { x: x, y: y };
|
||||
ctx.rect(x, y, w, h);
|
||||
break;
|
||||
case "RR": // roundedRect
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
w = c[3];
|
||||
h = c[4];
|
||||
radii = c[5];
|
||||
startPoint = { x: x, y: y };
|
||||
ctx.roundRect(x, y, w, h, radii);
|
||||
break;
|
||||
}
|
||||
if (!currentPoint) {
|
||||
currentPoint = { x: x, y: y };
|
||||
}
|
||||
else {
|
||||
currentPoint.x = x;
|
||||
currentPoint.y = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Polyfills CanvasRenderingContext2D stroke, fill and isPointInPath so that they support Path2D objects.
|
||||
* @param {WindowLike} window - window like object containing a CanvasRenderingContext2D constructor
|
||||
*/
|
||||
function polyfillPath2D(window) {
|
||||
if (!window || !window.CanvasRenderingContext2D || window.Path2D)
|
||||
return;
|
||||
var CanvasRenderingContext2D = window.CanvasRenderingContext2D;
|
||||
/* eslint-disable @typescript-eslint/unbound-method */
|
||||
// setting unbound functions here. Make sure this is set in function call later
|
||||
var cFill = CanvasRenderingContext2D.prototype.fill;
|
||||
var cStroke = CanvasRenderingContext2D.prototype.stroke;
|
||||
var cIsPointInPath = CanvasRenderingContext2D.prototype.isPointInPath;
|
||||
/* eslint-enable @typescript-eslint/unbound-method */
|
||||
CanvasRenderingContext2D.prototype.fill = function fill() {
|
||||
var args = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
args[_i] = arguments[_i];
|
||||
}
|
||||
if (args[0] instanceof Path2D) {
|
||||
var path = args[0];
|
||||
var fillRule = args[1] || "nonzero";
|
||||
buildPath(this, path.commands);
|
||||
cFill.apply(this, [fillRule]);
|
||||
}
|
||||
else {
|
||||
var fillRule = args[0] || "nonzero";
|
||||
return cFill.apply(this, [fillRule]);
|
||||
}
|
||||
};
|
||||
CanvasRenderingContext2D.prototype.stroke = function stroke(path) {
|
||||
if (path) {
|
||||
buildPath(this, path.commands);
|
||||
}
|
||||
cStroke.apply(this);
|
||||
};
|
||||
CanvasRenderingContext2D.prototype.isPointInPath = function isPointInPath() {
|
||||
var args = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
args[_i] = arguments[_i];
|
||||
}
|
||||
if (args[0] instanceof Path2D) {
|
||||
// first argument is a Path2D object
|
||||
var path = args[0];
|
||||
var x = args[1];
|
||||
var y = args[2];
|
||||
var fillRule = args[3] || "nonzero";
|
||||
buildPath(this, path.commands);
|
||||
return cIsPointInPath.apply(this, [x, y, fillRule]);
|
||||
}
|
||||
else {
|
||||
return cIsPointInPath.apply(this, args);
|
||||
}
|
||||
};
|
||||
window.Path2D = Path2D;
|
||||
}
|
||||
|
||||
function roundRect(x, y, width, height, radii) {
|
||||
var _this = this;
|
||||
if (radii === void 0) { radii = 0; }
|
||||
if (typeof radii === "number") {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
radii = [radii];
|
||||
}
|
||||
// check for range error
|
||||
if (Array.isArray(radii)) {
|
||||
if (radii.length === 0 || radii.length > 4) {
|
||||
throw new RangeError("Failed to execute 'roundRect' on '".concat(this.constructor.name, "': ").concat(radii.length, " radii provided. Between one and four radii are necessary."));
|
||||
}
|
||||
radii.forEach(function (v) {
|
||||
if (v < 0) {
|
||||
throw new RangeError("Failed to execute 'roundRect' on '".concat(_this.constructor.name, "': Radius value ").concat(v, " is negative."));
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
if (radii.length === 1 && radii[0] === 0) {
|
||||
return this.rect(x, y, width, height);
|
||||
}
|
||||
// set the corners
|
||||
// tl = top left radius
|
||||
// tr = top right radius
|
||||
// br = bottom right radius
|
||||
// bl = bottom left radius
|
||||
var minRadius = Math.min(width, height) / 2;
|
||||
var tr, br, bl;
|
||||
var tl = (tr = br = bl = Math.min(minRadius, radii[0]));
|
||||
if (radii.length === 2) {
|
||||
tr = bl = Math.min(minRadius, radii[1]);
|
||||
}
|
||||
if (radii.length === 3) {
|
||||
tr = bl = Math.min(minRadius, radii[1]);
|
||||
br = Math.min(minRadius, radii[2]);
|
||||
}
|
||||
if (radii.length === 4) {
|
||||
tr = Math.min(minRadius, radii[1]);
|
||||
br = Math.min(minRadius, radii[2]);
|
||||
bl = Math.min(minRadius, radii[3]);
|
||||
}
|
||||
// begin with closing current path
|
||||
// this.closePath();
|
||||
// let's draw the rounded rectangle
|
||||
this.moveTo(x, y + height - bl);
|
||||
this.arcTo(x, y, x + tl, y, tl);
|
||||
this.arcTo(x + width, y, x + width, y + tr, tr);
|
||||
this.arcTo(x + width, y + height, x + width - br, y + height, br);
|
||||
this.arcTo(x, y + height, x, y + height - bl, bl);
|
||||
// and move to rects control point for further path drawing
|
||||
this.moveTo(x, y);
|
||||
}
|
||||
/**
|
||||
* Polyfills roundRect on CanvasRenderingContext2D and Path2D
|
||||
* @param {WindowLike} window - window like object containing both CanvasRenderingContext2D and Path2D constructor
|
||||
*/
|
||||
function polyfillRoundRect(window) {
|
||||
if (!window || !window.CanvasRenderingContext2D)
|
||||
return;
|
||||
var CanvasRenderingContext2D = window.CanvasRenderingContext2D, Path2D = window.Path2D;
|
||||
// polyfill unsupported roundRect for e.g. firefox https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/roundRect#browser_compatibility
|
||||
if (CanvasRenderingContext2D && !CanvasRenderingContext2D.prototype.roundRect) {
|
||||
CanvasRenderingContext2D.prototype.roundRect = roundRect;
|
||||
}
|
||||
if (Path2D && !Path2D.prototype.roundRect) {
|
||||
Path2D.prototype.roundRect = roundRect;
|
||||
}
|
||||
}
|
||||
|
||||
export { Path2D, parsePath, polyfillPath2D, polyfillRoundRect };
|
||||
597
node_modules/path2d-polyfill/dist/path2d-polyfill.dev.js
generated
vendored
Normal file
597
node_modules/path2d-polyfill/dist/path2d-polyfill.dev.js
generated
vendored
Normal file
|
|
@ -0,0 +1,597 @@
|
|||
(function () {
|
||||
'use strict';
|
||||
|
||||
/******************************************************************************
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
***************************************************************************** */
|
||||
|
||||
function __spreadArray(to, from, pack) {
|
||||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
||||
if (ar || !(i in from)) {
|
||||
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
||||
ar[i] = from[i];
|
||||
}
|
||||
}
|
||||
return to.concat(ar || Array.prototype.slice.call(from));
|
||||
}
|
||||
|
||||
var ARG_LENGTH = {
|
||||
a: 7,
|
||||
c: 6,
|
||||
h: 1,
|
||||
l: 2,
|
||||
m: 2,
|
||||
q: 4,
|
||||
s: 4,
|
||||
t: 2,
|
||||
v: 1,
|
||||
z: 0
|
||||
};
|
||||
var SEGMENT_PATTERN = /([astvzqmhlc])([^astvzqmhlc]*)/gi;
|
||||
var NUMBER = /-?[0-9]*\.?[0-9]+(?:e[-+]?\d+)?/gi;
|
||||
function parseValues(args) {
|
||||
var numbers = args.match(NUMBER);
|
||||
return numbers ? numbers.map(Number) : [];
|
||||
}
|
||||
/**
|
||||
* parse an svg path data string. Generates an Array
|
||||
* of commands where each command is an Array of the
|
||||
* form `[command, arg1, arg2, ...]`
|
||||
*
|
||||
* https://www.w3.org/TR/SVG/paths.html#PathDataGeneralInformation
|
||||
* @ignore
|
||||
*
|
||||
* @param {string} path
|
||||
* @returns {array}
|
||||
*/
|
||||
function parsePath(path) {
|
||||
var data = [];
|
||||
var p = String(path).trim();
|
||||
// A path data segment (if there is one) must begin with a "moveto" command
|
||||
if (p[0] !== "M" && p[0] !== "m") {
|
||||
return data;
|
||||
}
|
||||
p.replace(SEGMENT_PATTERN, function (_, command, args) {
|
||||
var theArgs = parseValues(args);
|
||||
var type = command.toLowerCase();
|
||||
var theCommand = command;
|
||||
// overloaded moveTo
|
||||
if (type === "m" && theArgs.length > 2) {
|
||||
data.push(__spreadArray([theCommand], theArgs.splice(0, 2), true));
|
||||
type = "l";
|
||||
theCommand = theCommand === "m" ? "l" : "L";
|
||||
}
|
||||
// Ignore invalid commands
|
||||
if (theArgs.length < ARG_LENGTH[type]) {
|
||||
return "";
|
||||
}
|
||||
data.push(__spreadArray([theCommand], theArgs.splice(0, ARG_LENGTH[type]), true));
|
||||
// The command letter can be eliminated on subsequent commands if the
|
||||
// same command is used multiple times in a row (e.g., you can drop the
|
||||
// second "L" in "M 100 200 L 200 100 L -100 -200" and use
|
||||
// "M 100 200 L 200 100 -100 -200" instead).
|
||||
while (theArgs.length >= ARG_LENGTH[type] && theArgs.length && ARG_LENGTH[type]) {
|
||||
data.push(__spreadArray([theCommand], theArgs.splice(0, ARG_LENGTH[type]), true));
|
||||
}
|
||||
return "";
|
||||
});
|
||||
return data;
|
||||
}
|
||||
|
||||
function rotatePoint(point, angle) {
|
||||
var nx = point.x * Math.cos(angle) - point.y * Math.sin(angle);
|
||||
var ny = point.y * Math.cos(angle) + point.x * Math.sin(angle);
|
||||
point.x = nx;
|
||||
point.y = ny;
|
||||
}
|
||||
function translatePoint(point, dx, dy) {
|
||||
point.x += dx;
|
||||
point.y += dy;
|
||||
}
|
||||
function scalePoint(point, s) {
|
||||
point.x *= s;
|
||||
point.y *= s;
|
||||
}
|
||||
/**
|
||||
* Implements a browser's Path2D api
|
||||
*/
|
||||
var Path2D = /** @class */ (function () {
|
||||
function Path2D(path) {
|
||||
var _a;
|
||||
this.commands = [];
|
||||
if (path && path instanceof Path2D) {
|
||||
(_a = this.commands).push.apply(_a, path.commands);
|
||||
}
|
||||
else if (path) {
|
||||
this.commands = parsePath(path);
|
||||
}
|
||||
}
|
||||
Path2D.prototype.addPath = function (path) {
|
||||
var _a;
|
||||
if (path && path instanceof Path2D) {
|
||||
(_a = this.commands).push.apply(_a, path.commands);
|
||||
}
|
||||
};
|
||||
Path2D.prototype.moveTo = function (x, y) {
|
||||
this.commands.push(["M", x, y]);
|
||||
};
|
||||
Path2D.prototype.lineTo = function (x, y) {
|
||||
this.commands.push(["L", x, y]);
|
||||
};
|
||||
Path2D.prototype.arc = function (x, y, r, start, end, ccw) {
|
||||
this.commands.push(["AC", x, y, r, start, end, !!ccw]);
|
||||
};
|
||||
Path2D.prototype.arcTo = function (x1, y1, x2, y2, r) {
|
||||
this.commands.push(["AT", x1, y1, x2, y2, r]);
|
||||
};
|
||||
Path2D.prototype.ellipse = function (x, y, rx, ry, angle, start, end, ccw) {
|
||||
this.commands.push(["E", x, y, rx, ry, angle, start, end, !!ccw]);
|
||||
};
|
||||
Path2D.prototype.closePath = function () {
|
||||
this.commands.push(["Z"]);
|
||||
};
|
||||
Path2D.prototype.bezierCurveTo = function (cp1x, cp1y, cp2x, cp2y, x, y) {
|
||||
this.commands.push(["C", cp1x, cp1y, cp2x, cp2y, x, y]);
|
||||
};
|
||||
Path2D.prototype.quadraticCurveTo = function (cpx, cpy, x, y) {
|
||||
this.commands.push(["Q", cpx, cpy, x, y]);
|
||||
};
|
||||
Path2D.prototype.rect = function (x, y, width, height) {
|
||||
this.commands.push(["R", x, y, width, height]);
|
||||
};
|
||||
Path2D.prototype.roundRect = function (x, y, width, height, radii) {
|
||||
if (typeof radii === "undefined") {
|
||||
this.commands.push(["RR", x, y, width, height, 0]);
|
||||
}
|
||||
else {
|
||||
this.commands.push(["RR", x, y, width, height, radii]);
|
||||
}
|
||||
};
|
||||
return Path2D;
|
||||
}());
|
||||
function buildPath(ctx, commands) {
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
var endAngle;
|
||||
var startAngle;
|
||||
var largeArcFlag;
|
||||
var sweepFlag;
|
||||
var endPoint;
|
||||
var midPoint;
|
||||
var angle;
|
||||
var lambda;
|
||||
var t1;
|
||||
var t2;
|
||||
var x1;
|
||||
var y1;
|
||||
var r;
|
||||
var rx;
|
||||
var ry;
|
||||
var w;
|
||||
var h;
|
||||
var pathType;
|
||||
var centerPoint;
|
||||
var ccw;
|
||||
var radii;
|
||||
var cpx = null;
|
||||
var cpy = null;
|
||||
var qcpx = null;
|
||||
var qcpy = null;
|
||||
var startPoint = null;
|
||||
var currentPoint = null;
|
||||
ctx.beginPath();
|
||||
for (var i = 0; i < commands.length; ++i) {
|
||||
pathType = commands[i][0];
|
||||
// Reset control point if command is not cubic
|
||||
if (pathType !== "S" && pathType !== "s" && pathType !== "C" && pathType !== "c") {
|
||||
cpx = null;
|
||||
cpy = null;
|
||||
}
|
||||
if (pathType !== "T" && pathType !== "t" && pathType !== "Q" && pathType !== "q") {
|
||||
qcpx = null;
|
||||
qcpy = null;
|
||||
}
|
||||
var c = void 0;
|
||||
switch (pathType) {
|
||||
case "m":
|
||||
case "M":
|
||||
c = commands[i];
|
||||
if (pathType === "m") {
|
||||
x += c[1];
|
||||
y += c[2];
|
||||
}
|
||||
else {
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
}
|
||||
if (pathType === "M" || !startPoint) {
|
||||
startPoint = { x: x, y: y };
|
||||
}
|
||||
ctx.moveTo(x, y);
|
||||
break;
|
||||
case "l":
|
||||
c = commands[i];
|
||||
x += c[1];
|
||||
y += c[2];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "L":
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "H":
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "h":
|
||||
c = commands[i];
|
||||
x += c[1];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "V":
|
||||
c = commands[i];
|
||||
y = c[1];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "v":
|
||||
c = commands[i];
|
||||
y += c[1];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "a":
|
||||
case "A":
|
||||
c = commands[i];
|
||||
if (currentPoint === null) {
|
||||
throw new Error("This should never happen");
|
||||
}
|
||||
if (pathType === "a") {
|
||||
x += c[6];
|
||||
y += c[7];
|
||||
}
|
||||
else {
|
||||
x = c[6];
|
||||
y = c[7];
|
||||
}
|
||||
rx = c[1]; // rx
|
||||
ry = c[2]; // ry
|
||||
angle = (c[3] * Math.PI) / 180;
|
||||
largeArcFlag = !!c[4];
|
||||
sweepFlag = !!c[5];
|
||||
endPoint = { x: x, y: y };
|
||||
// https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
|
||||
midPoint = {
|
||||
x: (currentPoint.x - endPoint.x) / 2,
|
||||
y: (currentPoint.y - endPoint.y) / 2
|
||||
};
|
||||
rotatePoint(midPoint, -angle);
|
||||
// radius correction
|
||||
lambda = (midPoint.x * midPoint.x) / (rx * rx) + (midPoint.y * midPoint.y) / (ry * ry);
|
||||
if (lambda > 1) {
|
||||
lambda = Math.sqrt(lambda);
|
||||
rx *= lambda;
|
||||
ry *= lambda;
|
||||
}
|
||||
centerPoint = {
|
||||
x: (rx * midPoint.y) / ry,
|
||||
y: -(ry * midPoint.x) / rx
|
||||
};
|
||||
t1 = rx * rx * ry * ry;
|
||||
t2 = rx * rx * midPoint.y * midPoint.y + ry * ry * midPoint.x * midPoint.x;
|
||||
if (sweepFlag !== largeArcFlag) {
|
||||
scalePoint(centerPoint, Math.sqrt((t1 - t2) / t2) || 0);
|
||||
}
|
||||
else {
|
||||
scalePoint(centerPoint, -Math.sqrt((t1 - t2) / t2) || 0);
|
||||
}
|
||||
startAngle = Math.atan2((midPoint.y - centerPoint.y) / ry, (midPoint.x - centerPoint.x) / rx);
|
||||
endAngle = Math.atan2(-(midPoint.y + centerPoint.y) / ry, -(midPoint.x + centerPoint.x) / rx);
|
||||
rotatePoint(centerPoint, angle);
|
||||
translatePoint(centerPoint, (endPoint.x + currentPoint.x) / 2, (endPoint.y + currentPoint.y) / 2);
|
||||
ctx.save();
|
||||
ctx.translate(centerPoint.x, centerPoint.y);
|
||||
ctx.rotate(angle);
|
||||
ctx.scale(rx, ry);
|
||||
ctx.arc(0, 0, 1, startAngle, endAngle, !sweepFlag);
|
||||
ctx.restore();
|
||||
break;
|
||||
case "C":
|
||||
c = commands[i];
|
||||
cpx = c[3]; // Last control point
|
||||
cpy = c[4];
|
||||
x = c[5];
|
||||
y = c[6];
|
||||
ctx.bezierCurveTo(c[1], c[2], cpx, cpy, x, y);
|
||||
break;
|
||||
case "c":
|
||||
c = commands[i];
|
||||
ctx.bezierCurveTo(c[1] + x, c[2] + y, c[3] + x, c[4] + y, c[5] + x, c[6] + y);
|
||||
cpx = c[3] + x; // Last control point
|
||||
cpy = c[4] + y;
|
||||
x += c[5];
|
||||
y += c[6];
|
||||
break;
|
||||
case "S":
|
||||
c = commands[i];
|
||||
if (cpx === null || cpy === null) {
|
||||
cpx = x;
|
||||
cpy = y;
|
||||
}
|
||||
ctx.bezierCurveTo(2 * x - cpx, 2 * y - cpy, c[1], c[2], c[3], c[4]);
|
||||
cpx = c[1]; // last control point
|
||||
cpy = c[2];
|
||||
x = c[3];
|
||||
y = c[4];
|
||||
break;
|
||||
case "s":
|
||||
c = commands[i];
|
||||
if (cpx === null || cpy === null) {
|
||||
cpx = x;
|
||||
cpy = y;
|
||||
}
|
||||
ctx.bezierCurveTo(2 * x - cpx, 2 * y - cpy, c[1] + x, c[2] + y, c[3] + x, c[4] + y);
|
||||
cpx = c[1] + x; // last control point
|
||||
cpy = c[2] + y;
|
||||
x += c[3];
|
||||
y += c[4];
|
||||
break;
|
||||
case "Q":
|
||||
c = commands[i];
|
||||
qcpx = c[1]; // last control point
|
||||
qcpy = c[2];
|
||||
x = c[3];
|
||||
y = c[4];
|
||||
ctx.quadraticCurveTo(qcpx, qcpy, x, y);
|
||||
break;
|
||||
case "q":
|
||||
c = commands[i];
|
||||
qcpx = c[1] + x; // last control point
|
||||
qcpy = c[2] + y;
|
||||
x += c[3];
|
||||
y += c[4];
|
||||
ctx.quadraticCurveTo(qcpx, qcpy, x, y);
|
||||
break;
|
||||
case "T":
|
||||
c = commands[i];
|
||||
if (qcpx === null || qcpy === null) {
|
||||
qcpx = x;
|
||||
qcpy = y;
|
||||
}
|
||||
qcpx = 2 * x - qcpx; // last control point
|
||||
qcpy = 2 * y - qcpy;
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
ctx.quadraticCurveTo(qcpx, qcpy, x, y);
|
||||
break;
|
||||
case "t":
|
||||
c = commands[i];
|
||||
if (qcpx === null || qcpy === null) {
|
||||
qcpx = x;
|
||||
qcpy = y;
|
||||
}
|
||||
qcpx = 2 * x - qcpx; // last control point
|
||||
qcpy = 2 * y - qcpy;
|
||||
x += c[1];
|
||||
y += c[2];
|
||||
ctx.quadraticCurveTo(qcpx, qcpy, x, y);
|
||||
break;
|
||||
case "z":
|
||||
case "Z":
|
||||
if (startPoint) {
|
||||
x = startPoint.x;
|
||||
y = startPoint.y;
|
||||
}
|
||||
startPoint = null;
|
||||
ctx.closePath();
|
||||
break;
|
||||
case "AC": // arc
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
r = c[3];
|
||||
startAngle = c[4];
|
||||
endAngle = c[5];
|
||||
ccw = c[6];
|
||||
ctx.arc(x, y, r, startAngle, endAngle, ccw);
|
||||
break;
|
||||
case "AT": // arcTo
|
||||
c = commands[i];
|
||||
x1 = c[1];
|
||||
y1 = c[2];
|
||||
x = c[3];
|
||||
y = c[4];
|
||||
r = c[5];
|
||||
ctx.arcTo(x1, y1, x, y, r);
|
||||
break;
|
||||
case "E": // ellipse
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
rx = c[3];
|
||||
ry = c[4];
|
||||
angle = c[5];
|
||||
startAngle = c[6];
|
||||
endAngle = c[7];
|
||||
ccw = c[8];
|
||||
ctx.save();
|
||||
ctx.translate(x, y);
|
||||
ctx.rotate(angle);
|
||||
ctx.scale(rx, ry);
|
||||
ctx.arc(0, 0, 1, startAngle, endAngle, ccw);
|
||||
ctx.restore();
|
||||
break;
|
||||
case "R": // rect
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
w = c[3];
|
||||
h = c[4];
|
||||
startPoint = { x: x, y: y };
|
||||
ctx.rect(x, y, w, h);
|
||||
break;
|
||||
case "RR": // roundedRect
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
w = c[3];
|
||||
h = c[4];
|
||||
radii = c[5];
|
||||
startPoint = { x: x, y: y };
|
||||
ctx.roundRect(x, y, w, h, radii);
|
||||
break;
|
||||
}
|
||||
if (!currentPoint) {
|
||||
currentPoint = { x: x, y: y };
|
||||
}
|
||||
else {
|
||||
currentPoint.x = x;
|
||||
currentPoint.y = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Polyfills CanvasRenderingContext2D stroke, fill and isPointInPath so that they support Path2D objects.
|
||||
* @param {WindowLike} window - window like object containing a CanvasRenderingContext2D constructor
|
||||
*/
|
||||
function polyfillPath2D(window) {
|
||||
if (!window || !window.CanvasRenderingContext2D || window.Path2D)
|
||||
return;
|
||||
var CanvasRenderingContext2D = window.CanvasRenderingContext2D;
|
||||
/* eslint-disable @typescript-eslint/unbound-method */
|
||||
// setting unbound functions here. Make sure this is set in function call later
|
||||
var cFill = CanvasRenderingContext2D.prototype.fill;
|
||||
var cStroke = CanvasRenderingContext2D.prototype.stroke;
|
||||
var cIsPointInPath = CanvasRenderingContext2D.prototype.isPointInPath;
|
||||
/* eslint-enable @typescript-eslint/unbound-method */
|
||||
CanvasRenderingContext2D.prototype.fill = function fill() {
|
||||
var args = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
args[_i] = arguments[_i];
|
||||
}
|
||||
if (args[0] instanceof Path2D) {
|
||||
var path = args[0];
|
||||
var fillRule = args[1] || "nonzero";
|
||||
buildPath(this, path.commands);
|
||||
cFill.apply(this, [fillRule]);
|
||||
}
|
||||
else {
|
||||
var fillRule = args[0] || "nonzero";
|
||||
return cFill.apply(this, [fillRule]);
|
||||
}
|
||||
};
|
||||
CanvasRenderingContext2D.prototype.stroke = function stroke(path) {
|
||||
if (path) {
|
||||
buildPath(this, path.commands);
|
||||
}
|
||||
cStroke.apply(this);
|
||||
};
|
||||
CanvasRenderingContext2D.prototype.isPointInPath = function isPointInPath() {
|
||||
var args = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
args[_i] = arguments[_i];
|
||||
}
|
||||
if (args[0] instanceof Path2D) {
|
||||
// first argument is a Path2D object
|
||||
var path = args[0];
|
||||
var x = args[1];
|
||||
var y = args[2];
|
||||
var fillRule = args[3] || "nonzero";
|
||||
buildPath(this, path.commands);
|
||||
return cIsPointInPath.apply(this, [x, y, fillRule]);
|
||||
}
|
||||
else {
|
||||
return cIsPointInPath.apply(this, args);
|
||||
}
|
||||
};
|
||||
window.Path2D = Path2D;
|
||||
}
|
||||
|
||||
function roundRect(x, y, width, height, radii) {
|
||||
var _this = this;
|
||||
if (radii === void 0) { radii = 0; }
|
||||
if (typeof radii === "number") {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
radii = [radii];
|
||||
}
|
||||
// check for range error
|
||||
if (Array.isArray(radii)) {
|
||||
if (radii.length === 0 || radii.length > 4) {
|
||||
throw new RangeError("Failed to execute 'roundRect' on '".concat(this.constructor.name, "': ").concat(radii.length, " radii provided. Between one and four radii are necessary."));
|
||||
}
|
||||
radii.forEach(function (v) {
|
||||
if (v < 0) {
|
||||
throw new RangeError("Failed to execute 'roundRect' on '".concat(_this.constructor.name, "': Radius value ").concat(v, " is negative."));
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
if (radii.length === 1 && radii[0] === 0) {
|
||||
return this.rect(x, y, width, height);
|
||||
}
|
||||
// set the corners
|
||||
// tl = top left radius
|
||||
// tr = top right radius
|
||||
// br = bottom right radius
|
||||
// bl = bottom left radius
|
||||
var minRadius = Math.min(width, height) / 2;
|
||||
var tr, br, bl;
|
||||
var tl = (tr = br = bl = Math.min(minRadius, radii[0]));
|
||||
if (radii.length === 2) {
|
||||
tr = bl = Math.min(minRadius, radii[1]);
|
||||
}
|
||||
if (radii.length === 3) {
|
||||
tr = bl = Math.min(minRadius, radii[1]);
|
||||
br = Math.min(minRadius, radii[2]);
|
||||
}
|
||||
if (radii.length === 4) {
|
||||
tr = Math.min(minRadius, radii[1]);
|
||||
br = Math.min(minRadius, radii[2]);
|
||||
bl = Math.min(minRadius, radii[3]);
|
||||
}
|
||||
// begin with closing current path
|
||||
// this.closePath();
|
||||
// let's draw the rounded rectangle
|
||||
this.moveTo(x, y + height - bl);
|
||||
this.arcTo(x, y, x + tl, y, tl);
|
||||
this.arcTo(x + width, y, x + width, y + tr, tr);
|
||||
this.arcTo(x + width, y + height, x + width - br, y + height, br);
|
||||
this.arcTo(x, y + height, x, y + height - bl, bl);
|
||||
// and move to rects control point for further path drawing
|
||||
this.moveTo(x, y);
|
||||
}
|
||||
/**
|
||||
* Polyfills roundRect on CanvasRenderingContext2D and Path2D
|
||||
* @param {WindowLike} window - window like object containing both CanvasRenderingContext2D and Path2D constructor
|
||||
*/
|
||||
function polyfillRoundRect(window) {
|
||||
if (!window || !window.CanvasRenderingContext2D)
|
||||
return;
|
||||
var CanvasRenderingContext2D = window.CanvasRenderingContext2D, Path2D = window.Path2D;
|
||||
// polyfill unsupported roundRect for e.g. firefox https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/roundRect#browser_compatibility
|
||||
if (CanvasRenderingContext2D && !CanvasRenderingContext2D.prototype.roundRect) {
|
||||
CanvasRenderingContext2D.prototype.roundRect = roundRect;
|
||||
}
|
||||
if (Path2D && !Path2D.prototype.roundRect) {
|
||||
Path2D.prototype.roundRect = roundRect;
|
||||
}
|
||||
}
|
||||
|
||||
polyfillPath2D(window);
|
||||
polyfillRoundRect(window);
|
||||
|
||||
})();
|
||||
592
node_modules/path2d-polyfill/dist/path2d-polyfill.esm.js
generated
vendored
Normal file
592
node_modules/path2d-polyfill/dist/path2d-polyfill.esm.js
generated
vendored
Normal file
|
|
@ -0,0 +1,592 @@
|
|||
/******************************************************************************
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
***************************************************************************** */
|
||||
|
||||
function __spreadArray(to, from, pack) {
|
||||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
||||
if (ar || !(i in from)) {
|
||||
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
||||
ar[i] = from[i];
|
||||
}
|
||||
}
|
||||
return to.concat(ar || Array.prototype.slice.call(from));
|
||||
}
|
||||
|
||||
var ARG_LENGTH = {
|
||||
a: 7,
|
||||
c: 6,
|
||||
h: 1,
|
||||
l: 2,
|
||||
m: 2,
|
||||
q: 4,
|
||||
s: 4,
|
||||
t: 2,
|
||||
v: 1,
|
||||
z: 0
|
||||
};
|
||||
var SEGMENT_PATTERN = /([astvzqmhlc])([^astvzqmhlc]*)/gi;
|
||||
var NUMBER = /-?[0-9]*\.?[0-9]+(?:e[-+]?\d+)?/gi;
|
||||
function parseValues(args) {
|
||||
var numbers = args.match(NUMBER);
|
||||
return numbers ? numbers.map(Number) : [];
|
||||
}
|
||||
/**
|
||||
* parse an svg path data string. Generates an Array
|
||||
* of commands where each command is an Array of the
|
||||
* form `[command, arg1, arg2, ...]`
|
||||
*
|
||||
* https://www.w3.org/TR/SVG/paths.html#PathDataGeneralInformation
|
||||
* @ignore
|
||||
*
|
||||
* @param {string} path
|
||||
* @returns {array}
|
||||
*/
|
||||
function parsePath(path) {
|
||||
var data = [];
|
||||
var p = String(path).trim();
|
||||
// A path data segment (if there is one) must begin with a "moveto" command
|
||||
if (p[0] !== "M" && p[0] !== "m") {
|
||||
return data;
|
||||
}
|
||||
p.replace(SEGMENT_PATTERN, function (_, command, args) {
|
||||
var theArgs = parseValues(args);
|
||||
var type = command.toLowerCase();
|
||||
var theCommand = command;
|
||||
// overloaded moveTo
|
||||
if (type === "m" && theArgs.length > 2) {
|
||||
data.push(__spreadArray([theCommand], theArgs.splice(0, 2), true));
|
||||
type = "l";
|
||||
theCommand = theCommand === "m" ? "l" : "L";
|
||||
}
|
||||
// Ignore invalid commands
|
||||
if (theArgs.length < ARG_LENGTH[type]) {
|
||||
return "";
|
||||
}
|
||||
data.push(__spreadArray([theCommand], theArgs.splice(0, ARG_LENGTH[type]), true));
|
||||
// The command letter can be eliminated on subsequent commands if the
|
||||
// same command is used multiple times in a row (e.g., you can drop the
|
||||
// second "L" in "M 100 200 L 200 100 L -100 -200" and use
|
||||
// "M 100 200 L 200 100 -100 -200" instead).
|
||||
while (theArgs.length >= ARG_LENGTH[type] && theArgs.length && ARG_LENGTH[type]) {
|
||||
data.push(__spreadArray([theCommand], theArgs.splice(0, ARG_LENGTH[type]), true));
|
||||
}
|
||||
return "";
|
||||
});
|
||||
return data;
|
||||
}
|
||||
|
||||
function rotatePoint(point, angle) {
|
||||
var nx = point.x * Math.cos(angle) - point.y * Math.sin(angle);
|
||||
var ny = point.y * Math.cos(angle) + point.x * Math.sin(angle);
|
||||
point.x = nx;
|
||||
point.y = ny;
|
||||
}
|
||||
function translatePoint(point, dx, dy) {
|
||||
point.x += dx;
|
||||
point.y += dy;
|
||||
}
|
||||
function scalePoint(point, s) {
|
||||
point.x *= s;
|
||||
point.y *= s;
|
||||
}
|
||||
/**
|
||||
* Implements a browser's Path2D api
|
||||
*/
|
||||
var Path2D = /** @class */ (function () {
|
||||
function Path2D(path) {
|
||||
var _a;
|
||||
this.commands = [];
|
||||
if (path && path instanceof Path2D) {
|
||||
(_a = this.commands).push.apply(_a, path.commands);
|
||||
}
|
||||
else if (path) {
|
||||
this.commands = parsePath(path);
|
||||
}
|
||||
}
|
||||
Path2D.prototype.addPath = function (path) {
|
||||
var _a;
|
||||
if (path && path instanceof Path2D) {
|
||||
(_a = this.commands).push.apply(_a, path.commands);
|
||||
}
|
||||
};
|
||||
Path2D.prototype.moveTo = function (x, y) {
|
||||
this.commands.push(["M", x, y]);
|
||||
};
|
||||
Path2D.prototype.lineTo = function (x, y) {
|
||||
this.commands.push(["L", x, y]);
|
||||
};
|
||||
Path2D.prototype.arc = function (x, y, r, start, end, ccw) {
|
||||
this.commands.push(["AC", x, y, r, start, end, !!ccw]);
|
||||
};
|
||||
Path2D.prototype.arcTo = function (x1, y1, x2, y2, r) {
|
||||
this.commands.push(["AT", x1, y1, x2, y2, r]);
|
||||
};
|
||||
Path2D.prototype.ellipse = function (x, y, rx, ry, angle, start, end, ccw) {
|
||||
this.commands.push(["E", x, y, rx, ry, angle, start, end, !!ccw]);
|
||||
};
|
||||
Path2D.prototype.closePath = function () {
|
||||
this.commands.push(["Z"]);
|
||||
};
|
||||
Path2D.prototype.bezierCurveTo = function (cp1x, cp1y, cp2x, cp2y, x, y) {
|
||||
this.commands.push(["C", cp1x, cp1y, cp2x, cp2y, x, y]);
|
||||
};
|
||||
Path2D.prototype.quadraticCurveTo = function (cpx, cpy, x, y) {
|
||||
this.commands.push(["Q", cpx, cpy, x, y]);
|
||||
};
|
||||
Path2D.prototype.rect = function (x, y, width, height) {
|
||||
this.commands.push(["R", x, y, width, height]);
|
||||
};
|
||||
Path2D.prototype.roundRect = function (x, y, width, height, radii) {
|
||||
if (typeof radii === "undefined") {
|
||||
this.commands.push(["RR", x, y, width, height, 0]);
|
||||
}
|
||||
else {
|
||||
this.commands.push(["RR", x, y, width, height, radii]);
|
||||
}
|
||||
};
|
||||
return Path2D;
|
||||
}());
|
||||
function buildPath(ctx, commands) {
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
var endAngle;
|
||||
var startAngle;
|
||||
var largeArcFlag;
|
||||
var sweepFlag;
|
||||
var endPoint;
|
||||
var midPoint;
|
||||
var angle;
|
||||
var lambda;
|
||||
var t1;
|
||||
var t2;
|
||||
var x1;
|
||||
var y1;
|
||||
var r;
|
||||
var rx;
|
||||
var ry;
|
||||
var w;
|
||||
var h;
|
||||
var pathType;
|
||||
var centerPoint;
|
||||
var ccw;
|
||||
var radii;
|
||||
var cpx = null;
|
||||
var cpy = null;
|
||||
var qcpx = null;
|
||||
var qcpy = null;
|
||||
var startPoint = null;
|
||||
var currentPoint = null;
|
||||
ctx.beginPath();
|
||||
for (var i = 0; i < commands.length; ++i) {
|
||||
pathType = commands[i][0];
|
||||
// Reset control point if command is not cubic
|
||||
if (pathType !== "S" && pathType !== "s" && pathType !== "C" && pathType !== "c") {
|
||||
cpx = null;
|
||||
cpy = null;
|
||||
}
|
||||
if (pathType !== "T" && pathType !== "t" && pathType !== "Q" && pathType !== "q") {
|
||||
qcpx = null;
|
||||
qcpy = null;
|
||||
}
|
||||
var c = void 0;
|
||||
switch (pathType) {
|
||||
case "m":
|
||||
case "M":
|
||||
c = commands[i];
|
||||
if (pathType === "m") {
|
||||
x += c[1];
|
||||
y += c[2];
|
||||
}
|
||||
else {
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
}
|
||||
if (pathType === "M" || !startPoint) {
|
||||
startPoint = { x: x, y: y };
|
||||
}
|
||||
ctx.moveTo(x, y);
|
||||
break;
|
||||
case "l":
|
||||
c = commands[i];
|
||||
x += c[1];
|
||||
y += c[2];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "L":
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "H":
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "h":
|
||||
c = commands[i];
|
||||
x += c[1];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "V":
|
||||
c = commands[i];
|
||||
y = c[1];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "v":
|
||||
c = commands[i];
|
||||
y += c[1];
|
||||
ctx.lineTo(x, y);
|
||||
break;
|
||||
case "a":
|
||||
case "A":
|
||||
c = commands[i];
|
||||
if (currentPoint === null) {
|
||||
throw new Error("This should never happen");
|
||||
}
|
||||
if (pathType === "a") {
|
||||
x += c[6];
|
||||
y += c[7];
|
||||
}
|
||||
else {
|
||||
x = c[6];
|
||||
y = c[7];
|
||||
}
|
||||
rx = c[1]; // rx
|
||||
ry = c[2]; // ry
|
||||
angle = (c[3] * Math.PI) / 180;
|
||||
largeArcFlag = !!c[4];
|
||||
sweepFlag = !!c[5];
|
||||
endPoint = { x: x, y: y };
|
||||
// https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
|
||||
midPoint = {
|
||||
x: (currentPoint.x - endPoint.x) / 2,
|
||||
y: (currentPoint.y - endPoint.y) / 2
|
||||
};
|
||||
rotatePoint(midPoint, -angle);
|
||||
// radius correction
|
||||
lambda = (midPoint.x * midPoint.x) / (rx * rx) + (midPoint.y * midPoint.y) / (ry * ry);
|
||||
if (lambda > 1) {
|
||||
lambda = Math.sqrt(lambda);
|
||||
rx *= lambda;
|
||||
ry *= lambda;
|
||||
}
|
||||
centerPoint = {
|
||||
x: (rx * midPoint.y) / ry,
|
||||
y: -(ry * midPoint.x) / rx
|
||||
};
|
||||
t1 = rx * rx * ry * ry;
|
||||
t2 = rx * rx * midPoint.y * midPoint.y + ry * ry * midPoint.x * midPoint.x;
|
||||
if (sweepFlag !== largeArcFlag) {
|
||||
scalePoint(centerPoint, Math.sqrt((t1 - t2) / t2) || 0);
|
||||
}
|
||||
else {
|
||||
scalePoint(centerPoint, -Math.sqrt((t1 - t2) / t2) || 0);
|
||||
}
|
||||
startAngle = Math.atan2((midPoint.y - centerPoint.y) / ry, (midPoint.x - centerPoint.x) / rx);
|
||||
endAngle = Math.atan2(-(midPoint.y + centerPoint.y) / ry, -(midPoint.x + centerPoint.x) / rx);
|
||||
rotatePoint(centerPoint, angle);
|
||||
translatePoint(centerPoint, (endPoint.x + currentPoint.x) / 2, (endPoint.y + currentPoint.y) / 2);
|
||||
ctx.save();
|
||||
ctx.translate(centerPoint.x, centerPoint.y);
|
||||
ctx.rotate(angle);
|
||||
ctx.scale(rx, ry);
|
||||
ctx.arc(0, 0, 1, startAngle, endAngle, !sweepFlag);
|
||||
ctx.restore();
|
||||
break;
|
||||
case "C":
|
||||
c = commands[i];
|
||||
cpx = c[3]; // Last control point
|
||||
cpy = c[4];
|
||||
x = c[5];
|
||||
y = c[6];
|
||||
ctx.bezierCurveTo(c[1], c[2], cpx, cpy, x, y);
|
||||
break;
|
||||
case "c":
|
||||
c = commands[i];
|
||||
ctx.bezierCurveTo(c[1] + x, c[2] + y, c[3] + x, c[4] + y, c[5] + x, c[6] + y);
|
||||
cpx = c[3] + x; // Last control point
|
||||
cpy = c[4] + y;
|
||||
x += c[5];
|
||||
y += c[6];
|
||||
break;
|
||||
case "S":
|
||||
c = commands[i];
|
||||
if (cpx === null || cpy === null) {
|
||||
cpx = x;
|
||||
cpy = y;
|
||||
}
|
||||
ctx.bezierCurveTo(2 * x - cpx, 2 * y - cpy, c[1], c[2], c[3], c[4]);
|
||||
cpx = c[1]; // last control point
|
||||
cpy = c[2];
|
||||
x = c[3];
|
||||
y = c[4];
|
||||
break;
|
||||
case "s":
|
||||
c = commands[i];
|
||||
if (cpx === null || cpy === null) {
|
||||
cpx = x;
|
||||
cpy = y;
|
||||
}
|
||||
ctx.bezierCurveTo(2 * x - cpx, 2 * y - cpy, c[1] + x, c[2] + y, c[3] + x, c[4] + y);
|
||||
cpx = c[1] + x; // last control point
|
||||
cpy = c[2] + y;
|
||||
x += c[3];
|
||||
y += c[4];
|
||||
break;
|
||||
case "Q":
|
||||
c = commands[i];
|
||||
qcpx = c[1]; // last control point
|
||||
qcpy = c[2];
|
||||
x = c[3];
|
||||
y = c[4];
|
||||
ctx.quadraticCurveTo(qcpx, qcpy, x, y);
|
||||
break;
|
||||
case "q":
|
||||
c = commands[i];
|
||||
qcpx = c[1] + x; // last control point
|
||||
qcpy = c[2] + y;
|
||||
x += c[3];
|
||||
y += c[4];
|
||||
ctx.quadraticCurveTo(qcpx, qcpy, x, y);
|
||||
break;
|
||||
case "T":
|
||||
c = commands[i];
|
||||
if (qcpx === null || qcpy === null) {
|
||||
qcpx = x;
|
||||
qcpy = y;
|
||||
}
|
||||
qcpx = 2 * x - qcpx; // last control point
|
||||
qcpy = 2 * y - qcpy;
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
ctx.quadraticCurveTo(qcpx, qcpy, x, y);
|
||||
break;
|
||||
case "t":
|
||||
c = commands[i];
|
||||
if (qcpx === null || qcpy === null) {
|
||||
qcpx = x;
|
||||
qcpy = y;
|
||||
}
|
||||
qcpx = 2 * x - qcpx; // last control point
|
||||
qcpy = 2 * y - qcpy;
|
||||
x += c[1];
|
||||
y += c[2];
|
||||
ctx.quadraticCurveTo(qcpx, qcpy, x, y);
|
||||
break;
|
||||
case "z":
|
||||
case "Z":
|
||||
if (startPoint) {
|
||||
x = startPoint.x;
|
||||
y = startPoint.y;
|
||||
}
|
||||
startPoint = null;
|
||||
ctx.closePath();
|
||||
break;
|
||||
case "AC": // arc
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
r = c[3];
|
||||
startAngle = c[4];
|
||||
endAngle = c[5];
|
||||
ccw = c[6];
|
||||
ctx.arc(x, y, r, startAngle, endAngle, ccw);
|
||||
break;
|
||||
case "AT": // arcTo
|
||||
c = commands[i];
|
||||
x1 = c[1];
|
||||
y1 = c[2];
|
||||
x = c[3];
|
||||
y = c[4];
|
||||
r = c[5];
|
||||
ctx.arcTo(x1, y1, x, y, r);
|
||||
break;
|
||||
case "E": // ellipse
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
rx = c[3];
|
||||
ry = c[4];
|
||||
angle = c[5];
|
||||
startAngle = c[6];
|
||||
endAngle = c[7];
|
||||
ccw = c[8];
|
||||
ctx.save();
|
||||
ctx.translate(x, y);
|
||||
ctx.rotate(angle);
|
||||
ctx.scale(rx, ry);
|
||||
ctx.arc(0, 0, 1, startAngle, endAngle, ccw);
|
||||
ctx.restore();
|
||||
break;
|
||||
case "R": // rect
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
w = c[3];
|
||||
h = c[4];
|
||||
startPoint = { x: x, y: y };
|
||||
ctx.rect(x, y, w, h);
|
||||
break;
|
||||
case "RR": // roundedRect
|
||||
c = commands[i];
|
||||
x = c[1];
|
||||
y = c[2];
|
||||
w = c[3];
|
||||
h = c[4];
|
||||
radii = c[5];
|
||||
startPoint = { x: x, y: y };
|
||||
ctx.roundRect(x, y, w, h, radii);
|
||||
break;
|
||||
}
|
||||
if (!currentPoint) {
|
||||
currentPoint = { x: x, y: y };
|
||||
}
|
||||
else {
|
||||
currentPoint.x = x;
|
||||
currentPoint.y = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Polyfills CanvasRenderingContext2D stroke, fill and isPointInPath so that they support Path2D objects.
|
||||
* @param {WindowLike} window - window like object containing a CanvasRenderingContext2D constructor
|
||||
*/
|
||||
function polyfillPath2D(window) {
|
||||
if (!window || !window.CanvasRenderingContext2D || window.Path2D)
|
||||
return;
|
||||
var CanvasRenderingContext2D = window.CanvasRenderingContext2D;
|
||||
/* eslint-disable @typescript-eslint/unbound-method */
|
||||
// setting unbound functions here. Make sure this is set in function call later
|
||||
var cFill = CanvasRenderingContext2D.prototype.fill;
|
||||
var cStroke = CanvasRenderingContext2D.prototype.stroke;
|
||||
var cIsPointInPath = CanvasRenderingContext2D.prototype.isPointInPath;
|
||||
/* eslint-enable @typescript-eslint/unbound-method */
|
||||
CanvasRenderingContext2D.prototype.fill = function fill() {
|
||||
var args = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
args[_i] = arguments[_i];
|
||||
}
|
||||
if (args[0] instanceof Path2D) {
|
||||
var path = args[0];
|
||||
var fillRule = args[1] || "nonzero";
|
||||
buildPath(this, path.commands);
|
||||
cFill.apply(this, [fillRule]);
|
||||
}
|
||||
else {
|
||||
var fillRule = args[0] || "nonzero";
|
||||
return cFill.apply(this, [fillRule]);
|
||||
}
|
||||
};
|
||||
CanvasRenderingContext2D.prototype.stroke = function stroke(path) {
|
||||
if (path) {
|
||||
buildPath(this, path.commands);
|
||||
}
|
||||
cStroke.apply(this);
|
||||
};
|
||||
CanvasRenderingContext2D.prototype.isPointInPath = function isPointInPath() {
|
||||
var args = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
args[_i] = arguments[_i];
|
||||
}
|
||||
if (args[0] instanceof Path2D) {
|
||||
// first argument is a Path2D object
|
||||
var path = args[0];
|
||||
var x = args[1];
|
||||
var y = args[2];
|
||||
var fillRule = args[3] || "nonzero";
|
||||
buildPath(this, path.commands);
|
||||
return cIsPointInPath.apply(this, [x, y, fillRule]);
|
||||
}
|
||||
else {
|
||||
return cIsPointInPath.apply(this, args);
|
||||
}
|
||||
};
|
||||
window.Path2D = Path2D;
|
||||
}
|
||||
|
||||
function roundRect(x, y, width, height, radii) {
|
||||
var _this = this;
|
||||
if (radii === void 0) { radii = 0; }
|
||||
if (typeof radii === "number") {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
radii = [radii];
|
||||
}
|
||||
// check for range error
|
||||
if (Array.isArray(radii)) {
|
||||
if (radii.length === 0 || radii.length > 4) {
|
||||
throw new RangeError("Failed to execute 'roundRect' on '".concat(this.constructor.name, "': ").concat(radii.length, " radii provided. Between one and four radii are necessary."));
|
||||
}
|
||||
radii.forEach(function (v) {
|
||||
if (v < 0) {
|
||||
throw new RangeError("Failed to execute 'roundRect' on '".concat(_this.constructor.name, "': Radius value ").concat(v, " is negative."));
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
if (radii.length === 1 && radii[0] === 0) {
|
||||
return this.rect(x, y, width, height);
|
||||
}
|
||||
// set the corners
|
||||
// tl = top left radius
|
||||
// tr = top right radius
|
||||
// br = bottom right radius
|
||||
// bl = bottom left radius
|
||||
var minRadius = Math.min(width, height) / 2;
|
||||
var tr, br, bl;
|
||||
var tl = (tr = br = bl = Math.min(minRadius, radii[0]));
|
||||
if (radii.length === 2) {
|
||||
tr = bl = Math.min(minRadius, radii[1]);
|
||||
}
|
||||
if (radii.length === 3) {
|
||||
tr = bl = Math.min(minRadius, radii[1]);
|
||||
br = Math.min(minRadius, radii[2]);
|
||||
}
|
||||
if (radii.length === 4) {
|
||||
tr = Math.min(minRadius, radii[1]);
|
||||
br = Math.min(minRadius, radii[2]);
|
||||
bl = Math.min(minRadius, radii[3]);
|
||||
}
|
||||
// begin with closing current path
|
||||
// this.closePath();
|
||||
// let's draw the rounded rectangle
|
||||
this.moveTo(x, y + height - bl);
|
||||
this.arcTo(x, y, x + tl, y, tl);
|
||||
this.arcTo(x + width, y, x + width, y + tr, tr);
|
||||
this.arcTo(x + width, y + height, x + width - br, y + height, br);
|
||||
this.arcTo(x, y + height, x, y + height - bl, bl);
|
||||
// and move to rects control point for further path drawing
|
||||
this.moveTo(x, y);
|
||||
}
|
||||
/**
|
||||
* Polyfills roundRect on CanvasRenderingContext2D and Path2D
|
||||
* @param {WindowLike} window - window like object containing both CanvasRenderingContext2D and Path2D constructor
|
||||
*/
|
||||
function polyfillRoundRect(window) {
|
||||
if (!window || !window.CanvasRenderingContext2D)
|
||||
return;
|
||||
var CanvasRenderingContext2D = window.CanvasRenderingContext2D, Path2D = window.Path2D;
|
||||
// polyfill unsupported roundRect for e.g. firefox https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/roundRect#browser_compatibility
|
||||
if (CanvasRenderingContext2D && !CanvasRenderingContext2D.prototype.roundRect) {
|
||||
CanvasRenderingContext2D.prototype.roundRect = roundRect;
|
||||
}
|
||||
if (Path2D && !Path2D.prototype.roundRect) {
|
||||
Path2D.prototype.roundRect = roundRect;
|
||||
}
|
||||
}
|
||||
|
||||
polyfillPath2D(window);
|
||||
polyfillRoundRect(window);
|
||||
1
node_modules/path2d-polyfill/dist/path2d-polyfill.min.js
generated
vendored
Normal file
1
node_modules/path2d-polyfill/dist/path2d-polyfill.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
81
node_modules/path2d-polyfill/package.json
generated
vendored
Normal file
81
node_modules/path2d-polyfill/package.json
generated
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
{
|
||||
"name": "path2d-polyfill",
|
||||
"version": "2.0.1",
|
||||
"description": "Polyfills Path2D api for canvas rendering",
|
||||
"scripts": {
|
||||
"build": "rm -rf dist/* && rollup -c",
|
||||
"start": "rollup -c -w",
|
||||
"lint": "eslint .",
|
||||
"check-types": "tsc --noEmit",
|
||||
"test": "ts-mocha test/*.spec.ts",
|
||||
"test:watch": "ts-mocha --watch test/*.spec.ts",
|
||||
"test:coverage": "nyc --reporter=html --reporter=text --reporter=text-summary yarn test",
|
||||
"format:check": "prettier --check \"./**\"",
|
||||
"format:write": "prettier --write \"./**\"",
|
||||
"prepare": "husky install",
|
||||
"release": "release-it"
|
||||
},
|
||||
"main": "dist/path2d-node.cjs",
|
||||
"browser": "dist/path2d-polyfill.min.js",
|
||||
"exports": {
|
||||
"node": {
|
||||
"import": "./dist/path2d-node.mjs",
|
||||
"require": "./dist/path2d-node.cjs"
|
||||
},
|
||||
"development": "./dist/path2d-polyfill.dev.js",
|
||||
"module": "./dist/path2d-polyfill.esm.js",
|
||||
"default": "./dist/path2d-polyfill.min.js"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/nilzona/path2d-polyfill.git"
|
||||
},
|
||||
"keywords": [
|
||||
"Path2D",
|
||||
"polyfill",
|
||||
"canvas",
|
||||
"roundRect"
|
||||
],
|
||||
"author": "nilzona",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/nilzona/path2d-polyfill/issues"
|
||||
},
|
||||
"homepage": "https://github.com/nilzona/path2d-polyfill#readme",
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "17.3.0",
|
||||
"@commitlint/config-conventional": "17.3.0",
|
||||
"@release-it/conventional-changelog": "5.1.1",
|
||||
"@rollup/plugin-terser": "0.2.1",
|
||||
"@rollup/plugin-typescript": "10.0.1",
|
||||
"@types/chai": "^4.3.4",
|
||||
"@types/mocha": "^10.0.1",
|
||||
"@types/sinon": "^10.0.13",
|
||||
"@types/sinon-chai": "^3.2.9",
|
||||
"@typescript-eslint/eslint-plugin": "5.48.0",
|
||||
"@typescript-eslint/parser": "5.48.0",
|
||||
"chai": "4.3.7",
|
||||
"eslint": "8.31.0",
|
||||
"eslint-config-prettier": "8.6.0",
|
||||
"husky": "8.0.2",
|
||||
"lint-staged": "13.1.0",
|
||||
"mocha": "10.2.0",
|
||||
"nyc": "15.1.0",
|
||||
"prettier": "2.8.1",
|
||||
"release-it": "15.6.0",
|
||||
"rollup": "3.9.1",
|
||||
"rollup-plugin-livereload": "2.0.5",
|
||||
"rollup-plugin-serve": "2.0.2",
|
||||
"sinon": "15.0.1",
|
||||
"sinon-chai": "3.7.0",
|
||||
"ts-mocha": "^10.0.0",
|
||||
"typescript": "^4.9.4"
|
||||
},
|
||||
"dependencies": {},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue