Fix code quality violations and exclude Manifest from checks
Document application modes (development/debug/production) Add global file drop handler, order column normalization, SPA hash fix Serve CDN assets via /_vendor/ URLs instead of merging into bundles Add production minification with license preservation Improve JSON formatting for debugging and production optimization Add CDN asset caching with CSS URL inlining for production builds Add three-mode system (development, debug, production) Update Manifest CLAUDE.md to reflect helper class architecture Refactor Manifest.php into helper classes for better organization Pre-manifest-refactor checkpoint: Add app_mode documentation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
386
node_modules/svgo/plugins/_path.js
generated
vendored
386
node_modules/svgo/plugins/_path.js
generated
vendored
@@ -1,28 +1,41 @@
|
||||
'use strict';
|
||||
import { parsePathData, stringifyPathData } from '../lib/path.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types').XastElement} XastElement
|
||||
* @typedef {import('../lib/types').PathDataItem} PathDataItem
|
||||
* @typedef Js2PathParams
|
||||
* @property {number=} floatPrecision
|
||||
* @property {boolean=} noSpaceAfterFlags
|
||||
*
|
||||
* @typedef Point
|
||||
* @property {number[][]} list
|
||||
* @property {number} minX
|
||||
* @property {number} minY
|
||||
* @property {number} maxX
|
||||
* @property {number} maxY
|
||||
*
|
||||
* @typedef Points
|
||||
* @property {Point[]} list
|
||||
* @property {number} minX
|
||||
* @property {number} minY
|
||||
* @property {number} maxX
|
||||
* @property {number} maxY
|
||||
*/
|
||||
|
||||
const { parsePathData, stringifyPathData } = require('../lib/path.js');
|
||||
|
||||
/**
|
||||
* @type {[number, number]}
|
||||
*/
|
||||
var prevCtrlPoint;
|
||||
/** @type {[number, number]} */
|
||||
let prevCtrlPoint;
|
||||
|
||||
/**
|
||||
* Convert path string to JS representation.
|
||||
*
|
||||
* @type {(path: XastElement) => Array<PathDataItem>}
|
||||
* @param {import('../lib/types.js').XastElement} path
|
||||
* @returns {import('../lib/types.js').PathDataItem[]}
|
||||
*/
|
||||
const path2js = (path) => {
|
||||
// @ts-ignore legacy
|
||||
if (path.pathJS) return path.pathJS;
|
||||
/**
|
||||
* @type {Array<PathDataItem>}
|
||||
*/
|
||||
export const path2js = (path) => {
|
||||
// @ts-expect-error legacy
|
||||
if (path.pathJS) {
|
||||
// @ts-expect-error legacy
|
||||
return path.pathJS;
|
||||
}
|
||||
/** @type {import('../lib/types.js').PathDataItem[]} */
|
||||
const pathData = []; // JS representation of the path data
|
||||
const newPathData = parsePathData(path.attributes.d);
|
||||
for (const { command, args } of newPathData) {
|
||||
@@ -32,25 +45,22 @@ const path2js = (path) => {
|
||||
if (pathData.length && pathData[0].command == 'm') {
|
||||
pathData[0].command = 'M';
|
||||
}
|
||||
// @ts-ignore legacy
|
||||
// @ts-expect-error legacy
|
||||
path.pathJS = pathData;
|
||||
return pathData;
|
||||
};
|
||||
exports.path2js = path2js;
|
||||
|
||||
/**
|
||||
* Convert relative Path data to absolute.
|
||||
*
|
||||
* @type {(data: Array<PathDataItem>) => Array<PathDataItem>}
|
||||
*
|
||||
* @param {ReadonlyArray<import('../lib/types.js').PathDataItem>} data
|
||||
* @returns {import('../lib/types.js').PathDataItem[]}
|
||||
*/
|
||||
const convertRelativeToAbsolute = (data) => {
|
||||
/**
|
||||
* @type {Array<PathDataItem>}
|
||||
*/
|
||||
/** @type {import('../lib/types.js').PathDataItem[]} */
|
||||
const newData = [];
|
||||
let start = [0, 0];
|
||||
let cursor = [0, 0];
|
||||
const start = [0, 0];
|
||||
const cursor = [0, 0];
|
||||
|
||||
for (let { command, args } of data) {
|
||||
args = args.slice();
|
||||
@@ -172,17 +182,15 @@ const convertRelativeToAbsolute = (data) => {
|
||||
return newData;
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef {{ floatPrecision?: number, noSpaceAfterFlags?: boolean }} Js2PathParams
|
||||
*/
|
||||
|
||||
/**
|
||||
* Convert path array to string.
|
||||
*
|
||||
* @type {(path: XastElement, data: Array<PathDataItem>, params: Js2PathParams) => void}
|
||||
* @param {import('../lib/types.js').XastElement} path
|
||||
* @param {ReadonlyArray<import('../lib/types.js').PathDataItem>} data
|
||||
* @param {Js2PathParams} params
|
||||
*/
|
||||
exports.js2path = function (path, data, params) {
|
||||
// @ts-ignore legacy
|
||||
export const js2path = function (path, data, params) {
|
||||
// @ts-expect-error legacy
|
||||
path.pathJS = data;
|
||||
|
||||
const pathData = [];
|
||||
@@ -211,7 +219,9 @@ exports.js2path = function (path, data, params) {
|
||||
};
|
||||
|
||||
/**
|
||||
* @type {(dest: Array<number>, source: Array<number>) => Array<number>}
|
||||
* @param {number[]} dest
|
||||
* @param {ReadonlyArray<number>} source
|
||||
* @returns {number[]}
|
||||
*/
|
||||
function set(dest, source) {
|
||||
dest[0] = source[source.length - 2];
|
||||
@@ -224,9 +234,11 @@ function set(dest, source) {
|
||||
* collision using Gilbert-Johnson-Keerthi distance algorithm
|
||||
* https://web.archive.org/web/20180822200027/http://entropyinteractive.com/2011/04/gjk-algorithm/
|
||||
*
|
||||
* @type {(path1: Array<PathDataItem>, path2: Array<PathDataItem>) => boolean}
|
||||
* @param {ReadonlyArray<import('../lib/types.js').PathDataItem>} path1
|
||||
* @param {ReadonlyArray<import('../lib/types.js').PathDataItem>} path2
|
||||
* @returns {boolean}
|
||||
*/
|
||||
exports.intersects = function (path1, path2) {
|
||||
export const intersects = function (path1, path2) {
|
||||
// Collect points of every subpath.
|
||||
const points1 = gatherPoints(convertRelativeToAbsolute(path1));
|
||||
const points2 = gatherPoints(convertRelativeToAbsolute(path2));
|
||||
@@ -247,8 +259,9 @@ exports.intersects = function (path1, path2) {
|
||||
);
|
||||
});
|
||||
})
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get a convex hull from points of each subpath. Has the most complexity O(n·log n).
|
||||
const hullNest1 = points1.list.map(convexHull);
|
||||
@@ -256,58 +269,72 @@ exports.intersects = function (path1, path2) {
|
||||
|
||||
// Check intersection of every subpath of the first path with every subpath of the second.
|
||||
return hullNest1.some(function (hull1) {
|
||||
if (hull1.list.length < 3) return false;
|
||||
if (hull1.list.length < 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return hullNest2.some(function (hull2) {
|
||||
if (hull2.list.length < 3) return false;
|
||||
if (hull2.list.length < 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var simplex = [getSupport(hull1, hull2, [1, 0])], // create the initial simplex
|
||||
direction = minus(simplex[0]); // set the direction to point towards the origin
|
||||
const simplex = [getSupport(hull1, hull2, [1, 0])]; // create the initial simplex
|
||||
const direction = minus(simplex[0]); // set the direction to point towards the origin
|
||||
|
||||
let iterations = 1e4; // infinite loop protection, 10 000 iterations is more than enough
|
||||
|
||||
var iterations = 1e4; // infinite loop protection, 10 000 iterations is more than enough
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
if (iterations-- == 0) {
|
||||
console.error(
|
||||
'Error: infinite loop while processing mergePaths plugin.'
|
||||
'Error: infinite loop while processing mergePaths plugin.',
|
||||
);
|
||||
return true; // true is the safe value that means “do nothing with paths”
|
||||
}
|
||||
// add a new point
|
||||
simplex.push(getSupport(hull1, hull2, direction));
|
||||
// see if the new point was on the correct side of the origin
|
||||
if (dot(direction, simplex[simplex.length - 1]) <= 0) return false;
|
||||
if (dot(direction, simplex[simplex.length - 1]) <= 0) {
|
||||
return false;
|
||||
}
|
||||
// process the simplex
|
||||
if (processSimplex(simplex, direction)) return true;
|
||||
if (processSimplex(simplex, direction)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* @type {(a: Point, b: Point, direction: Array<number>) => Array<number>}
|
||||
* @param {Point} a
|
||||
* @param {Point} b
|
||||
* @param {ReadonlyArray<number>} direction
|
||||
* @returns {number[]}
|
||||
*/
|
||||
function getSupport(a, b, direction) {
|
||||
return sub(supportPoint(a, direction), supportPoint(b, minus(direction)));
|
||||
}
|
||||
|
||||
// Computes farthest polygon point in particular direction.
|
||||
// Thanks to knowledge of min/max x and y coordinates we can choose a quadrant to search in.
|
||||
// Since we're working on convex hull, the dot product is increasing until we find the farthest point.
|
||||
/**
|
||||
* @type {(polygon: Point, direction: Array<number>) => Array<number>}
|
||||
* Computes farthest polygon point in particular direction. Thanks to
|
||||
* knowledge of min/max x and y coordinates we can choose a quadrant to search
|
||||
* in. Since we're working on convex hull, the dot product is increasing until
|
||||
* we find the farthest point.
|
||||
*
|
||||
* @param {Point} polygon
|
||||
* @param {ReadonlyArray<number>} direction
|
||||
* @returns {number[]}
|
||||
*/
|
||||
function supportPoint(polygon, direction) {
|
||||
var index =
|
||||
direction[1] >= 0
|
||||
? direction[0] < 0
|
||||
? polygon.maxY
|
||||
: polygon.maxX
|
||||
: direction[0] < 0
|
||||
let index =
|
||||
direction[1] >= 0
|
||||
? direction[0] < 0
|
||||
? polygon.maxY
|
||||
: polygon.maxX
|
||||
: direction[0] < 0
|
||||
? polygon.minX
|
||||
: polygon.minY,
|
||||
max = -Infinity,
|
||||
value;
|
||||
: polygon.minY;
|
||||
let max = -Infinity;
|
||||
let value;
|
||||
while ((value = dot(polygon.list[index], direction)) > max) {
|
||||
max = value;
|
||||
index = ++index % polygon.list.length;
|
||||
@@ -317,16 +344,18 @@ exports.intersects = function (path1, path2) {
|
||||
};
|
||||
|
||||
/**
|
||||
* @type {(simplex: Array<Array<number>>, direction: Array<number>) => boolean}
|
||||
* @param {number[][]} simplex
|
||||
* @param {number[]} direction
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function processSimplex(simplex, direction) {
|
||||
// we only need to handle to 1-simplex and 2-simplex
|
||||
if (simplex.length == 2) {
|
||||
// 1-simplex
|
||||
let a = simplex[1],
|
||||
b = simplex[0],
|
||||
AO = minus(simplex[1]),
|
||||
AB = sub(b, a);
|
||||
const a = simplex[1];
|
||||
const b = simplex[0];
|
||||
const AO = minus(simplex[1]);
|
||||
const AB = sub(b, a);
|
||||
// AO is in the same direction as AB
|
||||
if (dot(AO, AB) > 0) {
|
||||
// get the vector perpendicular to AB facing O
|
||||
@@ -338,14 +367,14 @@ function processSimplex(simplex, direction) {
|
||||
}
|
||||
} else {
|
||||
// 2-simplex
|
||||
let a = simplex[2], // [a, b, c] = simplex
|
||||
b = simplex[1],
|
||||
c = simplex[0],
|
||||
AB = sub(b, a),
|
||||
AC = sub(c, a),
|
||||
AO = minus(a),
|
||||
ACB = orth(AB, AC), // the vector perpendicular to AB facing away from C
|
||||
ABC = orth(AC, AB); // the vector perpendicular to AC facing away from B
|
||||
const a = simplex[2]; // [a, b, c] = simplex
|
||||
const b = simplex[1];
|
||||
const c = simplex[0];
|
||||
const AB = sub(b, a);
|
||||
const AC = sub(c, a);
|
||||
const AO = minus(a);
|
||||
const ACB = orth(AB, AC); // the vector perpendicular to AB facing away from C
|
||||
const ABC = orth(AC, AB); // the vector perpendicular to AC facing away from B
|
||||
|
||||
if (dot(ACB, AO) > 0) {
|
||||
if (dot(AB, AO) > 0) {
|
||||
@@ -368,72 +397,62 @@ function processSimplex(simplex, direction) {
|
||||
simplex.splice(0, 2); // simplex = [a]
|
||||
}
|
||||
} // region 7
|
||||
else return true;
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {(v: Array<number>) => Array<number>}
|
||||
* @param {ReadonlyArray<number>} v
|
||||
* @returns {number[]}
|
||||
*/
|
||||
function minus(v) {
|
||||
return [-v[0], -v[1]];
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {(v1: Array<number>, v2: Array<number>) => Array<number>}
|
||||
* @param {ReadonlyArray<number>} v1
|
||||
* @param {ReadonlyArray<number>} v2
|
||||
* @returns {number[]}
|
||||
*/
|
||||
function sub(v1, v2) {
|
||||
return [v1[0] - v2[0], v1[1] - v2[1]];
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {(v1: Array<number>, v2: Array<number>) => number}
|
||||
* @param {ReadonlyArray<number>} v1
|
||||
* @param {ReadonlyArray<number>} v2
|
||||
* @returns {number}
|
||||
*/
|
||||
function dot(v1, v2) {
|
||||
return v1[0] * v2[0] + v1[1] * v2[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {(v1: Array<number>, v2: Array<number>) => Array<number>}
|
||||
* @param {ReadonlyArray<number>} v
|
||||
* @param {ReadonlyArray<number>} from
|
||||
* @returns {number[]}
|
||||
*/
|
||||
function orth(v, from) {
|
||||
var o = [-v[1], v[0]];
|
||||
const o = [-v[1], v[0]];
|
||||
return dot(o, minus(from)) < 0 ? minus(o) : o;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* list: Array<Array<number>>,
|
||||
* minX: number,
|
||||
* minY: number,
|
||||
* maxX: number,
|
||||
* maxY: number
|
||||
* }} Point
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* list: Array<Point>,
|
||||
* minX: number,
|
||||
* minY: number,
|
||||
* maxX: number,
|
||||
* maxY: number
|
||||
* }} Points
|
||||
*/
|
||||
|
||||
/**
|
||||
* @type {(pathData: Array<PathDataItem>) => Points}
|
||||
* @param {ReadonlyArray<import('../lib/types.js').PathDataItem>} pathData
|
||||
* @returns {Points}
|
||||
*/
|
||||
function gatherPoints(pathData) {
|
||||
/**
|
||||
* @type {Points}
|
||||
*/
|
||||
/** @type {Points} */
|
||||
const points = { list: [], minX: 0, minY: 0, maxX: 0, maxY: 0 };
|
||||
|
||||
// Writes data about the extreme points on each axle
|
||||
/**
|
||||
* @type {(path: Point, point: Array<number>) => void}
|
||||
* Writes data about the extreme points on each axle.
|
||||
*
|
||||
* @param {Point} path
|
||||
* @param {number[]} point
|
||||
*/
|
||||
const addPoint = (path, point) => {
|
||||
if (!path.list.length || point[1] > path.list[path.maxY][1]) {
|
||||
@@ -469,15 +488,17 @@ function gatherPoints(pathData) {
|
||||
points.list.length === 0
|
||||
? { list: [], minX: 0, minY: 0, maxX: 0, maxY: 0 }
|
||||
: points.list[points.list.length - 1];
|
||||
let prev = i === 0 ? null : pathData[i - 1];
|
||||
const prev = i === 0 ? null : pathData[i - 1];
|
||||
let basePoint =
|
||||
subPath.list.length === 0 ? null : subPath.list[subPath.list.length - 1];
|
||||
let data = pathDataItem.args;
|
||||
const data = pathDataItem.args;
|
||||
let ctrlPoint = basePoint;
|
||||
|
||||
// TODO fix null hack
|
||||
/**
|
||||
* @type {(n: number, i: number) => number}
|
||||
* TODO fix null hack
|
||||
* @param {number} n
|
||||
* @param {number} i
|
||||
* @returns {number}
|
||||
*/
|
||||
const toAbsolute = (n, i) => n + (basePoint == null ? 0 : basePoint[i % 2]);
|
||||
|
||||
@@ -521,7 +542,7 @@ function gatherPoints(pathData) {
|
||||
|
||||
case 'C':
|
||||
if (basePoint != null) {
|
||||
// Approximate quibic Bezier curve with middle points between control points
|
||||
// Approximate cubic Bezier curve with middle points between control points
|
||||
addPoint(subPath, [
|
||||
0.5 * (basePoint[0] + data[0]),
|
||||
0.5 * (basePoint[1] + data[1]),
|
||||
@@ -568,9 +589,9 @@ function gatherPoints(pathData) {
|
||||
|
||||
case 'A':
|
||||
if (basePoint != null) {
|
||||
// Convert the arc to bezier curves and use the same approximation
|
||||
// @ts-ignore no idea what's going on here
|
||||
var curves = a2c.apply(0, basePoint.concat(data));
|
||||
// Convert the arc to Bézier curves and use the same approximation
|
||||
// @ts-expect-error no idea what's going on here
|
||||
const curves = a2c.apply(0, basePoint.concat(data));
|
||||
for (
|
||||
var cData;
|
||||
(cData = curves.splice(0, 6).map(toAbsolute)).length;
|
||||
@@ -590,33 +611,39 @@ function gatherPoints(pathData) {
|
||||
0.5 * (cData[2] + cData[4]),
|
||||
0.5 * (cData[3] + cData[5]),
|
||||
]);
|
||||
if (curves.length) addPoint(subPath, (basePoint = cData.slice(-2)));
|
||||
if (curves.length) {
|
||||
addPoint(subPath, (basePoint = cData.slice(-2)));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Save final command coordinates
|
||||
if (data.length >= 2) addPoint(subPath, data.slice(-2));
|
||||
if (data.length >= 2) {
|
||||
addPoint(subPath, data.slice(-2));
|
||||
}
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forms a convex hull from set of points of every subpath using monotone chain convex hull algorithm.
|
||||
* https://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain
|
||||
* Forms a convex hull from set of points of every subpath using monotone chain
|
||||
* convex hull algorithm.
|
||||
*
|
||||
* @type {(points: Point) => Point}
|
||||
* @see https://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain
|
||||
* @param {Point} points
|
||||
* @returns {Point}
|
||||
*/
|
||||
function convexHull(points) {
|
||||
points.list.sort(function (a, b) {
|
||||
return a[0] == b[0] ? a[1] - b[1] : a[0] - b[0];
|
||||
});
|
||||
|
||||
var lower = [],
|
||||
minY = 0,
|
||||
bottom = 0;
|
||||
const lower = [];
|
||||
let minY = 0;
|
||||
let bottom = 0;
|
||||
for (let i = 0; i < points.list.length; i++) {
|
||||
while (
|
||||
lower.length >= 2 &&
|
||||
@@ -632,9 +659,9 @@ function convexHull(points) {
|
||||
lower.push(points.list[i]);
|
||||
}
|
||||
|
||||
var upper = [],
|
||||
maxY = points.list.length - 1,
|
||||
top = 0;
|
||||
const upper = [];
|
||||
let maxY = points.list.length - 1;
|
||||
let top = 0;
|
||||
for (let i = points.list.length; i--; ) {
|
||||
while (
|
||||
upper.length >= 2 &&
|
||||
@@ -656,9 +683,7 @@ function convexHull(points) {
|
||||
|
||||
const hullList = lower.concat(upper);
|
||||
|
||||
/**
|
||||
* @type {Point}
|
||||
*/
|
||||
/** @type {Point} */
|
||||
const hull = {
|
||||
list: hullList,
|
||||
minX: 0, // by sorting
|
||||
@@ -671,28 +696,30 @@ function convexHull(points) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {(o: Array<number>, a: Array<number>, b: Array<number>) => number}
|
||||
* @param {ReadonlyArray<number>} o
|
||||
* @param {ReadonlyArray<number>} a
|
||||
* @param {ReadonlyArray<number>} b
|
||||
* @returns {number}
|
||||
*/
|
||||
function cross(o, a, b) {
|
||||
return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Based on code from Snap.svg (Apache 2 license). http://snapsvg.io/
|
||||
* Thanks to Dmitry Baranovskiy for his great work!
|
||||
* Based on code from [Snap.svg](http://snapsvg.io/) (Apache 2 license). Thanks
|
||||
* to Dmitry Baranovskiy for his great work!
|
||||
*
|
||||
* @type {(
|
||||
* x1: number,
|
||||
* y1: number,
|
||||
* rx: number,
|
||||
* ry: number,
|
||||
* angle: number,
|
||||
* large_arc_flag: number,
|
||||
* sweep_flag: number,
|
||||
* x2: number,
|
||||
* y2: number,
|
||||
* recursive: Array<number>
|
||||
* ) => Array<number>}
|
||||
* @param {number} x1
|
||||
* @param {number} y1
|
||||
* @param {number} rx
|
||||
* @param {number} ry
|
||||
* @param {number} angle
|
||||
* @param {number} large_arc_flag
|
||||
* @param {number} sweep_flag
|
||||
* @param {number} x2
|
||||
* @param {number} y2
|
||||
* @param {ReadonlyArray<number>} recursive
|
||||
* @returns {number[]}
|
||||
*/
|
||||
const a2c = (
|
||||
x1,
|
||||
@@ -704,24 +731,29 @@ const a2c = (
|
||||
sweep_flag,
|
||||
x2,
|
||||
y2,
|
||||
recursive
|
||||
recursive,
|
||||
) => {
|
||||
// for more information of where this Math came from visit:
|
||||
// https://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
|
||||
const _120 = (Math.PI * 120) / 180;
|
||||
const rad = (Math.PI / 180) * (+angle || 0);
|
||||
/**
|
||||
* @type {Array<number>}
|
||||
*/
|
||||
/** @type {number[]} */
|
||||
let res = [];
|
||||
/**
|
||||
* @type {(x: number, y: number, rad: number) => number}
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
* @param {number} rad
|
||||
* @returns {number}
|
||||
*/
|
||||
const rotateX = (x, y, rad) => {
|
||||
return x * Math.cos(rad) - y * Math.sin(rad);
|
||||
};
|
||||
|
||||
/**
|
||||
* @type {(x: number, y: number, rad: number) => number}
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
* @param {number} rad
|
||||
* @returns {number}
|
||||
*/
|
||||
const rotateY = (x, y, rad) => {
|
||||
return x * Math.sin(rad) + y * Math.cos(rad);
|
||||
@@ -731,22 +763,22 @@ const a2c = (
|
||||
y1 = rotateY(x1, y1, -rad);
|
||||
x2 = rotateX(x2, y2, -rad);
|
||||
y2 = rotateY(x2, y2, -rad);
|
||||
var x = (x1 - x2) / 2,
|
||||
y = (y1 - y2) / 2;
|
||||
var h = (x * x) / (rx * rx) + (y * y) / (ry * ry);
|
||||
const x = (x1 - x2) / 2;
|
||||
const y = (y1 - y2) / 2;
|
||||
let h = (x * x) / (rx * rx) + (y * y) / (ry * ry);
|
||||
if (h > 1) {
|
||||
h = Math.sqrt(h);
|
||||
rx = h * rx;
|
||||
ry = h * ry;
|
||||
}
|
||||
var rx2 = rx * rx;
|
||||
var ry2 = ry * ry;
|
||||
var k =
|
||||
const rx2 = rx * rx;
|
||||
const ry2 = ry * ry;
|
||||
const k =
|
||||
(large_arc_flag == sweep_flag ? -1 : 1) *
|
||||
Math.sqrt(
|
||||
Math.abs(
|
||||
(rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x)
|
||||
)
|
||||
(rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x),
|
||||
),
|
||||
);
|
||||
var cx = (k * rx * y) / ry + (x1 + x2) / 2;
|
||||
var cy = (k * -ry * x) / rx + (y1 + y2) / 2;
|
||||
@@ -769,11 +801,11 @@ const a2c = (
|
||||
cx = recursive[2];
|
||||
cy = recursive[3];
|
||||
}
|
||||
var df = f2 - f1;
|
||||
let df = f2 - f1;
|
||||
if (Math.abs(df) > _120) {
|
||||
var f2old = f2,
|
||||
x2old = x2,
|
||||
y2old = y2;
|
||||
const f2old = f2;
|
||||
const x2old = x2;
|
||||
const y2old = y2;
|
||||
f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);
|
||||
x2 = cx + rx * Math.cos(f2);
|
||||
y2 = cy + ry * Math.sin(f2);
|
||||
@@ -785,27 +817,27 @@ const a2c = (
|
||||
]);
|
||||
}
|
||||
df = f2 - f1;
|
||||
var c1 = Math.cos(f1),
|
||||
s1 = Math.sin(f1),
|
||||
c2 = Math.cos(f2),
|
||||
s2 = Math.sin(f2),
|
||||
t = Math.tan(df / 4),
|
||||
hx = (4 / 3) * rx * t,
|
||||
hy = (4 / 3) * ry * t,
|
||||
m = [
|
||||
-hx * s1,
|
||||
hy * c1,
|
||||
x2 + hx * s2 - x1,
|
||||
y2 - hy * c2 - y1,
|
||||
x2 - x1,
|
||||
y2 - y1,
|
||||
];
|
||||
const c1 = Math.cos(f1);
|
||||
const s1 = Math.sin(f1);
|
||||
const c2 = Math.cos(f2);
|
||||
const s2 = Math.sin(f2);
|
||||
const t = Math.tan(df / 4);
|
||||
const hx = (4 / 3) * rx * t;
|
||||
const hy = (4 / 3) * ry * t;
|
||||
const m = [
|
||||
-hx * s1,
|
||||
hy * c1,
|
||||
x2 + hx * s2 - x1,
|
||||
y2 - hy * c2 - y1,
|
||||
x2 - x1,
|
||||
y2 - y1,
|
||||
];
|
||||
if (recursive) {
|
||||
return m.concat(res);
|
||||
} else {
|
||||
res = m.concat(res);
|
||||
var newres = [];
|
||||
for (var i = 0, n = res.length; i < n; i++) {
|
||||
const newres = [];
|
||||
for (let i = 0, n = res.length; i < n; i++) {
|
||||
newres[i] =
|
||||
i % 2
|
||||
? rotateY(res[i - 1], res[i], rad)
|
||||
|
||||
Reference in New Issue
Block a user