svg-path-commander 2.0.9 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.cjs +1 -0
- package/README.md +4 -4
- package/dist/svg-path-commander.cjs +1 -1
- package/dist/svg-path-commander.cjs.map +1 -1
- package/dist/svg-path-commander.d.ts +156 -39
- package/dist/svg-path-commander.js +1 -1
- package/dist/svg-path-commander.js.map +1 -1
- package/dist/svg-path-commander.mjs +869 -705
- package/dist/svg-path-commander.mjs.map +1 -1
- package/package.json +22 -24
- package/src/convert/pathToAbsolute.ts +1 -1
- package/src/convert/pathToCurve.ts +1 -1
- package/src/convert/pathToRelative.ts +1 -1
- package/src/index.ts +30 -26
- package/src/interface.ts +32 -32
- package/src/math/arcTools.ts +217 -0
- package/src/math/bezier.ts +261 -0
- package/src/math/cubicTools.ts +81 -0
- package/src/math/lineTools.ts +52 -0
- package/src/math/quadTools.ts +79 -0
- package/src/parser/isMoveCommand.ts +17 -0
- package/src/parser/parsePathString.ts +1 -1
- package/src/parser/scanSegment.ts +12 -3
- package/src/process/normalizePath.ts +1 -1
- package/src/process/replaceArc.ts +52 -0
- package/src/process/splitPath.ts +1 -1
- package/src/process/transformPath.ts +14 -34
- package/src/types.ts +5 -0
- package/src/util/distanceEpsilon.ts +3 -0
- package/src/util/getClosestPoint.ts +1 -1
- package/src/util/getPathBBox.ts +4 -3
- package/src/util/getPointAtLength.ts +3 -3
- package/src/util/getPropertiesAtLength.ts +2 -1
- package/src/util/getPropertiesAtPoint.ts +4 -1
- package/src/util/getTotalLength.ts +2 -2
- package/src/util/isPointInStroke.ts +2 -1
- package/src/util/pathFactory.ts +130 -0
- package/src/util/shapeToPathArray.ts +8 -4
- package/test/class.test.ts +501 -0
- package/test/fixtures/getMarkup.ts +17 -0
- package/{cypress → test}/fixtures/shapes.js +18 -18
- package/{cypress → test}/fixtures/simpleShapes.js +6 -6
- package/test/static.test.ts +304 -0
- package/tsconfig.json +9 -4
- package/{vite.config.ts → vite.config.mts} +10 -1
- package/vitest.config-ui.mts +26 -0
- package/vitest.config.mts +26 -0
- package/cypress/e2e/svg-path-commander.spec.ts +0 -868
- package/cypress/plugins/esbuild-istanbul.ts +0 -50
- package/cypress/plugins/tsCompile.ts +0 -34
- package/cypress/support/commands.ts +0 -37
- package/cypress/support/e2e.ts +0 -21
- package/cypress/test.html +0 -36
- package/src/util/pathLengthFactory.ts +0 -114
- package/src/util/segmentArcFactory.ts +0 -219
- package/src/util/segmentCubicFactory.ts +0 -114
- package/src/util/segmentLineFactory.ts +0 -45
- package/src/util/segmentQuadFactory.ts +0 -109
- /package/{cypress/fixtures/shapeObjects.js → test/fixtures/shapeObjects.ts} +0 -0
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
// sources
|
|
2
|
-
// * https://github.com/enketo/enketo-express/blob/master/tools/esbuild-plugin-istanbul.js
|
|
3
|
-
'use strict';
|
|
4
|
-
import esbuild from 'esbuild';
|
|
5
|
-
import { promises } from 'fs';
|
|
6
|
-
import { createInstrumenter } from 'istanbul-lib-instrument';
|
|
7
|
-
import { extname, sep } from 'path';
|
|
8
|
-
import tsCompile from './tsCompile';
|
|
9
|
-
|
|
10
|
-
// import Cypress settings
|
|
11
|
-
const sourceFolder = 'src';
|
|
12
|
-
const [name] = process.cwd().split(sep).slice(-1);
|
|
13
|
-
|
|
14
|
-
const sourceFilter = `${name}${sep}${sourceFolder}`;
|
|
15
|
-
const instrumenter = createInstrumenter({
|
|
16
|
-
compact: false,
|
|
17
|
-
esModules: true,
|
|
18
|
-
preserveComments: true,
|
|
19
|
-
autoWrap: true,
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
const createEsbuildIstanbulPlugin = (): esbuild.Plugin => {
|
|
23
|
-
return {
|
|
24
|
-
name: 'istanbul',
|
|
25
|
-
setup(build: esbuild.PluginBuild) {
|
|
26
|
-
build.onLoad(
|
|
27
|
-
{ filter: /\.(ts|tsx)$/ },
|
|
28
|
-
async ({ path }: esbuild.OnLoadArgs): Promise<{ contents: string } & Record<string, any>> => {
|
|
29
|
-
|
|
30
|
-
if (!path.includes(sourceFilter)) {
|
|
31
|
-
// console.log("> compiling typescript %s for output build", path);
|
|
32
|
-
const contents = await promises.readFile(path, 'utf8');
|
|
33
|
-
return {
|
|
34
|
-
contents: ['.ts', '.tsx'].includes(extname(path)) ? tsCompile(path).outputText : contents,
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// console.log("🧡 instrumenting %s for output coverage", path);
|
|
39
|
-
const { outputText, sourceMap } = tsCompile(path);
|
|
40
|
-
|
|
41
|
-
return {
|
|
42
|
-
contents: instrumenter.instrumentSync(outputText, path, sourceMap),
|
|
43
|
-
};
|
|
44
|
-
},
|
|
45
|
-
);
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
export default createEsbuildIstanbulPlugin;
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
// compile.ts
|
|
2
|
-
import TypeScript from 'typescript';
|
|
3
|
-
import { basename } from 'path';
|
|
4
|
-
import { RawSourceMap } from 'source-map';
|
|
5
|
-
import { readFileSync } from 'fs';
|
|
6
|
-
|
|
7
|
-
export default function tsCompile(
|
|
8
|
-
path: string,
|
|
9
|
-
ops?: Partial<TypeScript.TranspileOptions>,
|
|
10
|
-
): TypeScript.TranspileOutput & { sourceMap: RawSourceMap } {
|
|
11
|
-
// Default options -- you could also perform a merge, or use the project tsconfig.json
|
|
12
|
-
const options: TypeScript.TranspileOptions = Object.assign(
|
|
13
|
-
{
|
|
14
|
-
compilerOptions: {
|
|
15
|
-
allowJs: true,
|
|
16
|
-
esModuleInterop: true,
|
|
17
|
-
removeComments: false,
|
|
18
|
-
target: 99, // ESNext
|
|
19
|
-
allowSyntheticDefaultImports: true,
|
|
20
|
-
isolatedModules: true,
|
|
21
|
-
noEmitHelpers: true,
|
|
22
|
-
sourceMap: true,
|
|
23
|
-
} as Partial<TypeScript.CompilerOptions>,
|
|
24
|
-
},
|
|
25
|
-
ops,
|
|
26
|
-
);
|
|
27
|
-
const contents = readFileSync(path, { encoding: 'utf8' });
|
|
28
|
-
const { outputText, sourceMapText } = TypeScript.transpileModule(contents, options);
|
|
29
|
-
const sourceMap: RawSourceMap = JSON.parse(sourceMapText || '');
|
|
30
|
-
sourceMap.file = basename(path);
|
|
31
|
-
sourceMap.sources = [basename(path)];
|
|
32
|
-
|
|
33
|
-
return { outputText, sourceMap, sourceMapText };
|
|
34
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/// <reference types="cypress" />
|
|
2
|
-
// ***********************************************
|
|
3
|
-
// This example commands.ts shows you how to
|
|
4
|
-
// create various custom commands and overwrite
|
|
5
|
-
// existing commands.
|
|
6
|
-
//
|
|
7
|
-
// For more comprehensive examples of custom
|
|
8
|
-
// commands please read more here:
|
|
9
|
-
// https://on.cypress.io/custom-commands
|
|
10
|
-
// ***********************************************
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
// -- This is a parent command --
|
|
14
|
-
// Cypress.Commands.add('login', (email, password) => { ... })
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
// -- This is a child command --
|
|
18
|
-
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
// -- This is a dual command --
|
|
22
|
-
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
// -- This will overwrite an existing command --
|
|
26
|
-
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
|
27
|
-
//
|
|
28
|
-
// declare global {
|
|
29
|
-
// namespace Cypress {
|
|
30
|
-
// interface Chainable {
|
|
31
|
-
// login(email: string, password: string): Chainable<void>
|
|
32
|
-
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
|
|
33
|
-
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
|
|
34
|
-
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
|
|
35
|
-
// }
|
|
36
|
-
// }
|
|
37
|
-
// }
|
package/cypress/support/e2e.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// ***********************************************************
|
|
2
|
-
// This example support/e2e.ts is processed and
|
|
3
|
-
// loaded automatically before your test files.
|
|
4
|
-
//
|
|
5
|
-
// This is a great place to put global configuration and
|
|
6
|
-
// behavior that modifies Cypress.
|
|
7
|
-
//
|
|
8
|
-
// You can change the location of this file or turn off
|
|
9
|
-
// automatically serving support files with the
|
|
10
|
-
// 'supportFile' configuration option.
|
|
11
|
-
//
|
|
12
|
-
// You can read more here:
|
|
13
|
-
// https://on.cypress.io/configuration
|
|
14
|
-
// ***********************************************************
|
|
15
|
-
|
|
16
|
-
// Import commands.js using ES2015 syntax:
|
|
17
|
-
import "./commands";
|
|
18
|
-
|
|
19
|
-
// Alternatively you can use CommonJS syntax:
|
|
20
|
-
// require('./commands')
|
|
21
|
-
import "@cypress/code-coverage/support";
|
package/cypress/test.html
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8">
|
|
5
|
-
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0">
|
|
7
|
-
<title>SVGPathCommander Path Tools</title>
|
|
8
|
-
<meta name="description" content="SVGPathCommander Path Tools">
|
|
9
|
-
<meta name="keywords" content="javascript,svg,svg path,svgpathcommander,path to absolute,path to relative, normalize path">
|
|
10
|
-
<meta name="author" content="thednp">
|
|
11
|
-
<link href="../docs/assets/style.css" rel="stylesheet">
|
|
12
|
-
<link rel="shortcut icon" href="./assets/favicon.ico">
|
|
13
|
-
<link rel="apple-touch-icon" href="./assets/apple-touch-icon.png">
|
|
14
|
-
</head>
|
|
15
|
-
<body>
|
|
16
|
-
<h1><a href="https://github.com/thednp/svg-path-commander">
|
|
17
|
-
<svg id="svg-path-commander" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1135 256" aria-label="SVGPathCommander - modern path processing tool" fill="currentColor">
|
|
18
|
-
<path id="svg_" fill="orangered" d="M222.7 102.2l-1.7 1.6c-7.6 -10 -20.4 -14.3 -32.6 -11.6c-12 2.6 -20.9 12.5 -23.7 24.2c-2.9 12.1 -0.1 25.8 9.3 34.4c9.2 8.4 23.5 10.5 34.9 5.9c6.2 -2.5 11.2 -7.3 14 -13.4c2.4 -5.5 2.9 -11.2 2.9 -17.1l0.6 0.5h-29.6l0 -2.2h31.3c0 11.9 -2.5 24.5 -13.1 31.5c-10.8 7.2 -27 6.8 -37.9 0c-11.3 -7.1 -16.2 -20.4 -15.5 -33.3c0.8 -13.3 8 -25.6 20.5 -30.9c7 -3 15 -3.5 22.4 -1.7c7.5 1.7 13.5 6.3 18.2 12.1zM46.1 148.7l1.8 -1.6c6.3 9.8 19.2 13.8 30.3 11.2C83.6 157 89 153.5 91.1 148.1c2.2 -5.5 0.5 -11.3 -4.1 -14.8c-4.5 -3.4 -10.3 -5 -15.6 -6.5c-5.8 -1.7 -11.6 -3.3 -16.6 -6.7c-4.9 -3.4 -7.2 -8.7 -6.5 -14.6C49 99.9 52.8 95.1 57.7 92.4C63.5 89.2 70.5 88.6 77 89.5c6.5 1 12 4.3 16 9.5l-1.7 1.5C87.7 96 83.3 93 77.6 91.9C72 90.8 65.9 91 60.8 93.3c-5 2.2 -9.3 6.4 -10.1 11.9c-0.9 6 1.9 11 6.9 14.1c5.2 3.3 11.4 4.3 17.2 6c5.5 1.6 11.8 3.8 15.8 8c4 4.2 4.8 10.3 2.6 15.7c-2.1 5 -6.6 8.6 -11.6 10.4c-12.3 4.6 -28 0.1 -35.5 -10.7zM130 160.2h-2.7l-26.8 -70h2.6c2.9 7.7 5.8 15.5 8.8 23.2c4.3 11.4 8.6 22.8 13 34.3c0.5 1.4 1.1 2.9 1.6 4.3c0.1 0.2 0.2 0.4 0.2 0.6c0.5 1.4 1 2.7 1.6 4.1c0.3 0.8 1 1.9 1 2.7H128c0 -0.5 0.7 -1.7 0.9 -2.2c0.6 -1.4 1.1 -2.7 1.6 -4.1c0.1 -0.2 0.2 -0.5 0.3 -0.7c0.4 -1.1 0.9 -2.3 1.3 -3.4c1.8 -4.8 3.6 -9.6 5.5 -14.4c4.6 -12 9.1 -23.9 13.7 -35.9c1.1 -2.8 2.2 -5.7 3.2 -8.5h2.6l-27.1 70z"/>
|
|
19
|
-
<path id="path-commander_" d="M628.2 158.3h-16.1l0 -53.1h15.2l0 6.8c3 -4.9 9.7 -7.7 15.2 -7.8c6.6 -0.1 13.5 2.8 15.9 9.3c0.7 -1.8 2.7 -3.4 4.2 -4.6c1.9 -1.5 4 -2.6 6.2 -3.5c4.4 -1.7 9.2 -1.9 13.7 -0.6c9 2.4 12.6 11.1 12.7 19.7c0.1 7.9 0 15.8 0 23.7c0 3.3 0 6.6 0 9.9H679c0 -10.3 0 -20.5 0 -30.8c0 -4.5 -1.5 -9.2 -6.6 -9.8c-5.6 -0.6 -10.7 3.2 -10.8 9c-0.1 5 0 10 0 14.9c0 5.5 0 11.1 0 16.6h-16.1c0 -10.3 0 -20.6 0 -30.8c0 -4.7 -1.8 -9.2 -7 -9.7c-5.4 -0.5 -10.3 3.3 -10.4 8.9c-0.1 5 0 10 0 15c0 5.7 0 11.3 0.1 16.9v0zM724.4 158.3h-16.1l0 -53.1h15.2c0 0.7 0.4 6.7 0.2 6.7c0.2 0 1.1 -1.4 1.2 -1.6c0.5 -0.5 1 -1.1 1.6 -1.5c1.2 -1 2.5 -1.8 3.9 -2.5c2.9 -1.4 6 -2.2 9.3 -2.1c3.2 0.1 6.5 0.8 9.2 2.5c1.3 0.8 2.5 1.8 3.4 3c0.4 0.4 2 3.8 2.3 3.8c0 0 1.5 -2.1 1.7 -2.3c0.7 -0.8 1.5 -1.6 2.4 -2.3c1.9 -1.5 4 -2.6 6.2 -3.5c4.4 -1.7 9.2 -1.9 13.7 -0.6c9 2.4 12.6 11.1 12.7 19.7c0.1 7.9 0 15.8 0 23.7c0 3.3 0 6.6 0 9.9h-16.1c0 -10.3 0 -20.5 0 -30.8c0 -4.5 -1.5 -9.2 -6.6 -9.8c-5.6 -0.6 -10.7 3.2 -10.8 9c-0.1 5 0 10 0 14.9c0 5.5 0 11.1 0 16.6h-16.1c0 -10.3 0 -20.6 0 -30.8c0 -4.7 -1.8 -9.2 -7 -9.7c-5.4 -0.5 -10.2 3.4 -10.3 8.9c-0.1 5 0 10 0 15.1c0 5.6 0 11.2 0 16.8v0zM415.2 158.3v-74h15.7c0 7.9 0 15.8 0 23.6c0 1.2 0.2 2.5 -0.1 3.7c3.1 -3.1 6.4 -5.5 10.7 -6.7c4.4 -1.2 9.4 -0.9 13.6 0.8c7.9 3.2 10 12.3 10.1 20c0 7.7 0 15.5 0 23.2c0 3.1 0 6.3 0 9.4h-16.1c0 -10.3 0 -20.7 0 -31c0 -4.7 -1.6 -9.2 -6.9 -9.7c-5.6 -0.6 -11.1 2.8 -11.2 8.8c-0.1 5 0 9.9 0 14.9c0 5.6 0 11.3 0 16.9c-5.3 0 -10.5 0 -15.8 0v0.1zM1047.8 130.9l-0.1 4.3H1011c-0.7 -3.1 -0.8 -5.9 0 -9c3.7 0 7.5 0 11.2 0c2.5 0 5 0 7.6 0c0.8 0 2.6 0.4 3.2 -0.1c-0.3 -5.1 -4.8 -8.4 -9.6 -8.6c-4.8 -0.2 -9.6 2 -11.6 6.5c-1.8 4.3 -1.8 9.3 0.1 13.6c1.8 4.1 5.7 6.6 9.9 7.4c2.7 0.6 5.8 0.6 8.5 0c2.9 -0.7 5.3 -2.3 7.6 -4l7.5 10.6c-7.9 6.7 -18.6 9.4 -28.7 7c-9.7 -2.3 -17.7 -9.1 -20.3 -18.8c-2.6 -9.5 -0.3 -20.7 6.6 -27.8c7.1 -7.3 18.4 -9.8 28 -6.5c5.1 1.7 9.4 5.1 12.4 9.6c1.3 2.1 2.4 4.3 3.1 6.7c0.4 1.5 0.8 3 1 4.6c0 1.5 0.5 2.9 0.3 4.5zM538.8 98.1L528.4 110c-4.7 -4.7 -10.4 -7.7 -17.2 -7.2c-6.4 0.4 -12.2 3.8 -15.3 9.5c-3.1 5.8 -3.4 13.1 -1.1 19.3c2.3 6.2 7.8 10.2 14.1 11.4c7.6 1.4 15.5 -0.6 20.9 -6.4l8.2 13c-3.6 4 -8.8 6.3 -13.9 7.8c-5.8 1.6 -11.8 2.2 -17.7 1.4c-10.9 -1.5 -20.8 -7.6 -26.1 -17.4C474.8 131.3 474.2 118 479 107.6c4.6 -10.1 13.8 -17.3 24.5 -19.7c6.6 -1.5 13.7 -1.4 20.1 0.6c2.9 0.9 5.8 2.1 8.4 3.8c1.3 0.8 2.6 1.8 3.8 2.8c1.1 0.8 2 2 3 3zM870.5 158.3v-53.1h15.2c0.1 2.1 0.3 4.3 0.3 6.4c0 -0.3 0.9 -1 1.1 -1.2c0.8 -0.8 1.7 -1.6 2.7 -2.3c1.8 -1.3 3.8 -2.3 5.9 -3c4.4 -1.5 9.3 -1.4 13.7 0c8.7 2.9 11.1 12.2 11.2 20.4c0 7.7 0 15.4 0 23.1c0 3.2 0 6.3 0 9.5h-16.1c0 -10.3 0 -20.6 0 -30.9c0 -4.7 -1.6 -9.2 -6.9 -9.7c-5.6 -0.6 -11.1 2.8 -11.2 8.8c-0.1 5 0 9.9 0 14.9c0 5.6 0 11.3 0 16.9c-5.3 0 -10.5 0 -15.8 0v0.2zM969.8 110.5V84.3h16.1l0 74H971c-0.1 -1.1 -0.2 -2.2 -0.2 -3.4c0 -0.6 -0.5 -2.2 0 -2.7c-2.7 2.7 -5.4 4.8 -9.1 6c-3.9 1.2 -7.9 1.6 -11.9 0.8c-7.2 -1.3 -13 -6.5 -16.2 -13c-6.7 -14 -2.6 -35.5 13.6 -40.9c4.1 -1.4 8.6 -1.5 12.8 -0.4c2 0.5 4 1.3 5.8 2.4c1 0.6 1.9 1.2 2.7 2c0.3 0.3 1.2 1.4 1.3 1.4zM345.4 111.1v-5.9h15.9l0 53.1h-16.2c0 -0.7 0.4 -6.2 0.1 -6.3c-0.3 -0.1 -3.1 2.8 -3.5 3.1c-1.6 1.2 -3.3 2.1 -5.1 2.8c-3.6 1.3 -7.4 1.7 -11.2 1C318 157.7 312 152.5 308.8 145.8c-6.7 -13.9 -2.7 -35 13.3 -40.5c4.2 -1.5 8.8 -1.5 13.1 -0.4c2 0.5 4 1.3 5.7 2.5c1 0.7 1.9 1.4 2.7 2.3c0.5 0.3 1.1 1.4 1.8 1.4zM840.5 111.4v-6.1h15.9l0 53.1h-16.2l0 -6.7c0.3 0.9 -2.7 3 -3.4 3.5c-1.6 1.2 -3.3 2.1 -5.1 2.8c-3.6 1.3 -7.4 1.7 -11.2 1c-7.4 -1.2 -13.4 -6.4 -16.6 -13.1c-6.7 -13.9 -2.7 -35 13.3 -40.5c4.2 -1.5 8.8 -1.5 13.1 -0.4c2 0.5 4 1.3 5.7 2.5c0.9 0.6 1.8 1.3 2.6 2.1c0.5 0.5 1.4 2 1.9 2.2c0.1 -0.1 0 -0.4 0 -0.4zM263 158.3h-17l0 -70c9.9 0 19.9 0 29.8 0c4.6 0 9 1 12.9 3.5c4.8 3 8.3 7.8 9.7 13.3c3.1 11.9 -3.3 25.4 -15.4 28.9c-3.7 1.1 -7.6 0.9 -11.4 0.9c-2.9 0 -5.7 0 -8.6 0v23.4zM1074.1 158.3H1058l0 -53.1h15.2c0.1 1.4 0.1 2.9 0.2 4.3c0 1.2 0.3 2.7 0.1 3.9c4.3 -7.3 13.7 -11.3 21.8 -8.3l-4.4 17.7c-2.3 -1.7 -6 -1.9 -8.7 -1.4c-2.8 0.5 -5.1 2 -6.6 4.5c-1.4 2.4 -1.4 5.1 -1.4 7.7c0 6.3 0 12.6 0 18.9c0 1.9 0 3.9 0 5.8h-0.1zM564.8 158.3c-11.5 -3.1 -20.1 -13 -20.5 -25.1c-0.2 -6.1 1.2 -12 4.6 -17c3.1 -4.5 7.5 -8 12.6 -10c10.9 -4.3 24.5 -2.1 32.8 6.4s10.1 22.6 4 32.9c-6.7 11.5 -20.9 16.1 -33.5 12.8zM395.8 158.3h-16c0 -8.6 0 -17.2 0 -25.8c0 -9.1 0 -18.2 0 -27.4c0 -4.5 0 -8.9 0 -13.4h16l0 66.6zM380.1 119.2h-9.7l0 -14h9.7l0 14zM958.2 146.1c6.1 0 10.4 -4.5 11.5 -10.2c1 -5.1 0.4 -11.3 -3.4 -15.1c-3.9 -3.9 -10.4 -4.5 -14.9 -1.3s-5.6 9.4 -5.1 14.6c0.6 6.4 5 12 11.9 12zM573.1 145.5c12.4 0 16.3 -17.3 7.9 -24.9c-4.1 -3.7 -10.5 -3.9 -15 -0.7c-4.5 3.3 -5.8 9.2 -5.1 14.4c0.8 6.3 5.8 11.2 12.2 11.2zM333.5 145.7c5.9 0 10.2 -3.8 11.6 -9.4c1.3 -5.3 0.5 -11.8 -3.5 -15.7c-3.9 -3.8 -10.7 -4 -15 -0.8c-4.4 3.3 -5.5 9.3 -4.9 14.4c0.7 6.4 5.2 11.5 11.8 11.5zM828.6 145.7c5.9 0 10.2 -3.8 11.6 -9.4c1.3 -5.3 0.5 -11.8 -3.5 -15.7c-3.9 -3.8 -10.7 -4 -15 -0.8c-4.4 3.3 -5.5 9.3 -4.9 14.4c0.7 6.4 5.2 11.5 11.8 11.5zM262.7 103.3V120c2.3 0 4.6 0 6.9 0c2.8 0 5.8 0.4 8.4 -1.2c4.4 -2.7 5.2 -9.7 1.5 -13.3c-2.5 -2.4 -5.6 -2.2 -8.8 -2.2c-0.6 0 -8 0 -8 0zM395.8 105.2h11.7l0 14h-11.7l0 -14z"/>
|
|
20
|
-
<path id="subtext_" fill-opacity="0.6" d="M253.2 190.3c0 -5 5.2 -8.8 10 -7.5c3.9 1 4.6 4.9 4.6 8.3c0 5.1 0 10.2 0 15.3c0 0.9 0 1.9 0 2.8c0 0.6 -0.1 0.5 0.4 0.7c1.1 0.3 2.8 0 3.9 0c0.4 0 1.9 0.2 2.1 0c0.2 -0.2 0 -1.4 0 -1.7c0 -1.2 0 -2.4 0 -3.5c0 -3 0 -5.9 0 -8.9c0 -1.7 0 -3.5 0 -5.2c0.1 -4.7 3.8 -7.9 8.4 -7.8c7.3 0.1 6.2 8.6 6.2 13.8c0 2.9 0 5.8 0 8.7c0 1.1 0 2.3 0 3.4c0 0.2 -0.1 1.1 0 1.2c0.3 0.3 2.5 0 2.9 0c0.7 0 1.4 0 2.1 0c0.2 0 1.1 0.1 1.3 0c0.4 -0.4 0.1 -3.4 0.1 -4c0 -5 0 -10.1 0 -15.1c0 -3.7 -0.4 -8 -3 -10.9c-3.5 -4 -9.4 -3.6 -13.7 -1.4c-2.3 1.2 -4.1 3 -5.4 5.1c-1.4 -4.2 -4.9 -6.6 -9.2 -6.8c-3.9 -0.2 -9.1 2 -11 5.7c0 -1.3 0 -2.6 0 -3.9s0.2 -1.3 -1.1 -1.3c-1.6 0 -3.1 0 -4.7 0c-0.7 0 -0.5 -0.1 -0.7 0.4c-0.2 0.6 0 1.5 0 2.2c0 1.2 0 2.3 0 3.5c0 3.2 0 6.5 0 9.7c0 5.4 0 10.7 0 16.1c0 0.3 -0.1 0.6 0.1 0.7c0.3 0.2 1.3 0 1.6 0c0.8 0 1.7 0 2.5 0c0.5 0 1.9 0.2 2.1 -0.1c0.3 -0.4 0 -1.9 0 -2.4c0 -3.6 0 -7.1 0 -10.7c0 -1.5 0 -3 0 -4.6c0.2 -0.6 -0.1 -1.9 0.5 -1.8zM410.6 190.7c-0.4 -6.8 -5.4 -12.7 -12.2 -13.9c-6.9 -1.2 -13.9 2.1 -17.2 8.3c-3.3 6.1 -2.7 14.4 2 19.7c4.5 5.1 11.7 6.6 18.1 4.9c1.9 -0.5 3.8 -1.3 5.5 -2.4c0.6 -0.4 1.7 -1 2.1 -1.6c0.4 -0.7 0.3 0 0.1 -0.6c-0.3 -0.8 -1.2 -1.7 -1.7 -2.4c-0.4 -0.6 -0.9 -1.2 -1.3 -1.8c-2.3 2 -4.9 3.5 -8.1 3.7c-2.9 0.2 -6 -0.4 -8.4 -2.2c-4.6 -3.5 -5.3 -11.8 -1.9 -16.4c3.4 -4.5 11.3 -4.5 14.8 -0.1c0.5 0.7 2.3 3.8 1.3 4.3c-0.7 0.3 -2.3 0 -3.1 0c-3.4 0 -6.8 0 -10.3 0c-1.2 0 -2.5 0 -3.7 0c-1 0 -0.9 0 -1.1 1.2c-0.1 0.5 -0.4 3.6 0.1 3.9c0.4 0.3 1.8 0 2.3 0c3.1 0 6.3 0 9.4 0c3.6 0 7.2 0 10.7 0c0.4 0 2 0.2 2.2 0c0.5 -0.4 0.4 -4.1 0.4 -4.6zM816.1 190.7c-0.4 -6.8 -5.4 -12.7 -12.2 -13.9c-6.9 -1.2 -13.9 2.1 -17.2 8.3c-3.3 6.1 -2.7 14.4 2 19.7c4.5 5.1 11.6 6.6 18.1 4.9c1.9 -0.5 3.8 -1.3 5.5 -2.4c0.6 -0.4 1.7 -1 2.1 -1.6c0.4 -0.7 0.3 0 0.1 -0.6c-0.3 -0.8 -1.2 -1.7 -1.7 -2.4c-0.4 -0.6 -0.9 -1.2 -1.3 -1.8c-3.2 2.8 -7 4.2 -11.3 3.6c-4.2 -0.6 -7.6 -3.3 -8.7 -7.5c-0.9 -3.5 -0.6 -8.3 1.8 -11.2c2.3 -2.9 6.9 -3.9 10.4 -2.9c2 0.6 3.9 2 4.9 3.8c0.5 1 0.5 2 0.9 3c0.1 0.2 -0.1 0.3 0.1 0.4c0.1 0.1 0.6 0 0.8 0c-3.4 0 -6.9 0 -10.3 0c-2.2 0 -4.4 0 -6.6 0c-0.5 0 -1.3 -0.2 -1.8 0s-0.4 0.5 -0.5 1.1c-0.1 0.8 -0.5 2.9 -0.1 3.7c0.2 0.4 0 0.2 0.5 0.3c1.4 0.3 3 0 4.4 0c4.7 0 9.5 0 14.2 0c1.6 0 3.6 0.3 5.1 0c0.6 -0.1 0.4 0.2 0.5 -0.6c0.1 -0.6 0 -1.2 0.1 -1.8c0.1 -0.7 0.3 -1.4 0.2 -2.1zM944.1 223c8.9 2.7 19.9 0.4 22.8 -9.5c1.1 -3.7 0.8 -7.6 0.8 -11.4c0 -5.1 0 -10.2 0 -15.2c0 -2.1 0 -4.3 0 -6.4c0 -0.5 0.3 -2.7 0 -3.1c-0.2 -0.2 -1.5 0 -1.9 0c-1.3 0 -2.7 -0.1 -4 0c-0.2 0 -0.5 -0.1 -0.6 0.1c-0.2 0.2 0 1.2 0 1.4c0 0.5 -0.3 2.7 0.1 2.9c-0.8 -0.6 -1.5 -1.5 -2.3 -2.1c-1.1 -0.8 -2.2 -1.5 -3.5 -2c-2.4 -1 -5.1 -1.3 -7.7 -0.9c-5.1 0.8 -9.3 4 -11.7 8.5c-4.8 9.1 -0.3 22.1 10.1 24.7c2.8 0.7 5.7 0.7 8.5 -0.3c2.4 -0.8 5.3 -2.5 6.5 -4.9c-0.2 0.3 0 1.3 0 1.7c0 0.7 0 1.5 0 2.2c0 2.7 -0.6 5.4 -2.7 7.3c-4.4 4.2 -13.4 3 -17.8 -0.6c-0.7 1.4 -1.3 2.7 -2 4.1c-0.5 1 -0.5 0.9 0.6 1.5c1.6 0.8 3.2 1.5 4.8 2zM600.4 209.8c0.6 0 1.2 0 1.8 0c0.6 0 2.4 0.3 2.9 0c0.3 -0.3 0.1 -1.9 0.1 -2.4c0 -4.3 0 -8.5 0 -12.8c0 -3.8 -0.5 -7.6 2.9 -10.2c2.6 -2.1 7.4 -2.9 10.3 -0.8c2.2 1.6 2.3 4.8 2.3 7.2c0 3.7 0 7.4 0 11c0 1.9 0 3.9 0 5.8c0 0.5 -0.2 2 0.1 2.2c0.4 0.3 1.9 0 2.4 0c1.1 0 2.1 0 3.2 0c1 0 0.7 -0.5 0.7 -1.5c0 -4 0 -8.1 0 -12.1c0 -4.3 0.6 -9.4 -1 -13.4c-3.5 -8.9 -15.9 -7.6 -20.8 -0.5c-0.1 -5.1 0 -10.2 0 -15.3c0 -0.7 0.3 -2.1 0 -2.8c-0.2 -0.5 -1.1 -0.3 -1.7 -0.3c-0.8 0 -1.5 0 -2.3 0c-0.6 0 -1.5 -0.2 -2 0s-0.2 -0.1 -0.4 0.4c-0.3 1.4 0 3.3 0 4.7c0 2.8 0 5.5 0 8.3c0 6.7 0 13.4 0 20c0 4.1 0 8.2 0 12.4c0.5 0.1 1 0.1 1.5 0.1zM444.1 209.8c0.6 0 1.3 0 1.9 0c0.5 0 2.3 0.3 2.8 0c0.3 -0.3 0.1 -1.9 0.1 -2.4c0 -4.3 0 -8.5 0 -12.8c0 -3.9 -0.4 -7.9 3.3 -10.5c2.7 -1.9 7.6 -2.6 10.2 -0.3c1.9 1.7 2 4.7 2 7.1c0 3.7 0 7.5 0 11.2c0 2 0 4 0 6c0 0.4 -0.2 1.2 0 1.5c0.2 0.4 -0.1 0.1 0.4 0.3c0.9 0.2 2 0 2.9 0c0.7 0 2.1 0.3 2.8 0c0.4 -0.2 0.1 0.1 0.3 -0.3c0.1 -0.4 0 -1.2 0 -1.6c0 -4.2 0 -8.4 0 -12.6c0 -3.7 0.4 -7.9 -0.7 -11.5c-1.1 -3.7 -3.6 -6.2 -7.4 -7c-4.1 -0.9 -8.2 0.4 -11.4 3c-0.8 0.6 -1.7 1.5 -2.2 2.4c0.2 -0.4 0 -1.4 0 -1.8c0 -0.8 0.3 -2.2 0 -2.9c-0.2 -0.4 0 -0.3 -0.7 -0.3c-1 0 -2 0 -2.9 0c-0.6 0 -2.5 -0.3 -2.8 0.2c-0.3 0.4 0 1.9 0 2.4c0 7.7 0 15.4 0 23.1c0 2.3 0 4.6 0 6.9c0.4 -0.1 0.9 -0.1 1.4 -0.1zM901.2 209.8c0.6 0 1.2 0 1.8 0c0.6 0 2.4 0.3 2.9 0c0.3 -0.3 0.1 -1.9 0.1 -2.4c0 -4.3 0 -8.5 0 -12.8c0 -4 -0.4 -7.9 3.3 -10.5c2.6 -1.8 7.2 -2.5 9.9 -0.5c2.2 1.6 2.3 4.8 2.3 7.2c0 3.7 0 7.4 0 11c0 2 0 4 0 6c0 0.6 -0.2 1.8 0.2 2.1c0.5 0.3 2 0 2.6 0c1 0 2.1 0.2 3.1 0c0.5 -0.1 0.3 0.1 0.5 -0.2c0.2 -0.2 0 -1.1 0 -1.3c0 -4.1 0 -8.3 0 -12.4c0 -4.4 0.5 -9.4 -1.2 -13.5c-1.8 -4.3 -5.9 -6.1 -10.4 -5.9c-4.2 0.2 -8.1 2.6 -10.4 6.1c0.7 -1.1 0.2 -3.4 0.2 -4.6c0 -0.6 0.1 -0.6 -0.2 -0.8c-0.5 -0.3 -2 0 -2.6 0s-3.3 -0.3 -3.6 0.1c-0.2 0.3 0 1.7 0 2.2c0 7.7 0 15.4 0 23.1c0 2.4 0 4.8 0 7.1c0.5 0 1 0 1.5 0zM366.1 181.3c-7.4 -7.4 -19.8 -5.6 -24.4 4c-4.2 8.8 -0.9 21.6 9.2 24.5c5.4 1.6 11.5 0.1 15.1 -4.4c0 1.1 0 2.3 0 3.4s-0.2 1.1 1 1.1c1.4 0 2.8 0 4.2 0c0.3 0 1.1 0.1 1.3 -0.1c0.4 -0.5 0 -2.6 0 -3.2c0 -2.2 0 -4.3 0 -6.5c0 -11 0 -22 0 -32.9c0 -0.5 0.3 -2.9 0 -3.2c-0.3 -0.3 -2.4 0 -2.8 0c-1.2 0 -2.4 0 -3.6 0c-0.1 5.7 0 11.9 0 17.3zM503.1 205.6c2.8 3.5 7.9 5.1 12.2 4.7c5 -0.5 9.2 -3.7 11.5 -8.1c4.6 -8.7 1.3 -21.9 -8.9 -24.8c-5.1 -1.4 -11.8 0 -14.9 4.6c0.1 -0.2 0 -0.7 0 -0.9c0 -0.8 0 -1.6 0 -2.4c0 -1.2 0.2 -1.2 -1 -1.2c-1.4 0 -2.8 0 -4.2 0c-0.4 0 -1.1 -0.1 -1.3 0.1c-0.4 0.5 0 2.6 0 3.1c0 2.2 0 4.4 0 6.6c0 11 0 22 0 33c0 0.5 -0.3 2.8 0 3.2c0.3 0.3 2.4 0 2.8 0c1.2 0 2.4 0 3.6 0c0 -3.1 0 -6.2 0 -9.3c0 -2.1 0 -4.1 0 -6.2c0.2 -0.5 0.4 -2.2 0.2 -2.4zM660.1 206.3c3.2 3.2 8.2 4.6 12.7 3.8c4.8 -0.9 8.8 -4.4 10.8 -8.9c3.9 -8.8 0.5 -21.3 -9.5 -24c-4.9 -1.3 -11.6 0.1 -14.6 4.7c0.2 -0.3 0 -1.4 0 -1.7c0 -0.5 0.3 -2.1 0 -2.6s-2.7 -0.2 -3.3 -0.2c-0.5 0 -2.8 -0.3 -3.1 0.1c-0.1 0.2 0 1.2 0 1.4c0 6.1 0 12.3 0 18.4c0 7.2 0 14.4 0 21.5c0 1.1 0 2.1 0 3.2c0 0.3 -0.2 1.2 0 1.5c0.3 0.3 2.3 0.1 2.8 0.1c0.6 0 3.2 0.4 3.6 0c0.3 -0.3 0 -2.8 0 -3.2c0 -2.1 0 -4.2 0 -6.3c0 -2 0 -4.1 0 -6.1c0 -0.6 -0.2 -1.7 0 -2.3c-0.2 0 0.6 0.6 0.6 0.6zM826.6 209c4.2 1.7 9.5 2.1 13.6 0c4.4 -2.2 6.3 -6.5 5.1 -11.2c-1.1 -4.5 -6.2 -6.1 -10.1 -7.2c-1.7 -0.5 -3.7 -0.9 -5.2 -1.9c-1.8 -1.2 -2.4 -4.1 -0.5 -5.5c3.8 -3 9.6 -0.2 12.6 2.8c0.9 -1 1.8 -2 2.7 -3c0.2 -0.2 0.9 -0.8 0.9 -1c0.1 -0.7 -2.3 -2.2 -2.8 -2.6c-5 -3.3 -12.6 -3.8 -17.4 0c-5 3.8 -4.2 11.2 1 14.4c2.6 1.6 5.4 2.2 8.3 3c2 0.6 5 1.4 5.3 3.9c0.4 3.2 -2.9 4.7 -5.6 4.7c-3.3 -0.1 -6.6 -1.3 -8.5 -4.1c-1.2 1.1 -2.4 2.1 -3.7 3.2c-0.1 0.1 -0.6 0.4 -0.6 0.5c-0.1 0.3 0.7 1 0.9 1.3c1 1.1 2.4 2.1 4 2.7zM856.2 209c4.2 1.7 9.5 2.1 13.6 0c4.4 -2.2 6.3 -6.5 5.1 -11.2c-1.1 -4.5 -6.2 -6.1 -10.1 -7.2c-1.7 -0.5 -3.7 -0.9 -5.2 -1.9c-1.8 -1.2 -2.4 -4.1 -0.5 -5.5c3.8 -3 9.6 -0.2 12.6 2.8c0.9 -1 1.8 -2 2.7 -3c0.2 -0.2 0.9 -0.8 0.9 -1c0.1 -0.7 -2.3 -2.2 -2.8 -2.6c-5 -3.3 -12.6 -3.8 -17.4 0c-5 3.8 -4.2 11.2 1 14.4c2.6 1.6 5.4 2.2 8.3 3c2 0.6 5 1.4 5.3 3.9c0.4 3.2 -2.9 4.7 -5.6 4.7c-3.3 -0.1 -6.6 -1.3 -8.5 -4.1c-1.2 1.1 -2.4 2.1 -3.7 3.2c-0.1 0.1 -0.6 0.4 -0.6 0.5c-0.1 0.3 0.7 1 0.9 1.3c1 1.1 2.4 2.1 4 2.7zM778.7 180.6c-4.4 -4 -11.7 -5 -17.1 -2.8c-5.6 2.3 -9 7.9 -9.7 13.8c-0.7 6.2 1.8 12.5 6.9 16.2s11.8 3.4 17.2 0.6c1.5 -0.8 2.9 -1.8 4 -3.1c0.8 -1 0.9 -0.9 0.2 -1.8c-1 -1.2 -1.9 -2.4 -2.9 -3.5c-2.6 3.9 -7.6 6 -12.1 4.5c-4.4 -1.5 -7.1 -5.9 -7.3 -10.4c-0.1 -4.4 2.2 -9.2 6.6 -10.7c4.8 -1.7 9.9 0.4 12.8 4.5c0.8 -1 1.6 -2 2.4 -3c0.2 -0.3 1 -0.9 1 -1.3c0.2 -0.9 -1.5 -2.5 -2 -3zM545.4 177c-10.4 2.6 -14.1 15.8 -9.7 24.7c2.1 4.3 5.8 7.8 10.6 8.6c5 0.8 10.5 -1.2 13.6 -5.3c0 1 -0.5 4.4 0.2 4.8s2.6 0 3.4 0c0.5 0 2.4 0.3 2.8 0c0.2 -0.2 0 -1.5 0 -1.8c0 -1.7 0 -3.3 0 -5c0 -4.7 0 -9.4 0 -14.1c0 -3.5 0 -7.1 0 -10.6c0 -1 0.1 -1 -1 -1c-1.8 0 -3.6 0 -5.4 0c0 1 0 1.9 0 2.9c0 0.5 -0.2 2.1 0 2.3c-3 -5 -9.1 -6.8 -14.5 -5.5zM424 191.9c0 -6 6.2 -10 11.7 -7.8c0.3 -1.1 0.5 -2.2 0.8 -3.3c0.2 -0.8 0.4 -1.6 0.6 -2.5c0.1 -0.2 0.4 -0.9 0.3 -1.1c-0.2 -0.4 -2.4 -0.6 -2.8 -0.6c-1.5 -0.1 -3.1 0.2 -4.5 0.8c-2.7 1.1 -5.2 3.4 -6.3 6.1c0.3 -0.8 0.1 -2.1 0.1 -3c0 -0.5 0.3 -3 0 -3.3c-0.1 -0.1 -1.1 0 -1.3 0c-0.8 0 -1.6 0 -2.3 0c-0.5 0 -2.5 -0.3 -2.8 0c-0.1 0.1 0 1.1 0 1.3c0 1 0 2 0 2.9c0 2.9 0 5.9 0 8.8c0 5.9 0 11.8 0 17.6c0 0.3 -0.2 1.3 0 1.6c0.2 0.3 1.2 0.2 1.6 0.2c0.8 0 1.5 0 2.3 0c0.6 0 1.6 0.2 2.2 0c0.5 -0.2 0.4 -0.2 0.4 -0.9c-0.1 -5.5 0 -11.2 0 -16.8zM698.4 191.9c0 -6 6.2 -10 11.7 -7.8c0.3 -1.1 0.5 -2.2 0.8 -3.3c0.2 -0.8 0.4 -1.6 0.6 -2.5c0.1 -0.2 0.4 -0.9 0.3 -1.1c-0.2 -0.4 -2.4 -0.6 -2.8 -0.6c-1.5 -0.1 -3.1 0.2 -4.5 0.8c-2.7 1.1 -5.1 3.5 -6.3 6.2c0.4 -0.8 0.1 -2.1 0.1 -3c0 -0.5 0.3 -3 0 -3.3c-0.1 -0.1 -1.1 0 -1.3 0c-0.8 0 -1.6 0 -2.4 0c-0.4 0 -2.3 -0.3 -2.6 0c-0.2 0.2 0 1.2 0 1.4c0 1 0 1.9 0 2.9c0 3 0 6 0 9c0 5.8 0 11.6 0 17.4c0 0.3 -0.2 1.4 0 1.7c0.2 0.3 1.3 0.1 1.7 0.1c0.8 0 1.5 0 2.3 0c0.6 0 1.5 0.2 2 0s0.4 -0.2 0.4 -1c0 -5.6 0 -11.3 0 -16.9zM313.4 209.7c6.6 2 14.1 -0.1 18.4 -5.6c4.3 -5.7 4.5 -14.1 0.7 -20c-3.8 -6 -11.1 -8.5 -17.9 -7c-6.8 1.5 -11.7 7.6 -12.4 14.4c-0.4 4 0.4 8.1 2.6 11.5c1.8 2.9 5.1 5.8 8.6 6.7zM725 209.7c6.6 1.9 14 0 18.2 -5.5c4.5 -5.7 4.6 -14.2 0.8 -20.2c-3.8 -5.9 -10.9 -8.5 -17.7 -7c-6.8 1.4 -11.7 7.2 -12.6 14c-0.9 7.7 3.4 16.5 11.3 18.7zM1026.9 209.7c6.6 2 14.1 -0.1 18.4 -5.6c4.3 -5.7 4.5 -14.1 0.7 -20c-3.8 -6 -11.1 -8.5 -17.9 -7c-6.8 1.5 -11.7 7.6 -12.4 14.4c-0.4 4 0.4 8.1 2.6 11.5c1.8 2.9 5.1 5.8 8.6 6.7zM1065 209.7c6.6 2 14.1 -0.1 18.4 -5.6c4.3 -5.7 4.5 -14.1 0.7 -20c-3.8 -6 -11.1 -8.5 -17.9 -7c-6.8 1.5 -11.7 7.6 -12.4 14.4c-0.4 4 0.4 8.1 2.6 11.5c1.8 2.9 5.1 5.8 8.6 6.7zM1100.1 164c-1.9 0 -3.8 0 -5.6 0c-0.9 0 -0.8 0 -0.8 0.9c0 3.1 0 6.1 0 9.2c0 9.5 0 19.1 0 28.6c0 1.6 0 3.2 0 4.8c0 0.4 -0.3 1.9 0 2.3c0.4 0.5 3.3 0.1 4 0.1c0.3 0 2.2 0.2 2.4 0c0.1 -0.1 0 -0.3 0 -0.4c0.3 -0.8 0 -2.1 0 -2.9c0 -1.7 0 -3.5 0 -5.2c0 -4.7 0 -9.5 0 -14.2c0 -7.5 0 -15.1 0 -22.6c0 -0.3 0 -0.5 0 -0.6zM585.4 169c-0.8 0 -1.7 0 -2.5 0c-1 0 -2.5 -0.3 -3.5 0c-0.6 0.2 -0.4 0.1 -0.4 0.9c0 1.2 0 2.5 0 3.7c0 1 0.2 2.2 0 3.3c-0.1 0.6 0 0.5 -0.8 0.5c-1.3 0 -2.5 0 -3.8 0c-0.3 0 -1.9 -0.2 -2.2 0c-0.3 0.3 0 2.6 0 3.1c0 1 0 2.1 0 3.1c2.3 0 4.5 0 6.8 0c0 4.3 0 8.7 0 13c0 3 0 6 0 9c0 1 0 2 0 3c0 0.2 -0.1 1.1 0 1.3c0.2 0.3 2.4 0 2.8 0c0.7 0 1.5 0 2.2 0c0.2 0 1.2 0.1 1.4 0c0.1 -0.1 0 -0.8 0 -0.9c0 -0.9 0 -1.9 0 -2.8c0 -6 0 -11.9 0 -17.9c0 -1.2 0 -2.4 0 -3.5c0 -0.2 -0.1 -1.1 0 -1.2c0.2 -0.1 1.1 0 1.3 0c0.9 0 1.7 0 2.6 0c1.2 0 2.4 0 3.6 0c0 -0.9 0 -1.7 0 -2.6c0 -0.7 0 -1.4 0 -2.1c0 -0.3 0.1 -1.1 0 -1.3c-0.2 -0.4 -0.7 -0.2 -1.3 -0.2c-1.3 0 -2.6 0 -3.9 0c-0.3 0 -2.1 0.2 -2.3 0c-0.2 -0.2 0 -1.8 0 -2.1c0 -2.2 0 -4.3 0 -6.3zM889.8 177.3c-1.4 0 -2.8 0 -4.1 0c-0.5 0 -2 -0.2 -2.3 0.1c-0.2 0.3 0 1.6 0 2c0 1.2 0 2.5 0 3.7c0 7.1 0 14.1 0 21.2c0 1.2 0 2.5 0 3.7c0 0.3 -0.2 1.5 0 1.8s2.2 0.1 2.7 0.1c0.8 0 1.7 0 2.5 0c0.1 0 1.2 0.1 1.3 0c0.1 -0.2 0 -1.1 0 -1.3c0 -1.1 0 -2.3 0 -3.4c0 -3.4 0 -6.9 0 -10.3c-0.1 -5.9 -0.1 -11.8 -0.1 -17.6zM951.3 204.6c-5.3 0 -9.6 -4.3 -10.2 -9.4c-0.5 -4.4 1 -8.9 4.9 -11.4c3.7 -2.4 9.2 -1.6 12.4 1.3c3.3 3 4.1 8.1 2.8 12.3c-1.4 4.3 -5.3 7.2 -9.9 7.2zM356.5 205c-5.4 0 -9.1 -4.5 -9.8 -9.6c-0.6 -4.3 0.7 -9.2 4.4 -11.8c3.6 -2.5 8.9 -2.1 11.9 1.1c6 6.4 3.7 20.3 -6.5 20.3zM322 204.1c-2.7 1 -5.3 1 -7.9 -0.2c-2 -1 -3.7 -2.8 -4.6 -4.9c-1.7 -3.9 -1.5 -9.2 1.2 -12.6c2.7 -3.5 7.4 -4.8 11.5 -3.2c8.5 3.2 8.7 17.9 -0.2 20.9zM733.6 204.1c-2.7 1 -5.3 1 -7.9 -0.2c-2 -1 -3.7 -2.8 -4.6 -4.9c-1.7 -3.9 -1.5 -9.2 1.2 -12.6c2.7 -3.5 7.4 -4.8 11.5 -3.2c8.5 3.2 8.7 17.9 -0.2 20.9zM1035.5 204.1c-2.7 1 -5.3 1 -7.9 -0.2c-2 -1 -3.7 -2.8 -4.6 -4.9c-1.7 -3.9 -1.5 -9.2 1.2 -12.6c2.7 -3.5 7.4 -4.8 11.5 -3.2c8.5 3.2 8.7 17.9 -0.2 20.9zM1073.6 204.1c-2.7 1 -5.3 1 -7.9 -0.2c-2 -1 -3.7 -2.8 -4.6 -4.9c-1.7 -3.9 -1.5 -9.2 1.2 -12.6c2.7 -3.5 7.4 -4.8 11.5 -3.2c8.5 3.2 8.7 17.9 -0.2 20.9zM559.9 195.4c-0.7 5.1 -4.5 9.2 -9.9 9.2c-9.7 0 -12.9 -13.1 -6.6 -19.4c3 -3 8.2 -3.5 11.8 -1.2c3.7 2.4 5.3 7.1 4.7 11.4zM512.8 204.5c-2.5 0 -4.7 -0.6 -6.6 -2.4c-1.8 -1.6 -2.8 -3.9 -3.3 -6.2c-0.8 -4.3 0.6 -8.9 4.2 -11.5c3.7 -2.7 9.1 -2.3 12.4 0.9c6.2 6.1 2.8 19.2 -6.7 19.2zM669 204.5c-2.5 0 -4.7 -0.6 -6.6 -2.4c-1.8 -1.6 -2.8 -3.9 -3.3 -6.2c-0.8 -4.3 0.6 -8.9 4.2 -11.5c3.7 -2.7 9.1 -2.3 12.4 0.9c6.2 6.1 2.8 19.2 -6.7 19.2zM887.9 170c2.5 -0.4 3.5 -3.5 2.7 -5.6s-3.3 -2.7 -5.3 -2.2c-2.4 0.5 -3.6 3.4 -2.7 5.6c0.8 2.1 3.3 2.6 5.3 2.2zM1004.5 169c-0.8 0 -1.7 0 -2.5 0c-1 0 -2.5 -0.3 -3.5 0c-0.6 0.2 -0.4 0.1 -0.4 0.9c0 1.2 0 2.5 0 3.7c0 1 0.2 2.2 0 3.3c-0.1 0.6 0 0.5 -0.8 0.5c-1.3 0 -2.5 0 -3.8 0c-0.3 0 -1.9 -0.2 -2.2 0c-0.3 0.3 0 2.6 0 3.1c0 1 0 2.1 0 3.1c2.3 0 4.5 0 6.8 0c0 4.3 0 8.7 0 13c0 3 0 6 0 9c0 1 0 2 0 3c0 0.2 -0.1 1.1 0 1.3c0.2 0.3 2.4 0 2.8 0c0.7 0 1.5 0 2.2 0c0.2 0 1.2 0.1 1.4 0c0.1 -0.1 0 -0.8 0 -0.9c0 -0.9 0 -1.9 0 -2.8c0 -6 0 -11.9 0 -17.9c0 -1.2 0 -2.4 0 -3.5c0 -0.2 -0.1 -1.1 0 -1.2c0.2 -0.1 1.1 0 1.3 0c0.9 0 1.7 0 2.6 0c1.2 0 2.4 0 3.6 0c0 -0.9 0 -1.7 0 -2.6c0 -0.7 0 -1.4 0 -2.1c0 -0.3 0.1 -1.1 0 -1.3c-0.2 -0.4 -0.7 -0.2 -1.3 -0.2c-1.3 0 -2.6 0 -3.9 0c-0.3 0 -2.1 0.2 -2.3 0c-0.2 -0.2 0 -1.8 0 -2.1c0 -2.2 0 -4.2 0 -6.3z"/>
|
|
21
|
-
</svg>
|
|
22
|
-
</a></h1>
|
|
23
|
-
|
|
24
|
-
<div class="row row-lg">
|
|
25
|
-
<div class="col col-md-4 mx-auto">
|
|
26
|
-
<div class="text-center">
|
|
27
|
-
<svg id="test-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
|
28
|
-
<path d="M0 0L0 0" fill="rgba(255,0,255,0.75)"></path>
|
|
29
|
-
</svg>
|
|
30
|
-
</div>
|
|
31
|
-
</div>
|
|
32
|
-
</div>
|
|
33
|
-
|
|
34
|
-
</body>
|
|
35
|
-
|
|
36
|
-
</html>
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import type { MSegment, PathArray } from '../types';
|
|
2
|
-
import type { LengthFactory } from '../interface';
|
|
3
|
-
import normalizePath from '../process/normalizePath';
|
|
4
|
-
import segmentLineFactory from './segmentLineFactory';
|
|
5
|
-
import segmentArcFactory from './segmentArcFactory';
|
|
6
|
-
import segmentCubicFactory from './segmentCubicFactory';
|
|
7
|
-
import segmentQuadFactory from './segmentQuadFactory';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Returns a {x,y} point at a given length
|
|
11
|
-
* of a shape, the shape total length and
|
|
12
|
-
* the shape minimum and maximum {x,y} coordinates.
|
|
13
|
-
*
|
|
14
|
-
* @param pathInput the `pathArray` to look into
|
|
15
|
-
* @param distance the length of the shape to look at
|
|
16
|
-
* @returns the path length, point, min & max
|
|
17
|
-
*/
|
|
18
|
-
const pathLengthFactory = (pathInput: string | PathArray, distance?: number): LengthFactory => {
|
|
19
|
-
const path = normalizePath(pathInput);
|
|
20
|
-
const distanceIsNumber = typeof distance === 'number';
|
|
21
|
-
let isM;
|
|
22
|
-
let data = [] as number[];
|
|
23
|
-
let pathCommand;
|
|
24
|
-
let x = 0;
|
|
25
|
-
let y = 0;
|
|
26
|
-
let mx = 0;
|
|
27
|
-
let my = 0;
|
|
28
|
-
let seg;
|
|
29
|
-
let MIN = [] as { x: number; y: number }[];
|
|
30
|
-
let MAX = [] as { x: number; y: number }[];
|
|
31
|
-
let length = 0;
|
|
32
|
-
let min = { x: 0, y: 0 };
|
|
33
|
-
let max = min;
|
|
34
|
-
let point = min;
|
|
35
|
-
let POINT = min;
|
|
36
|
-
let LENGTH = 0;
|
|
37
|
-
|
|
38
|
-
for (let i = 0, ll = path.length; i < ll; i += 1) {
|
|
39
|
-
seg = path[i];
|
|
40
|
-
[pathCommand] = seg;
|
|
41
|
-
isM = pathCommand === 'M';
|
|
42
|
-
data = !isM ? [x, y, ...(seg.slice(1) as number[])] : data;
|
|
43
|
-
|
|
44
|
-
// this segment is always ZERO
|
|
45
|
-
/* istanbul ignore else */
|
|
46
|
-
if (isM) {
|
|
47
|
-
// remember mx, my for Z
|
|
48
|
-
[, mx, my] = seg as MSegment;
|
|
49
|
-
min = { x: mx, y: my };
|
|
50
|
-
max = min;
|
|
51
|
-
length = 0;
|
|
52
|
-
|
|
53
|
-
if (distanceIsNumber && distance < 0.001) {
|
|
54
|
-
POINT = min;
|
|
55
|
-
}
|
|
56
|
-
} else if (pathCommand === 'L') {
|
|
57
|
-
({ length, min, max, point } = segmentLineFactory(
|
|
58
|
-
...(data as [number, number, number, number]),
|
|
59
|
-
(distance || 0) - LENGTH,
|
|
60
|
-
));
|
|
61
|
-
} else if (pathCommand === 'A') {
|
|
62
|
-
({ length, min, max, point } = segmentArcFactory(
|
|
63
|
-
...(data as [number, number, number, number, number, number, number, number, number]),
|
|
64
|
-
(distance || 0) - LENGTH,
|
|
65
|
-
));
|
|
66
|
-
} else if (pathCommand === 'C') {
|
|
67
|
-
({ length, min, max, point } = segmentCubicFactory(
|
|
68
|
-
...(data as [number, number, number, number, number, number, number]),
|
|
69
|
-
(distance || 0) - LENGTH,
|
|
70
|
-
));
|
|
71
|
-
} else if (pathCommand === 'Q') {
|
|
72
|
-
({ length, min, max, point } = segmentQuadFactory(
|
|
73
|
-
...(data as [number, number, number, number, number, number]),
|
|
74
|
-
(distance || 0) - LENGTH,
|
|
75
|
-
));
|
|
76
|
-
} else if (pathCommand === 'Z') {
|
|
77
|
-
data = [x, y, mx, my];
|
|
78
|
-
({ length, min, max, point } = segmentLineFactory(
|
|
79
|
-
...(data as [number, number, number, number]),
|
|
80
|
-
(distance || 0) - LENGTH,
|
|
81
|
-
));
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (distanceIsNumber && LENGTH < distance && LENGTH + length >= distance) {
|
|
85
|
-
POINT = point;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
MAX = [...MAX, max];
|
|
89
|
-
MIN = [...MIN, min];
|
|
90
|
-
LENGTH += length;
|
|
91
|
-
|
|
92
|
-
[x, y] = pathCommand !== 'Z' ? (seg.slice(-2) as [number, number]) : [mx, my];
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// native `getPointAtLength` behavior when the given distance
|
|
96
|
-
// is higher than total length
|
|
97
|
-
if (distanceIsNumber && distance >= LENGTH) {
|
|
98
|
-
POINT = { x, y };
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return {
|
|
102
|
-
length: LENGTH,
|
|
103
|
-
point: POINT,
|
|
104
|
-
min: {
|
|
105
|
-
x: Math.min(...MIN.map(n => n.x)),
|
|
106
|
-
y: Math.min(...MIN.map(n => n.y)),
|
|
107
|
-
},
|
|
108
|
-
max: {
|
|
109
|
-
x: Math.max(...MAX.map(n => n.x)),
|
|
110
|
-
y: Math.max(...MAX.map(n => n.y)),
|
|
111
|
-
},
|
|
112
|
-
};
|
|
113
|
-
};
|
|
114
|
-
export default pathLengthFactory;
|
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
import type { LengthFactory } from '../interface';
|
|
2
|
-
import segmentLineFactory from './segmentLineFactory';
|
|
3
|
-
import distanceSquareRoot from '../math/distanceSquareRoot';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Returns an angle value between two points.
|
|
7
|
-
*
|
|
8
|
-
* @param v0
|
|
9
|
-
* @param v1
|
|
10
|
-
* @returns a number representing an angle
|
|
11
|
-
*/
|
|
12
|
-
const angleBetween = (v0: { x: number; y: number }, v1: { x: number; y: number }): number => {
|
|
13
|
-
const { x: v0x, y: v0y } = v0;
|
|
14
|
-
const { x: v1x, y: v1y } = v1;
|
|
15
|
-
const p = v0x * v1x + v0y * v1y;
|
|
16
|
-
const n = Math.sqrt((v0x ** 2 + v0y ** 2) * (v1x ** 2 + v1y ** 2));
|
|
17
|
-
const sign = v0x * v1y - v0y * v1x < 0 ? -1 : 1;
|
|
18
|
-
const angle = sign * Math.acos(p / n);
|
|
19
|
-
|
|
20
|
-
return angle;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Returns a {x,y} point at a given length, the total length and
|
|
25
|
-
* the minimum and maximum {x,y} coordinates of a C (cubic-bezier) segment.
|
|
26
|
-
*
|
|
27
|
-
* @see https://github.com/MadLittleMods/svg-curve-lib/blob/master/src/js/svg-curve-lib.js
|
|
28
|
-
*
|
|
29
|
-
* @param x1 the starting x position
|
|
30
|
-
* @param y1 the starting y position
|
|
31
|
-
* @param RX x-radius of the arc
|
|
32
|
-
* @param RY y-radius of the arc
|
|
33
|
-
* @param angle x-axis-rotation of the arc
|
|
34
|
-
* @param LAF large-arc-flag of the arc
|
|
35
|
-
* @param SF sweep-flag of the arc
|
|
36
|
-
* @param x the ending x position
|
|
37
|
-
* @param y the ending y position
|
|
38
|
-
* @param t the point distance
|
|
39
|
-
* @returns the requested point
|
|
40
|
-
*/
|
|
41
|
-
const getPointAtArcSegmentLength = (
|
|
42
|
-
x1: number,
|
|
43
|
-
y1: number,
|
|
44
|
-
RX: number,
|
|
45
|
-
RY: number,
|
|
46
|
-
angle: number,
|
|
47
|
-
LAF: number,
|
|
48
|
-
SF: number,
|
|
49
|
-
x: number,
|
|
50
|
-
y: number,
|
|
51
|
-
t: number,
|
|
52
|
-
): { x: number; y: number } => {
|
|
53
|
-
const { abs, sin, cos, sqrt, PI } = Math;
|
|
54
|
-
let rx = abs(RX);
|
|
55
|
-
let ry = abs(RY);
|
|
56
|
-
const xRot = ((angle % 360) + 360) % 360;
|
|
57
|
-
const xRotRad = xRot * (PI / 180);
|
|
58
|
-
|
|
59
|
-
if (x1 === x && y1 === y) {
|
|
60
|
-
return { x: x1, y: y1 };
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (rx === 0 || ry === 0) {
|
|
64
|
-
return segmentLineFactory(x1, y1, x, y, t).point;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const dx = (x1 - x) / 2;
|
|
68
|
-
const dy = (y1 - y) / 2;
|
|
69
|
-
|
|
70
|
-
const transformedPoint = {
|
|
71
|
-
x: cos(xRotRad) * dx + sin(xRotRad) * dy,
|
|
72
|
-
y: -sin(xRotRad) * dx + cos(xRotRad) * dy,
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const radiiCheck = transformedPoint.x ** 2 / rx ** 2 + transformedPoint.y ** 2 / ry ** 2;
|
|
76
|
-
|
|
77
|
-
if (radiiCheck > 1) {
|
|
78
|
-
rx *= sqrt(radiiCheck);
|
|
79
|
-
ry *= sqrt(radiiCheck);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const cSquareNumerator = rx ** 2 * ry ** 2 - rx ** 2 * transformedPoint.y ** 2 - ry ** 2 * transformedPoint.x ** 2;
|
|
83
|
-
|
|
84
|
-
const cSquareRootDenom = rx ** 2 * transformedPoint.y ** 2 + ry ** 2 * transformedPoint.x ** 2;
|
|
85
|
-
|
|
86
|
-
let cRadicand = cSquareNumerator / cSquareRootDenom;
|
|
87
|
-
cRadicand = cRadicand < 0 ? 0 : cRadicand;
|
|
88
|
-
const cCoef = (LAF !== SF ? 1 : -1) * sqrt(cRadicand);
|
|
89
|
-
const transformedCenter = {
|
|
90
|
-
x: cCoef * ((rx * transformedPoint.y) / ry),
|
|
91
|
-
y: cCoef * (-(ry * transformedPoint.x) / rx),
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
const center = {
|
|
95
|
-
x: cos(xRotRad) * transformedCenter.x - sin(xRotRad) * transformedCenter.y + (x1 + x) / 2,
|
|
96
|
-
y: sin(xRotRad) * transformedCenter.x + cos(xRotRad) * transformedCenter.y + (y1 + y) / 2,
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
const startVector = {
|
|
100
|
-
x: (transformedPoint.x - transformedCenter.x) / rx,
|
|
101
|
-
y: (transformedPoint.y - transformedCenter.y) / ry,
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
const startAngle = angleBetween({ x: 1, y: 0 }, startVector);
|
|
105
|
-
|
|
106
|
-
const endVector = {
|
|
107
|
-
x: (-transformedPoint.x - transformedCenter.x) / rx,
|
|
108
|
-
y: (-transformedPoint.y - transformedCenter.y) / ry,
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
let sweepAngle = angleBetween(startVector, endVector);
|
|
112
|
-
if (!SF && sweepAngle > 0) {
|
|
113
|
-
sweepAngle -= 2 * PI;
|
|
114
|
-
} else if (SF && sweepAngle < 0) {
|
|
115
|
-
sweepAngle += 2 * PI;
|
|
116
|
-
}
|
|
117
|
-
sweepAngle %= 2 * PI;
|
|
118
|
-
|
|
119
|
-
const alpha = startAngle + sweepAngle * t;
|
|
120
|
-
const ellipseComponentX = rx * cos(alpha);
|
|
121
|
-
const ellipseComponentY = ry * sin(alpha);
|
|
122
|
-
|
|
123
|
-
const point = {
|
|
124
|
-
x: cos(xRotRad) * ellipseComponentX - sin(xRotRad) * ellipseComponentY + center.x,
|
|
125
|
-
y: sin(xRotRad) * ellipseComponentX + cos(xRotRad) * ellipseComponentY + center.y,
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
// to be used later
|
|
129
|
-
// point.ellipticalArcStartAngle = startAngle;
|
|
130
|
-
// point.ellipticalArcEndAngle = startAngle + sweepAngle;
|
|
131
|
-
// point.ellipticalArcAngle = alpha;
|
|
132
|
-
|
|
133
|
-
// point.ellipticalArcCenter = center;
|
|
134
|
-
// point.resultantRx = rx;
|
|
135
|
-
// point.resultantRy = ry;
|
|
136
|
-
|
|
137
|
-
return point;
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Returns a {x,y} point at a given length, the total length and
|
|
142
|
-
* the shape minimum and maximum {x,y} coordinates of an A (arc-to) segment.
|
|
143
|
-
*
|
|
144
|
-
* @param X1 the starting x position
|
|
145
|
-
* @param Y1 the starting y position
|
|
146
|
-
* @param RX x-radius of the arc
|
|
147
|
-
* @param RY y-radius of the arc
|
|
148
|
-
* @param angle x-axis-rotation of the arc
|
|
149
|
-
* @param LAF large-arc-flag of the arc
|
|
150
|
-
* @param SF sweep-flag of the arc
|
|
151
|
-
* @param X2 the ending x position
|
|
152
|
-
* @param Y2 the ending y position
|
|
153
|
-
* @param distance the point distance
|
|
154
|
-
* @returns the segment length, point, min & max
|
|
155
|
-
*/
|
|
156
|
-
const segmentArcFactory = (
|
|
157
|
-
X1: number,
|
|
158
|
-
Y1: number,
|
|
159
|
-
RX: number,
|
|
160
|
-
RY: number,
|
|
161
|
-
angle: number,
|
|
162
|
-
LAF: number,
|
|
163
|
-
SF: number,
|
|
164
|
-
X2: number,
|
|
165
|
-
Y2: number,
|
|
166
|
-
distance: number,
|
|
167
|
-
): LengthFactory => {
|
|
168
|
-
const distanceIsNumber = typeof distance === 'number';
|
|
169
|
-
let x = X1;
|
|
170
|
-
let y = Y1;
|
|
171
|
-
let LENGTH = 0;
|
|
172
|
-
let prev = [x, y, LENGTH];
|
|
173
|
-
let cur = [x, y] as [number, number];
|
|
174
|
-
let t = 0;
|
|
175
|
-
let POINT = { x: 0, y: 0 };
|
|
176
|
-
let POINTS = [{ x, y }];
|
|
177
|
-
|
|
178
|
-
if (distanceIsNumber && distance <= 0) {
|
|
179
|
-
POINT = { x, y };
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const sampleSize = 300;
|
|
183
|
-
for (let j = 0; j <= sampleSize; j += 1) {
|
|
184
|
-
t = j / sampleSize;
|
|
185
|
-
|
|
186
|
-
({ x, y } = getPointAtArcSegmentLength(X1, Y1, RX, RY, angle, LAF, SF, X2, Y2, t));
|
|
187
|
-
POINTS = [...POINTS, { x, y }];
|
|
188
|
-
LENGTH += distanceSquareRoot(cur, [x, y]);
|
|
189
|
-
cur = [x, y];
|
|
190
|
-
|
|
191
|
-
if (distanceIsNumber && LENGTH > distance && distance > prev[2]) {
|
|
192
|
-
const dv = (LENGTH - distance) / (LENGTH - prev[2]);
|
|
193
|
-
|
|
194
|
-
POINT = {
|
|
195
|
-
x: cur[0] * (1 - dv) + prev[0] * dv,
|
|
196
|
-
y: cur[1] * (1 - dv) + prev[1] * dv,
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
prev = [x, y, LENGTH];
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
if (distanceIsNumber && distance >= LENGTH) {
|
|
203
|
-
POINT = { x: X2, y: Y2 };
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
return {
|
|
207
|
-
length: LENGTH,
|
|
208
|
-
point: POINT,
|
|
209
|
-
min: {
|
|
210
|
-
x: Math.min(...POINTS.map(n => n.x)),
|
|
211
|
-
y: Math.min(...POINTS.map(n => n.y)),
|
|
212
|
-
},
|
|
213
|
-
max: {
|
|
214
|
-
x: Math.max(...POINTS.map(n => n.x)),
|
|
215
|
-
y: Math.max(...POINTS.map(n => n.y)),
|
|
216
|
-
},
|
|
217
|
-
};
|
|
218
|
-
};
|
|
219
|
-
export default segmentArcFactory;
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { LengthFactory } from 'src/interface';
|
|
2
|
-
import distanceSquareRoot from '../math/distanceSquareRoot';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Returns a {x,y} point at a given length, the total length and
|
|
6
|
-
* the minimum and maximum {x,y} coordinates of a C (cubic-bezier) segment.
|
|
7
|
-
*
|
|
8
|
-
* @param x1 the starting point X
|
|
9
|
-
* @param y1 the starting point Y
|
|
10
|
-
* @param c1x the first control point X
|
|
11
|
-
* @param c1y the first control point Y
|
|
12
|
-
* @param c2x the second control point X
|
|
13
|
-
* @param c2y the second control point Y
|
|
14
|
-
* @param x2 the ending point X
|
|
15
|
-
* @param y2 the ending point Y
|
|
16
|
-
* @param t a [0-1] ratio
|
|
17
|
-
* @returns the point at cubic-bezier segment length
|
|
18
|
-
*/
|
|
19
|
-
const getPointAtCubicSegmentLength = (
|
|
20
|
-
x1: number,
|
|
21
|
-
y1: number,
|
|
22
|
-
c1x: number,
|
|
23
|
-
c1y: number,
|
|
24
|
-
c2x: number,
|
|
25
|
-
c2y: number,
|
|
26
|
-
x2: number,
|
|
27
|
-
y2: number,
|
|
28
|
-
t: number,
|
|
29
|
-
): { x: number; y: number } => {
|
|
30
|
-
const t1 = 1 - t;
|
|
31
|
-
return {
|
|
32
|
-
x: t1 ** 3 * x1 + 3 * t1 ** 2 * t * c1x + 3 * t1 * t ** 2 * c2x + t ** 3 * x2,
|
|
33
|
-
y: t1 ** 3 * y1 + 3 * t1 ** 2 * t * c1y + 3 * t1 * t ** 2 * c2y + t ** 3 * y2,
|
|
34
|
-
};
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Returns the length of a C (cubic-bezier) segment
|
|
39
|
-
* or an {x,y} point at a given length.
|
|
40
|
-
*
|
|
41
|
-
* @param x1 the starting point X
|
|
42
|
-
* @param y1 the starting point Y
|
|
43
|
-
* @param c1x the first control point X
|
|
44
|
-
* @param c1y the first control point Y
|
|
45
|
-
* @param c2x the second control point X
|
|
46
|
-
* @param c2y the second control point Y
|
|
47
|
-
* @param x2 the ending point X
|
|
48
|
-
* @param y2 the ending point Y
|
|
49
|
-
* @param distance the point distance
|
|
50
|
-
* @returns the segment length, point, min & max
|
|
51
|
-
*/
|
|
52
|
-
const segmentCubicFactory = (
|
|
53
|
-
x1: number,
|
|
54
|
-
y1: number,
|
|
55
|
-
c1x: number,
|
|
56
|
-
c1y: number,
|
|
57
|
-
c2x: number,
|
|
58
|
-
c2y: number,
|
|
59
|
-
x2: number,
|
|
60
|
-
y2: number,
|
|
61
|
-
distance?: number,
|
|
62
|
-
): LengthFactory => {
|
|
63
|
-
const distanceIsNumber = typeof distance === 'number';
|
|
64
|
-
let x = x1;
|
|
65
|
-
let y = y1;
|
|
66
|
-
let LENGTH = 0;
|
|
67
|
-
let prev = [x, y, LENGTH];
|
|
68
|
-
let cur = [x, y] as [number, number];
|
|
69
|
-
let t = 0;
|
|
70
|
-
let POINT = { x: 0, y: 0 };
|
|
71
|
-
let POINTS = [{ x, y }];
|
|
72
|
-
|
|
73
|
-
if (distanceIsNumber && distance <= 0) {
|
|
74
|
-
POINT = { x, y };
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const sampleSize = 300;
|
|
78
|
-
for (let j = 0; j <= sampleSize; j += 1) {
|
|
79
|
-
t = j / sampleSize;
|
|
80
|
-
|
|
81
|
-
({ x, y } = getPointAtCubicSegmentLength(x1, y1, c1x, c1y, c2x, c2y, x2, y2, t));
|
|
82
|
-
POINTS = [...POINTS, { x, y }];
|
|
83
|
-
LENGTH += distanceSquareRoot(cur, [x, y]);
|
|
84
|
-
cur = [x, y];
|
|
85
|
-
|
|
86
|
-
if (distanceIsNumber && LENGTH > distance && distance > prev[2]) {
|
|
87
|
-
const dv = (LENGTH - distance) / (LENGTH - prev[2]);
|
|
88
|
-
|
|
89
|
-
POINT = {
|
|
90
|
-
x: cur[0] * (1 - dv) + prev[0] * dv,
|
|
91
|
-
y: cur[1] * (1 - dv) + prev[1] * dv,
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
prev = [x, y, LENGTH];
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (distanceIsNumber && distance >= LENGTH) {
|
|
98
|
-
POINT = { x: x2, y: y2 };
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return {
|
|
102
|
-
length: LENGTH,
|
|
103
|
-
point: POINT,
|
|
104
|
-
min: {
|
|
105
|
-
x: Math.min(...POINTS.map(n => n.x)),
|
|
106
|
-
y: Math.min(...POINTS.map(n => n.y)),
|
|
107
|
-
},
|
|
108
|
-
max: {
|
|
109
|
-
x: Math.max(...POINTS.map(n => n.x)),
|
|
110
|
-
y: Math.max(...POINTS.map(n => n.y)),
|
|
111
|
-
},
|
|
112
|
-
};
|
|
113
|
-
};
|
|
114
|
-
export default segmentCubicFactory;
|