@visactor/vrender-components
Version:
components library for dp visualization
1,251 lines (1,226 loc) • 1.63 MB
JavaScript
import { isFunction, EventEmitter, Logger, isBoolean, isObject, tau, halfPi as halfPi$1, AABBBounds, degreeToRadian, Point, PointService, abs, max, min, atan2, epsilon, Matrix, pi2, isArray, cos, sin, pi, isString, pointAt, isNumber, sqrt, isPointInLine, Color, OBBBounds, isEqual, isNil, normalTransform, isValidUrl, isBase64, isPlainObject as isPlainObject$2, merge, getContextFont, rotatePoint, transformBoundsWithMatrix, clampAngleByRadian, asin, isNumberClose, TextMeasure, Bounds, getRectIntersect, isRectIntersect, arrayEqual, acos, isValid, clamp, clampRange, normalizePadding, debounce, throttle, hexToRgb, crossProduct, isEmpty, array, rectInsideAnotherRect, radianToDegree, getAngleByPoint, polarToCartesian, normalizeAngle, isValidNumber, flattenArray, isRotateAABBIntersect, isLess, isGreater, aabbSeparation, obbSeparation, cloneDeep, get, last, mixin, interpolateString, minInArray, maxInArray, binaryFuzzySearchInNumberRange, pointInRect, calculateAnchorOfBounds, computeQuadrant, polygonContainPoint } from '@visactor/vutils';
import { isContinuous, isDiscrete, LinearScale } from '@visactor/vscale';
class FederatedEvent {
get layerX() {
return this.layer.x;
}
get layerY() {
return this.layer.y;
}
get pageX() {
return this.page.x;
}
get pageY() {
return this.page.y;
}
get x() {
return this.canvas.x;
}
get y() {
return this.canvas.y;
}
get canvasX() {
return this.canvas.x;
}
get canvasY() {
return this.canvas.y;
}
get viewX() {
return this.viewport.x;
}
get viewY() {
return this.viewport.y;
}
constructor(manager) {
this.bubbles = !0, this.cancelBubble = !0, this.cancelable = !1, this.composed = !1, this.defaultPrevented = !1, this.eventPhase = FederatedEvent.prototype.NONE, this.propagationStopped = !1, this.propagationImmediatelyStopped = !1, this.layer = {
x: 0,
y: 0
}, this.page = {
x: 0,
y: 0
}, this.canvas = {
x: 0,
y: 0
}, this.viewport = {
x: 0,
y: 0
}, this.NONE = 0, this.CAPTURING_PHASE = 1, this.AT_TARGET = 2, this.BUBBLING_PHASE = 3, this.manager = manager;
}
composedPath() {
return !this.manager || this.path && this.path[this.path.length - 1] === this.target || (this.path = this.target ? this.manager.propagationPath(this.target) : []), this.composedDetailPath(), this.path;
}
composedDetailPath() {
return this.pickParams && this.pickParams.graphic ? (this.detailPath = this.path.slice(), this._composedDetailPath(this.pickParams)) : this.detailPath = this.path.slice(), this.detailPath;
}
_composedDetailPath(params) {
if (params && params.graphic) {
const g = params.graphic;
if (g.stage) {
const path = g.stage.eventSystem.manager.propagationPath(g);
this.detailPath.push(path), this._composedDetailPath(params.params);
}
}
}
preventDefault() {
try {
this.nativeEvent instanceof Event && this.nativeEvent.cancelable && this.nativeEvent.preventDefault();
} catch (err) {
this.nativeEvent.preventDefault && isFunction(this.nativeEvent.preventDefault) && this.nativeEvent.preventDefault();
}
this.defaultPrevented = !0;
}
stopImmediatePropagation() {
this.propagationImmediatelyStopped = !0;
}
stopPropagation() {
try {
this.nativeEvent instanceof Event && this.nativeEvent.cancelable && this.nativeEvent.stopPropagation();
} catch (err) {
this.nativeEvent.stopPropagation && isFunction(this.nativeEvent.stopPropagation) && this.nativeEvent.stopPropagation();
}
this.propagationStopped = !0;
}
initEvent() {}
initUIEvent() {}
clone() {
throw new Error("Method not implemented.");
}
}
class CustomEvent extends FederatedEvent {
constructor(eventName, object) {
super(), this.type = eventName, this.detail = object;
}
}
var UpdateTag;
!function (UpdateTag) {
UpdateTag[UpdateTag.NONE = 0] = "NONE", UpdateTag[UpdateTag.UPDATE_BOUNDS = 1] = "UPDATE_BOUNDS", UpdateTag[UpdateTag.UPDATE_SHAPE = 2] = "UPDATE_SHAPE", UpdateTag[UpdateTag.CLEAR_SHAPE = 253] = "CLEAR_SHAPE", UpdateTag[UpdateTag.UPDATE_SHAPE_AND_BOUNDS = 3] = "UPDATE_SHAPE_AND_BOUNDS", UpdateTag[UpdateTag.INIT = 179] = "INIT", UpdateTag[UpdateTag.CLEAR_BOUNDS = 254] = "CLEAR_BOUNDS", UpdateTag[UpdateTag.UPDATE_GLOBAL_MATRIX = 32] = "UPDATE_GLOBAL_MATRIX", UpdateTag[UpdateTag.CLEAR_GLOBAL_MATRIX = 223] = "CLEAR_GLOBAL_MATRIX", UpdateTag[UpdateTag.UPDATE_LOCAL_MATRIX = 16] = "UPDATE_LOCAL_MATRIX", UpdateTag[UpdateTag.CLEAR_LOCAL_MATRIX = 239] = "CLEAR_LOCAL_MATRIX", UpdateTag[UpdateTag.UPDATE_GLOBAL_LOCAL_MATRIX = 48] = "UPDATE_GLOBAL_LOCAL_MATRIX", UpdateTag[UpdateTag.UPDATE_PAINT = 64] = "UPDATE_PAINT", UpdateTag[UpdateTag.CLEAR_PAINT = 191] = "CLEAR_PAINT", UpdateTag[UpdateTag.UPDATE_LAYOUT = 128] = "UPDATE_LAYOUT", UpdateTag[UpdateTag.CLEAR_LAYOUT = 127] = "CLEAR_LAYOUT";
}(UpdateTag || (UpdateTag = {}));
var IContainPointMode;
!function (IContainPointMode) {
IContainPointMode[IContainPointMode.GLOBAL = 1] = "GLOBAL", IContainPointMode[IContainPointMode.LOCAL = 16] = "LOCAL", IContainPointMode[IContainPointMode.GLOBAL_ACCURATE = 3] = "GLOBAL_ACCURATE", IContainPointMode[IContainPointMode.LOCAL_ACCURATE = 48] = "LOCAL_ACCURATE";
}(IContainPointMode || (IContainPointMode = {}));
var AttributeUpdateType;
!function (AttributeUpdateType) {
AttributeUpdateType[AttributeUpdateType.INIT = 0] = "INIT", AttributeUpdateType[AttributeUpdateType.DEFAULT = 1] = "DEFAULT", AttributeUpdateType[AttributeUpdateType.STATE = 2] = "STATE", AttributeUpdateType[AttributeUpdateType.ANIMATE_BIND = 10] = "ANIMATE_BIND", AttributeUpdateType[AttributeUpdateType.ANIMATE_PLAY = 11] = "ANIMATE_PLAY", AttributeUpdateType[AttributeUpdateType.ANIMATE_START = 12] = "ANIMATE_START", AttributeUpdateType[AttributeUpdateType.ANIMATE_UPDATE = 13] = "ANIMATE_UPDATE", AttributeUpdateType[AttributeUpdateType.ANIMATE_END = 14] = "ANIMATE_END", AttributeUpdateType[AttributeUpdateType.TRANSLATE = 20] = "TRANSLATE", AttributeUpdateType[AttributeUpdateType.TRANSLATE_TO = 21] = "TRANSLATE_TO", AttributeUpdateType[AttributeUpdateType.SCALE = 22] = "SCALE", AttributeUpdateType[AttributeUpdateType.SCALE_TO = 23] = "SCALE_TO", AttributeUpdateType[AttributeUpdateType.ROTATE = 24] = "ROTATE", AttributeUpdateType[AttributeUpdateType.ROTATE_TO = 25] = "ROTATE_TO";
}(AttributeUpdateType || (AttributeUpdateType = {}));
var Direction;
!function (Direction) {
Direction[Direction.ROW = 1] = "ROW", Direction[Direction.COLUMN = 2] = "COLUMN";
}(Direction || (Direction = {}));
var CurveTypeEnum;
!function (CurveTypeEnum) {
CurveTypeEnum[CurveTypeEnum.CubicBezierCurve = 0] = "CubicBezierCurve", CurveTypeEnum[CurveTypeEnum.QuadraticBezierCurve = 1] = "QuadraticBezierCurve", CurveTypeEnum[CurveTypeEnum.ArcCurve = 2] = "ArcCurve", CurveTypeEnum[CurveTypeEnum.LineCurve = 3] = "LineCurve", CurveTypeEnum[CurveTypeEnum.EllipseCurve = 4] = "EllipseCurve", CurveTypeEnum[CurveTypeEnum.MoveCurve = 5] = "MoveCurve";
}(CurveTypeEnum || (CurveTypeEnum = {}));
var BaseRenderContributionTime;
!function (BaseRenderContributionTime) {
BaseRenderContributionTime[BaseRenderContributionTime.beforeFillStroke = 0] = "beforeFillStroke", BaseRenderContributionTime[BaseRenderContributionTime.afterFillStroke = 1] = "afterFillStroke";
}(BaseRenderContributionTime || (BaseRenderContributionTime = {}));
var AnimateMode;
!function (AnimateMode) {
AnimateMode[AnimateMode.NORMAL = 0] = "NORMAL", AnimateMode[AnimateMode.SET_ATTR_IMMEDIATELY = 1] = "SET_ATTR_IMMEDIATELY";
}(AnimateMode || (AnimateMode = {}));
var AnimateStepType;
!function (AnimateStepType) {
AnimateStepType.wait = "wait", AnimateStepType.from = "from", AnimateStepType.to = "to", AnimateStepType.customAnimate = "customAnimate";
}(AnimateStepType || (AnimateStepType = {}));
var AnimateStatus;
!function (AnimateStatus) {
AnimateStatus[AnimateStatus.INITIAL = 0] = "INITIAL", AnimateStatus[AnimateStatus.RUNNING = 1] = "RUNNING", AnimateStatus[AnimateStatus.PAUSED = 2] = "PAUSED", AnimateStatus[AnimateStatus.END = 3] = "END";
}(AnimateStatus || (AnimateStatus = {}));
var STATUS$1;
!function (STATUS) {
STATUS[STATUS.INITIAL = 0] = "INITIAL", STATUS[STATUS.RUNNING = 1] = "RUNNING", STATUS[STATUS.PAUSE = 2] = "PAUSE";
}(STATUS$1 || (STATUS$1 = {}));
class Application {}
const APPLICATION_STATE_SYMBOL = Symbol.for("@visactor/vrender-core/application-state");
function createApplicationState() {
return {
application: new Application()
};
}
function getApplicationState() {
const scope = globalThis;
return scope[APPLICATION_STATE_SYMBOL] || (scope[APPLICATION_STATE_SYMBOL] = createApplicationState()), scope[APPLICATION_STATE_SYMBOL];
}
const application = getApplicationState().application;
class Generator {
static GenAutoIncrementId() {
return Generator.auto_increment_id++;
}
}
Generator.auto_increment_id = 0;
var __awaiter$4 = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
}
function rejected(value) {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
}
function step(result) {
var value;
result.done ? resolve(result.value) : (value = result.value, value instanceof P ? value : new P(function (resolve) {
resolve(value);
})).then(fulfilled, rejected);
}
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
class Node extends EventEmitter {
get previousSibling() {
return this._prev;
}
get nextSibling() {
return this._next;
}
get children() {
return this.getChildren();
}
get firstChild() {
return this._firstChild;
}
get lastChild() {
return this._lastChild;
}
get count() {
return this._count;
}
get childrenCount() {
return this._idMap ? this._idMap.size : 0;
}
constructor() {
super(), this._uid = Generator.GenAutoIncrementId(), this._firstChild = null, this._lastChild = null, this.parent = null, this._count = 1;
}
onParentSharedStateTreeChanged(_stage, _layer) {}
forEachChildren(cb, reverse = !1) {
if (reverse) {
let child = this._lastChild,
i = 0;
for (; child;) {
if (cb(child, i++)) return;
child = child._prev;
}
} else {
let child = this._firstChild,
i = 0;
for (; child;) {
if (cb(child, i++)) return;
child = child._next;
}
}
}
forEachChildrenAsync(cb, reverse = !1) {
return __awaiter$4(this, void 0, void 0, function* () {
if (reverse) {
let child = this._lastChild,
i = 0;
for (; child;) {
let breakTag = cb(child, i++);
if (breakTag.then && (breakTag = yield breakTag), breakTag) return;
child = child._prev;
}
} else {
let child = this._firstChild,
i = 0;
for (; child;) {
let breakTag = cb(child, i++);
if (breakTag.then && (breakTag = yield breakTag), breakTag) return;
child = child._next;
}
}
});
}
forEach(cb) {
return this.forEachChildren(cb);
}
appendChild(node, highPerformance = !0) {
if (this._uid === node._uid) return null;
if (!highPerformance && node.isAncestorsOf(this)) throw new Error("【Node::appendChild】不能将父辈元素append为子元素");
return node.parent && node.parent.removeChild(node), node.parent = this, this._lastChild ? (this._lastChild._next = node, node._prev = this._lastChild, this._lastChild = node) : (this._firstChild = this._lastChild = node, node._prev = node._next = null), this._idMap || (this._idMap = new Map()), this._idMap.set(node._uid, node), this.setCount(node.count), this._structEdit = !0, node;
}
appendChildArrHighPerformance(nodes, replace = !1) {
return console.error("暂不支持该函数"), nodes;
}
insertBefore(newNode, referenceNode) {
if (!referenceNode) return this.appendChild(newNode);
if (this === newNode || newNode === referenceNode) return null;
if (newNode.isAncestorsOf(this)) throw new Error("【Node::insertBefore】不能将父辈元素insert为子元素");
return referenceNode.parent !== this ? null : (newNode.parent && newNode.parent.removeChild(newNode), newNode.parent = this, newNode._prev = referenceNode._prev, referenceNode._prev ? referenceNode._prev._next = newNode : this._firstChild = newNode, referenceNode._prev = newNode, newNode._next = referenceNode, this._idMap || (this._idMap = new Map()), this._idMap.set(newNode._uid, newNode), this._structEdit = !0, this.setCount(newNode.count), newNode);
}
insertAfter(newNode, referenceNode) {
if (!referenceNode) return this.appendChild(newNode);
if (this === newNode || newNode === referenceNode) return null;
if (newNode.isAncestorsOf(this)) throw new Error("【Node::insertAfter】不能将父辈元素insert为子元素");
return referenceNode.parent !== this ? null : (newNode.parent && newNode.parent.removeChild(newNode), newNode.parent = this, referenceNode._next ? (referenceNode._next._prev = newNode, newNode._next = referenceNode._next) : this._lastChild = newNode, referenceNode._next = newNode, newNode._prev = referenceNode, this._idMap || (this._idMap = new Map()), this._idMap.set(newNode._uid, newNode), this._structEdit = !0, this.setCount(newNode.count), newNode);
}
insertInto(newNode, idx) {
if (!this._ignoreWarn && this._nodeList && Logger.getInstance().warn("insertIntoKeepIdx和insertInto混用可能会存在错误"), idx >= this.childrenCount) return this.appendChild(newNode);
if (this === newNode) return null;
if (newNode.isAncestorsOf(this)) throw new Error("【Node::insertBefore】不能将父辈元素insert为子元素");
if (newNode.parent && newNode.parent.removeChild(newNode), newNode.parent = this, 0 === idx) newNode._next = this._firstChild, this._firstChild && (this._firstChild._prev = newNode), newNode._prev = null, this._firstChild = newNode;else {
let child = this._firstChild;
for (let i = 0; i < idx; i++) {
if (!child) return null;
i > 0 && (child = child._next);
}
if (!child) return null;
newNode._next = child._next, newNode._prev = child, child._next = newNode, newNode._next && (newNode._next._prev = newNode);
}
return this._idMap || (this._idMap = new Map()), this._idMap.set(newNode._uid, newNode), this._structEdit = !0, this.setCount(newNode.count), newNode;
}
insertIntoKeepIdx(newNode, idx) {
if (this._nodeList || (this._nodeList = this.children), this._nodeList[idx]) {
const node = this._nodeList[idx];
return this._nodeList.splice(idx, 0, newNode), this.insertBefore(newNode, node);
}
let node;
this._nodeList[idx] = newNode;
for (let i = idx - 1; i >= 0 && (node = this._nodeList[i], !node); i--);
if (node) return node._next ? this.insertBefore(newNode, node._next) : this.appendChild(newNode);
this._ignoreWarn = !0;
const data = this.insertInto(newNode, 0);
return this._ignoreWarn = !1, data;
}
removeChild(child) {
if (!this._idMap) return null;
if (!this._idMap.has(child._uid)) return null;
if (this._idMap.delete(child._uid), this._nodeList) {
const idx = this._nodeList.findIndex(n => n === child);
idx >= 0 && this._nodeList.splice(idx, 1);
}
return child._prev ? child._prev._next = child._next : this._firstChild = child._next, child._next ? child._next._prev = child._prev : this._lastChild = child._prev, child.parent = null, child._prev = null, child._next = null, this._structEdit = !0, this.setCount(-child.count), child;
}
delete() {
this.parent && this.parent.removeChild(this);
}
removeAllChild(deep) {
if (!this._idMap) return;
this._nodeList && (this._nodeList.length = 0);
let child = this._firstChild;
for (; child;) {
const next = child._next;
child.parent = null, child._prev = null, child._next = null, child = child._next, child = next;
}
this._firstChild = null, this._lastChild = null, this._idMap.clear(), this._structEdit = !0, this.setCount(1 - this._count);
}
replaceChild(newChild, oldChild) {
throw new Error("暂不支持");
}
find(callback, deep = !1) {
let target = null;
return this.forEachChildren((node, index) => !(node === this || !callback(node, index)) && (target = node, !0)), deep && this.forEachChildren(child => {
if (child.isContainer) {
const node = child.find(callback, !0);
if (node) return target = node, !0;
}
return !1;
}), target;
}
findAll(callback, deep = !1) {
let nodes = [];
return this.forEachChildren((node, index) => {
node !== this && callback(node, index) && nodes.push(node);
}), deep && this.forEachChildren(child => {
if (child.isContainer) {
const targets = child.findAll(callback, !0);
targets.length && (nodes = nodes.concat(targets));
}
}), nodes;
}
getElementById(id) {
return this.find(node => node.id === id, !0);
}
findChildById(id) {
return this.getElementById(id);
}
findChildByUid(uid) {
return this._idMap && this._idMap.get(uid) || null;
}
getElementsByName(name) {
return this.findAll(node => node.name === name, !0);
}
findChildrenByName(name) {
return this.getElementsByName(name);
}
getElementsByType(type) {
return this.findAll(node => node.type === type, !0);
}
getChildByName(name, deep = !1) {
return this.find(node => node.name === name, deep);
}
getChildAt(idx) {
let c = this._firstChild;
if (!c) return null;
for (let i = 0; i < idx; i++) {
if (!c._next) return null;
c = c._next;
}
return c;
}
at(idx) {
return this.getChildAt(idx);
}
containNode(node) {
if (!this._idMap) return !1;
if (this._idMap.has(node._uid)) return !0;
let child = this._firstChild;
for (; child;) {
if (child.containNode(node)) return !0;
child = child._next;
}
return !1;
}
getRootNode() {
let parent = this.parent;
for (; null == parent ? void 0 : parent.parent;) parent = parent.parent;
return parent || this;
}
hasChildNodes() {
return null !== this._firstChild;
}
addChild(node) {
return this.appendChild(node);
}
add(node) {
return this.appendChild(node);
}
getChildren() {
const nodes = [];
let child = this._firstChild;
for (; child;) nodes.push(child), child = child._next;
return nodes;
}
isChildOf(node) {
return !!this.parent && this.parent._uid === node._uid;
}
isParentOf(node) {
return node.isChildOf(this);
}
isDescendantsOf(node) {
let parent = this.parent;
if (!parent) return !1;
do {
if (parent._uid === node._uid) return !0;
parent = parent.parent;
} while (null !== parent);
return !1;
}
isAncestorsOf(node) {
return node.isDescendantsOf(this);
}
getAncestor(idx) {
throw new Error("暂不支持");
}
setAllDescendantsProps(propsName, propsValue) {
let child = this._firstChild;
for (; child;) child[propsName] = propsValue, child.setAllDescendantsProps(propsName, propsValue), child = child._next;
}
setCount(deltaCount) {
this._count += deltaCount;
let parent = this.parent;
if (parent) do {
parent._count += deltaCount, parent = parent.parent;
} while (null !== parent);
}
clone() {
throw new Error("暂不支持");
}
cloneTo(node) {
throw new Error("暂不支持");
}
getParent() {
return this.parent;
}
del(child) {
return this.removeChild(child);
}
addEventListener(type, listener, options) {
const capture = isBoolean(options, !0) && options || isObject(options) && options.capture,
once = isObject(options) && options.once,
context = isFunction(listener) ? void 0 : listener;
return type = capture ? `${type}capture` : type, listener = isFunction(listener) ? listener : listener.handleEvent, once ? super.once(type, listener, context) : super.on(type, listener, context), this;
}
on(type, listener, options) {
return this.addEventListener(type, listener, options);
}
removeEventListener(type, listener, options) {
const capture = isBoolean(options, !0) && options || isObject(options) && options.capture,
context = isFunction(listener) ? void 0 : listener;
type = capture ? `${type}capture` : type, listener = isFunction(listener) ? listener : listener.handleEvent;
const once = isObject(options) && options.once;
return super.off(type, listener, context, once), this;
}
off(type, listener, options) {
return this.removeEventListener(type, listener, options);
}
once(type, listener, options) {
return isObject(options) ? (options.once = !0, this.addEventListener(type, listener, options)) : this.addEventListener(type, listener, {
once: !0
});
}
removeAllEventListeners() {
return super.removeAllListeners(), this;
}
removeAllListeners() {
return this.removeAllEventListeners();
}
dispatchEvent(event, ...args) {
return super.emit(event.type, event, ...args), !event.defaultPrevented;
}
emit(event, data) {
return this.dispatchEvent(event, data);
}
release() {
this.removeAllListeners();
}
}
const EventTarget = {
dispatchEvent(e) {
var _a;
if (!(e instanceof FederatedEvent)) throw new Error("DisplayObject cannot propagate events outside of the Federated Events API");
return e.defaultPrevented = !1, e.path = [], e.detailPath && (e.detailPath = []), e.target = this, null === (_a = null == e ? void 0 : e.manager) || void 0 === _a || _a.dispatchEvent(e), !e.defaultPrevented;
},
emit(eventName, object) {
return this.dispatchEvent(new CustomEvent(eventName, object));
}
};
const circleThreshold = tau - 1e-8;
class BoundsContext {
constructor(bounds) {
this.init(bounds);
}
init(bounds) {
this.bounds = bounds;
}
arc(cx, cy, r, sa, ea, ccw) {
if (Math.abs(ea - sa) > circleThreshold) return this.bounds.add(cx - r, cy - r), void this.bounds.add(cx + r, cy + r);
let s,
i,
x,
y,
xmin = 1 / 0,
xmax = -1 / 0,
ymin = 1 / 0,
ymax = -1 / 0;
function update(a) {
x = r * Math.cos(a), y = r * Math.sin(a), x < xmin && (xmin = x), x > xmax && (xmax = x), y < ymin && (ymin = y), y > ymax && (ymax = y);
}
if (update(sa), update(ea), ea !== sa) if ((sa %= tau) < 0 && (sa += tau), (ea %= tau) < 0 && (ea += tau), ea < sa && (ccw = !ccw, s = sa, sa = ea, ea = s), ccw) for (ea -= tau, s = sa - sa % halfPi$1, i = 0; i < 4 && s > ea; ++i, s -= halfPi$1) update(s);else for (s = sa - sa % halfPi$1 + halfPi$1, i = 0; i < 4 && s < ea; ++i, s += halfPi$1) update(s);
this.bounds.add(cx + xmin, cy + ymin), this.bounds.add(cx + xmax, cy + ymax);
}
arcTo(x1, y1, x2, y2, radius) {
this.bounds.add(x1, y1);
}
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) {
this.bounds.add(cp1x, cp1y), this.bounds.add(cp2x, cp2y), this.bounds.add(x, y);
}
closePath() {}
ellipse() {
throw new Error("不支持ellipse");
}
lineTo(x, y) {
this.bounds.add(x, y);
}
moveTo(x, y) {
this.bounds.add(x, y);
}
quadraticCurveTo(cpx, cpy, x, y) {
this.bounds.add(cpx, cpy), this.bounds.add(x, y);
}
rect(x, y, w, h) {
this.bounds.add(x, y), this.bounds.add(x + w, y + h);
}
clear() {
this.bounds.clear();
}
release(...params) {}
}
class CurvePath {
constructor() {
this._curves = [], this.bounds = new AABBBounds();
}
get curves() {
return this._curves;
}
getCurveLengths() {
return this._curves.map(curve => curve.getLength());
}
getPointAt(t) {
return {
x: 0,
y: 0
};
}
getLength() {
return 0;
}
getBounds() {
return this.bounds;
}
}
const rePathCommand = /([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:[eE][-+]?\d+)?)/gi,
commandLengths = {
m: 2,
l: 2,
h: 1,
v: 1,
c: 6,
s: 4,
q: 4,
t: 2,
a: 7,
M: 2,
L: 2,
H: 1,
V: 1,
C: 6,
S: 4,
Q: 4,
T: 2,
A: 7
};
const enumCommandMap = {
A: 0,
AT: 1,
C: 2,
Z: 3,
E: 4,
L: 5,
M: 6,
Q: 7,
R: 8
};
let currPath, coordsStr, commandChar, coordStr, coordNumber, standardCommandLen;
function parseSvgPath(str) {
if (!str) return [];
const paths = str.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi);
if (null === paths) return [];
let currCommandData, coordsStrArr;
const result = [];
for (let i = 0, len = paths.length; i < len; i++) if (currPath = paths[i], coordsStr = currPath.slice(1), commandChar = currPath[0], currCommandData = [commandChar], coordsStrArr = coordsStr.match(rePathCommand), null !== coordsStrArr) {
for (let i = 0, len = coordsStrArr.length; i < len; i++) coordStr = coordsStrArr[i], coordNumber = parseFloat(coordStr), Number.isNaN(coordNumber) || currCommandData.push(coordNumber);
if (standardCommandLen = commandLengths[commandChar], currCommandData.length - 1 > standardCommandLen) {
let subCommand,
bestCommandChar = commandChar;
for (let i = 1, len = currCommandData.length; i < len; i += standardCommandLen) {
subCommand = [bestCommandChar];
for (let j = i, subLen = i + standardCommandLen; j < subLen; j++) subCommand.push(currCommandData[j]);
result.push(subCommand), "m" === bestCommandChar ? bestCommandChar = "l" : "M" === bestCommandChar && (bestCommandChar = "L");
}
} else result.push(currCommandData);
} else result.push(currCommandData);
return result;
}
function segments(x, y, rx, ry, large, sweep, rotateX, ox, oy) {
const th = degreeToRadian(rotateX),
sin_th = Math.sin(th),
cos_th = Math.cos(th),
px = cos_th * (ox - x) * .5 + sin_th * (oy - y) * .5,
py = cos_th * (oy - y) * .5 - sin_th * (ox - x) * .5;
let pl = px * px / ((rx = Math.abs(rx)) * rx) + py * py / ((ry = Math.abs(ry)) * ry);
pl > 1 && (pl = Math.sqrt(pl), rx *= pl, ry *= pl);
const a00 = cos_th / rx,
a01 = sin_th / rx,
a10 = -sin_th / ry,
a11 = cos_th / ry,
x0 = a00 * ox + a01 * oy,
y0 = a10 * ox + a11 * oy,
x1 = a00 * x + a01 * y,
y1 = a10 * x + a11 * y;
let sfactor_sq = 1 / ((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)) - .25;
sfactor_sq < 0 && (sfactor_sq = 0);
let sfactor = Math.sqrt(sfactor_sq);
sweep === large && (sfactor = -sfactor);
const xc = .5 * (x0 + x1) - sfactor * (y1 - y0),
yc = .5 * (y0 + y1) + sfactor * (x1 - x0),
th0 = Math.atan2(y0 - yc, x0 - xc);
let th_arc = Math.atan2(y1 - yc, x1 - xc) - th0;
th_arc < 0 && 1 === sweep ? th_arc += tau : th_arc > 0 && 0 === sweep && (th_arc -= tau);
const segs = Math.ceil(Math.abs(th_arc / (halfPi$1 + .001))),
result = [];
for (let i = 0; i < segs; ++i) {
const th2 = th0 + i * th_arc / segs,
th3 = th0 + (i + 1) * th_arc / segs;
result[i] = [xc, yc, th2, th3, rx, ry, sin_th, cos_th];
}
return result;
}
function bezier(params) {
const cx = params[0],
cy = params[1],
th0 = params[2],
th1 = params[3],
rx = params[4],
ry = params[5],
sin_th = params[6],
cos_th = params[7],
a00 = cos_th * rx,
a01 = -sin_th * ry,
a10 = sin_th * rx,
a11 = cos_th * ry,
cos_th0 = Math.cos(th0),
sin_th0 = Math.sin(th0),
cos_th1 = Math.cos(th1),
sin_th1 = Math.sin(th1),
th_half = .5 * (th1 - th0),
sin_th_h2 = Math.sin(.5 * th_half),
t = 8 / 3 * sin_th_h2 * sin_th_h2 / Math.sin(th_half),
x1 = cx + cos_th0 - t * sin_th0,
y1 = cy + sin_th0 + t * cos_th0,
x3 = cx + cos_th1,
y3 = cy + sin_th1,
x2 = x3 + t * sin_th1,
y2 = y3 - t * cos_th1;
return [a00 * x1 + a01 * y1, a10 * x1 + a11 * y1, a00 * x2 + a01 * y2, a10 * x2 + a11 * y2, a00 * x3 + a01 * y3, a10 * x3 + a11 * y3];
}
function drawArc(context, x, y, coords) {
const seg = segments(coords[5], coords[6], coords[0], coords[1], coords[3], coords[4], coords[2], x, y);
for (let i = 0; i < seg.length; ++i) {
const bez = bezier(seg[i]);
context.bezierCurveTo(bez[0], bez[1], bez[2], bez[3], bez[4], bez[5]);
}
}
const addArcToBezierPath = (bezierPath, startAngle, endAngle, cx, cy, rx, ry, counterclockwise = !1) => {
const PI2 = 2 * Math.PI,
sAngle = (startAngle % PI2 + PI2) % PI2;
let deltaAngle,
eAngle = (endAngle % PI2 + PI2) % PI2;
counterclockwise ? (eAngle >= sAngle && (eAngle -= PI2), deltaAngle = eAngle - sAngle) : (eAngle <= sAngle && (eAngle += PI2), deltaAngle = eAngle - sAngle);
const count = Math.ceil(Math.abs(deltaAngle) / (.5 * Math.PI)),
stepAngle = deltaAngle / count;
for (let i = 0; i < count; i++) {
const sa = sAngle + stepAngle * i,
ea = sAngle + stepAngle * (i + 1),
len = 4 / 3 * Math.tan(Math.abs(stepAngle) / 4),
c1 = Math.cos(sa),
s1 = Math.sin(sa),
c2 = Math.cos(ea),
s2 = Math.sin(ea),
x1 = c1 * rx + cx,
y1 = s1 * ry + cy,
x4 = c2 * rx + cx,
y4 = s2 * ry + cy,
sign = counterclockwise ? -1 : 1,
hx = rx * len * sign,
hy = ry * len * sign;
bezierPath.push(x1 - hx * s1, y1 + hy * c1, x4 + hx * s2, y4 - hy * c2, x4, y4);
}
};
const commandFuncs = [(command, context, x, y, sx, sy, z) => context.arc(command[1] * sx + x, command[2] * sy + y, command[3] * (sx + sy) / 2, command[4], command[5], command[6], z), (command, context, x, y, sx, sy, z) => context.arcTo(command[1] * sx + x, command[2] * sy + y, command[3] * sx + x, command[4] * sy + y, command[5] * (sx + sy) / 2, z), (command, context, x, y, sx, sy, z) => context.bezierCurveTo(command[1] * sx + x, command[2] * sy + y, command[3] * sx + x, command[4] * sy + y, command[5] * sx + x, command[6] * sy + y, z), (command, context, x, y) => context.closePath(), (command, context, x, y, sx, sy) => context.ellipse(command[1] * sx + x, command[2] * sy + y, command[3] * sx, command[4] * sy, command[5], command[6], command[7], command[8]), (command, context, x, y, sx, sy, z) => context.lineTo(command[1] * sx + x, command[2] * sy + y, z), (command, context, x, y, sx, sy, z) => context.moveTo(command[1] * sx + x, command[2] * sy + y, z), (command, context, x, y, sx, sy, z) => context.quadraticCurveTo(command[1] * sx + x, command[2] * sy + y, command[3] * sx + x, command[4] * sy + y, z), (command, context, x, y, sx, sy, z) => context.rect(command[1] * sx + x, command[2] * sy + y, command[3] * sx, command[4] * sy, z)];
function renderCommandList(commandList, context, x = 0, y = 0, sx = 1, sy = 1, z) {
for (let i = 0; i < commandList.length; i++) {
const command = commandList[i];
commandFuncs[command[0]](command, context, x, y, sx, sy, z);
}
}
class Curve {
getLength(direction) {
return null != direction ? this.calcProjLength(direction) : (Number.isFinite(this.length) || (this.length = this.calcLength()), this.length);
}
}
function snapLength(xArr, yArr) {
let totalLength = 0;
const count = xArr.length;
for (let i = 0; i < count; i++) {
const x = xArr[i],
y = yArr[i],
nextX = xArr[(i + 1) % count],
nextY = yArr[(i + 1) % count];
totalLength += PointService.distanceNN(x, y, nextX, nextY);
}
return totalLength / 2;
}
function cubicLength(p0, p1, p2, p3, iterationCount) {
return snapLength([p0.x, p1.x, p2.x, p3.x], [p0.y, p1.y, p2.y, p3.y]);
}
function cubicCalc(p0, p1, p2, p3, t) {
const one = 1 - t;
return one * one * one * p0 + 3 * p1 * t * one * one + 3 * p2 * t * t * one + p3 * t * t * t;
}
function cubicPointAt(p0, p1, p2, p3, t) {
const x = cubicCalc(p0.x, p1.x, p2.x, p3.x, t),
y = cubicCalc(p0.y, p1.y, p2.y, p3.y, t);
return new Point(x, y);
}
function quadCalc(p0, p1, p2, t) {
const one = 1 - t;
return one * one * p0 + 2 * one * t * p1 + t * t * p2;
}
function quadPointAt(p0, p1, p2, t) {
const x = quadCalc(p0.x, p1.x, p2.x, t),
y = quadCalc(p0.y, p1.y, p2.y, t);
return new Point(x, y);
}
function quadLength(p0, p1, p2, iterationCount) {
return snapLength([p0.x, p1.x, p2.x], [p0.y, p1.y, p2.y]);
}
function divideCubic(curve, t) {
const {
p0: p0,
p1: p1,
p2: p2,
p3: p3
} = curve,
pt = cubicPointAt(p0, p1, p2, p3, t),
c1 = PointService.pointAtPP(p0, p1, t),
c2 = PointService.pointAtPP(p1, p2, t),
c3 = PointService.pointAtPP(p2, p3, t),
c12 = PointService.pointAtPP(c1, c2, t),
c23 = PointService.pointAtPP(c2, c3, t);
return [new CubicBezierCurve(p0, c1, c12, pt), new CubicBezierCurve(pt, c23, c3, p3)];
}
class CubicBezierCurve extends Curve {
constructor(p0, p1, p2, p3) {
super(), this.type = CurveTypeEnum.CubicBezierCurve, this.p0 = p0, this.p1 = p1, this.p2 = p2, this.p3 = p3;
}
_validPoint() {
return Number.isFinite(this.p0.x + this.p0.y + this.p1.x + this.p1.y + this.p2.x + this.p2.y + this.p3.x + this.p3.y);
}
getPointAt(t) {
if (!1 !== this.defined) return cubicPointAt(this.p0, this.p1, this.p2, this.p3, t);
throw new Error("defined为false的点不能getPointAt");
}
calcLength() {
return this._validPoint() ? cubicLength(this.p0, this.p1, this.p2, this.p3) : 60;
}
calcProjLength(direction) {
return direction === Direction.ROW ? abs(this.p0.x - this.p3.x) : direction === Direction.COLUMN ? abs(this.p0.y - this.p3.y) : 0;
}
getAngleAt(t) {
const minT = max(t - .01, 0),
maxT = min(t + .01, 1),
minP = this.getPointAt(minT),
maxP = this.getPointAt(maxT);
return atan2(maxP.y - minP.y, maxP.x - minP.x);
}
draw(path, x, y, sx, sy, percent) {
if (path.moveTo(this.p0.x * sx + x, this.p0.y * sy + y), percent >= 1) path.bezierCurveTo(this.p1.x * sx + x, this.p1.y * sy + y, this.p2.x * sx + x, this.p2.y * sy + y, this.p3.x * sx + x, this.p3.y * sy + y);else if (percent > 0) {
const [curve1] = divideCubic(this, percent);
path.bezierCurveTo(curve1.p1.x * sx + x, curve1.p1.y * sy + y, curve1.p2.x * sx + x, curve1.p2.y * sy + y, curve1.p3.x * sx + x, curve1.p3.y * sy + y);
}
}
includeX(x) {
const minX = min(this.p0.x, this.p1.x, this.p2.x, this.p3.x),
maxX = max(this.p0.x, this.p1.x, this.p2.x, this.p3.x);
return x >= minX && x <= maxX;
}
getYAt(x) {
const minX = min(this.p0.x, this.p1.x, this.p2.x, this.p3.x),
t = (x - minX) / (max(this.p0.x, this.p1.x, this.p2.x, this.p3.x) - minX);
return this.getPointAt(t).y;
}
}
function divideLinear(curve, t) {
const {
p0: p0,
p1: p1
} = curve,
c1 = PointService.pointAtPP(p0, p1, t);
return [new LineCurve(p0, c1), new LineCurve(c1, p1)];
}
class LineCurve extends Curve {
constructor(p0, p1) {
super(), this.type = CurveTypeEnum.LineCurve, this.p0 = p0, this.p1 = p1;
}
getPointAt(t) {
if (!1 !== this.defined) return PointService.pointAtPP(this.p0, this.p1, t);
throw new Error("defined为false的点不能getPointAt");
}
getAngleAt(t) {
return null == this.angle && (this.angle = atan2(this.p1.y - this.p0.y, this.p1.x - this.p0.x)), this.angle;
}
_validPoint() {
return Number.isFinite(this.p0.x + this.p0.y + this.p1.x + this.p1.y);
}
calcLength() {
return this._validPoint() ? PointService.distancePP(this.p0, this.p1) : 60;
}
calcProjLength(direction) {
return direction === Direction.ROW ? abs(this.p0.x - this.p1.x) : direction === Direction.COLUMN ? abs(this.p0.y - this.p1.y) : 0;
}
draw(path, x, y, sx, sy, percent) {
if (path.moveTo(this.p0.x * sx + x, this.p0.y * sy + y), percent >= 1) path.lineTo(this.p1.x * sx + x, this.p1.y * sy + y);else if (percent > 0) {
const p = this.getPointAt(percent);
path.lineTo(p.x * sx + x, p.y * sy + y);
}
}
includeX(x) {
return x >= this.p0.x && x <= this.p1.x || x >= this.p1.x && x <= this.p0.x;
}
getYAt(x) {
if (this.includeX(x)) {
let minP = this.p0,
maxP = this.p1;
this.p0.x > this.p1.x && (minP = this.p1, maxP = this.p0);
const percent = (x - minP.x) / (maxP.x - minP.x);
return minP.y + percent * (maxP.y - minP.y);
}
return 1 / 0;
}
}
class SegContext {
get endX() {
return this._lastX;
}
get endY() {
return this._lastY;
}
constructor(curveType, direction) {
this.init(curveType, direction);
}
init(curveType, direction) {
this._lastX = this._lastY = this._startX = this._startY = 0, this.curveType = curveType, this.direction = direction, this.curves = [];
}
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y, defined, p) {
const curve = new CubicBezierCurve(new Point(this._lastX, this._lastY), new Point(cp1x, cp1y), new Point(cp2x, cp2y), new Point(x, y));
curve.originP1 = this._lastOriginP, curve.originP2 = p, curve.defined = defined, this.curves.push(curve), this._lastX = x, this._lastY = y, this._lastOriginP = p;
}
closePath() {
if (this.curves.length < 2) return;
const lastCurve = this.curves[this.curves.length - 1];
this.lineTo(this._startX, this._startY, lastCurve.defined, this._startOriginP);
}
ellipse() {
throw new Error("SegContext不支持调用ellipse");
}
lineTo(x, y, defined, p) {
const curve = this.addLinearCurve(x, y, defined, this._lastOriginP, p);
this.curves.push(curve), this._lastX = x, this._lastY = y, this._lastOriginP = p;
}
moveTo(x, y, p) {
return this._lastX = this._startX = x, this._lastY = this._startY = y, this._lastOriginP = p, this._startOriginP = p, this;
}
quadraticCurveTo(cpx, cpy, x, y) {
throw new Error("SegContext不支持调用quadraticCurveTo");
}
clear() {
this.curves = [], this.length = NaN;
}
tryUpdateLength(direction) {
return this.getLength(direction);
}
addLinearCurve(x, y, defined, p1, p2) {
const curve = new LineCurve(new Point(this._lastX, this._lastY), new Point(x, y));
return curve.originP1 = p1, curve.originP2 = p2, curve.defined = defined, curve;
}
getPointAt(t) {
throw new Error("暂未实现");
}
getCurveLengths() {
return [];
}
getLength(direction) {
var _a, _b;
if (direction === Direction.COLUMN) {
if (!this.curves.length) return 0;
const sc = this.curves[0],
ec = this.curves[this.curves.length - 1],
endP = null !== (_a = ec.p3) && void 0 !== _a ? _a : ec.p1;
return abs(sc.p0.y - endP.y);
}
if (direction === Direction.ROW) {
if (!this.curves.length) return 0;
const sc = this.curves[0],
ec = this.curves[this.curves.length - 1],
endP = null !== (_b = ec.p3) && void 0 !== _b ? _b : ec.p1;
return abs(sc.p0.x - endP.x);
}
return Number.isFinite(this.length) || (this.length = this.curves.reduce((l, c) => l + c.getLength(), 0)), this.length;
}
}
class ReflectSegContext extends SegContext {
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y, defined, p) {
return super.bezierCurveTo(cp1y, cp1x, cp2y, cp2x, y, x, defined, p);
}
lineTo(x, y, defined, p) {
return super.lineTo(y, x, defined, p);
}
moveTo(x, y, p) {
return super.moveTo(y, x, p);
}
clear() {
return super.clear();
}
}
function genCurveSegments(path, points, step = 1) {
let defined0 = !1;
for (let i = 0, n = points.length; i <= n; i++) i >= n === defined0 && ((defined0 = !defined0) ? path.lineStart() : path.lineEnd()), defined0 && path.point(points[i]);
}
function genSegContext(curveType, direction, points) {
const curveDirection = null != direction ? direction : abs(points[points.length - 1].x - points[0].x) > abs(points[points.length - 1].y - points[0].y) ? Direction.ROW : Direction.COLUMN;
return "monotoneY" === curveType ? new ReflectSegContext(curveType, curveDirection) : new SegContext(curveType, curveDirection);
}
class Linear {
constructor(context, startPoint) {
this.context = context, startPoint && (this.startPoint = startPoint);
}
areaStart() {
this._line = 0;
}
areaEnd() {
this._line = NaN;
}
lineStart() {
this._point = 0, this.startPoint && this.point(this.startPoint);
}
lineEnd() {
(this._line || 0 !== this._line && 1 === this._point) && this.context.closePath(), this._line = 1 - this._line;
}
point(p) {
const x = p.x,
y = p.y;
switch (this._point) {
case 0:
this._point = 1, this._line ? this.context.lineTo(x, y, !1 !== this._lastDefined && !1 !== p.defined, p) : this.context.moveTo(x, y, p);
break;
case 1:
this._point = 2;
default:
this.context.lineTo(x, y, !1 !== this._lastDefined && !1 !== p.defined, p);
}
this._lastDefined = p.defined;
}
tryUpdateLength() {
return this.context.tryUpdateLength();
}
}
function genLinearSegments(points, params = {}) {
const {
direction: direction,
startPoint: startPoint
} = params;
if (points.length < 2 - Number(!!startPoint)) return null;
const segContext = genSegContext("linear", direction, points);
return genLinearTypeSegments(new Linear(segContext, startPoint), points), segContext;
}
function genLinearTypeSegments(path, points) {
return genCurveSegments(path, points, 1);
}
function point$3(curveClass, x, y, defined, p) {
curveClass.context.bezierCurveTo((2 * curveClass._x0 + curveClass._x1) / 3, (2 * curveClass._y0 + curveClass._y1) / 3, (curveClass._x0 + 2 * curveClass._x1) / 3, (curveClass._y0 + 2 * curveClass._y1) / 3, (curveClass._x0 + 4 * curveClass._x1 + x) / 6, (curveClass._y0 + 4 * curveClass._y1 + y) / 6, defined, curveClass.lastPoint1);
}
class Basis {
constructor(context, startPoint) {
this.context = context, this.startPoint = startPoint;
}
areaStart() {
this._line = 0;
}
areaEnd() {
this._line = NaN;
}
lineStart() {
this._x0 = this._x1 = this._y0 = this._y1 = NaN, this._point = 0, this.startPoint && this.point(this.startPoint);
}
lineEnd() {
if (2 === this._point) point$3(this, 6 * this._x1 - (this._x0 + 4 * this._x1), 6 * this._y1 - (this._y0 + 4 * this._y1), !1 !== this._lastDefined1 && !1 !== this._lastDefined2, this.lastPoint1);
(this._line || 0 !== this._line && 1 === this._point) && this.context.closePath(), this._line = 1 - this._line;
}
point(p) {
const x = p.x,
y = p.y;
switch (this._point) {
case 0:
this._point = 1, this._line ? this.context.lineTo(x, y, !1 !== this._lastDefined1 && !1 !== this._lastDefined2, p) : this.context.moveTo(x, y, p);
break;
case 1:
this._point = 2;
break;
default:
point$3(this, x, y, !1 !== this._lastDefined1 && !1 !== this._lastDefined2);
}
this._x0 = this._x1, this._x1 = x, this._y0 = this._y1, this._y1 = y, this._lastDefined1 = this._lastDefined2, this._lastDefined2 = p.defined, this.lastPoint0 = this.lastPoint1, this.lastPoint1 = p;
}
tryUpdateLength() {
return this.context.tryUpdateLength();
}
}
function genBasisTypeSegments(path, points) {
return genCurveSegments(path, points, 2);
}
function genBasisSegments(points, params = {}) {
const {
direction: direction,
startPoint: startPoint
} = params;
if (points.length < 2 - Number(!!startPoint)) return null;
if (points.length < 3 - Number(!!startPoint)) return genLinearSegments(points, params);
const segContext = genSegContext("basis", direction, points);
return genBasisTypeSegments(new Basis(segContext, startPoint), points), segContext;
}
function sign(x) {
return x < 0 ? -1 : 1;
}
function slope3(curveClass, x2, y2) {
const h0 = curveClass._x1 - curveClass._x0,
h1 = x2 - curveClass._x1,
s0 = (curveClass._y1 - curveClass._y0) / (h0 || Number(h1 < 0 && -0)),
s1 = (y2 - curveClass._y1) / (h1 || Number(h0 < 0 && -0)),
p = (s0 * h1 + s1 * h0) / (h0 + h1);
return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), .5 * Math.abs(p)) || 0;
}
function slope2(curveClass, t) {
const h = curveClass._x1 - curveClass._x0;
return h ? (3 * (curveClass._y1 - curveClass._y0) / h - t) / 2 : t;
}
function point$2(curveClass, t0, t1, defined, p) {
const x0 = curveClass._x0,
y0 = curveClass._y0,
x1 = curveClass._x1,
y1 = curveClass._y1,
dx = (x1 - x0) / 3;
curveClass.context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1, defined, curveClass.lastPoint1);
}
class MonotoneX {
constructor(context, startPoint) {
this.context = context, this.startPoint = startPoint;
}
areaStart() {
this._line = 0;
}
areaEnd() {
this._line = NaN;
}
lineStart() {
this._x0 = this._x1 = this._y0 = this._y1 = this._t0 = NaN, this._point = 0, this.startPoint && this.point(this.startPoint);
}
lineEnd() {
switch (this._point) {
case 2:
this.context.lineTo(this._x1, this._y1, !1 !== this._lastDefined1 && !1 !== this._lastDefined2, this.lastPoint1);
break;
case 3:
point$2(this, this._t0, slope2(this, this._t0), !1 !== this._lastDefined1 && !1 !== this._lastDefined2, this.lastPoint1);
}
(this._line || 0 !== this._line && 1 === this._point) && this.context.closePath(), this._line = 1 - this._line;
}
point(p) {
let t1 = NaN;
const x = p.x,
y = p.y;
switch (this._point) {
case 0:
this._point = 1, this._line ? this.context.lineTo(x, y, !1 !== this._lastDefined1 && !1 !== this._lastDefined2, p) : this.context.moveTo(x, y, p);
break;
case 1:
this._point = 2;
break;
case 2:
this._point = 3, point$2(this, slope2(this, t1 = slope3(this, x, y)), t1, !1 !== this._lastDefined1 && !1 !== this._lastDefined2);
break;
default:
point$2(this, this._t0, t1 = slope3(this, x, y), !1 !== this._lastDefined1 && !1 !== this._lastDefined2);
}
this._x0 = this._x1, this._x1 = x, this._y0 = this._y1, this._y1 = y, this._t0 = t1, this._lastDefined1 = this._lastDefined2, this._lastDefined2 = !1 !== p.defined, this.lastPoint0 = this.lastPoint1, this.lastPoint1 = p;
}
tryUpdateLength() {
return this.context.tryUpdateLength();
}
}
class MonotoneY extends MonotoneX {
constructor(context, startPoint) {
super(context, startPoint);
}
point(p) {
return super.point({
y: p.x,
x: p.y,
defined: p.defined
});
}
}
function genMonotoneXTypeSegments(path, points) {
return genCurveSegments(path, points, 2);
}
function genMonotoneXSegments(points, params = {}) {
const {
direction: direction,
startPoint: startPoint
} = params;
if (points.length < 2 - Number(!!startPoint)) return null;
if (points.length < 3 - Number(!!startPoint)) return genLinearSegments(points, params);
const segContext = genSegContext("monotoneX", direction, points);
return genMonotoneXTypeSegments(new MonotoneX(segContext, startPoint), points), segContext;
}
function genMonotoneYTypeSegments(path, points) {
return genCurveSegments(path, points, 2);
}
function genMonotoneYSegments(points, params = {}) {
const {
direction: direction,
startPoint: startPoint
} = params;
if (points.length < 2 - Number(!!startPoint)) return null;
if (points.length < 3 - Number(!!startPoint)) return genLinearSegments(points, params);
const segContext = genSegContext("monotoneY", direction, points);
return genMonotoneYTypeSegments(new MonotoneY(segContext, startPoint), points), segContext;
}
let Step$1 = class Step {
constructor(context, t = .5, startPoint) {
this.context = context, this._t = t, this.startPoint = startPoint;
}
areaStart() {
this._line = 0;
}
areaEnd() {
this._line = NaN;
}
lineStart() {
this._x = this._y = NaN, this._point = 0, this.startPoint && this.point(this.startPoint);
}
lineEnd() {
0 < this._t && this._t < 1 && 2 === this._point && this.context.lineTo(this._x, this._y, !1 !== this._lastDefined, this.lastPoint), (this._line || 0 !== this._line && 1 === this._point) && this.context.closePath(), this._line >= 0 && (this._t = 1 - this._t, this._line = 1 - this._line);
}
point(p) {
const x = p.x,
y = p.y;
switch (this._point) {
case 0:
this._point = 1, this._line ? this.context.lineTo(x, y, !1 !== this._lastDefined && !1 !== p.defined, p) : this.context.moveTo(x, y, p);
break;
case 1:
this._point = 2;
default:
if (this._t <= 0) this.context.lineTo(this._x, y, !1 !== this._lastDefined && !1 !== p.defined, this.lastPoint), this.context.lineTo(x, y, !1 !== this._lastDefined && !1 !== p.defined, p);else {
const x1 = this._x * (1 - this._t) + x * this._t;
.5 === this._t ? this.context.lineTo(x1, this._y, !1 !== this._lastDefined, this.lastPoint) : this.context.lineTo(x1, this._y, !1 !== this._lastDefined && !1 !== p.defined, this.lastPoint), this.context.lineTo(x1, y, !1 !== this._lastDefined && !1 !== p.defined, p);
}
}
this._lastDefined = p.defined, this._x = x, this._y = y, this.lastPoint = p;
}
tryUpdateLength() {
return this.context.tryUpdateLength();
}
};
class StepClosed extends Step$1 {
lineEnd() {
this.context.closePath();
}
}
function genStepSegments(points, t, params = {}) {
const {
direction: direction,
startPoint: startPoint
} = params;
if (points.length < 2 - Number(!!startPoint)) return null;
const segContext = new SegContext("step", null != direction ? direction : abs(points[points.length - 1].x - points[0].x) > abs(points[points.length - 1].y - points[0].y) ? Direction.ROW : Direction.COLUMN);
return genStepTypeSegments(new Step$1(segContext, t, startPoint), points), segContext;
}
function genStepTypeSegments(path, points) {
return genCurveSegments(path, points, 1);
}
function genStepClosedSegments(points, t, params = {}) {
const {
direction: direction,
startPoint: startPoint
} = params;
if (points.length < 2 - Number(!!startPoint)) return null;
const segContext = new SegContext("step", null != direction ? direction : abs(points[points.length - 1].x - points[0].x) > abs(points[points.length - 1].y - poin