feat: add canvas-roundrect-polyfill package (#6675)
* feat: add canvas-roundrect-polyfill instead of maintaining a copy of it and transplile it since its not transpiled in the package * transform canvas-roundrect-polyfill in jest
This commit is contained in:
parent
1747e93957
commit
4d7d96eb7b
@ -28,6 +28,7 @@
|
|||||||
"@testing-library/react": "12.1.5",
|
"@testing-library/react": "12.1.5",
|
||||||
"@tldraw/vec": "1.7.1",
|
"@tldraw/vec": "1.7.1",
|
||||||
"browser-fs-access": "0.29.1",
|
"browser-fs-access": "0.29.1",
|
||||||
|
"canvas-roundrect-polyfill": "0.0.1",
|
||||||
"clsx": "1.1.1",
|
"clsx": "1.1.1",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"fake-indexeddb": "3.1.7",
|
"fake-indexeddb": "3.1.7",
|
||||||
@ -107,7 +108,7 @@
|
|||||||
"<rootDir>/src/packages/excalidraw/example"
|
"<rootDir>/src/packages/excalidraw/example"
|
||||||
],
|
],
|
||||||
"transformIgnorePatterns": [
|
"transformIgnorePatterns": [
|
||||||
"node_modules/(?!(roughjs|points-on-curve|path-data-parser|points-on-path|browser-fs-access)/)"
|
"node_modules/(?!(roughjs|points-on-curve|path-data-parser|points-on-path|browser-fs-access|canvas-roundrect-polyfill)/)"
|
||||||
],
|
],
|
||||||
"resetMocks": false
|
"resetMocks": false
|
||||||
},
|
},
|
||||||
|
@ -44,7 +44,8 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.(ts|tsx|js|jsx|mjs)$/,
|
test: /\.(ts|tsx|js|jsx|mjs)$/,
|
||||||
exclude: /node_modules\/(?!browser-fs-access)/,
|
exclude:
|
||||||
|
/node_modules\/(?!(browser-fs-access|canvas-roundrect-polyfill))/,
|
||||||
use: [
|
use: [
|
||||||
{
|
{
|
||||||
loader: "ts-loader",
|
loader: "ts-loader",
|
||||||
|
@ -46,7 +46,9 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.(ts|tsx|js|jsx|mjs)$/,
|
test: /\.(ts|tsx|js|jsx|mjs)$/,
|
||||||
exclude: /node_modules\/(?!browser-fs-access)/,
|
exclude:
|
||||||
|
/node_modules\/(?!(browser-fs-access|canvas-roundrect-polyfill))/,
|
||||||
|
|
||||||
use: [
|
use: [
|
||||||
{
|
{
|
||||||
loader: "ts-loader",
|
loader: "ts-loader",
|
||||||
|
@ -56,7 +56,7 @@ import {
|
|||||||
getLinkHandleFromCoords,
|
getLinkHandleFromCoords,
|
||||||
} from "../element/Hyperlink";
|
} from "../element/Hyperlink";
|
||||||
import { isLinearElement } from "../element/typeChecks";
|
import { isLinearElement } from "../element/typeChecks";
|
||||||
import "./roundRect.polyfill";
|
import "canvas-roundrect-polyfill";
|
||||||
|
|
||||||
export const DEFAULT_SPACING = 2;
|
export const DEFAULT_SPACING = 2;
|
||||||
|
|
||||||
|
@ -1,356 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
|
|
||||||
// source: https://github.com/Kaiido/roundRect/
|
|
||||||
// rewritten to remove globalThis and Nullish coalescing assignment operator
|
|
||||||
|
|
||||||
export {};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Implements the .roundRect() method of the CanvasPath mixin
|
|
||||||
* as introduced by https://github.com/whatwg/html/pull/6765
|
|
||||||
*/
|
|
||||||
(() => {
|
|
||||||
Path2D.prototype.roundRect ??= roundRect;
|
|
||||||
if (
|
|
||||||
typeof window !== "undefined" &&
|
|
||||||
window.CanvasRenderingContext2D &&
|
|
||||||
!window.CanvasRenderingContext2D.prototype.roundRect
|
|
||||||
) {
|
|
||||||
window.CanvasRenderingContext2D.prototype.roundRect = roundRect;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
typeof window !== "undefined" &&
|
|
||||||
window.OffscreenCanvasRenderingContext2D &&
|
|
||||||
!window.OffscreenCanvasRenderingContext2D.prototype.roundRect
|
|
||||||
) {
|
|
||||||
window.OffscreenCanvasRenderingContext2D.prototype.roundRect = roundRect;
|
|
||||||
}
|
|
||||||
|
|
||||||
function roundRect(x, y, w, h, radii) {
|
|
||||||
if (![x, y, w, h].every((input) => Number.isFinite(input))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
radii = parseRadiiArgument(radii);
|
|
||||||
|
|
||||||
let upperLeft;
|
|
||||||
let upperRight;
|
|
||||||
let lowerRight;
|
|
||||||
let lowerLeft;
|
|
||||||
|
|
||||||
if (radii.length === 4) {
|
|
||||||
upperLeft = toCornerPoint(radii[0]);
|
|
||||||
upperRight = toCornerPoint(radii[1]);
|
|
||||||
lowerRight = toCornerPoint(radii[2]);
|
|
||||||
lowerLeft = toCornerPoint(radii[3]);
|
|
||||||
} else if (radii.length === 3) {
|
|
||||||
upperLeft = toCornerPoint(radii[0]);
|
|
||||||
upperRight = toCornerPoint(radii[1]);
|
|
||||||
lowerLeft = toCornerPoint(radii[1]);
|
|
||||||
lowerRight = toCornerPoint(radii[2]);
|
|
||||||
} else if (radii.length === 2) {
|
|
||||||
upperLeft = toCornerPoint(radii[0]);
|
|
||||||
lowerRight = toCornerPoint(radii[0]);
|
|
||||||
upperRight = toCornerPoint(radii[1]);
|
|
||||||
lowerLeft = toCornerPoint(radii[1]);
|
|
||||||
} else if (radii.length === 1) {
|
|
||||||
upperLeft = toCornerPoint(radii[0]);
|
|
||||||
upperRight = toCornerPoint(radii[0]);
|
|
||||||
lowerRight = toCornerPoint(radii[0]);
|
|
||||||
lowerLeft = toCornerPoint(radii[0]);
|
|
||||||
} else {
|
|
||||||
throw new RangeError(
|
|
||||||
`${getErrorMessageHeader(this)} ${
|
|
||||||
radii.length
|
|
||||||
} is not a valid size for radii sequence.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const corners = [upperLeft, upperRight, lowerRight, lowerLeft];
|
|
||||||
const negativeCorner = corners.find(({ x, y }) => x < 0 || y < 0);
|
|
||||||
|
|
||||||
if (
|
|
||||||
corners.some(({ x, y }) => !Number.isFinite(x) || !Number.isFinite(y))
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (negativeCorner) {
|
|
||||||
throw new RangeError(
|
|
||||||
`${getErrorMessageHeader(
|
|
||||||
this,
|
|
||||||
)} Radius value ${negativeCorner} is negative.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fixOverlappingCorners(corners);
|
|
||||||
|
|
||||||
if (w < 0 && h < 0) {
|
|
||||||
this.moveTo(x - upperLeft.x, y);
|
|
||||||
this.ellipse(
|
|
||||||
x + w + upperRight.x,
|
|
||||||
y - upperRight.y,
|
|
||||||
upperRight.x,
|
|
||||||
upperRight.y,
|
|
||||||
0,
|
|
||||||
-Math.PI * 1.5,
|
|
||||||
-Math.PI,
|
|
||||||
);
|
|
||||||
this.ellipse(
|
|
||||||
x + w + lowerRight.x,
|
|
||||||
y + h + lowerRight.y,
|
|
||||||
lowerRight.x,
|
|
||||||
lowerRight.y,
|
|
||||||
0,
|
|
||||||
-Math.PI,
|
|
||||||
-Math.PI / 2,
|
|
||||||
);
|
|
||||||
this.ellipse(
|
|
||||||
x - lowerLeft.x,
|
|
||||||
y + h + lowerLeft.y,
|
|
||||||
lowerLeft.x,
|
|
||||||
lowerLeft.y,
|
|
||||||
0,
|
|
||||||
-Math.PI / 2,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
this.ellipse(
|
|
||||||
x - upperLeft.x,
|
|
||||||
y - upperLeft.y,
|
|
||||||
upperLeft.x,
|
|
||||||
upperLeft.y,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
-Math.PI / 2,
|
|
||||||
);
|
|
||||||
} else if (w < 0) {
|
|
||||||
this.moveTo(x - upperLeft.x, y);
|
|
||||||
this.ellipse(
|
|
||||||
x + w + upperRight.x,
|
|
||||||
y + upperRight.y,
|
|
||||||
upperRight.x,
|
|
||||||
upperRight.y,
|
|
||||||
0,
|
|
||||||
-Math.PI / 2,
|
|
||||||
-Math.PI,
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
this.ellipse(
|
|
||||||
x + w + lowerRight.x,
|
|
||||||
y + h - lowerRight.y,
|
|
||||||
lowerRight.x,
|
|
||||||
lowerRight.y,
|
|
||||||
0,
|
|
||||||
-Math.PI,
|
|
||||||
-Math.PI * 1.5,
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
this.ellipse(
|
|
||||||
x - lowerLeft.x,
|
|
||||||
y + h - lowerLeft.y,
|
|
||||||
lowerLeft.x,
|
|
||||||
lowerLeft.y,
|
|
||||||
0,
|
|
||||||
Math.PI / 2,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
this.ellipse(
|
|
||||||
x - upperLeft.x,
|
|
||||||
y + upperLeft.y,
|
|
||||||
upperLeft.x,
|
|
||||||
upperLeft.y,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
-Math.PI / 2,
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
} else if (h < 0) {
|
|
||||||
this.moveTo(x + upperLeft.x, y);
|
|
||||||
this.ellipse(
|
|
||||||
x + w - upperRight.x,
|
|
||||||
y - upperRight.y,
|
|
||||||
upperRight.x,
|
|
||||||
upperRight.y,
|
|
||||||
0,
|
|
||||||
Math.PI / 2,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
this.ellipse(
|
|
||||||
x + w - lowerRight.x,
|
|
||||||
y + h + lowerRight.y,
|
|
||||||
lowerRight.x,
|
|
||||||
lowerRight.y,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
-Math.PI / 2,
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
this.ellipse(
|
|
||||||
x + lowerLeft.x,
|
|
||||||
y + h + lowerLeft.y,
|
|
||||||
lowerLeft.x,
|
|
||||||
lowerLeft.y,
|
|
||||||
0,
|
|
||||||
-Math.PI / 2,
|
|
||||||
-Math.PI,
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
this.ellipse(
|
|
||||||
x + upperLeft.x,
|
|
||||||
y - upperLeft.y,
|
|
||||||
upperLeft.x,
|
|
||||||
upperLeft.y,
|
|
||||||
0,
|
|
||||||
-Math.PI,
|
|
||||||
-Math.PI * 1.5,
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
this.moveTo(x + upperLeft.x, y);
|
|
||||||
this.ellipse(
|
|
||||||
x + w - upperRight.x,
|
|
||||||
y + upperRight.y,
|
|
||||||
upperRight.x,
|
|
||||||
upperRight.y,
|
|
||||||
0,
|
|
||||||
-Math.PI / 2,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
this.ellipse(
|
|
||||||
x + w - lowerRight.x,
|
|
||||||
y + h - lowerRight.y,
|
|
||||||
lowerRight.x,
|
|
||||||
lowerRight.y,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
Math.PI / 2,
|
|
||||||
);
|
|
||||||
this.ellipse(
|
|
||||||
x + lowerLeft.x,
|
|
||||||
y + h - lowerLeft.y,
|
|
||||||
lowerLeft.x,
|
|
||||||
lowerLeft.y,
|
|
||||||
0,
|
|
||||||
Math.PI / 2,
|
|
||||||
Math.PI,
|
|
||||||
);
|
|
||||||
this.ellipse(
|
|
||||||
x + upperLeft.x,
|
|
||||||
y + upperLeft.y,
|
|
||||||
upperLeft.x,
|
|
||||||
upperLeft.y,
|
|
||||||
0,
|
|
||||||
Math.PI,
|
|
||||||
Math.PI * 1.5,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.closePath();
|
|
||||||
this.moveTo(x, y);
|
|
||||||
|
|
||||||
function toDOMPointInit(value) {
|
|
||||||
const { x, y, z, w } = value;
|
|
||||||
return { x, y, z, w };
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseRadiiArgument(value) {
|
|
||||||
// https://webidl.spec.whatwg.org/#es-union
|
|
||||||
// with 'optional (unrestricted double or DOMPointInit
|
|
||||||
// or sequence<(unrestricted double or DOMPointInit)>) radii = 0'
|
|
||||||
const type = typeof value;
|
|
||||||
|
|
||||||
if (type === "undefined" || value === null) {
|
|
||||||
return [0];
|
|
||||||
}
|
|
||||||
if (type === "function") {
|
|
||||||
return [NaN];
|
|
||||||
}
|
|
||||||
if (type === "object") {
|
|
||||||
if (typeof value[Symbol.iterator] === "function") {
|
|
||||||
return [...value].map((elem) => {
|
|
||||||
// https://webidl.spec.whatwg.org/#es-union
|
|
||||||
// with '(unrestricted double or DOMPointInit)'
|
|
||||||
const elemType = typeof elem;
|
|
||||||
if (elemType === "undefined" || elem === null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (elemType === "function") {
|
|
||||||
return NaN;
|
|
||||||
}
|
|
||||||
if (elemType === "object") {
|
|
||||||
return toDOMPointInit(elem);
|
|
||||||
}
|
|
||||||
return toUnrestrictedNumber(elem);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return [toDOMPointInit(value)];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [toUnrestrictedNumber(value)];
|
|
||||||
}
|
|
||||||
|
|
||||||
function toUnrestrictedNumber(value) {
|
|
||||||
return +value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function toCornerPoint(value) {
|
|
||||||
const asNumber = toUnrestrictedNumber(value);
|
|
||||||
if (Number.isFinite(asNumber)) {
|
|
||||||
return {
|
|
||||||
x: asNumber,
|
|
||||||
y: asNumber,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (Object(value) === value) {
|
|
||||||
return {
|
|
||||||
x: toUnrestrictedNumber(value.x ?? 0),
|
|
||||||
y: toUnrestrictedNumber(value.y ?? 0),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
x: NaN,
|
|
||||||
y: NaN,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function fixOverlappingCorners(corners) {
|
|
||||||
const [upperLeft, upperRight, lowerRight, lowerLeft] = corners;
|
|
||||||
const factors = [
|
|
||||||
Math.abs(w) / (upperLeft.x + upperRight.x),
|
|
||||||
Math.abs(h) / (upperRight.y + lowerRight.y),
|
|
||||||
Math.abs(w) / (lowerRight.x + lowerLeft.x),
|
|
||||||
Math.abs(h) / (upperLeft.y + lowerLeft.y),
|
|
||||||
];
|
|
||||||
const minFactor = Math.min(...factors);
|
|
||||||
if (minFactor <= 1) {
|
|
||||||
for (const radii of corners) {
|
|
||||||
radii.x *= minFactor;
|
|
||||||
radii.y *= minFactor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getErrorMessageHeader(instance) {
|
|
||||||
return `Failed to execute 'roundRect' on '${getConstructorName(
|
|
||||||
instance,
|
|
||||||
)}':`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getConstructorName(instance) {
|
|
||||||
if (typeof window === "undefined") {
|
|
||||||
return "UNKNOWN";
|
|
||||||
}
|
|
||||||
return Object(instance) === instance && instance instanceof Path2D
|
|
||||||
? "Path2D"
|
|
||||||
: instance instanceof window?.CanvasRenderingContext2D
|
|
||||||
? "CanvasRenderingContext2D"
|
|
||||||
: instance instanceof window?.OffscreenCanvasRenderingContext2D
|
|
||||||
? "OffscreenCanvasRenderingContext2D"
|
|
||||||
: instance?.constructor.name || instance;
|
|
||||||
}
|
|
||||||
})();
|
|
@ -3830,6 +3830,11 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001449, caniuse-lite@^1.0.30001464:
|
|||||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001478.tgz#0ef8a1cf8b16be47a0f9fc4ecfc952232724b32a"
|
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001478.tgz#0ef8a1cf8b16be47a0f9fc4ecfc952232724b32a"
|
||||||
integrity sha512-gMhDyXGItTHipJj2ApIvR+iVB5hd0KP3svMWWXDvZOmjzJJassGLMfxRkQCSYgGd2gtdL/ReeiyvMSFD1Ss6Mw==
|
integrity sha512-gMhDyXGItTHipJj2ApIvR+iVB5hd0KP3svMWWXDvZOmjzJJassGLMfxRkQCSYgGd2gtdL/ReeiyvMSFD1Ss6Mw==
|
||||||
|
|
||||||
|
canvas-roundrect-polyfill@0.0.1:
|
||||||
|
version "0.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/canvas-roundrect-polyfill/-/canvas-roundrect-polyfill-0.0.1.tgz#70bf107ebe2037f26d839d7f809a26f4a95f5696"
|
||||||
|
integrity sha512-yWq+R3U3jE+coOeEb3a3GgE2j/0MMiDKM/QpLb6h9ihf5fGY9UXtvK9o4vNqjWXoZz7/3EaSVU3IX53TvFFUOw==
|
||||||
|
|
||||||
case-sensitive-paths-webpack-plugin@^2.4.0:
|
case-sensitive-paths-webpack-plugin@^2.4.0:
|
||||||
version "2.4.0"
|
version "2.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4"
|
resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user