modern-canvas 0.1.2 → 0.1.4

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/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { extend, colord } from 'colord';
2
2
  import namesPlugin from 'colord/plugins/names';
3
- import earcut from 'earcut';
3
+ import { Path2D, strokeTriangulate, BoundingBox } from 'modern-path2d';
4
4
  import { getDefaultTextStyle, getDefaultTransformStyle } from 'modern-idoc';
5
5
  import { textDefaultStyle, Text } from 'modern-text';
6
6
 
@@ -617,13 +617,13 @@ class Geometry extends Resource {
617
617
  }
618
618
  }
619
619
 
620
- var __defProp$B = Object.defineProperty;
621
- var __decorateClass$B = (decorators, target, key, kind) => {
620
+ var __defProp$A = Object.defineProperty;
621
+ var __decorateClass$A = (decorators, target, key, kind) => {
622
622
  var result = void 0 ;
623
623
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
624
624
  if (decorator = decorators[i])
625
625
  result = (decorator(target, key, result) ) || result;
626
- if (result) __defProp$B(target, key, result);
626
+ if (result) __defProp$A(target, key, result);
627
627
  return result;
628
628
  };
629
629
  class IndexBuffer extends Resource {
@@ -667,20 +667,20 @@ class IndexBuffer extends Resource {
667
667
  return result;
668
668
  }
669
669
  }
670
- __decorateClass$B([
670
+ __decorateClass$A([
671
671
  protectedProperty({ default: null })
672
672
  ], IndexBuffer.prototype, "data");
673
- __decorateClass$B([
673
+ __decorateClass$A([
674
674
  protectedProperty({ default: false })
675
675
  ], IndexBuffer.prototype, "dynamic");
676
676
 
677
- var __defProp$A = Object.defineProperty;
678
- var __decorateClass$A = (decorators, target, key, kind) => {
677
+ var __defProp$z = Object.defineProperty;
678
+ var __decorateClass$z = (decorators, target, key, kind) => {
679
679
  var result = void 0 ;
680
680
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
681
681
  if (decorator = decorators[i])
682
682
  result = (decorator(target, key, result) ) || result;
683
- if (result) __defProp$A(target, key, result);
683
+ if (result) __defProp$z(target, key, result);
684
684
  return result;
685
685
  };
686
686
  class VertexBuffer extends Resource {
@@ -724,20 +724,20 @@ class VertexBuffer extends Resource {
724
724
  return result;
725
725
  }
726
726
  }
727
- __decorateClass$A([
727
+ __decorateClass$z([
728
728
  protectedProperty({ default: null })
729
729
  ], VertexBuffer.prototype, "data");
730
- __decorateClass$A([
730
+ __decorateClass$z([
731
731
  protectedProperty({ default: false })
732
732
  ], VertexBuffer.prototype, "dynamic");
733
733
 
734
- var __defProp$z = Object.defineProperty;
735
- var __decorateClass$z = (decorators, target, key, kind) => {
734
+ var __defProp$y = Object.defineProperty;
735
+ var __decorateClass$y = (decorators, target, key, kind) => {
736
736
  var result = void 0 ;
737
737
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
738
738
  if (decorator = decorators[i])
739
739
  result = (decorator(target, key, result) ) || result;
740
- if (result) __defProp$z(target, key, result);
740
+ if (result) __defProp$y(target, key, result);
741
741
  return result;
742
742
  };
743
743
  class VertexAttribute extends Resource {
@@ -774,25 +774,25 @@ class VertexAttribute extends Resource {
774
774
  return result;
775
775
  }
776
776
  }
777
- __decorateClass$z([
777
+ __decorateClass$y([
778
778
  protectedProperty()
779
779
  ], VertexAttribute.prototype, "buffer");
780
- __decorateClass$z([
780
+ __decorateClass$y([
781
781
  protectedProperty({ default: 0 })
782
782
  ], VertexAttribute.prototype, "size");
783
- __decorateClass$z([
783
+ __decorateClass$y([
784
784
  protectedProperty({ default: false })
785
785
  ], VertexAttribute.prototype, "normalized");
786
- __decorateClass$z([
786
+ __decorateClass$y([
787
787
  protectedProperty({ default: "float" })
788
788
  ], VertexAttribute.prototype, "type");
789
- __decorateClass$z([
789
+ __decorateClass$y([
790
790
  protectedProperty()
791
791
  ], VertexAttribute.prototype, "stride");
792
- __decorateClass$z([
792
+ __decorateClass$y([
793
793
  protectedProperty()
794
794
  ], VertexAttribute.prototype, "offset");
795
- __decorateClass$z([
795
+ __decorateClass$y([
796
796
  protectedProperty()
797
797
  ], VertexAttribute.prototype, "divisor");
798
798
 
@@ -976,13 +976,13 @@ class UvGeometry extends Geometry {
976
976
  }
977
977
  }
978
978
 
979
- var __defProp$y = Object.defineProperty;
980
- var __decorateClass$y = (decorators, target, key, kind) => {
979
+ var __defProp$x = Object.defineProperty;
980
+ var __decorateClass$x = (decorators, target, key, kind) => {
981
981
  var result = void 0 ;
982
982
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
983
983
  if (decorator = decorators[i])
984
984
  result = (decorator(target, key, result) ) || result;
985
- if (result) __defProp$y(target, key, result);
985
+ if (result) __defProp$x(target, key, result);
986
986
  return result;
987
987
  };
988
988
  class MainLoop extends _Object {
@@ -1023,1731 +1023,182 @@ class MainLoop extends _Object {
1023
1023
  }
1024
1024
  }
1025
1025
  }
1026
- __decorateClass$y([
1026
+ __decorateClass$x([
1027
1027
  property({ default: 24 })
1028
1028
  ], MainLoop.prototype, "fps");
1029
- __decorateClass$y([
1029
+ __decorateClass$x([
1030
1030
  property({ default: 1 })
1031
1031
  ], MainLoop.prototype, "speed");
1032
1032
 
1033
- const RECURSION_LIMIT$1 = 8;
1034
- const FLT_EPSILON$1 = 11920929e-14;
1035
- const PATH_DISTANCE_EPSILON$1 = 1;
1036
- function buildAdaptiveBezier(points, sX, sY, cp1x, cp1y, cp2x, cp2y, eX, eY, smoothness = 0.5) {
1037
- const scale = 1;
1038
- const smoothing = Math.min(
1039
- 0.99,
1040
- // a value of 1.0 actually inverts smoothing, so we cap it at 0.99
1041
- Math.max(0, smoothness)
1042
- );
1043
- let distanceTolerance = (PATH_DISTANCE_EPSILON$1 - smoothing) / scale;
1044
- distanceTolerance *= distanceTolerance;
1045
- begin$1(sX, sY, cp1x, cp1y, cp2x, cp2y, eX, eY, points, distanceTolerance);
1046
- return points;
1047
- }
1048
- function begin$1(sX, sY, cp1x, cp1y, cp2x, cp2y, eX, eY, points, distanceTolerance) {
1049
- recursive$1(sX, sY, cp1x, cp1y, cp2x, cp2y, eX, eY, points, distanceTolerance, 0);
1050
- points.push(eX, eY);
1051
- }
1052
- function recursive$1(x1, y1, x2, y2, x3, y3, x4, y4, points, distanceTolerance, level) {
1053
- if (level > RECURSION_LIMIT$1)
1054
- return;
1055
- const x12 = (x1 + x2) / 2;
1056
- const y12 = (y1 + y2) / 2;
1057
- const x23 = (x2 + x3) / 2;
1058
- const y23 = (y2 + y3) / 2;
1059
- const x34 = (x3 + x4) / 2;
1060
- const y34 = (y3 + y4) / 2;
1061
- const x123 = (x12 + x23) / 2;
1062
- const y123 = (y12 + y23) / 2;
1063
- const x234 = (x23 + x34) / 2;
1064
- const y234 = (y23 + y34) / 2;
1065
- const x1234 = (x123 + x234) / 2;
1066
- const y1234 = (y123 + y234) / 2;
1067
- if (level > 0) {
1068
- let dx = x4 - x1;
1069
- let dy = y4 - y1;
1070
- const d2 = Math.abs((x2 - x4) * dy - (y2 - y4) * dx);
1071
- const d3 = Math.abs((x3 - x4) * dy - (y3 - y4) * dx);
1072
- if (d2 > FLT_EPSILON$1 && d3 > FLT_EPSILON$1) {
1073
- if ((d2 + d3) * (d2 + d3) <= distanceTolerance * (dx * dx + dy * dy)) {
1074
- {
1075
- points.push(x1234, y1234);
1076
- return;
1077
- }
1033
+ class Vector extends EventEmitter {
1034
+ constructor(dim) {
1035
+ super();
1036
+ this.dim = dim;
1037
+ }
1038
+ _array = [];
1039
+ get length() {
1040
+ return this.dim;
1041
+ }
1042
+ _operate(operator, target, output) {
1043
+ const { dim: length, _array: array } = this;
1044
+ let targetArray;
1045
+ if (typeof target === "number") {
1046
+ targetArray = Array.from({ length }, () => target);
1047
+ } else if (target instanceof Matrix || target instanceof Vector) {
1048
+ targetArray = target.toArray();
1049
+ } else {
1050
+ targetArray = target;
1051
+ }
1052
+ let outputObject;
1053
+ let outputArray = [];
1054
+ if (!output) {
1055
+ outputObject = this;
1056
+ } else if (output instanceof Vector) {
1057
+ outputObject = output;
1058
+ } else {
1059
+ outputArray = output;
1060
+ }
1061
+ if (target instanceof Matrix) {
1062
+ const { cols } = target;
1063
+ switch (operator) {
1064
+ case "*":
1065
+ for (let x = 0; x < length; x++) {
1066
+ let val = 0;
1067
+ for (let y = 0; y < length; y++) {
1068
+ val += array[x] * targetArray[y * cols + x];
1069
+ }
1070
+ outputArray[x] = val;
1071
+ }
1072
+ break;
1073
+ default:
1074
+ throw new Error(`Not support operator in '${this.toName()} ${operator} ${target.toName()}'`);
1078
1075
  }
1079
- } else if (d2 > FLT_EPSILON$1) {
1080
- if (d2 * d2 <= distanceTolerance * (dx * dx + dy * dy)) {
1081
- {
1082
- points.push(x1234, y1234);
1083
- return;
1076
+ } else {
1077
+ switch (operator) {
1078
+ case "+":
1079
+ for (let i = 0; i < length; i++) {
1080
+ outputArray[i] = array[i] + targetArray[i];
1081
+ }
1082
+ break;
1083
+ case "-":
1084
+ for (let i = 0; i < length; i++) {
1085
+ outputArray[i] = array[i] - targetArray[i];
1086
+ }
1087
+ break;
1088
+ case "*":
1089
+ for (let i = 0; i < length; i++) {
1090
+ outputArray[i] = array[i] * targetArray[i];
1091
+ }
1092
+ break;
1093
+ case "/":
1094
+ for (let i = 0; i < length; i++) {
1095
+ outputArray[i] = array[i] / targetArray[i];
1096
+ }
1097
+ break;
1098
+ case "rot": {
1099
+ const c = Math.cos(targetArray[0]);
1100
+ const s = Math.sin(targetArray[0]);
1101
+ outputArray[0] = array[0] * c - array[1] * s;
1102
+ outputArray[1] = array[1] * c + array[0] * s;
1103
+ break;
1084
1104
  }
1085
- }
1086
- } else if (d3 > FLT_EPSILON$1) {
1087
- if (d3 * d3 <= distanceTolerance * (dx * dx + dy * dy)) {
1088
- {
1089
- points.push(x1234, y1234);
1090
- return;
1105
+ case "==": {
1106
+ let flag = true;
1107
+ for (let i = 0; i < length; i++) {
1108
+ flag = flag && array[i] === targetArray[i];
1109
+ }
1110
+ return flag;
1091
1111
  }
1112
+ case "=":
1113
+ for (let i = 0; i < length; i++) {
1114
+ const val = targetArray[i];
1115
+ if (val !== void 0) {
1116
+ array[i] = val;
1117
+ }
1118
+ }
1119
+ this._emitUpdate(array);
1120
+ return this;
1121
+ default:
1122
+ throw new Error(`Not support operator in '${this.toName()} ${operator} Vector'`);
1092
1123
  }
1093
- } else {
1094
- dx = x1234 - (x1 + x4) / 2;
1095
- dy = y1234 - (y1 + y4) / 2;
1096
- if (dx * dx + dy * dy <= distanceTolerance) {
1097
- points.push(x1234, y1234);
1098
- return;
1099
- }
1100
- }
1101
- }
1102
- recursive$1(x1, y1, x12, y12, x123, y123, x1234, y1234, points, distanceTolerance, level + 1);
1103
- recursive$1(x1234, y1234, x234, y234, x34, y34, x4, y4, points, distanceTolerance, level + 1);
1104
- }
1105
-
1106
- const RECURSION_LIMIT = 8;
1107
- const FLT_EPSILON = 11920929e-14;
1108
- const PATH_DISTANCE_EPSILON = 1;
1109
- function buildAdaptiveQuadratic(points, sX, sY, cp1x, cp1y, eX, eY, smoothness = 0.5) {
1110
- const scale = 1;
1111
- const smoothing = Math.min(
1112
- 0.99,
1113
- // a value of 1.0 actually inverts smoothing, so we cap it at 0.99
1114
- Math.max(0, smoothness)
1115
- );
1116
- let distanceTolerance = (PATH_DISTANCE_EPSILON - smoothing) / scale;
1117
- distanceTolerance *= distanceTolerance;
1118
- begin(sX, sY, cp1x, cp1y, eX, eY, points, distanceTolerance);
1119
- return points;
1120
- }
1121
- function begin(sX, sY, cp1x, cp1y, eX, eY, points, distanceTolerance) {
1122
- recursive(points, sX, sY, cp1x, cp1y, eX, eY, distanceTolerance, 0);
1123
- points.push(eX, eY);
1124
- }
1125
- function recursive(points, x1, y1, x2, y2, x3, y3, distanceTolerance, level) {
1126
- if (level > RECURSION_LIMIT)
1127
- return;
1128
- const x12 = (x1 + x2) / 2;
1129
- const y12 = (y1 + y2) / 2;
1130
- const x23 = (x2 + x3) / 2;
1131
- const y23 = (y2 + y3) / 2;
1132
- const x123 = (x12 + x23) / 2;
1133
- const y123 = (y12 + y23) / 2;
1134
- let dx = x3 - x1;
1135
- let dy = y3 - y1;
1136
- const d = Math.abs((x2 - x3) * dy - (y2 - y3) * dx);
1137
- if (d > FLT_EPSILON) {
1138
- if (d * d <= distanceTolerance * (dx * dx + dy * dy)) {
1139
- {
1140
- points.push(x123, y123);
1141
- return;
1142
- }
1143
- }
1144
- } else {
1145
- dx = x123 - (x1 + x3) / 2;
1146
- dy = y123 - (y1 + y3) / 2;
1147
- if (dx * dx + dy * dy <= distanceTolerance) {
1148
- points.push(x123, y123);
1149
- return;
1150
- }
1151
- }
1152
- recursive(points, x1, y1, x12, y12, x123, y123, distanceTolerance, level + 1);
1153
- recursive(points, x123, y123, x23, y23, x3, y3, distanceTolerance, level + 1);
1154
- }
1155
-
1156
- function buildArc(points, x, y, radius, start, end, clockwise, steps) {
1157
- let dist = Math.abs(start - end);
1158
- if (!clockwise && start > end) {
1159
- dist = 2 * Math.PI - dist;
1160
- } else if (clockwise && end > start) {
1161
- dist = 2 * Math.PI - dist;
1162
- }
1163
- steps = steps || Math.max(6, Math.floor(6 * radius ** (1 / 3) * (dist / Math.PI)));
1164
- steps = Math.max(steps, 3);
1165
- let f = dist / steps;
1166
- let t = start;
1167
- f *= clockwise ? -1 : 1;
1168
- for (let i = 0; i < steps + 1; i++) {
1169
- const cs = Math.cos(t);
1170
- const sn = Math.sin(t);
1171
- const nx = x + cs * radius;
1172
- const ny = y + sn * radius;
1173
- points.push(nx, ny);
1174
- t += f;
1175
- }
1176
- }
1177
-
1178
- function buildArcTo(points, x1, y1, x2, y2, radius) {
1179
- const fromX = points[points.length - 2];
1180
- const fromY = points[points.length - 1];
1181
- const a1 = fromY - y1;
1182
- const b1 = fromX - x1;
1183
- const a2 = y2 - y1;
1184
- const b2 = x2 - x1;
1185
- const mm = Math.abs(a1 * b2 - b1 * a2);
1186
- if (mm < 1e-8 || radius === 0) {
1187
- if (points[points.length - 2] !== x1 || points[points.length - 1] !== y1) {
1188
- points.push(x1, y1);
1189
- }
1190
- return;
1191
- }
1192
- const dd = a1 * a1 + b1 * b1;
1193
- const cc = a2 * a2 + b2 * b2;
1194
- const tt = a1 * a2 + b1 * b2;
1195
- const k1 = radius * Math.sqrt(dd) / mm;
1196
- const k2 = radius * Math.sqrt(cc) / mm;
1197
- const j1 = k1 * tt / dd;
1198
- const j2 = k2 * tt / cc;
1199
- const cx = k1 * b2 + k2 * b1;
1200
- const cy = k1 * a2 + k2 * a1;
1201
- const px = b1 * (k2 + j1);
1202
- const py = a1 * (k2 + j1);
1203
- const qx = b2 * (k1 + j2);
1204
- const qy = a2 * (k1 + j2);
1205
- const startAngle = Math.atan2(py - cy, px - cx);
1206
- const endAngle = Math.atan2(qy - cy, qx - cx);
1207
- buildArc(points, cx + x1, cy + y1, radius, startAngle, endAngle, b1 * a2 > b2 * a1);
1208
- }
1209
-
1210
- const TAU = Math.PI * 2;
1211
- const out = {
1212
- centerX: 0,
1213
- centerY: 0,
1214
- ang1: 0,
1215
- ang2: 0
1216
- };
1217
- function mapToEllipse({ x, y }, rx, ry, cosPhi, sinPhi, centerX, centerY, out2) {
1218
- x *= rx;
1219
- y *= ry;
1220
- const xp = cosPhi * x - sinPhi * y;
1221
- const yp = sinPhi * x + cosPhi * y;
1222
- out2.x = xp + centerX;
1223
- out2.y = yp + centerY;
1224
- return out2;
1225
- }
1226
- function approxUnitArc(ang1, ang2) {
1227
- const a1 = ang2 === -1.5707963267948966 ? -0.551915024494 : 4 / 3 * Math.tan(ang2 / 4);
1228
- const a = ang2 === 1.5707963267948966 ? 0.551915024494 : a1;
1229
- const x1 = Math.cos(ang1);
1230
- const y1 = Math.sin(ang1);
1231
- const x2 = Math.cos(ang1 + ang2);
1232
- const y2 = Math.sin(ang1 + ang2);
1233
- return [
1234
- {
1235
- x: x1 - y1 * a,
1236
- y: y1 + x1 * a
1237
- },
1238
- {
1239
- x: x2 + y2 * a,
1240
- y: y2 - x2 * a
1241
- },
1242
- {
1243
- x: x2,
1244
- y: y2
1245
1124
  }
1246
- ];
1247
- }
1248
- function vectorAngle(ux, uy, vx, vy) {
1249
- const sign = ux * vy - uy * vx < 0 ? -1 : 1;
1250
- let dot = ux * vx + uy * vy;
1251
- if (dot > 1) {
1252
- dot = 1;
1253
- }
1254
- if (dot < -1) {
1255
- dot = -1;
1256
- }
1257
- return sign * Math.acos(dot);
1258
- }
1259
- function getArcCenter(px, py, cx, cy, rx, ry, largeArcFlag, sweepFlag, sinPhi, cosPhi, pxp, pyp, out2) {
1260
- const rxSq = rx ** 2;
1261
- const rySq = ry ** 2;
1262
- const pxpSq = pxp ** 2;
1263
- const pypSq = pyp ** 2;
1264
- let radicant = rxSq * rySq - rxSq * pypSq - rySq * pxpSq;
1265
- if (radicant < 0) {
1266
- radicant = 0;
1267
- }
1268
- radicant /= rxSq * pypSq + rySq * pxpSq;
1269
- radicant = Math.sqrt(radicant) * (largeArcFlag === sweepFlag ? -1 : 1);
1270
- const centerXp = radicant * rx / ry * pyp;
1271
- const centerYp = radicant * -ry / rx * pxp;
1272
- const centerX = cosPhi * centerXp - sinPhi * centerYp + (px + cx) / 2;
1273
- const centerY = sinPhi * centerXp + cosPhi * centerYp + (py + cy) / 2;
1274
- const vx1 = (pxp - centerXp) / rx;
1275
- const vy1 = (pyp - centerYp) / ry;
1276
- const vx2 = (-pxp - centerXp) / rx;
1277
- const vy2 = (-pyp - centerYp) / ry;
1278
- const ang1 = vectorAngle(1, 0, vx1, vy1);
1279
- let ang2 = vectorAngle(vx1, vy1, vx2, vy2);
1280
- if (sweepFlag === 0 && ang2 > 0) {
1281
- ang2 -= TAU;
1282
- }
1283
- if (sweepFlag === 1 && ang2 < 0) {
1284
- ang2 += TAU;
1285
- }
1286
- out2.centerX = centerX;
1287
- out2.centerY = centerY;
1288
- out2.ang1 = ang1;
1289
- out2.ang2 = ang2;
1290
- }
1291
- function buildArcToSvg(points, px, py, cx, cy, rx, ry, xAxisRotation = 0, largeArcFlag = 0, sweepFlag = 0) {
1292
- if (rx === 0 || ry === 0) {
1293
- return;
1294
- }
1295
- const sinPhi = Math.sin(xAxisRotation * TAU / 360);
1296
- const cosPhi = Math.cos(xAxisRotation * TAU / 360);
1297
- const pxp = cosPhi * (px - cx) / 2 + sinPhi * (py - cy) / 2;
1298
- const pyp = -sinPhi * (px - cx) / 2 + cosPhi * (py - cy) / 2;
1299
- if (pxp === 0 && pyp === 0) {
1300
- return;
1301
- }
1302
- rx = Math.abs(rx);
1303
- ry = Math.abs(ry);
1304
- const lambda = pxp ** 2 / rx ** 2 + pyp ** 2 / ry ** 2;
1305
- if (lambda > 1) {
1306
- rx *= Math.sqrt(lambda);
1307
- ry *= Math.sqrt(lambda);
1308
- }
1309
- getArcCenter(px, py, cx, cy, rx, ry, largeArcFlag, sweepFlag, sinPhi, cosPhi, pxp, pyp, out);
1310
- let { ang1, ang2 } = out;
1311
- const { centerX, centerY } = out;
1312
- let ratio = Math.abs(ang2) / (TAU / 4);
1313
- if (Math.abs(1 - ratio) < 1e-7) {
1314
- ratio = 1;
1315
- }
1316
- const segments = Math.max(Math.ceil(ratio), 1);
1317
- ang2 /= segments;
1318
- let lastX = points[points.length - 2];
1319
- let lastY = points[points.length - 1];
1320
- const outCurvePoint = { x: 0, y: 0 };
1321
- for (let i = 0; i < segments; i++) {
1322
- const curve = approxUnitArc(ang1, ang2);
1323
- const { x: x1, y: y1 } = mapToEllipse(curve[0], rx, ry, cosPhi, sinPhi, centerX, centerY, outCurvePoint);
1324
- const { x: x2, y: y2 } = mapToEllipse(curve[1], rx, ry, cosPhi, sinPhi, centerX, centerY, outCurvePoint);
1325
- const { x, y } = mapToEllipse(curve[2], rx, ry, cosPhi, sinPhi, centerX, centerY, outCurvePoint);
1326
- buildAdaptiveBezier(points, lastX, lastY, x1, y1, x2, y2, x, y);
1327
- lastX = x;
1328
- lastY = y;
1329
- ang1 += ang2;
1330
- }
1331
- }
1332
-
1333
- class Circle {
1334
- constructor(x = 0, y = 0, radius = 0) {
1335
- this.x = x;
1336
- this.y = y;
1337
- this.radius = radius;
1338
- }
1339
- contains(x, y) {
1340
- if (this.radius <= 0)
1341
- return false;
1342
- const r2 = this.radius * this.radius;
1343
- let dx = this.x - x;
1344
- let dy = this.y - y;
1345
- dx *= dx;
1346
- dy *= dy;
1347
- return dx + dy <= r2;
1348
- }
1349
- strokeContains(x, y, width) {
1350
- if (this.radius === 0)
1351
- return false;
1352
- const dx = this.x - x;
1353
- const dy = this.y - y;
1354
- const r = this.radius;
1355
- const w2 = width / 2;
1356
- const distance = Math.sqrt(dx * dx + dy * dy);
1357
- return distance < r + w2 && distance > r - w2;
1358
- }
1359
- clone() {
1360
- return new Circle(this.x, this.y, this.radius);
1361
- }
1362
- copyFrom(circle) {
1363
- this.x = circle.x;
1364
- this.y = circle.y;
1365
- this.radius = circle.radius;
1366
- return this;
1125
+ return outputObject?.set(outputArray) ?? outputArray;
1367
1126
  }
1368
- copyTo(circle) {
1369
- circle.copyFrom(this);
1370
- return circle;
1127
+ add(value, output) {
1128
+ return this._operate("+", value, output);
1371
1129
  }
1372
- getBounds(out) {
1373
- out = out || new Rectangle();
1374
- out.x = this.x - this.radius;
1375
- out.y = this.y - this.radius;
1376
- out.width = this.radius * 2;
1377
- out.height = this.radius * 2;
1378
- return out;
1130
+ sub(value, output) {
1131
+ return this._operate("-", value, output);
1379
1132
  }
1380
- buildOutline(points) {
1381
- buildCircle.build(this, points);
1133
+ multiply(value, output) {
1134
+ return this._operate("*", value, output);
1382
1135
  }
1383
- buildGeometry(vertices, indices) {
1384
- const points = [];
1385
- this.buildOutline(points);
1386
- buildCircle.triangulate(points, vertices, 2, 0, indices, 0);
1136
+ divide(value, output) {
1137
+ return this._operate("/", value, output);
1387
1138
  }
1388
- }
1389
-
1390
- class Ellipse {
1391
- constructor(x = 0, y = 0, halfWidth = 0, halfHeight = 0) {
1392
- this.x = x;
1393
- this.y = y;
1394
- this.halfWidth = halfWidth;
1395
- this.halfHeight = halfHeight;
1139
+ rotate(angle) {
1140
+ return this._operate("rot", angle);
1396
1141
  }
1397
- contains(x, y) {
1398
- if (this.halfWidth <= 0 || this.halfHeight <= 0) {
1399
- return false;
1142
+ set(value, ...args) {
1143
+ if (args.length && typeof value === "number") {
1144
+ value = [value, ...args];
1400
1145
  }
1401
- let normx = (x - this.x) / this.halfWidth;
1402
- let normy = (y - this.y) / this.halfHeight;
1403
- normx *= normx;
1404
- normy *= normy;
1405
- return normx + normy <= 1;
1146
+ return this._operate("=", value);
1406
1147
  }
1407
- strokeContains(x, y, width) {
1408
- const { halfWidth, halfHeight } = this;
1409
- if (halfWidth <= 0 || halfHeight <= 0) {
1410
- return false;
1411
- }
1412
- const halfStrokeWidth = width / 2;
1413
- const innerA = halfWidth - halfStrokeWidth;
1414
- const innerB = halfHeight - halfStrokeWidth;
1415
- const outerA = halfWidth + halfStrokeWidth;
1416
- const outerB = halfHeight + halfStrokeWidth;
1417
- const normalizedX = x - this.x;
1418
- const normalizedY = y - this.y;
1419
- const innerEllipse = normalizedX * normalizedX / (innerA * innerA) + normalizedY * normalizedY / (innerB * innerB);
1420
- const outerEllipse = normalizedX * normalizedX / (outerA * outerA) + normalizedY * normalizedY / (outerB * outerB);
1421
- return innerEllipse > 1 && outerEllipse <= 1;
1148
+ equals(value) {
1149
+ return this._operate("==", value);
1422
1150
  }
1423
1151
  clone() {
1424
- return new Ellipse(this.x, this.y, this.halfWidth, this.halfHeight);
1152
+ const cloned = new this.constructor();
1153
+ cloned.set(this.toArray());
1154
+ return cloned;
1425
1155
  }
1426
- copyFrom(ellipse) {
1427
- this.x = ellipse.x;
1428
- this.y = ellipse.y;
1429
- this.halfWidth = ellipse.halfWidth;
1430
- this.halfHeight = ellipse.halfHeight;
1156
+ onUpdate(callback) {
1157
+ this.on("update", callback);
1431
1158
  return this;
1432
1159
  }
1433
- copyTo(ellipse) {
1434
- ellipse.copyFrom(this);
1435
- return ellipse;
1436
- }
1437
- getBounds() {
1438
- return new Rectangle(this.x - this.halfWidth, this.y - this.halfHeight, this.halfWidth * 2, this.halfHeight * 2);
1439
- }
1440
- buildOutline(points) {
1441
- buildCircle.build(this, points);
1442
- }
1443
- buildGeometry(vertices, indices) {
1444
- const points = [];
1445
- this.buildOutline(points);
1446
- buildCircle.triangulate(points, vertices, 2, 0, indices, 0);
1447
- }
1448
- }
1449
-
1450
- function squaredDistanceToLineSegment(x, y, x1, y1, x2, y2) {
1451
- const a = x - x1;
1452
- const b = y - y1;
1453
- const c = x2 - x1;
1454
- const d = y2 - y1;
1455
- const dot = a * c + b * d;
1456
- const lenSq = c * c + d * d;
1457
- let param = -1;
1458
- if (lenSq !== 0) {
1459
- param = dot / lenSq;
1460
- }
1461
- let xx;
1462
- let yy;
1463
- if (param < 0) {
1464
- xx = x1;
1465
- yy = y1;
1466
- } else if (param > 1) {
1467
- xx = x2;
1468
- yy = y2;
1469
- } else {
1470
- xx = x1 + param * c;
1471
- yy = y1 + param * d;
1472
- }
1473
- const dx = x - xx;
1474
- const dy = y - yy;
1475
- return dx * dx + dy * dy;
1476
- }
1477
- class Triangle {
1478
- constructor(x = 0, y = 0, x2 = 0, y2 = 0, x3 = 0, y3 = 0) {
1479
- this.x = x;
1480
- this.y = y;
1481
- this.x2 = x2;
1482
- this.y2 = y2;
1483
- this.x3 = x3;
1484
- this.y3 = y3;
1485
- }
1486
- contains(x, y) {
1487
- const s = (this.x - this.x3) * (y - this.y3) - (this.y - this.y3) * (x - this.x3);
1488
- const t = (this.x2 - this.x) * (y - this.y) - (this.y2 - this.y) * (x - this.x);
1489
- if (s < 0 !== t < 0 && s !== 0 && t !== 0)
1490
- return false;
1491
- const d = (this.x3 - this.x2) * (y - this.y2) - (this.y3 - this.y2) * (x - this.x2);
1492
- return d === 0 || d < 0 === s + t <= 0;
1493
- }
1494
- strokeContains(pointX, pointY, strokeWidth) {
1495
- const halfStrokeWidth = strokeWidth / 2;
1496
- const halfStrokeWidthSquared = halfStrokeWidth * halfStrokeWidth;
1497
- const { x, x2, x3, y, y2, y3 } = this;
1498
- if (squaredDistanceToLineSegment(pointX, pointY, x, y, x2, y3) <= halfStrokeWidthSquared || squaredDistanceToLineSegment(pointX, pointY, x2, y2, x3, y3) <= halfStrokeWidthSquared || squaredDistanceToLineSegment(pointX, pointY, x3, y3, x, y) <= halfStrokeWidthSquared) {
1499
- return true;
1500
- }
1501
- return false;
1502
- }
1503
- clone() {
1504
- return new Triangle(this.x, this.y, this.x2, this.y2, this.x3, this.y3);
1505
- }
1506
- copyFrom(triangle) {
1507
- this.x = triangle.x;
1508
- this.y = triangle.y;
1509
- this.x2 = triangle.x2;
1510
- this.y2 = triangle.y2;
1511
- this.x3 = triangle.x3;
1512
- this.y3 = triangle.y3;
1160
+ offUpdate(callback) {
1161
+ this.off("update", callback);
1513
1162
  return this;
1514
1163
  }
1515
- copyTo(triangle) {
1516
- triangle.copyFrom(this);
1517
- return triangle;
1164
+ _emitUpdate(array) {
1165
+ this._onUpdate(array);
1166
+ this.emit("update", array);
1518
1167
  }
1519
- getBounds(out) {
1520
- out = out || new Rectangle();
1521
- const minX = Math.min(this.x, this.x2, this.x3);
1522
- const maxX = Math.max(this.x, this.x2, this.x3);
1523
- const minY = Math.min(this.y, this.y2, this.y3);
1524
- const maxY = Math.max(this.y, this.y2, this.y3);
1525
- out.x = minX;
1526
- out.y = minY;
1527
- out.width = maxX - minX;
1528
- out.height = maxY - minY;
1529
- return out;
1168
+ _onUpdate(_array) {
1530
1169
  }
1531
- buildOutline(points) {
1532
- buildTriangle.build(this, points);
1170
+ toArray() {
1171
+ return this._array.slice();
1533
1172
  }
1534
- buildGeometry(vertices, indices) {
1535
- const points = [];
1536
- this.buildOutline(points);
1537
- buildTriangle.triangulate(points, vertices, 2, 0, indices, 0);
1173
+ toName() {
1174
+ return `Vector${this.dim}`;
1538
1175
  }
1539
1176
  }
1540
1177
 
1541
- class Polygon {
1542
- points;
1543
- closed;
1544
- get lastX() {
1545
- return this.points[this.points.length - 2];
1546
- }
1547
- get lastY() {
1548
- return this.points[this.points.length - 1];
1549
- }
1550
- get x() {
1551
- return this.points[this.points.length - 2];
1552
- }
1553
- get y() {
1554
- return this.points[this.points.length - 1];
1555
- }
1556
- constructor(...points) {
1557
- let flat = Array.isArray(points[0]) ? points[0] : points;
1558
- if (typeof flat[0] !== "number") {
1559
- const p = [];
1560
- for (let i = 0, il = flat.length; i < il; i++) {
1561
- p.push(flat[i].x, flat[i].y);
1562
- }
1563
- flat = p;
1178
+ class Matrix extends EventEmitter {
1179
+ constructor(rows, cols, array) {
1180
+ super();
1181
+ this.rows = rows;
1182
+ this.cols = cols;
1183
+ if (array) {
1184
+ this.set(array);
1185
+ } else {
1186
+ this.identity();
1564
1187
  }
1565
- this.points = flat;
1566
- this.closed = true;
1567
1188
  }
1568
- reset() {
1569
- this.points.length = 0;
1570
- return this;
1189
+ _array = [];
1190
+ get length() {
1191
+ return this.cols * this.rows;
1571
1192
  }
1572
- contains(x, y) {
1573
- let inside = false;
1574
- const length = this.points.length / 2;
1575
- for (let i = 0, j = length - 1; i < length; j = i++) {
1576
- const xi = this.points[i * 2];
1577
- const yi = this.points[i * 2 + 1];
1578
- const xj = this.points[j * 2];
1579
- const yj = this.points[j * 2 + 1];
1580
- const intersect = yi > y !== yj > y && x < (xj - xi) * ((y - yi) / (yj - yi)) + xi;
1581
- if (intersect) {
1582
- inside = !inside;
1583
- }
1584
- }
1585
- return inside;
1586
- }
1587
- strokeContains(x, y, strokeWidth) {
1588
- const halfStrokeWidth = strokeWidth / 2;
1589
- const halfStrokeWidthSqrd = halfStrokeWidth * halfStrokeWidth;
1590
- const { points } = this;
1591
- const iterationLength = points.length - (this.closed ? 0 : 2);
1592
- for (let i = 0; i < iterationLength; i += 2) {
1593
- const x1 = points[i];
1594
- const y1 = points[i + 1];
1595
- const x2 = points[(i + 2) % points.length];
1596
- const y2 = points[(i + 3) % points.length];
1597
- const distanceSqrd = squaredDistanceToLineSegment(x, y, x1, y1, x2, y2);
1598
- if (distanceSqrd <= halfStrokeWidthSqrd) {
1599
- return true;
1600
- }
1601
- }
1602
- return false;
1603
- }
1604
- clone() {
1605
- const points = this.points.slice();
1606
- const polygon = new Polygon(points);
1607
- polygon.closed = this.closed;
1608
- return polygon;
1609
- }
1610
- copyFrom(polygon) {
1611
- this.points = polygon.points.slice();
1612
- this.closed = polygon.closed;
1613
- return this;
1614
- }
1615
- copyTo(polygon) {
1616
- polygon.copyFrom(this);
1617
- return polygon;
1618
- }
1619
- getBounds(out) {
1620
- out = out || new Rectangle();
1621
- const points = this.points;
1622
- let minX = Infinity;
1623
- let maxX = -Infinity;
1624
- let minY = Infinity;
1625
- let maxY = -Infinity;
1626
- for (let i = 0, n = points.length; i < n; i += 2) {
1627
- const x = points[i];
1628
- const y = points[i + 1];
1629
- minX = x < minX ? x : minX;
1630
- maxX = x > maxX ? x : maxX;
1631
- minY = y < minY ? y : minY;
1632
- maxY = y > maxY ? y : maxY;
1633
- }
1634
- out.x = minX;
1635
- out.width = maxX - minX;
1636
- out.y = minY;
1637
- out.height = maxY - minY;
1638
- return out;
1639
- }
1640
- buildOutline(points) {
1641
- buildPolygon.build(this, points);
1642
- }
1643
- buildGeometry(vertices, indices) {
1644
- const points = [];
1645
- this.buildOutline(points);
1646
- buildPolygon.triangulate(points, vertices, 2, 0, indices, 0);
1647
- }
1648
- }
1649
-
1650
- function isCornerWithinStroke(pX, pY, cornerX, cornerY, radius, halfStrokeWidth) {
1651
- const dx = pX - cornerX;
1652
- const dy = pY - cornerY;
1653
- const distance = Math.sqrt(dx * dx + dy * dy);
1654
- return distance >= radius - halfStrokeWidth && distance <= radius + halfStrokeWidth;
1655
- }
1656
- class RoundedRectangle {
1657
- constructor(x = 0, y = 0, width = 0, height = 0, radius = width / 4) {
1658
- this.x = x;
1659
- this.y = y;
1660
- this.width = width;
1661
- this.height = height;
1662
- this.radius = radius;
1663
- }
1664
- getBounds(out) {
1665
- out = out || new Rectangle();
1666
- out.x = this.x;
1667
- out.y = this.y;
1668
- out.width = this.width;
1669
- out.height = this.height;
1670
- return out;
1671
- }
1672
- clone() {
1673
- return new RoundedRectangle(this.x, this.y, this.width, this.height, this.radius);
1674
- }
1675
- copyFrom(rectangle) {
1676
- this.x = rectangle.x;
1677
- this.y = rectangle.y;
1678
- this.width = rectangle.width;
1679
- this.height = rectangle.height;
1680
- return this;
1681
- }
1682
- copyTo(rectangle) {
1683
- rectangle.copyFrom(this);
1684
- return rectangle;
1685
- }
1686
- contains(x, y) {
1687
- if (this.width <= 0 || this.height <= 0) {
1688
- return false;
1689
- }
1690
- if (x >= this.x && x <= this.x + this.width) {
1691
- if (y >= this.y && y <= this.y + this.height) {
1692
- const radius = Math.max(0, Math.min(this.radius, Math.min(this.width, this.height) / 2));
1693
- if (y >= this.y + radius && y <= this.y + this.height - radius || x >= this.x + radius && x <= this.x + this.width - radius) {
1694
- return true;
1695
- }
1696
- let dx = x - (this.x + radius);
1697
- let dy = y - (this.y + radius);
1698
- const radius2 = radius * radius;
1699
- if (dx * dx + dy * dy <= radius2) {
1700
- return true;
1701
- }
1702
- dx = x - (this.x + this.width - radius);
1703
- if (dx * dx + dy * dy <= radius2) {
1704
- return true;
1705
- }
1706
- dy = y - (this.y + this.height - radius);
1707
- if (dx * dx + dy * dy <= radius2) {
1708
- return true;
1709
- }
1710
- dx = x - (this.x + radius);
1711
- if (dx * dx + dy * dy <= radius2) {
1712
- return true;
1713
- }
1714
- }
1715
- }
1716
- return false;
1717
- }
1718
- strokeContains(pX, pY, strokeWidth) {
1719
- const { x, y, width, height, radius } = this;
1720
- const halfStrokeWidth = strokeWidth / 2;
1721
- const innerX = x + radius;
1722
- const innerY = y + radius;
1723
- const innerWidth = width - radius * 2;
1724
- const innerHeight = height - radius * 2;
1725
- const rightBound = x + width;
1726
- const bottomBound = y + height;
1727
- if ((pX >= x - halfStrokeWidth && pX <= x + halfStrokeWidth || pX >= rightBound - halfStrokeWidth && pX <= rightBound + halfStrokeWidth) && pY >= innerY && pY <= innerY + innerHeight) {
1728
- return true;
1729
- }
1730
- if ((pY >= y - halfStrokeWidth && pY <= y + halfStrokeWidth || pY >= bottomBound - halfStrokeWidth && pY <= bottomBound + halfStrokeWidth) && pX >= innerX && pX <= innerX + innerWidth) {
1731
- return true;
1732
- }
1733
- return (
1734
- // Top-left
1735
- pX < innerX && pY < innerY && isCornerWithinStroke(pX, pY, innerX, innerY, radius, halfStrokeWidth) || pX > rightBound - radius && pY < innerY && isCornerWithinStroke(pX, pY, rightBound - radius, innerY, radius, halfStrokeWidth) || pX > rightBound - radius && pY > bottomBound - radius && isCornerWithinStroke(pX, pY, rightBound - radius, bottomBound - radius, radius, halfStrokeWidth) || pX < innerX && pY > bottomBound - radius && isCornerWithinStroke(pX, pY, innerX, bottomBound - radius, radius, halfStrokeWidth)
1736
- );
1737
- }
1738
- buildOutline(points) {
1739
- buildCircle.build(this, points);
1740
- }
1741
- buildGeometry(vertices, indices) {
1742
- const points = [];
1743
- this.buildOutline(points);
1744
- buildCircle.triangulate(points, vertices, 2, 0, indices, 0);
1745
- }
1746
- }
1747
-
1748
- class Star extends Polygon {
1749
- constructor(x = 0, y = 0, points = 5, radius = 1, innerRadius, rotation = 0) {
1750
- innerRadius = innerRadius || radius / 2;
1751
- const startAngle = -1 * Math.PI / 2 + rotation;
1752
- const len = points * 2;
1753
- const delta = PI_2 / len;
1754
- const polygon = [];
1755
- for (let i = 0; i < len; i++) {
1756
- const r = i % 2 ? innerRadius : radius;
1757
- const angle = i * delta + startAngle;
1758
- polygon.push(
1759
- x + r * Math.cos(angle),
1760
- y + r * Math.sin(angle)
1761
- );
1762
- }
1763
- super(polygon);
1764
- }
1765
- }
1766
-
1767
- const buildCircle = {
1768
- build(shape, points) {
1769
- let x;
1770
- let y;
1771
- let dx;
1772
- let dy;
1773
- let rx;
1774
- let ry;
1775
- if (shape instanceof Circle) {
1776
- x = shape.x;
1777
- y = shape.y;
1778
- rx = ry = shape.radius;
1779
- dx = dy = 0;
1780
- } else if (shape instanceof Ellipse) {
1781
- x = shape.x;
1782
- y = shape.y;
1783
- rx = shape.halfWidth;
1784
- ry = shape.halfHeight;
1785
- dx = dy = 0;
1786
- } else {
1787
- const roundedRect = shape;
1788
- const halfWidth = roundedRect.width / 2;
1789
- const halfHeight = roundedRect.height / 2;
1790
- x = roundedRect.x + halfWidth;
1791
- y = roundedRect.y + halfHeight;
1792
- rx = ry = Math.max(0, Math.min(roundedRect.radius, Math.min(halfWidth, halfHeight)));
1793
- dx = halfWidth - rx;
1794
- dy = halfHeight - ry;
1795
- }
1796
- if (!(rx >= 0 && ry >= 0 && dx >= 0 && dy >= 0)) {
1797
- return points;
1798
- }
1799
- const n = Math.ceil(2.3 * Math.sqrt(rx + ry));
1800
- const m = n * 8 + (dx ? 4 : 0) + (dy ? 4 : 0);
1801
- if (m === 0) {
1802
- return points;
1803
- }
1804
- if (n === 0) {
1805
- points[0] = points[6] = x + dx;
1806
- points[1] = points[3] = y + dy;
1807
- points[2] = points[4] = x - dx;
1808
- points[5] = points[7] = y - dy;
1809
- return points;
1810
- }
1811
- let j1 = 0;
1812
- let j2 = n * 4 + (dx ? 2 : 0) + 2;
1813
- let j3 = j2;
1814
- let j4 = m;
1815
- let x0 = dx + rx;
1816
- let y0 = dy;
1817
- let x1 = x + x0;
1818
- let x2 = x - x0;
1819
- let y1 = y + y0;
1820
- points[j1++] = x1;
1821
- points[j1++] = y1;
1822
- points[--j2] = y1;
1823
- points[--j2] = x2;
1824
- if (dy) {
1825
- const y22 = y - y0;
1826
- points[j3++] = x2;
1827
- points[j3++] = y22;
1828
- points[--j4] = y22;
1829
- points[--j4] = x1;
1830
- }
1831
- for (let i = 1; i < n; i++) {
1832
- const a = Math.PI / 2 * (i / n);
1833
- const x02 = dx + Math.cos(a) * rx;
1834
- const y02 = dy + Math.sin(a) * ry;
1835
- const x12 = x + x02;
1836
- const x22 = x - x02;
1837
- const y12 = y + y02;
1838
- const y22 = y - y02;
1839
- points[j1++] = x12;
1840
- points[j1++] = y12;
1841
- points[--j2] = y12;
1842
- points[--j2] = x22;
1843
- points[j3++] = x22;
1844
- points[j3++] = y22;
1845
- points[--j4] = y22;
1846
- points[--j4] = x12;
1847
- }
1848
- x0 = dx;
1849
- y0 = dy + ry;
1850
- x1 = x + x0;
1851
- x2 = x - x0;
1852
- y1 = y + y0;
1853
- const y2 = y - y0;
1854
- points[j1++] = x1;
1855
- points[j1++] = y1;
1856
- points[--j4] = y2;
1857
- points[--j4] = x1;
1858
- if (dx) {
1859
- points[j1++] = x2;
1860
- points[j1++] = y1;
1861
- points[--j4] = y2;
1862
- points[--j4] = x2;
1863
- }
1864
- return points;
1865
- },
1866
- triangulate(points, vertices, verticesStride, verticesOffset, indices, indicesOffset) {
1867
- if (points.length === 0) {
1868
- return;
1869
- }
1870
- let centerX = 0;
1871
- let centerY = 0;
1872
- for (let i = 0; i < points.length; i += 2) {
1873
- centerX += points[i];
1874
- centerY += points[i + 1];
1875
- }
1876
- centerX /= points.length / 2;
1877
- centerY /= points.length / 2;
1878
- let count = verticesOffset;
1879
- vertices[count * verticesStride] = centerX;
1880
- vertices[count * verticesStride + 1] = centerY;
1881
- const centerIndex = count++;
1882
- for (let i = 0; i < points.length; i += 2) {
1883
- vertices[count * verticesStride] = points[i];
1884
- vertices[count * verticesStride + 1] = points[i + 1];
1885
- if (i > 0) {
1886
- indices[indicesOffset++] = count;
1887
- indices[indicesOffset++] = centerIndex;
1888
- indices[indicesOffset++] = count - 1;
1889
- }
1890
- count++;
1891
- }
1892
- indices[indicesOffset++] = centerIndex + 1;
1893
- indices[indicesOffset++] = centerIndex;
1894
- indices[indicesOffset++] = count - 1;
1895
- }
1896
- };
1897
-
1898
- class Point {
1899
- constructor(x = 0, y = 0) {
1900
- this.x = x;
1901
- this.y = y;
1902
- }
1903
- static _shared;
1904
- static get shared() {
1905
- const point = this._shared ?? new Point();
1906
- point.x = 0;
1907
- point.y = 0;
1908
- return point;
1909
- }
1910
- copyFrom(p) {
1911
- this.set(p.x, p.y);
1912
- return this;
1913
- }
1914
- copyTo(p) {
1915
- p.set(this.x, this.y);
1916
- return p;
1917
- }
1918
- equals(p) {
1919
- return p.x === this.x && p.y === this.y;
1920
- }
1921
- set(x = 0, y = x) {
1922
- this.x = x;
1923
- this.y = y;
1924
- return this;
1925
- }
1926
- }
1927
-
1928
- function getOrientationOfPoints(points) {
1929
- const m = points.length;
1930
- if (m < 6) {
1931
- return 1;
1932
- }
1933
- let area = 0;
1934
- for (let i = 0, x1 = points[m - 2], y1 = points[m - 1]; i < m; i += 2) {
1935
- const x2 = points[i];
1936
- const y2 = points[i + 1];
1937
- area += (x2 - x1) * (y2 + y1);
1938
- x1 = x2;
1939
- y1 = y2;
1940
- }
1941
- if (area < 0) {
1942
- return -1;
1943
- }
1944
- return 1;
1945
- }
1946
-
1947
- function triangulateWithHoles(points, holes, vertices, verticesStride, verticesOffset, indices, indicesOffset) {
1948
- const triangles = earcut(points, holes, 2);
1949
- if (!triangles) {
1950
- return;
1951
- }
1952
- for (let i = 0; i < triangles.length; i += 3) {
1953
- indices[indicesOffset++] = triangles[i] + verticesOffset;
1954
- indices[indicesOffset++] = triangles[i + 1] + verticesOffset;
1955
- indices[indicesOffset++] = triangles[i + 2] + verticesOffset;
1956
- }
1957
- let index = verticesOffset * verticesStride;
1958
- for (let i = 0; i < points.length; i += 2) {
1959
- vertices[index] = points[i];
1960
- vertices[index + 1] = points[i + 1];
1961
- index += verticesStride;
1962
- }
1963
- }
1964
-
1965
- const closePointEps = 1e-4;
1966
- const curveEps = 1e-4;
1967
- function square(x, y, nx, ny, innerWeight, outerWeight, clockwise, verts) {
1968
- const ix = x - nx * innerWeight;
1969
- const iy = y - ny * innerWeight;
1970
- const ox = x + nx * outerWeight;
1971
- const oy = y + ny * outerWeight;
1972
- let exx;
1973
- let eyy;
1974
- if (clockwise) {
1975
- exx = ny;
1976
- eyy = -nx;
1977
- } else {
1978
- exx = -ny;
1979
- eyy = nx;
1980
- }
1981
- const eix = ix + exx;
1982
- const eiy = iy + eyy;
1983
- const eox = ox + exx;
1984
- const eoy = oy + eyy;
1985
- verts.push(eix, eiy);
1986
- verts.push(eox, eoy);
1987
- return 2;
1988
- }
1989
- function round(cx, cy, sx, sy, ex, ey, verts, clockwise) {
1990
- const cx2p0x = sx - cx;
1991
- const cy2p0y = sy - cy;
1992
- let angle0 = Math.atan2(cx2p0x, cy2p0y);
1993
- let angle1 = Math.atan2(ex - cx, ey - cy);
1994
- if (clockwise && angle0 < angle1) {
1995
- angle0 += Math.PI * 2;
1996
- } else if (!clockwise && angle0 > angle1) {
1997
- angle1 += Math.PI * 2;
1998
- }
1999
- let startAngle = angle0;
2000
- const angleDiff = angle1 - angle0;
2001
- const absAngleDiff = Math.abs(angleDiff);
2002
- const radius = Math.sqrt(cx2p0x * cx2p0x + cy2p0y * cy2p0y);
2003
- const segCount = (15 * absAngleDiff * Math.sqrt(radius) / Math.PI >> 0) + 1;
2004
- const angleInc = angleDiff / segCount;
2005
- startAngle += angleInc;
2006
- if (clockwise) {
2007
- verts.push(cx, cy);
2008
- verts.push(sx, sy);
2009
- for (let i = 1, angle = startAngle; i < segCount; i++, angle += angleInc) {
2010
- verts.push(cx, cy);
2011
- verts.push(cx + Math.sin(angle) * radius, cy + Math.cos(angle) * radius);
2012
- }
2013
- verts.push(cx, cy);
2014
- verts.push(ex, ey);
2015
- } else {
2016
- verts.push(sx, sy);
2017
- verts.push(cx, cy);
2018
- for (let i = 1, angle = startAngle; i < segCount; i++, angle += angleInc) {
2019
- verts.push(cx + Math.sin(angle) * radius, cy + Math.cos(angle) * radius);
2020
- verts.push(cx, cy);
2021
- }
2022
- verts.push(ex, ey);
2023
- verts.push(cx, cy);
2024
- }
2025
- return segCount * 2;
2026
- }
2027
- function buildLine(points, lineStyle, flipAlignment, closed, vertices, _verticesStride, _verticesOffset, indices, _indicesOffset) {
2028
- const eps = closePointEps;
2029
- if (points.length === 0) {
2030
- return;
2031
- }
2032
- const style = lineStyle;
2033
- let alignment = style.alignment;
2034
- if (lineStyle.alignment !== 0.5) {
2035
- let orientation = getOrientationOfPoints(points);
2036
- if (flipAlignment)
2037
- orientation *= -1;
2038
- alignment = (alignment - 0.5) * orientation + 0.5;
2039
- }
2040
- const firstPoint = new Point(points[0], points[1]);
2041
- const lastPoint = new Point(points[points.length - 2], points[points.length - 1]);
2042
- const closedShape = closed;
2043
- const closedPath = Math.abs(firstPoint.x - lastPoint.x) < eps && Math.abs(firstPoint.y - lastPoint.y) < eps;
2044
- if (closedShape) {
2045
- points = points.slice();
2046
- if (closedPath) {
2047
- points.pop();
2048
- points.pop();
2049
- lastPoint.set(points[points.length - 2], points[points.length - 1]);
2050
- }
2051
- const midPointX = (firstPoint.x + lastPoint.x) * 0.5;
2052
- const midPointY = (lastPoint.y + firstPoint.y) * 0.5;
2053
- points.unshift(midPointX, midPointY);
2054
- points.push(midPointX, midPointY);
2055
- }
2056
- const verts = vertices;
2057
- const length = points.length / 2;
2058
- let indexCount = points.length;
2059
- const indexStart = verts.length / 2;
2060
- const width = style.width / 2;
2061
- const widthSquared = width * width;
2062
- const miterLimitSquared = style.miterLimit * style.miterLimit;
2063
- let x0 = points[0];
2064
- let y0 = points[1];
2065
- let x1 = points[2];
2066
- let y1 = points[3];
2067
- let x2 = 0;
2068
- let y2 = 0;
2069
- let perpX = -(y0 - y1);
2070
- let perpY = x0 - x1;
2071
- let perp1x = 0;
2072
- let perp1y = 0;
2073
- let dist = Math.sqrt(perpX * perpX + perpY * perpY);
2074
- perpX /= dist;
2075
- perpY /= dist;
2076
- perpX *= width;
2077
- perpY *= width;
2078
- const ratio = alignment;
2079
- const innerWeight = (1 - ratio) * 2;
2080
- const outerWeight = ratio * 2;
2081
- if (!closedShape) {
2082
- if (style.cap === "round") {
2083
- indexCount += round(
2084
- x0 - perpX * (innerWeight - outerWeight) * 0.5,
2085
- y0 - perpY * (innerWeight - outerWeight) * 0.5,
2086
- x0 - perpX * innerWeight,
2087
- y0 - perpY * innerWeight,
2088
- x0 + perpX * outerWeight,
2089
- y0 + perpY * outerWeight,
2090
- verts,
2091
- true
2092
- ) + 2;
2093
- } else if (style.cap === "square") {
2094
- indexCount += square(x0, y0, perpX, perpY, innerWeight, outerWeight, true, verts);
2095
- }
2096
- }
2097
- verts.push(
2098
- x0 - perpX * innerWeight,
2099
- y0 - perpY * innerWeight
2100
- );
2101
- verts.push(
2102
- x0 + perpX * outerWeight,
2103
- y0 + perpY * outerWeight
2104
- );
2105
- for (let i = 1; i < length - 1; ++i) {
2106
- x0 = points[(i - 1) * 2];
2107
- y0 = points[(i - 1) * 2 + 1];
2108
- x1 = points[i * 2];
2109
- y1 = points[i * 2 + 1];
2110
- x2 = points[(i + 1) * 2];
2111
- y2 = points[(i + 1) * 2 + 1];
2112
- perpX = -(y0 - y1);
2113
- perpY = x0 - x1;
2114
- dist = Math.sqrt(perpX * perpX + perpY * perpY);
2115
- perpX /= dist;
2116
- perpY /= dist;
2117
- perpX *= width;
2118
- perpY *= width;
2119
- perp1x = -(y1 - y2);
2120
- perp1y = x1 - x2;
2121
- dist = Math.sqrt(perp1x * perp1x + perp1y * perp1y);
2122
- perp1x /= dist;
2123
- perp1y /= dist;
2124
- perp1x *= width;
2125
- perp1y *= width;
2126
- const dx0 = x1 - x0;
2127
- const dy0 = y0 - y1;
2128
- const dx1 = x1 - x2;
2129
- const dy1 = y2 - y1;
2130
- const dot = dx0 * dx1 + dy0 * dy1;
2131
- const cross = dy0 * dx1 - dy1 * dx0;
2132
- const clockwise = cross < 0;
2133
- if (Math.abs(cross) < 1e-3 * Math.abs(dot)) {
2134
- verts.push(
2135
- x1 - perpX * innerWeight,
2136
- y1 - perpY * innerWeight
2137
- );
2138
- verts.push(
2139
- x1 + perpX * outerWeight,
2140
- y1 + perpY * outerWeight
2141
- );
2142
- if (dot >= 0) {
2143
- if (style.join === "round") {
2144
- indexCount += round(
2145
- x1,
2146
- y1,
2147
- x1 - perpX * innerWeight,
2148
- y1 - perpY * innerWeight,
2149
- x1 - perp1x * innerWeight,
2150
- y1 - perp1y * innerWeight,
2151
- verts,
2152
- false
2153
- ) + 4;
2154
- } else {
2155
- indexCount += 2;
2156
- }
2157
- verts.push(
2158
- x1 - perp1x * outerWeight,
2159
- y1 - perp1y * outerWeight
2160
- );
2161
- verts.push(
2162
- x1 + perp1x * innerWeight,
2163
- y1 + perp1y * innerWeight
2164
- );
2165
- }
2166
- continue;
2167
- }
2168
- const c1 = (-perpX + x0) * (-perpY + y1) - (-perpX + x1) * (-perpY + y0);
2169
- const c2 = (-perp1x + x2) * (-perp1y + y1) - (-perp1x + x1) * (-perp1y + y2);
2170
- const px = (dx0 * c2 - dx1 * c1) / cross;
2171
- const py = (dy1 * c1 - dy0 * c2) / cross;
2172
- const pDist = (px - x1) * (px - x1) + (py - y1) * (py - y1);
2173
- const imx = x1 + (px - x1) * innerWeight;
2174
- const imy = y1 + (py - y1) * innerWeight;
2175
- const omx = x1 - (px - x1) * outerWeight;
2176
- const omy = y1 - (py - y1) * outerWeight;
2177
- const smallerInsideSegmentSq = Math.min(dx0 * dx0 + dy0 * dy0, dx1 * dx1 + dy1 * dy1);
2178
- const insideWeight = clockwise ? innerWeight : outerWeight;
2179
- const smallerInsideDiagonalSq = smallerInsideSegmentSq + insideWeight * insideWeight * widthSquared;
2180
- const insideMiterOk = pDist <= smallerInsideDiagonalSq;
2181
- if (insideMiterOk) {
2182
- if (style.join === "bevel" || pDist / widthSquared > miterLimitSquared) {
2183
- if (clockwise) {
2184
- verts.push(imx, imy);
2185
- verts.push(x1 + perpX * outerWeight, y1 + perpY * outerWeight);
2186
- verts.push(imx, imy);
2187
- verts.push(x1 + perp1x * outerWeight, y1 + perp1y * outerWeight);
2188
- } else {
2189
- verts.push(x1 - perpX * innerWeight, y1 - perpY * innerWeight);
2190
- verts.push(omx, omy);
2191
- verts.push(x1 - perp1x * innerWeight, y1 - perp1y * innerWeight);
2192
- verts.push(omx, omy);
2193
- }
2194
- indexCount += 2;
2195
- } else if (style.join === "round") {
2196
- if (clockwise) {
2197
- verts.push(imx, imy);
2198
- verts.push(x1 + perpX * outerWeight, y1 + perpY * outerWeight);
2199
- indexCount += round(
2200
- x1,
2201
- y1,
2202
- x1 + perpX * outerWeight,
2203
- y1 + perpY * outerWeight,
2204
- x1 + perp1x * outerWeight,
2205
- y1 + perp1y * outerWeight,
2206
- verts,
2207
- true
2208
- ) + 4;
2209
- verts.push(imx, imy);
2210
- verts.push(x1 + perp1x * outerWeight, y1 + perp1y * outerWeight);
2211
- } else {
2212
- verts.push(x1 - perpX * innerWeight, y1 - perpY * innerWeight);
2213
- verts.push(omx, omy);
2214
- indexCount += round(
2215
- x1,
2216
- y1,
2217
- x1 - perpX * innerWeight,
2218
- y1 - perpY * innerWeight,
2219
- x1 - perp1x * innerWeight,
2220
- y1 - perp1y * innerWeight,
2221
- verts,
2222
- false
2223
- ) + 4;
2224
- verts.push(x1 - perp1x * innerWeight, y1 - perp1y * innerWeight);
2225
- verts.push(omx, omy);
2226
- }
2227
- } else {
2228
- verts.push(imx, imy);
2229
- verts.push(omx, omy);
2230
- }
2231
- } else {
2232
- verts.push(x1 - perpX * innerWeight, y1 - perpY * innerWeight);
2233
- verts.push(x1 + perpX * outerWeight, y1 + perpY * outerWeight);
2234
- if (style.join === "round") {
2235
- if (clockwise) {
2236
- indexCount += round(
2237
- x1,
2238
- y1,
2239
- x1 + perpX * outerWeight,
2240
- y1 + perpY * outerWeight,
2241
- x1 + perp1x * outerWeight,
2242
- y1 + perp1y * outerWeight,
2243
- verts,
2244
- true
2245
- ) + 2;
2246
- } else {
2247
- indexCount += round(
2248
- x1,
2249
- y1,
2250
- x1 - perpX * innerWeight,
2251
- y1 - perpY * innerWeight,
2252
- x1 - perp1x * innerWeight,
2253
- y1 - perp1y * innerWeight,
2254
- verts,
2255
- false
2256
- ) + 2;
2257
- }
2258
- } else if (style.join === "miter" && pDist / widthSquared <= miterLimitSquared) {
2259
- if (clockwise) {
2260
- verts.push(omx, omy);
2261
- verts.push(omx, omy);
2262
- } else {
2263
- verts.push(imx, imy);
2264
- verts.push(imx, imy);
2265
- }
2266
- indexCount += 2;
2267
- }
2268
- verts.push(x1 - perp1x * innerWeight, y1 - perp1y * innerWeight);
2269
- verts.push(x1 + perp1x * outerWeight, y1 + perp1y * outerWeight);
2270
- indexCount += 2;
2271
- }
2272
- }
2273
- x0 = points[(length - 2) * 2];
2274
- y0 = points[(length - 2) * 2 + 1];
2275
- x1 = points[(length - 1) * 2];
2276
- y1 = points[(length - 1) * 2 + 1];
2277
- perpX = -(y0 - y1);
2278
- perpY = x0 - x1;
2279
- dist = Math.sqrt(perpX * perpX + perpY * perpY);
2280
- perpX /= dist;
2281
- perpY /= dist;
2282
- perpX *= width;
2283
- perpY *= width;
2284
- verts.push(x1 - perpX * innerWeight, y1 - perpY * innerWeight);
2285
- verts.push(x1 + perpX * outerWeight, y1 + perpY * outerWeight);
2286
- if (!closedShape) {
2287
- if (style.cap === "round") {
2288
- indexCount += round(
2289
- x1 - perpX * (innerWeight - outerWeight) * 0.5,
2290
- y1 - perpY * (innerWeight - outerWeight) * 0.5,
2291
- x1 - perpX * innerWeight,
2292
- y1 - perpY * innerWeight,
2293
- x1 + perpX * outerWeight,
2294
- y1 + perpY * outerWeight,
2295
- verts,
2296
- false
2297
- ) + 2;
2298
- } else if (style.cap === "square") {
2299
- indexCount += square(x1, y1, perpX, perpY, innerWeight, outerWeight, false, verts);
2300
- }
2301
- }
2302
- const eps2 = curveEps * curveEps;
2303
- for (let i = indexStart; i < indexCount + indexStart - 2; ++i) {
2304
- x0 = verts[i * 2];
2305
- y0 = verts[i * 2 + 1];
2306
- x1 = verts[(i + 1) * 2];
2307
- y1 = verts[(i + 1) * 2 + 1];
2308
- x2 = verts[(i + 2) * 2];
2309
- y2 = verts[(i + 2) * 2 + 1];
2310
- if (Math.abs(x0 * (y1 - y2) + x1 * (y2 - y0) + x2 * (y0 - y1)) < eps2) {
2311
- continue;
2312
- }
2313
- indices.push(i, i + 1, i + 2);
2314
- }
2315
- }
2316
-
2317
- const emptyArray = [];
2318
- const buildPolygon = {
2319
- build(shape, points) {
2320
- for (let i = 0; i < shape.points.length; i++) {
2321
- points[i] = shape.points[i];
2322
- }
2323
- return points;
2324
- },
2325
- triangulate(points, vertices, verticesStride, verticesOffset, indices, indicesOffset) {
2326
- triangulateWithHoles(points, emptyArray, vertices, verticesStride, verticesOffset, indices, indicesOffset);
2327
- }
2328
- };
2329
-
2330
- const buildRectangle = {
2331
- build(shape, points) {
2332
- const rectData = shape;
2333
- const x = rectData.x;
2334
- const y = rectData.y;
2335
- const width = rectData.width;
2336
- const height = rectData.height;
2337
- if (!(width >= 0 && height >= 0)) {
2338
- return points;
2339
- }
2340
- points[0] = x;
2341
- points[1] = y;
2342
- points[2] = x + width;
2343
- points[3] = y;
2344
- points[4] = x + width;
2345
- points[5] = y + height;
2346
- points[6] = x;
2347
- points[7] = y + height;
2348
- return points;
2349
- },
2350
- triangulate(points, vertices, verticesStride, verticesOffset, indices, indicesOffset) {
2351
- let count = 0;
2352
- verticesOffset *= verticesStride;
2353
- vertices[verticesOffset + count] = points[0];
2354
- vertices[verticesOffset + count + 1] = points[1];
2355
- count += verticesStride;
2356
- vertices[verticesOffset + count] = points[2];
2357
- vertices[verticesOffset + count + 1] = points[3];
2358
- count += verticesStride;
2359
- vertices[verticesOffset + count] = points[6];
2360
- vertices[verticesOffset + count + 1] = points[7];
2361
- count += verticesStride;
2362
- vertices[verticesOffset + count] = points[4];
2363
- vertices[verticesOffset + count + 1] = points[5];
2364
- count += verticesStride;
2365
- const verticesIndex = verticesOffset / verticesStride;
2366
- indices[indicesOffset++] = verticesIndex;
2367
- indices[indicesOffset++] = verticesIndex + 1;
2368
- indices[indicesOffset++] = verticesIndex + 2;
2369
- indices[indicesOffset++] = verticesIndex + 1;
2370
- indices[indicesOffset++] = verticesIndex + 3;
2371
- indices[indicesOffset++] = verticesIndex + 2;
2372
- }
2373
- };
2374
-
2375
- const buildTriangle = {
2376
- build(shape, points) {
2377
- points[0] = shape.x;
2378
- points[1] = shape.y;
2379
- points[2] = shape.x2;
2380
- points[3] = shape.y2;
2381
- points[4] = shape.x3;
2382
- points[5] = shape.y3;
2383
- return points;
2384
- },
2385
- triangulate(points, vertices, verticesStride, verticesOffset, indices, indicesOffset) {
2386
- let count = 0;
2387
- verticesOffset *= verticesStride;
2388
- vertices[verticesOffset + count] = points[0];
2389
- vertices[verticesOffset + count + 1] = points[1];
2390
- count += verticesStride;
2391
- vertices[verticesOffset + count] = points[2];
2392
- vertices[verticesOffset + count + 1] = points[3];
2393
- count += verticesStride;
2394
- vertices[verticesOffset + count] = points[4];
2395
- vertices[verticesOffset + count + 1] = points[5];
2396
- const verticesIndex = verticesOffset / verticesStride;
2397
- indices[indicesOffset++] = verticesIndex;
2398
- indices[indicesOffset++] = verticesIndex + 1;
2399
- indices[indicesOffset++] = verticesIndex + 2;
2400
- }
2401
- };
2402
-
2403
- const tempPoints = [new Point(), new Point(), new Point(), new Point()];
2404
- class Rectangle {
2405
- constructor(x = 0, y = 0, width = 0, height = 0) {
2406
- this.x = x;
2407
- this.y = y;
2408
- this.width = width;
2409
- this.height = height;
2410
- }
2411
- get left() {
2412
- return this.x;
2413
- }
2414
- get right() {
2415
- return this.x + this.width;
2416
- }
2417
- get top() {
2418
- return this.y;
2419
- }
2420
- get bottom() {
2421
- return this.y + this.height;
2422
- }
2423
- isEmpty() {
2424
- return this.left === this.right || this.top === this.bottom;
2425
- }
2426
- copyFromBounds(bounds) {
2427
- this.x = bounds.minX;
2428
- this.y = bounds.minY;
2429
- this.width = bounds.maxX - bounds.minX;
2430
- this.height = bounds.maxY - bounds.minY;
2431
- return this;
2432
- }
2433
- contains(x, y) {
2434
- if (this.width <= 0 || this.height <= 0) {
2435
- return false;
2436
- }
2437
- if (x >= this.x && x < this.x + this.width) {
2438
- if (y >= this.y && y < this.y + this.height) {
2439
- return true;
2440
- }
2441
- }
2442
- return false;
2443
- }
2444
- strokeContains(x, y, strokeWidth) {
2445
- const { width, height } = this;
2446
- if (width <= 0 || height <= 0)
2447
- return false;
2448
- const _x = this.x;
2449
- const _y = this.y;
2450
- const outerLeft = _x - strokeWidth / 2;
2451
- const outerRight = _x + width + strokeWidth / 2;
2452
- const outerTop = _y - strokeWidth / 2;
2453
- const outerBottom = _y + height + strokeWidth / 2;
2454
- const innerLeft = _x + strokeWidth / 2;
2455
- const innerRight = _x + width - strokeWidth / 2;
2456
- const innerTop = _y + strokeWidth / 2;
2457
- const innerBottom = _y + height - strokeWidth / 2;
2458
- return x >= outerLeft && x <= outerRight && y >= outerTop && y <= outerBottom && !(x > innerLeft && x < innerRight && y > innerTop && y < innerBottom);
2459
- }
2460
- clone() {
2461
- return new Rectangle(this.x, this.y, this.width, this.height);
2462
- }
2463
- copyFrom(rectangle) {
2464
- this.x = rectangle.x;
2465
- this.y = rectangle.y;
2466
- this.width = rectangle.width;
2467
- this.height = rectangle.height;
2468
- }
2469
- copyTo(rectangle) {
2470
- rectangle.copyFrom(this);
2471
- }
2472
- intersects(other, transform) {
2473
- if (!transform) {
2474
- const x02 = this.x < other.x ? other.x : this.x;
2475
- const x12 = this.right > other.right ? other.right : this.right;
2476
- if (x12 <= x02) {
2477
- return false;
2478
- }
2479
- const y02 = this.y < other.y ? other.y : this.y;
2480
- const y12 = this.bottom > other.bottom ? other.bottom : this.bottom;
2481
- return y12 > y02;
2482
- }
2483
- const x0 = this.left;
2484
- const x1 = this.right;
2485
- const y0 = this.top;
2486
- const y1 = this.bottom;
2487
- if (x1 <= x0 || y1 <= y0) {
2488
- return false;
2489
- }
2490
- const lt = tempPoints[0].set(other.left, other.top);
2491
- const lb = tempPoints[1].set(other.left, other.bottom);
2492
- const rt = tempPoints[2].set(other.right, other.top);
2493
- const rb = tempPoints[3].set(other.right, other.bottom);
2494
- if (rt.x <= lt.x || lb.y <= lt.y) {
2495
- return false;
2496
- }
2497
- const { a, d, b, c } = transform.toObject();
2498
- const s = Math.sign(a * d - b * c);
2499
- if (s === 0) {
2500
- return false;
2501
- }
2502
- [lt.x, lt.y] = transform.applyToPoint(lt.x, lt.y);
2503
- [lb.x, lb.y] = transform.applyToPoint(lb.x, lb.y);
2504
- [rt.x, rt.y] = transform.applyToPoint(rt.x, rt.y);
2505
- [rb.x, rb.y] = transform.applyToPoint(rb.x, lt.y);
2506
- if (Math.max(lt.x, lb.x, rt.x, rb.x) <= x0 || Math.min(lt.x, lb.x, rt.x, rb.x) >= x1 || Math.max(lt.y, lb.y, rt.y, rb.y) <= y0 || Math.min(lt.y, lb.y, rt.y, rb.y) >= y1) {
2507
- return false;
2508
- }
2509
- const nx = s * (lb.y - lt.y);
2510
- const ny = s * (lt.x - lb.x);
2511
- const n00 = nx * x0 + ny * y0;
2512
- const n10 = nx * x1 + ny * y0;
2513
- const n01 = nx * x0 + ny * y1;
2514
- const n11 = nx * x1 + ny * y1;
2515
- if (Math.max(n00, n10, n01, n11) <= nx * lt.x + ny * lt.y || Math.min(n00, n10, n01, n11) >= nx * rb.x + ny * rb.y) {
2516
- return false;
2517
- }
2518
- const mx = s * (lt.y - rt.y);
2519
- const my = s * (rt.x - lt.x);
2520
- const m00 = mx * x0 + my * y0;
2521
- const m10 = mx * x1 + my * y0;
2522
- const m01 = mx * x0 + my * y1;
2523
- const m11 = mx * x1 + my * y1;
2524
- if (Math.max(m00, m10, m01, m11) <= mx * lt.x + my * lt.y || Math.min(m00, m10, m01, m11) >= mx * rb.x + my * rb.y) {
2525
- return false;
2526
- }
2527
- return true;
2528
- }
2529
- pad(paddingX = 0, paddingY = paddingX) {
2530
- this.x -= paddingX;
2531
- this.y -= paddingY;
2532
- this.width += paddingX * 2;
2533
- this.height += paddingY * 2;
2534
- return this;
2535
- }
2536
- fit(rectangle) {
2537
- const x1 = Math.max(this.x, rectangle.x);
2538
- const x2 = Math.min(this.x + this.width, rectangle.x + rectangle.width);
2539
- const y1 = Math.max(this.y, rectangle.y);
2540
- const y2 = Math.min(this.y + this.height, rectangle.y + rectangle.height);
2541
- this.x = x1;
2542
- this.width = Math.max(x2 - x1, 0);
2543
- this.y = y1;
2544
- this.height = Math.max(y2 - y1, 0);
2545
- return this;
2546
- }
2547
- ceil(resolution = 1, eps = 1e-3) {
2548
- const x2 = Math.ceil((this.x + this.width - eps) * resolution) / resolution;
2549
- const y2 = Math.ceil((this.y + this.height - eps) * resolution) / resolution;
2550
- this.x = Math.floor((this.x + eps) * resolution) / resolution;
2551
- this.y = Math.floor((this.y + eps) * resolution) / resolution;
2552
- this.width = x2 - this.x;
2553
- this.height = y2 - this.y;
2554
- return this;
2555
- }
2556
- enlarge(rectangle) {
2557
- const x1 = Math.min(this.x, rectangle.x);
2558
- const x2 = Math.max(this.x + this.width, rectangle.x + rectangle.width);
2559
- const y1 = Math.min(this.y, rectangle.y);
2560
- const y2 = Math.max(this.y + this.height, rectangle.y + rectangle.height);
2561
- this.x = x1;
2562
- this.width = x2 - x1;
2563
- this.y = y1;
2564
- this.height = y2 - y1;
2565
- return this;
2566
- }
2567
- getBounds(out) {
2568
- out = out || new Rectangle();
2569
- out.copyFrom(this);
2570
- return out;
2571
- }
2572
- buildOutline(points) {
2573
- buildRectangle.build(this, points);
2574
- }
2575
- buildGeometry(vertices, indices) {
2576
- const points = [];
2577
- this.buildOutline(points);
2578
- buildRectangle.triangulate(points, vertices, 2, 0, indices, 0);
2579
- }
2580
- }
2581
-
2582
- class Vector extends EventEmitter {
2583
- constructor(dim) {
2584
- super();
2585
- this.dim = dim;
2586
- }
2587
- _array = [];
2588
- get length() {
2589
- return this.dim;
2590
- }
2591
- _operate(operator, target, output) {
2592
- const { dim: length, _array: array } = this;
2593
- let targetArray;
2594
- if (typeof target === "number") {
2595
- targetArray = Array.from({ length }, () => target);
2596
- } else if (target instanceof Matrix || target instanceof Vector) {
2597
- targetArray = target.toArray();
2598
- } else {
2599
- targetArray = target;
2600
- }
2601
- let outputObject;
2602
- let outputArray = [];
2603
- if (!output) {
2604
- outputObject = this;
2605
- } else if (output instanceof Vector) {
2606
- outputObject = output;
2607
- } else {
2608
- outputArray = output;
2609
- }
2610
- if (target instanceof Matrix) {
2611
- const { cols } = target;
2612
- switch (operator) {
2613
- case "*":
2614
- for (let x = 0; x < length; x++) {
2615
- let val = 0;
2616
- for (let y = 0; y < length; y++) {
2617
- val += array[x] * targetArray[y * cols + x];
2618
- }
2619
- outputArray[x] = val;
2620
- }
2621
- break;
2622
- default:
2623
- throw new Error(`Not support operator in '${this.toName()} ${operator} ${target.toName()}'`);
2624
- }
2625
- } else {
2626
- switch (operator) {
2627
- case "+":
2628
- for (let i = 0; i < length; i++) {
2629
- outputArray[i] = array[i] + targetArray[i];
2630
- }
2631
- break;
2632
- case "-":
2633
- for (let i = 0; i < length; i++) {
2634
- outputArray[i] = array[i] - targetArray[i];
2635
- }
2636
- break;
2637
- case "*":
2638
- for (let i = 0; i < length; i++) {
2639
- outputArray[i] = array[i] * targetArray[i];
2640
- }
2641
- break;
2642
- case "/":
2643
- for (let i = 0; i < length; i++) {
2644
- outputArray[i] = array[i] / targetArray[i];
2645
- }
2646
- break;
2647
- case "rot": {
2648
- const c = Math.cos(targetArray[0]);
2649
- const s = Math.sin(targetArray[0]);
2650
- outputArray[0] = array[0] * c - array[1] * s;
2651
- outputArray[1] = array[1] * c + array[0] * s;
2652
- break;
2653
- }
2654
- case "==": {
2655
- let flag = true;
2656
- for (let i = 0; i < length; i++) {
2657
- flag = flag && array[i] === targetArray[i];
2658
- }
2659
- return flag;
2660
- }
2661
- case "=":
2662
- for (let i = 0; i < length; i++) {
2663
- const val = targetArray[i];
2664
- if (val !== void 0) {
2665
- array[i] = val;
2666
- }
2667
- }
2668
- this._emitUpdate(array);
2669
- return this;
2670
- default:
2671
- throw new Error(`Not support operator in '${this.toName()} ${operator} Vector'`);
2672
- }
2673
- }
2674
- return outputObject?.set(outputArray) ?? outputArray;
2675
- }
2676
- add(value, output) {
2677
- return this._operate("+", value, output);
2678
- }
2679
- sub(value, output) {
2680
- return this._operate("-", value, output);
2681
- }
2682
- multiply(value, output) {
2683
- return this._operate("*", value, output);
2684
- }
2685
- divide(value, output) {
2686
- return this._operate("/", value, output);
2687
- }
2688
- rotate(angle) {
2689
- return this._operate("rot", angle);
2690
- }
2691
- set(value, ...args) {
2692
- if (args.length && typeof value === "number") {
2693
- value = [value, ...args];
2694
- }
2695
- return this._operate("=", value);
2696
- }
2697
- equals(value) {
2698
- return this._operate("==", value);
2699
- }
2700
- clone() {
2701
- const cloned = new this.constructor();
2702
- cloned.set(this.toArray());
2703
- return cloned;
2704
- }
2705
- onUpdate(callback) {
2706
- this.on("update", callback);
2707
- return this;
2708
- }
2709
- offUpdate(callback) {
2710
- this.off("update", callback);
2711
- return this;
2712
- }
2713
- _emitUpdate(array) {
2714
- this._onUpdate(array);
2715
- this.emit("update", array);
2716
- }
2717
- _onUpdate(_array) {
2718
- }
2719
- toArray() {
2720
- return this._array.slice();
2721
- }
2722
- toName() {
2723
- return `Vector${this.dim}`;
2724
- }
2725
- }
2726
-
2727
- class Matrix extends EventEmitter {
2728
- constructor(rows, cols, array) {
2729
- super();
2730
- this.rows = rows;
2731
- this.cols = cols;
2732
- if (array) {
2733
- this.set(array);
2734
- } else {
2735
- this.identity();
2736
- }
2737
- }
2738
- _array = [];
2739
- get length() {
2740
- return this.cols * this.rows;
2741
- }
2742
- _operate(operator, target, output) {
2743
- const { cols, rows, length, _array: array } = this;
2744
- let targetArray;
2745
- if (typeof target === "number") {
2746
- targetArray = Array.from({ length }, () => target);
2747
- } else if (target instanceof Vector || target instanceof Matrix) {
2748
- targetArray = target.toArray();
2749
- } else {
2750
- targetArray = target;
1193
+ _operate(operator, target, output) {
1194
+ const { cols, rows, length, _array: array } = this;
1195
+ let targetArray;
1196
+ if (typeof target === "number") {
1197
+ targetArray = Array.from({ length }, () => target);
1198
+ } else if (target instanceof Vector || target instanceof Matrix) {
1199
+ targetArray = target.toArray();
1200
+ } else {
1201
+ targetArray = target;
2751
1202
  }
2752
1203
  let outputObject;
2753
1204
  let outputArray = [];
@@ -2870,6 +1321,12 @@ class Matrix extends EventEmitter {
2870
1321
  }
2871
1322
  }
2872
1323
 
1324
+ class Matrix2 extends Matrix {
1325
+ constructor(array) {
1326
+ super(2, 2, array);
1327
+ }
1328
+ }
1329
+
2873
1330
  class Matrix3 extends Matrix {
2874
1331
  constructor(array) {
2875
1332
  super(3, 3, array);
@@ -2908,6 +1365,72 @@ class Matrix3 extends Matrix {
2908
1365
  }
2909
1366
  }
2910
1367
 
1368
+ class Matrix4 extends Matrix {
1369
+ constructor(array) {
1370
+ super(4, 4, array);
1371
+ }
1372
+ }
1373
+
1374
+ class Projection2D extends Matrix3 {
1375
+ constructor(_x = 0, _y = 0, _width = 0, _height = 0, _flipY = false) {
1376
+ super();
1377
+ this._x = _x;
1378
+ this._y = _y;
1379
+ this._width = _width;
1380
+ this._height = _height;
1381
+ this._flipY = _flipY;
1382
+ this._performUpdateArray();
1383
+ }
1384
+ flipY(flipY) {
1385
+ if (this._flipY !== flipY) {
1386
+ this._flipY = flipY;
1387
+ this._performUpdateArray();
1388
+ }
1389
+ return this;
1390
+ }
1391
+ translate(x, y) {
1392
+ if (this._x !== x || this._y !== y) {
1393
+ this._x = x;
1394
+ this._y = y;
1395
+ this._performUpdateArray();
1396
+ }
1397
+ return this;
1398
+ }
1399
+ resize(width, height) {
1400
+ if (this._width !== width || this._height !== height) {
1401
+ this._width = width;
1402
+ this._height = height;
1403
+ this._performUpdateArray();
1404
+ }
1405
+ return this;
1406
+ }
1407
+ _performUpdateArray() {
1408
+ const width = this._width;
1409
+ const height = this._height;
1410
+ if (!width || !height) {
1411
+ return;
1412
+ }
1413
+ const x = this._x;
1414
+ const y = this._y;
1415
+ const sign = !this._flipY ? 1 : -1;
1416
+ const a = 1 / width * 2;
1417
+ const d = sign * (1 / height * 2);
1418
+ const tx = -1 - x * a;
1419
+ const ty = -sign - y * d;
1420
+ this.set([
1421
+ a,
1422
+ 0,
1423
+ tx,
1424
+ 0,
1425
+ d,
1426
+ ty,
1427
+ 0,
1428
+ 0,
1429
+ 1
1430
+ ]);
1431
+ }
1432
+ }
1433
+
2911
1434
  class Transform2D extends Matrix3 {
2912
1435
  constructor(autoUpdate = true) {
2913
1436
  super();
@@ -3028,869 +1551,106 @@ class Transform2D extends Matrix3 {
3028
1551
  translateY(y) {
3029
1552
  return this.translate(this._translateX, y);
3030
1553
  }
3031
- translateZ(z) {
3032
- return this.translate(this._translateX, this._translateY, z);
3033
- }
3034
- translate3d(x, y, z) {
3035
- return this.translate(x, y, z);
3036
- }
3037
- scale(x, y, _z = 1) {
3038
- this._scaleX = x;
3039
- this._scaleY = y;
3040
- this._requestUpdateArray();
3041
- return this;
3042
- }
3043
- scaleX(x) {
3044
- return this.scale(x, this._scaleY);
3045
- }
3046
- scaleY(y) {
3047
- return this.scale(this._scaleX, y);
3048
- }
3049
- scale3d(x, y, z) {
3050
- return this.scale(x, y, z);
3051
- }
3052
- rotate(rad) {
3053
- this._rotate = rad;
3054
- this._updateSkew();
3055
- this._requestUpdateArray();
3056
- return this;
3057
- }
3058
- rotateX(x) {
3059
- return this.scaleY(this._rotateToScale(x));
3060
- }
3061
- rotateY(y) {
3062
- return this.scaleX(this._rotateToScale(y));
3063
- }
3064
- rotateZ(z) {
3065
- return this.rotate(z);
3066
- }
3067
- rotate3d(x, y, z, rad) {
3068
- const [rx, ry, rz] = this._rotate3d(x, y, z, rad);
3069
- rx && this.rotateX(rx);
3070
- ry && this.rotateY(ry);
3071
- rz && this.rotateZ(rz);
3072
- return this;
3073
- }
3074
- _rotateToScale(rad) {
3075
- const val = rad / PI_2;
3076
- return val <= 0.5 ? val * -4 + 1 : (val - 1) * 4 + 1;
3077
- }
3078
- _rotate3d(x, y, z, rad) {
3079
- if (x === 1 && y === 0 && z === 0) {
3080
- return [rad, 0, 0];
3081
- } else if (x === 0 && y === 1 && z === 0) {
3082
- return [0, rad, 0];
3083
- } else if (x === 0 && y === 0) {
3084
- return [0, 0, rad];
3085
- } else {
3086
- const cos = Math.cos(rad);
3087
- const sin = Math.sin(rad);
3088
- const m11 = cos + x * x * (1 - cos);
3089
- const m12 = x * y * (1 - cos) - z * sin;
3090
- const m13 = x * z * (1 - cos) + y * sin;
3091
- const m22 = cos + y * y * (1 - cos);
3092
- const m23 = y * z * (1 - cos) - x * sin;
3093
- const m33 = cos + z * z * (1 - cos);
3094
- const rotateX = -Math.atan2(-m23, m22);
3095
- const rotateY = -Math.atan2(m13, Math.sqrt(m23 * m23 + m33 * m33));
3096
- const rotateZ = -Math.atan2(-m12, m11);
3097
- return [rotateX, rotateY, rotateZ];
3098
- }
3099
- }
3100
- applyToPoint(x, y) {
3101
- const { a, c, tx, b, d, ty } = this.toObject();
3102
- return [
3103
- a * x + c * y + tx,
3104
- b * x + d * y + ty
3105
- ];
3106
- }
3107
- inverse() {
3108
- return this.clone().invert();
3109
- }
3110
- update() {
3111
- let updated = false;
3112
- if (this._needsUpdateArray) {
3113
- this._needsUpdateArray = false;
3114
- this._performUpdateArray();
3115
- updated = true;
3116
- }
3117
- if (this._needsUpdateFields) {
3118
- this._needsUpdateFields = false;
3119
- this._performUpdateFields();
3120
- updated = true;
3121
- }
3122
- return updated;
3123
- }
3124
- isIdentity() {
3125
- const { a, b, c, d, tx, ty } = this.toObject();
3126
- return a === 1 && b === 0 && c === 0 && d === 1 && tx === 0 && ty === 0;
3127
- }
3128
- toObject() {
3129
- const [a, c, tx, b, d, ty, , , tz] = this._array;
3130
- return { a, c, tx, b, d, ty, tz };
3131
- }
3132
- }
3133
-
3134
- const defaultMatrix = new Transform2D();
3135
- class Bounds {
3136
- constructor(minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity) {
3137
- this.minX = minX;
3138
- this.minY = minY;
3139
- this.maxX = maxX;
3140
- this.maxY = maxY;
3141
- }
3142
- matrix = defaultMatrix;
3143
- _rectangle;
3144
- get x() {
3145
- return this.minX;
3146
- }
3147
- set x(value) {
3148
- const width = this.maxX - this.minX;
3149
- this.minX = value;
3150
- this.maxX = value + width;
3151
- }
3152
- get y() {
3153
- return this.minY;
3154
- }
3155
- set y(value) {
3156
- const height = this.maxY - this.minY;
3157
- this.minY = value;
3158
- this.maxY = value + height;
3159
- }
3160
- get width() {
3161
- return this.maxX - this.minX;
3162
- }
3163
- set width(value) {
3164
- this.maxX = this.minX + value;
3165
- }
3166
- get height() {
3167
- return this.maxY - this.minY;
3168
- }
3169
- set height(value) {
3170
- this.maxY = this.minY + value;
3171
- }
3172
- get left() {
3173
- return this.minX;
3174
- }
3175
- get right() {
3176
- return this.maxX;
3177
- }
3178
- get top() {
3179
- return this.minY;
3180
- }
3181
- get bottom() {
3182
- return this.maxY;
3183
- }
3184
- get isPositive() {
3185
- return this.maxX - this.minX > 0 && this.maxY - this.minY > 0;
3186
- }
3187
- get isValid() {
3188
- return this.minX + this.minY !== Infinity;
3189
- }
3190
- isEmpty() {
3191
- return this.minX > this.maxX || this.minY > this.maxY;
3192
- }
3193
- get rectangle() {
3194
- if (!this._rectangle) {
3195
- this._rectangle = new Rectangle();
3196
- }
3197
- const rectangle = this._rectangle;
3198
- if (this.minX > this.maxX || this.minY > this.maxY) {
3199
- rectangle.x = 0;
3200
- rectangle.y = 0;
3201
- rectangle.width = 0;
3202
- rectangle.height = 0;
3203
- } else {
3204
- rectangle.copyFromBounds(this);
3205
- }
3206
- return rectangle;
3207
- }
3208
- clear() {
3209
- this.minX = Infinity;
3210
- this.minY = Infinity;
3211
- this.maxX = -Infinity;
3212
- this.maxY = -Infinity;
3213
- this.matrix = defaultMatrix;
3214
- return this;
3215
- }
3216
- set(x0, y0, x1, y1) {
3217
- this.minX = x0;
3218
- this.minY = y0;
3219
- this.maxX = x1;
3220
- this.maxY = y1;
3221
- return this;
3222
- }
3223
- addFrame(x0, y0, x1, y1, matrix) {
3224
- matrix ||= this.matrix;
3225
- const { a, b, c, d, tx, ty } = matrix.toObject();
3226
- let minX = this.minX;
3227
- let minY = this.minY;
3228
- let maxX = this.maxX;
3229
- let maxY = this.maxY;
3230
- let x = a * x0 + c * y0 + tx;
3231
- let y = b * x0 + d * y0 + ty;
3232
- if (x < minX)
3233
- minX = x;
3234
- if (y < minY)
3235
- minY = y;
3236
- if (x > maxX)
3237
- maxX = x;
3238
- if (y > maxY)
3239
- maxY = y;
3240
- x = a * x1 + c * y0 + tx;
3241
- y = b * x1 + d * y0 + ty;
3242
- if (x < minX)
3243
- minX = x;
3244
- if (y < minY)
3245
- minY = y;
3246
- if (x > maxX)
3247
- maxX = x;
3248
- if (y > maxY)
3249
- maxY = y;
3250
- x = a * x0 + c * y1 + tx;
3251
- y = b * x0 + d * y1 + ty;
3252
- if (x < minX)
3253
- minX = x;
3254
- if (y < minY)
3255
- minY = y;
3256
- if (x > maxX)
3257
- maxX = x;
3258
- if (y > maxY)
3259
- maxY = y;
3260
- x = a * x1 + c * y1 + tx;
3261
- y = b * x1 + d * y1 + ty;
3262
- if (x < minX)
3263
- minX = x;
3264
- if (y < minY)
3265
- minY = y;
3266
- if (x > maxX)
3267
- maxX = x;
3268
- if (y > maxY)
3269
- maxY = y;
3270
- this.minX = minX;
3271
- this.minY = minY;
3272
- this.maxX = maxX;
3273
- this.maxY = maxY;
3274
- }
3275
- addRect(rect, matrix) {
3276
- this.addFrame(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height, matrix);
3277
- return this;
3278
- }
3279
- addBounds(bounds, matrix) {
3280
- this.addFrame(bounds.minX, bounds.minY, bounds.maxX, bounds.maxY, matrix);
3281
- return this;
3282
- }
3283
- addBoundsMask(mask) {
3284
- this.minX = this.minX > mask.minX ? this.minX : mask.minX;
3285
- this.minY = this.minY > mask.minY ? this.minY : mask.minY;
3286
- this.maxX = this.maxX < mask.maxX ? this.maxX : mask.maxX;
3287
- this.maxY = this.maxY < mask.maxY ? this.maxY : mask.maxY;
3288
- }
3289
- applyMatrix(matrix) {
3290
- const minX = this.minX;
3291
- const minY = this.minY;
3292
- const maxX = this.maxX;
3293
- const maxY = this.maxY;
3294
- const { a, b, c, d, tx, ty } = matrix.toObject();
3295
- let x = a * minX + c * minY + tx;
3296
- let y = b * minX + d * minY + ty;
3297
- this.minX = x;
3298
- this.minY = y;
3299
- this.maxX = x;
3300
- this.maxY = y;
3301
- x = a * maxX + c * minY + tx;
3302
- y = b * maxX + d * minY + ty;
3303
- this.minX = x < this.minX ? x : this.minX;
3304
- this.minY = y < this.minY ? y : this.minY;
3305
- this.maxX = x > this.maxX ? x : this.maxX;
3306
- this.maxY = y > this.maxY ? y : this.maxY;
3307
- x = a * minX + c * maxY + tx;
3308
- y = b * minX + d * maxY + ty;
3309
- this.minX = x < this.minX ? x : this.minX;
3310
- this.minY = y < this.minY ? y : this.minY;
3311
- this.maxX = x > this.maxX ? x : this.maxX;
3312
- this.maxY = y > this.maxY ? y : this.maxY;
3313
- x = a * maxX + c * maxY + tx;
3314
- y = b * maxX + d * maxY + ty;
3315
- this.minX = x < this.minX ? x : this.minX;
3316
- this.minY = y < this.minY ? y : this.minY;
3317
- this.maxX = x > this.maxX ? x : this.maxX;
3318
- this.maxY = y > this.maxY ? y : this.maxY;
3319
- }
3320
- fit(rect) {
3321
- if (this.minX < rect.left)
3322
- this.minX = rect.left;
3323
- if (this.maxX > rect.right)
3324
- this.maxX = rect.right;
3325
- if (this.minY < rect.top)
3326
- this.minY = rect.top;
3327
- if (this.maxY > rect.bottom)
3328
- this.maxY = rect.bottom;
3329
- return this;
3330
- }
3331
- fitBounds(left, right, top, bottom) {
3332
- if (this.minX < left)
3333
- this.minX = left;
3334
- if (this.maxX > right)
3335
- this.maxX = right;
3336
- if (this.minY < top)
3337
- this.minY = top;
3338
- if (this.maxY > bottom)
3339
- this.maxY = bottom;
3340
- return this;
3341
- }
3342
- pad(paddingX, paddingY = paddingX) {
3343
- this.minX -= paddingX;
3344
- this.maxX += paddingX;
3345
- this.minY -= paddingY;
3346
- this.maxY += paddingY;
3347
- return this;
3348
- }
3349
- ceil() {
3350
- this.minX = Math.floor(this.minX);
3351
- this.minY = Math.floor(this.minY);
3352
- this.maxX = Math.ceil(this.maxX);
3353
- this.maxY = Math.ceil(this.maxY);
3354
- return this;
3355
- }
3356
- clone() {
3357
- return new Bounds(this.minX, this.minY, this.maxX, this.maxY);
3358
- }
3359
- scale(x, y = x) {
3360
- this.minX *= x;
3361
- this.minY *= y;
3362
- this.maxX *= x;
3363
- this.maxY *= y;
3364
- return this;
3365
- }
3366
- addVertexData(vertexData, beginOffset, endOffset, matrix) {
3367
- let minX = this.minX;
3368
- let minY = this.minY;
3369
- let maxX = this.maxX;
3370
- let maxY = this.maxY;
3371
- matrix ||= this.matrix;
3372
- const { a, b, c, d, tx, ty } = matrix.toObject();
3373
- for (let i = beginOffset; i < endOffset; i += 2) {
3374
- const localX = vertexData[i];
3375
- const localY = vertexData[i + 1];
3376
- const x = a * localX + c * localY + tx;
3377
- const y = b * localX + d * localY + ty;
3378
- minX = x < minX ? x : minX;
3379
- minY = y < minY ? y : minY;
3380
- maxX = x > maxX ? x : maxX;
3381
- maxY = y > maxY ? y : maxY;
3382
- }
3383
- this.minX = minX;
3384
- this.minY = minY;
3385
- this.maxX = maxX;
3386
- this.maxY = maxY;
3387
- }
3388
- containsPoint(x, y) {
3389
- if (this.minX <= x && this.minY <= y && this.maxX >= x && this.maxY >= y) {
3390
- return true;
3391
- }
3392
- return false;
3393
- }
3394
- }
3395
-
3396
- const dSegmentRE = /([astvzqmhlc])([^astvzqmhlc]*)/gi;
3397
- const dNumberRE = /-?\d*\.?\d+(?:e[-+]?\d+)?/gi;
3398
- const dLengthMap = { a: 7, c: 6, h: 1, l: 2, m: 2, q: 4, s: 4, t: 2, v: 1, z: 0 };
3399
- class SVGPath {
3400
- defines = [];
3401
- _calls = [];
3402
- _dirty = false;
3403
- get path2D() {
3404
- const path2D = new Path2D();
3405
- if (this._dirty) {
3406
- this._dirty = false;
3407
- this._calls.forEach((call) => {
3408
- path2D[call.method](...call.args);
3409
- });
3410
- }
3411
- return path2D;
3412
- }
3413
- constructor(d) {
3414
- if (typeof d === "string") {
3415
- this.defines = this._parseDefines(d);
3416
- } else {
3417
- this.defines = d.defines.slice();
3418
- }
3419
- this.update();
3420
- }
3421
- _addCall(method, args = [], dirty = true) {
3422
- this._calls.push({ method, args });
3423
- if (dirty) {
3424
- this._dirty = true;
3425
- }
3426
- return this;
3427
- }
3428
- _parseDefines(d) {
3429
- const defines = [];
3430
- d.replace(dSegmentRE, (_, rawCommand, rawArgs) => {
3431
- const args = rawArgs.match(dNumberRE)?.map(Number) ?? [];
3432
- let command = rawCommand.toLowerCase();
3433
- if (command === "m" && args.length > 2) {
3434
- defines.push({ command: rawCommand, args: args.splice(0, 2) });
3435
- command = "l";
3436
- rawCommand = rawCommand === "m" ? "l" : "L";
3437
- }
3438
- while (true) {
3439
- if (args.length === dLengthMap[command]) {
3440
- defines.push({ command: rawCommand, args });
3441
- return "";
3442
- }
3443
- if (args.length < dLengthMap[command])
3444
- throw new Error("malformed path defines");
3445
- defines.push({ command: rawCommand, args: args.splice(0, dLengthMap[command]) });
3446
- }
3447
- });
3448
- return defines;
3449
- }
3450
- update() {
3451
- const subpaths = [];
3452
- let currentSubPath = null;
3453
- let lastX = 0;
3454
- let lastY = 0;
3455
- for (let i = 0; i < this.defines.length; i++) {
3456
- const { command, args } = this.defines[i];
3457
- switch (command) {
3458
- case "M":
3459
- this._addCall("moveTo", [lastX = args[0], lastY = args[1]]);
3460
- break;
3461
- case "m":
3462
- this._addCall("moveTo", [lastX += args[0], lastY += args[1]]);
3463
- break;
3464
- case "H":
3465
- this._addCall("lineTo", [lastX = args[0], lastY]);
3466
- break;
3467
- case "h":
3468
- this._addCall("lineTo", [lastX += args[0], lastY]);
3469
- break;
3470
- case "V":
3471
- this._addCall("lineTo", [lastX, lastY = args[0]]);
3472
- break;
3473
- case "v":
3474
- this._addCall("lineTo", [lastX, lastY += args[0]]);
3475
- break;
3476
- case "L":
3477
- this._addCall("lineTo", [lastX = args[0], lastY = args[1]]);
3478
- break;
3479
- case "l":
3480
- this._addCall("lineTo", [lastX += args[0], lastY += args[1]]);
3481
- break;
3482
- case "C":
3483
- this._addCall("bezierCurveTo", [args[0], args[1], args[2], args[3], args[4], args[5]]);
3484
- lastX = args[4];
3485
- lastY = args[5];
3486
- break;
3487
- case "c":
3488
- this._addCall("bezierCurveTo", [
3489
- lastX + args[0],
3490
- lastY + args[1],
3491
- lastX + args[2],
3492
- lastY + args[3],
3493
- lastX + args[4],
3494
- lastY + args[5]
3495
- ]);
3496
- lastX += args[4];
3497
- lastY += args[5];
3498
- break;
3499
- case "Q":
3500
- this._addCall("quadraticCurveTo", [args[0], args[1], args[2], args[3]]);
3501
- lastX = args[2];
3502
- lastY = args[3];
3503
- break;
3504
- case "q":
3505
- this._addCall("quadraticCurveTo", [
3506
- lastX + args[0],
3507
- lastY + args[1],
3508
- lastX + args[2],
3509
- lastY + args[3]
3510
- ]);
3511
- lastX += args[2];
3512
- lastY += args[3];
3513
- break;
3514
- case "S":
3515
- this._smoothBezierCurveTo(args[0], args[1], args[2], args[3]);
3516
- lastX = args[2];
3517
- lastY = args[3];
3518
- break;
3519
- case "s":
3520
- this._smoothBezierCurveTo(
3521
- lastX + args[0],
3522
- lastY + args[1],
3523
- lastX + args[2],
3524
- lastY + args[3]
3525
- );
3526
- lastX += args[2];
3527
- lastY += args[3];
3528
- break;
3529
- case "T":
3530
- this._smoothQuadraticCurveTo(lastX = args[0], lastY = args[1]);
3531
- break;
3532
- case "t":
3533
- this._smoothQuadraticCurveTo(lastX += args[0], lastY += args[1]);
3534
- break;
3535
- case "A":
3536
- this._addCall("ellipticalArc", [args[0], args[1], args[2], args[3], args[4], args[5], args[6]]);
3537
- lastX = args[5];
3538
- lastY = args[6];
3539
- break;
3540
- case "a":
3541
- this._addCall("ellipticalArc", [args[0], args[1], args[2], args[3], args[4], args[5], args[6]]);
3542
- lastX += args[5];
3543
- lastY += args[6];
3544
- break;
3545
- case "Z":
3546
- case "z":
3547
- this._addCall("closePath");
3548
- if (subpaths.length > 0) {
3549
- currentSubPath = subpaths.pop();
3550
- if (currentSubPath) {
3551
- lastX = currentSubPath.startX;
3552
- lastY = currentSubPath.startY;
3553
- } else {
3554
- lastX = 0;
3555
- lastY = 0;
3556
- }
3557
- }
3558
- currentSubPath = null;
3559
- break;
3560
- default:
3561
- console.warn(`Unknown SVG path command: ${command}`);
3562
- }
3563
- if (command !== "Z" && command !== "z") {
3564
- if (currentSubPath === null) {
3565
- currentSubPath = { startX: lastX, startY: lastY };
3566
- subpaths.push(currentSubPath);
3567
- }
3568
- }
3569
- }
3570
- }
3571
- _getLastPoint(out) {
3572
- let index = this._calls.length - 1;
3573
- let call = this._calls[index];
3574
- if (!call) {
3575
- out.x = 0;
3576
- out.y = 0;
3577
- return out;
3578
- }
3579
- while (call.method === "closePath") {
3580
- index--;
3581
- if (index < 0) {
3582
- out.x = 0;
3583
- out.y = 0;
3584
- return out;
3585
- }
3586
- call = this._calls[index];
3587
- }
3588
- switch (call.method) {
3589
- case "moveTo":
3590
- case "lineTo":
3591
- out.set(call.args[0], call.args[1]);
3592
- break;
3593
- case "quadraticCurveTo":
3594
- out.set(call.args[2], call.args[3]);
3595
- break;
3596
- case "bezierCurveTo":
3597
- out.set(call.args[4], call.args[5]);
3598
- break;
3599
- case "arc":
3600
- case "ellipticalArc":
3601
- out.set(call.args[5], call.args[6]);
3602
- break;
3603
- case "addPath":
3604
- call.args[0]._getLastPoint(out);
3605
- break;
3606
- }
3607
- return out;
3608
- }
3609
- _smoothBezierCurveTo(cp2x, cp2y, x, y, smoothness) {
3610
- const last = this._calls[this._calls.length - 1];
3611
- const lastPoint = this._getLastPoint(Point.shared);
3612
- let cp1x;
3613
- let cp1y;
3614
- if (!last || last.method !== "bezierCurveTo") {
3615
- cp1x = lastPoint.x;
3616
- cp1y = lastPoint.y;
3617
- } else {
3618
- cp1x = last.args[2];
3619
- cp1y = last.args[3];
3620
- const currentX = lastPoint.x;
3621
- const currentY = lastPoint.y;
3622
- cp1x = currentX + (currentX - cp1x);
3623
- cp1y = currentY + (currentY - cp1y);
3624
- }
3625
- this._addCall("bezierCurveTo", [cp1x, cp1y, cp2x, cp2y, x, y, smoothness]);
3626
- return this;
3627
- }
3628
- _smoothQuadraticCurveTo(x, y, smoothness) {
3629
- const last = this._calls[this._calls.length - 1];
3630
- const lastPoint = this._getLastPoint(Point.shared);
3631
- let cpx1;
3632
- let cpy1;
3633
- if (!last || last.method !== "quadraticCurveTo") {
3634
- cpx1 = lastPoint.x;
3635
- cpy1 = lastPoint.y;
3636
- } else {
3637
- cpx1 = last.args[0];
3638
- cpy1 = last.args[1];
3639
- const currentX = lastPoint.x;
3640
- const currentY = lastPoint.y;
3641
- cpx1 = currentX + (currentX - cpx1);
3642
- cpy1 = currentY + (currentY - cpy1);
3643
- }
3644
- this._addCall("quadraticCurveTo", [cpx1, cpy1, x, y, smoothness]);
3645
- return this;
3646
- }
3647
- }
3648
-
3649
- const tempRectangle = new Rectangle();
3650
- class Path2D {
3651
- _polygon;
3652
- _bounds = new Bounds();
3653
- shapes = [];
3654
- get bounds() {
3655
- const bounds = this._bounds;
3656
- bounds.clear();
3657
- const shapes = this.shapes;
3658
- for (let i = 0; i < shapes.length; i++) {
3659
- const shape = shapes[i];
3660
- const boundsRect = shape.shape.getBounds(tempRectangle);
3661
- if (shape.transform) {
3662
- bounds.addRect(boundsRect, shape.transform);
3663
- } else {
3664
- bounds.addRect(boundsRect);
3665
- }
3666
- }
3667
- return bounds;
3668
- }
3669
- startPolygon(x, y) {
3670
- if (this._polygon) {
3671
- this.endPolygon();
3672
- }
3673
- this._polygon = new Polygon([x, y]);
3674
- return this;
3675
- }
3676
- endPolygon(closePath = false) {
3677
- const polygon = this._polygon;
3678
- if (polygon && polygon.points.length > 2) {
3679
- polygon.closed = closePath;
3680
- this.shapes.push({
3681
- shape: polygon
3682
- });
3683
- }
3684
- this._polygon = void 0;
3685
- return this;
3686
- }
3687
- ensurePolygon(start = true) {
3688
- if (this._polygon)
3689
- return;
3690
- this._polygon = new Polygon();
3691
- if (start) {
3692
- const lastShape = this.shapes[this.shapes.length - 1];
3693
- if (lastShape) {
3694
- let lx = lastShape.shape.x;
3695
- let ly = lastShape.shape.y;
3696
- if (!lastShape.transform?.isIdentity()) {
3697
- const t = lastShape.transform.toObject();
3698
- const tempX = lx;
3699
- lx = t.a * lx + t.c * ly + t.tx;
3700
- ly = t.b * tempX + t.d * ly + t.ty;
3701
- }
3702
- this._polygon.points.push(lx, ly);
3703
- } else {
3704
- this._polygon.points.push(0, 0);
3705
- }
3706
- }
3707
- }
3708
- beginPath() {
3709
- return this;
3710
- }
3711
- moveTo(x, y) {
3712
- this.startPolygon(x, y);
3713
- return this;
3714
- }
3715
- lineTo(x, y) {
3716
- this.ensurePolygon();
3717
- const points = this._polygon.points;
3718
- const fromX = points[points.length - 2];
3719
- const fromY = points[points.length - 1];
3720
- if (fromX !== x || fromY !== y) {
3721
- points.push(x, y);
3722
- }
3723
- return this;
3724
- }
3725
- bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y, smoothness) {
3726
- this.ensurePolygon();
3727
- buildAdaptiveBezier(
3728
- this._polygon.points,
3729
- this._polygon.lastX,
3730
- this._polygon.lastY,
3731
- cp1x,
3732
- cp1y,
3733
- cp2x,
3734
- cp2y,
3735
- x,
3736
- y,
3737
- smoothness
3738
- );
3739
- return this;
3740
- }
3741
- quadraticCurveTo(cp1x, cp1y, x, y, smoothing) {
3742
- this.ensurePolygon();
3743
- buildAdaptiveQuadratic(
3744
- this._polygon.points,
3745
- this._polygon.lastX,
3746
- this._polygon.lastY,
3747
- cp1x,
3748
- cp1y,
3749
- x,
3750
- y,
3751
- smoothing
3752
- );
3753
- return this;
3754
- }
3755
- rect(x, y, width, height, transform) {
3756
- this.addShape(new Rectangle(x, y, width, height), transform);
3757
- }
3758
- roundRect(x, y, width, height, radii, transform) {
3759
- this.addShape(new RoundedRectangle(x, y, width, height, radii), transform);
1554
+ translateZ(z) {
1555
+ return this.translate(this._translateX, this._translateY, z);
3760
1556
  }
3761
- ellipse(x, y, radiusX, radiusY, transform) {
3762
- this.addShape(new Ellipse(x, y, radiusX, radiusY), transform);
1557
+ translate3d(x, y, z) {
1558
+ return this.translate(x, y, z);
3763
1559
  }
3764
- arc(x, y, radius, startAngle, endAngle, counterclockwise) {
3765
- this.ensurePolygon(false);
3766
- const points = this._polygon.points;
3767
- buildArc(points, x, y, radius, startAngle, endAngle, counterclockwise);
1560
+ scale(x, y, _z = 1) {
1561
+ this._scaleX = x;
1562
+ this._scaleY = y;
1563
+ this._requestUpdateArray();
3768
1564
  return this;
3769
1565
  }
3770
- ellipticalArc(rx, ry, xAxisRotation, largeArcFlag, sweepFlag, x, y) {
3771
- buildArcToSvg(
3772
- this._polygon.points,
3773
- this._polygon.lastX,
3774
- this._polygon.lastY,
3775
- x,
3776
- y,
3777
- rx,
3778
- ry,
3779
- xAxisRotation,
3780
- largeArcFlag,
3781
- sweepFlag
3782
- );
3783
- return this;
1566
+ scaleX(x) {
1567
+ return this.scale(x, this._scaleY);
3784
1568
  }
3785
- poly(points, close = false, transform) {
3786
- const polygon = new Polygon(points);
3787
- polygon.closed = close;
3788
- this.addShape(polygon, transform);
3789
- return this;
1569
+ scaleY(y) {
1570
+ return this.scale(this._scaleX, y);
3790
1571
  }
3791
- addShape(shape, transform) {
3792
- this.endPolygon();
3793
- this.shapes.push({ shape, transform });
3794
- return this;
1572
+ scale3d(x, y, z) {
1573
+ return this.scale(x, y, z);
3795
1574
  }
3796
- addPath(path2D) {
3797
- this.endPolygon();
3798
- path2D.endPolygon();
3799
- path2D.shapes.forEach((shape) => {
3800
- this.shapes.push(shape);
3801
- });
1575
+ rotate(rad) {
1576
+ this._rotate = rad;
1577
+ this._updateSkew();
1578
+ this._requestUpdateArray();
3802
1579
  return this;
3803
1580
  }
3804
- addSVGPath(d) {
3805
- this.addPath(new SVGPath(d).path2D);
3806
- return this;
1581
+ rotateX(x) {
1582
+ return this.scaleY(this._rotateToScale(x));
3807
1583
  }
3808
- closePath() {
3809
- this.endPolygon(true);
3810
- return this;
1584
+ rotateY(y) {
1585
+ return this.scaleX(this._rotateToScale(y));
3811
1586
  }
3812
- buildOutline(points = []) {
3813
- this.shapes.forEach((item) => item.shape.buildOutline(points));
3814
- return points;
1587
+ rotateZ(z) {
1588
+ return this.rotate(z);
3815
1589
  }
3816
- buildGeometry(vertices = [], indices = []) {
3817
- this.shapes.forEach((item) => item.shape.buildGeometry(vertices, indices));
3818
- return {
3819
- vertices,
3820
- indices
3821
- };
1590
+ rotate3d(x, y, z, rad) {
1591
+ const [rx, ry, rz] = this._rotate3d(x, y, z, rad);
1592
+ rx && this.rotateX(rx);
1593
+ ry && this.rotateY(ry);
1594
+ rz && this.rotateZ(rz);
1595
+ return this;
3822
1596
  }
3823
- }
3824
-
3825
- class Matrix2 extends Matrix {
3826
- constructor(array) {
3827
- super(2, 2, array);
1597
+ _rotateToScale(rad) {
1598
+ const val = rad / PI_2;
1599
+ return val <= 0.5 ? val * -4 + 1 : (val - 1) * 4 + 1;
3828
1600
  }
3829
- }
3830
-
3831
- class Matrix4 extends Matrix {
3832
- constructor(array) {
3833
- super(4, 4, array);
1601
+ _rotate3d(x, y, z, rad) {
1602
+ if (x === 1 && y === 0 && z === 0) {
1603
+ return [rad, 0, 0];
1604
+ } else if (x === 0 && y === 1 && z === 0) {
1605
+ return [0, rad, 0];
1606
+ } else if (x === 0 && y === 0) {
1607
+ return [0, 0, rad];
1608
+ } else {
1609
+ const cos = Math.cos(rad);
1610
+ const sin = Math.sin(rad);
1611
+ const m11 = cos + x * x * (1 - cos);
1612
+ const m12 = x * y * (1 - cos) - z * sin;
1613
+ const m13 = x * z * (1 - cos) + y * sin;
1614
+ const m22 = cos + y * y * (1 - cos);
1615
+ const m23 = y * z * (1 - cos) - x * sin;
1616
+ const m33 = cos + z * z * (1 - cos);
1617
+ const rotateX = -Math.atan2(-m23, m22);
1618
+ const rotateY = -Math.atan2(m13, Math.sqrt(m23 * m23 + m33 * m33));
1619
+ const rotateZ = -Math.atan2(-m12, m11);
1620
+ return [rotateX, rotateY, rotateZ];
1621
+ }
3834
1622
  }
3835
- }
3836
-
3837
- class Projection2D extends Matrix3 {
3838
- constructor(_x = 0, _y = 0, _width = 0, _height = 0, _flipY = false) {
3839
- super();
3840
- this._x = _x;
3841
- this._y = _y;
3842
- this._width = _width;
3843
- this._height = _height;
3844
- this._flipY = _flipY;
3845
- this._performUpdateArray();
1623
+ applyToPoint(x, y) {
1624
+ const { a, c, tx, b, d, ty } = this.toObject();
1625
+ return [
1626
+ a * x + c * y + tx,
1627
+ b * x + d * y + ty
1628
+ ];
3846
1629
  }
3847
- flipY(flipY) {
3848
- if (this._flipY !== flipY) {
3849
- this._flipY = flipY;
3850
- this._performUpdateArray();
3851
- }
3852
- return this;
1630
+ inverse() {
1631
+ return this.clone().invert();
3853
1632
  }
3854
- translate(x, y) {
3855
- if (this._x !== x || this._y !== y) {
3856
- this._x = x;
3857
- this._y = y;
1633
+ update() {
1634
+ let updated = false;
1635
+ if (this._needsUpdateArray) {
1636
+ this._needsUpdateArray = false;
3858
1637
  this._performUpdateArray();
1638
+ updated = true;
3859
1639
  }
3860
- return this;
3861
- }
3862
- resize(width, height) {
3863
- if (this._width !== width || this._height !== height) {
3864
- this._width = width;
3865
- this._height = height;
3866
- this._performUpdateArray();
1640
+ if (this._needsUpdateFields) {
1641
+ this._needsUpdateFields = false;
1642
+ this._performUpdateFields();
1643
+ updated = true;
3867
1644
  }
3868
- return this;
1645
+ return updated;
3869
1646
  }
3870
- _performUpdateArray() {
3871
- const width = this._width;
3872
- const height = this._height;
3873
- if (!width || !height) {
3874
- return;
3875
- }
3876
- const x = this._x;
3877
- const y = this._y;
3878
- const sign = !this._flipY ? 1 : -1;
3879
- const a = 1 / width * 2;
3880
- const d = sign * (1 / height * 2);
3881
- const tx = -1 - x * a;
3882
- const ty = -sign - y * d;
3883
- this.set([
3884
- a,
3885
- 0,
3886
- tx,
3887
- 0,
3888
- d,
3889
- ty,
3890
- 0,
3891
- 0,
3892
- 1
3893
- ]);
1647
+ isIdentity() {
1648
+ const { a, b, c, d, tx, ty } = this.toObject();
1649
+ return a === 1 && b === 0 && c === 0 && d === 1 && tx === 0 && ty === 0;
1650
+ }
1651
+ toObject() {
1652
+ const [a, c, tx, b, d, ty, , , tz] = this._array;
1653
+ return { a, c, tx, b, d, ty, tz };
3894
1654
  }
3895
1655
  }
3896
1656
 
@@ -3999,14 +1759,14 @@ class Vector4 extends Vector {
3999
1759
  }
4000
1760
  }
4001
1761
 
4002
- var __defProp$x = Object.defineProperty;
1762
+ var __defProp$w = Object.defineProperty;
4003
1763
  var __getOwnPropDesc$t = Object.getOwnPropertyDescriptor;
4004
- var __decorateClass$x = (decorators, target, key, kind) => {
1764
+ var __decorateClass$w = (decorators, target, key, kind) => {
4005
1765
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$t(target, key) : target;
4006
1766
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
4007
1767
  if (decorator = decorators[i])
4008
1768
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
4009
- if (kind && result) __defProp$x(target, key, result);
1769
+ if (kind && result) __defProp$w(target, key, result);
4010
1770
  return result;
4011
1771
  };
4012
1772
  var InternalMode = /* @__PURE__ */ ((InternalMode2) => {
@@ -4404,22 +2164,22 @@ let Node = class extends Reference {
4404
2164
  return node;
4405
2165
  }
4406
2166
  };
4407
- __decorateClass$x([
2167
+ __decorateClass$w([
4408
2168
  property()
4409
2169
  ], Node.prototype, "name", 2);
4410
- __decorateClass$x([
2170
+ __decorateClass$w([
4411
2171
  property()
4412
2172
  ], Node.prototype, "mask", 2);
4413
- __decorateClass$x([
2173
+ __decorateClass$w([
4414
2174
  property({ default: "visible" })
4415
2175
  ], Node.prototype, "visibility", 2);
4416
- __decorateClass$x([
2176
+ __decorateClass$w([
4417
2177
  property({ default: 0 })
4418
2178
  ], Node.prototype, "visibleDelay", 2);
4419
- __decorateClass$x([
2179
+ __decorateClass$w([
4420
2180
  property({ default: Number.MAX_SAFE_INTEGER })
4421
2181
  ], Node.prototype, "visibleDuration", 2);
4422
- Node = __decorateClass$x([
2182
+ Node = __decorateClass$w([
4423
2183
  customNode("Node")
4424
2184
  ], Node);
4425
2185
 
@@ -4449,14 +2209,14 @@ class RenderStack {
4449
2209
  }
4450
2210
  }
4451
2211
 
4452
- var __defProp$w = Object.defineProperty;
2212
+ var __defProp$v = Object.defineProperty;
4453
2213
  var __getOwnPropDesc$s = Object.getOwnPropertyDescriptor;
4454
- var __decorateClass$w = (decorators, target, key, kind) => {
2214
+ var __decorateClass$v = (decorators, target, key, kind) => {
4455
2215
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$s(target, key) : target;
4456
2216
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
4457
2217
  if (decorator = decorators[i])
4458
2218
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
4459
- if (kind && result) __defProp$w(target, key, result);
2219
+ if (kind && result) __defProp$v(target, key, result);
4460
2220
  return result;
4461
2221
  };
4462
2222
  let Timer = class extends Node {
@@ -4498,29 +2258,29 @@ let Timer = class extends Node {
4498
2258
  this.addTime(delta);
4499
2259
  }
4500
2260
  };
4501
- __decorateClass$w([
2261
+ __decorateClass$v([
4502
2262
  property({ default: 0 })
4503
2263
  ], Timer.prototype, "start", 2);
4504
- __decorateClass$w([
2264
+ __decorateClass$v([
4505
2265
  property({ default: 0 })
4506
2266
  ], Timer.prototype, "current", 2);
4507
- __decorateClass$w([
2267
+ __decorateClass$v([
4508
2268
  property({ default: Number.MAX_SAFE_INTEGER })
4509
2269
  ], Timer.prototype, "end", 2);
4510
- __decorateClass$w([
2270
+ __decorateClass$v([
4511
2271
  property({ default: false })
4512
2272
  ], Timer.prototype, "loop", 2);
4513
- Timer = __decorateClass$w([
2273
+ Timer = __decorateClass$v([
4514
2274
  customNode("Timer")
4515
2275
  ], Timer);
4516
2276
 
4517
- var __defProp$v = Object.defineProperty;
4518
- var __decorateClass$v = (decorators, target, key, kind) => {
2277
+ var __defProp$u = Object.defineProperty;
2278
+ var __decorateClass$u = (decorators, target, key, kind) => {
4519
2279
  var result = void 0 ;
4520
2280
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
4521
2281
  if (decorator = decorators[i])
4522
2282
  result = (decorator(target, key, result) ) || result;
4523
- if (result) __defProp$v(target, key, result);
2283
+ if (result) __defProp$u(target, key, result);
4524
2284
  return result;
4525
2285
  };
4526
2286
  class Texture extends Resource {
@@ -4646,22 +2406,22 @@ class Texture extends Resource {
4646
2406
  }
4647
2407
  }
4648
2408
  }
4649
- __decorateClass$v([
2409
+ __decorateClass$u([
4650
2410
  protectedProperty()
4651
2411
  ], Texture.prototype, "source");
4652
- __decorateClass$v([
2412
+ __decorateClass$u([
4653
2413
  protectedProperty({ default: 0 })
4654
2414
  ], Texture.prototype, "width");
4655
- __decorateClass$v([
2415
+ __decorateClass$u([
4656
2416
  protectedProperty({ default: 0 })
4657
2417
  ], Texture.prototype, "height");
4658
- __decorateClass$v([
2418
+ __decorateClass$u([
4659
2419
  protectedProperty({ default: "linear" })
4660
2420
  ], Texture.prototype, "filterMode");
4661
- __decorateClass$v([
2421
+ __decorateClass$u([
4662
2422
  protectedProperty({ default: "clamp_to_edge" })
4663
2423
  ], Texture.prototype, "wrapMode");
4664
- __decorateClass$v([
2424
+ __decorateClass$u([
4665
2425
  protectedProperty({ default: 1 })
4666
2426
  ], Texture.prototype, "pixelRatio");
4667
2427
 
@@ -4797,13 +2557,13 @@ class PixelsTexture extends Texture {
4797
2557
  }
4798
2558
  }
4799
2559
 
4800
- var __defProp$u = Object.defineProperty;
4801
- var __decorateClass$u = (decorators, target, key, kind) => {
2560
+ var __defProp$t = Object.defineProperty;
2561
+ var __decorateClass$t = (decorators, target, key, kind) => {
4802
2562
  var result = void 0 ;
4803
2563
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
4804
2564
  if (decorator = decorators[i])
4805
2565
  result = (decorator(target, key, result) ) || result;
4806
- if (result) __defProp$u(target, key, result);
2566
+ if (result) __defProp$t(target, key, result);
4807
2567
  return result;
4808
2568
  };
4809
2569
  function resolveOptions(options) {
@@ -5046,10 +2806,10 @@ const _VideoTexture = class _VideoTexture extends Texture {
5046
2806
  }
5047
2807
  }
5048
2808
  };
5049
- __decorateClass$u([
2809
+ __decorateClass$t([
5050
2810
  protectedProperty({ default: true })
5051
2811
  ], _VideoTexture.prototype, "autoUpdate");
5052
- __decorateClass$u([
2812
+ __decorateClass$t([
5053
2813
  protectedProperty({ default: 0 })
5054
2814
  ], _VideoTexture.prototype, "fps");
5055
2815
  let VideoTexture = _VideoTexture;
@@ -5058,14 +2818,14 @@ class ViewportTexture extends PixelsTexture {
5058
2818
  //
5059
2819
  }
5060
2820
 
5061
- var __defProp$t = Object.defineProperty;
2821
+ var __defProp$s = Object.defineProperty;
5062
2822
  var __getOwnPropDesc$r = Object.getOwnPropertyDescriptor;
5063
- var __decorateClass$t = (decorators, target, key, kind) => {
2823
+ var __decorateClass$s = (decorators, target, key, kind) => {
5064
2824
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$r(target, key) : target;
5065
2825
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
5066
2826
  if (decorator = decorators[i])
5067
2827
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
5068
- if (kind && result) __defProp$t(target, key, result);
2828
+ if (kind && result) __defProp$s(target, key, result);
5069
2829
  return result;
5070
2830
  };
5071
2831
  let Viewport = class extends Node {
@@ -5186,19 +2946,19 @@ let Viewport = class extends Node {
5186
2946
  return this._projection.toArray(transpose);
5187
2947
  }
5188
2948
  };
5189
- __decorateClass$t([
2949
+ __decorateClass$s([
5190
2950
  property({ default: 0 })
5191
2951
  ], Viewport.prototype, "x", 2);
5192
- __decorateClass$t([
2952
+ __decorateClass$s([
5193
2953
  property({ default: 0 })
5194
2954
  ], Viewport.prototype, "y", 2);
5195
- __decorateClass$t([
2955
+ __decorateClass$s([
5196
2956
  property({ default: 0 })
5197
2957
  ], Viewport.prototype, "width", 2);
5198
- __decorateClass$t([
2958
+ __decorateClass$s([
5199
2959
  property({ default: 0 })
5200
2960
  ], Viewport.prototype, "height", 2);
5201
- Viewport = __decorateClass$t([
2961
+ Viewport = __decorateClass$s([
5202
2962
  customNode({
5203
2963
  tag: "Viewport",
5204
2964
  renderable: true
@@ -5617,30 +3377,7 @@ class ColorTexture extends Texture {
5617
3377
  }
5618
3378
  }
5619
3379
 
5620
- var __defProp$s = Object.defineProperty;
5621
- var __decorateClass$s = (decorators, target, key, kind) => {
5622
- var result = void 0 ;
5623
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
5624
- if (decorator = decorators[i])
5625
- result = (decorator(target, key, result) ) || result;
5626
- if (result) __defProp$s(target, key, result);
5627
- return result;
5628
- };
5629
- function proxy$1() {
5630
- return function(target, method) {
5631
- Object.defineProperty(target.constructor.prototype, method, {
5632
- get() {
5633
- return (...args) => {
5634
- this._path2D[method](...args);
5635
- return this;
5636
- };
5637
- },
5638
- configurable: true,
5639
- enumerable: true
5640
- });
5641
- };
5642
- }
5643
- class CanvasContext {
3380
+ class CanvasContext extends Path2D {
5644
3381
  textureTransform;
5645
3382
  fillStyle;
5646
3383
  strokeStyle;
@@ -5648,7 +3385,6 @@ class CanvasContext {
5648
3385
  lineJoin;
5649
3386
  lineWidth;
5650
3387
  miterLimit;
5651
- _path2D = new Path2D();
5652
3388
  _defaultStyle = Texture.EMPTY;
5653
3389
  _stroked = [];
5654
3390
  _filled = [];
@@ -5661,10 +3397,9 @@ class CanvasContext {
5661
3397
  texture = new ColorTexture(this.strokeStyle);
5662
3398
  }
5663
3399
  }
5664
- this._path2D.endPolygon();
5665
- if (this._path2D.shapes.length) {
3400
+ if (this.curves.length) {
5666
3401
  this._stroked.push({
5667
- shapes: this._path2D.shapes.slice(),
3402
+ shapes: this.curves.slice(),
5668
3403
  texture,
5669
3404
  textureTransform: this.textureTransform,
5670
3405
  style: {
@@ -5675,7 +3410,7 @@ class CanvasContext {
5675
3410
  miterLimit: this.miterLimit ?? 10
5676
3411
  }
5677
3412
  });
5678
- this._path2D.shapes.length = 0;
3413
+ this.curves = [this.currentCurve];
5679
3414
  }
5680
3415
  }
5681
3416
  fillRect(x, y, width, height) {
@@ -5694,11 +3429,11 @@ class CanvasContext {
5694
3429
  }
5695
3430
  }
5696
3431
  this._filled.push({
5697
- shapes: this._path2D.shapes.slice(),
3432
+ shapes: this.curves.slice(),
5698
3433
  texture,
5699
3434
  textureTransform: this.textureTransform
5700
3435
  });
5701
- this._path2D.shapes.length = 0;
3436
+ this.curves = [this.currentCurve];
5702
3437
  }
5703
3438
  reset() {
5704
3439
  this.strokeStyle = void 0;
@@ -5708,8 +3443,7 @@ class CanvasContext {
5708
3443
  this.lineJoin = void 0;
5709
3444
  this.lineWidth = void 0;
5710
3445
  this.miterLimit = void 0;
5711
- this._path2D.endPolygon();
5712
- this._path2D.shapes.length = 0;
3446
+ this.curves = [this.currentCurve];
5713
3447
  this._stroked.length = 0;
5714
3448
  this._filled.length = 0;
5715
3449
  }
@@ -5750,14 +3484,20 @@ class CanvasContext {
5750
3484
  texture = void 0;
5751
3485
  };
5752
3486
  for (let len = this._stroked.length, i = 0; i < len; i++) {
3487
+ startUv = vertices.length;
5753
3488
  const graphics = this._stroked[i];
5754
3489
  texture ??= graphics.texture;
5755
3490
  const points = [];
5756
3491
  for (let len2 = graphics.shapes.length, i2 = 0; i2 < len2; i2++) {
5757
- graphics.shapes[i2].shape.buildOutline(points);
3492
+ graphics.shapes[i2].getAdaptivePointArray(points);
5758
3493
  }
5759
- startUv = vertices.length;
5760
- buildLine(points, graphics.style, false, true, vertices, 0, 0, indices);
3494
+ strokeTriangulate(points, {
3495
+ vertices,
3496
+ indices,
3497
+ lineStyle: graphics.style,
3498
+ flipAlignment: false,
3499
+ closed: true
3500
+ });
5761
3501
  this.buildUvs(startUv, vertices, uvs, graphics.texture, graphics.textureTransform);
5762
3502
  push("stroke");
5763
3503
  }
@@ -5769,7 +3509,10 @@ class CanvasContext {
5769
3509
  }
5770
3510
  startUv = vertices.length;
5771
3511
  for (let len2 = graphics.shapes.length, i2 = 0; i2 < len2; i2++) {
5772
- graphics.shapes[i2].shape.buildGeometry(vertices, indices);
3512
+ graphics.shapes[i2].fillTriangulate({
3513
+ vertices,
3514
+ indices
3515
+ });
5773
3516
  }
5774
3517
  this.buildUvs(startUv, vertices, uvs, graphics.texture, graphics.textureTransform);
5775
3518
  }
@@ -5779,48 +3522,6 @@ class CanvasContext {
5779
3522
  return batchables;
5780
3523
  }
5781
3524
  }
5782
- __decorateClass$s([
5783
- proxy$1()
5784
- ], CanvasContext.prototype, "moveTo");
5785
- __decorateClass$s([
5786
- proxy$1()
5787
- ], CanvasContext.prototype, "lineTo");
5788
- __decorateClass$s([
5789
- proxy$1()
5790
- ], CanvasContext.prototype, "bezierCurveTo");
5791
- __decorateClass$s([
5792
- proxy$1()
5793
- ], CanvasContext.prototype, "quadraticCurveTo");
5794
- __decorateClass$s([
5795
- proxy$1()
5796
- ], CanvasContext.prototype, "ellipticalArc");
5797
- __decorateClass$s([
5798
- proxy$1()
5799
- ], CanvasContext.prototype, "rect");
5800
- __decorateClass$s([
5801
- proxy$1()
5802
- ], CanvasContext.prototype, "roundRect");
5803
- __decorateClass$s([
5804
- proxy$1()
5805
- ], CanvasContext.prototype, "ellipse");
5806
- __decorateClass$s([
5807
- proxy$1()
5808
- ], CanvasContext.prototype, "arc");
5809
- __decorateClass$s([
5810
- proxy$1()
5811
- ], CanvasContext.prototype, "poly");
5812
- __decorateClass$s([
5813
- proxy$1()
5814
- ], CanvasContext.prototype, "addShape");
5815
- __decorateClass$s([
5816
- proxy$1()
5817
- ], CanvasContext.prototype, "addPath");
5818
- __decorateClass$s([
5819
- proxy$1()
5820
- ], CanvasContext.prototype, "addSvgPath");
5821
- __decorateClass$s([
5822
- proxy$1()
5823
- ], CanvasContext.prototype, "closePath");
5824
3525
 
5825
3526
  class Loader {
5826
3527
  }
@@ -7023,7 +4724,7 @@ let Node2D = class extends CanvasItem {
7023
4724
  width = newWidth;
7024
4725
  height = newHeight;
7025
4726
  }
7026
- return new Rectangle(left, top, width, height);
4727
+ return new BoundingBox(left, top, width, height);
7027
4728
  }
7028
4729
  _onUpdateStyleProperty(key, value, oldValue) {
7029
4730
  super._onUpdateStyleProperty(key, value, oldValue);
@@ -7527,6 +5228,7 @@ let Text2D = class extends Node2D {
7527
5228
  switch (key) {
7528
5229
  case "content":
7529
5230
  case "effects":
5231
+ case "measureDom":
7530
5232
  case "fonts":
7531
5233
  case "split":
7532
5234
  this._updateSplit();
@@ -13827,4 +11529,4 @@ async function render(options) {
13827
11529
  });
13828
11530
  }
13829
11531
 
13830
- export { Animation2D, Assets, Audio, AudioPipeline, AudioProcessor, AudioSpectrum, AudioWaveform, BlurEffect, Bounds, CanvasContext, CanvasItem, Circle, Color, ColorAdjustEffect, ColorFilterEffect, ColorMatrix, ColorOverlayEffect, ColorRemoveEffect, ColorReplaceEffect, ColorTexture, DEG_TO_RAD, DEVICE_PIXEL_RATIO, Effect, EffectMaterial, Ellipse, EmbossEffect, Engine, EventEmitter, FontLoader, Geometry, GifLoader, GlitchEffect, GodrayEffect, Graphics2D, HTMLAudio, HTMLAudioContext, HTMLSound, IN_BROWSER, Image2D, Image2DResource, ImageTexture, IndexBuffer, Input, InternalMode, JsonLoader, KawaseEffect, LeftEraseEffect, Loader, Lottie2D, LottieLoader, MainLoop, MaskEffect, Material, Matrix, Matrix2, Matrix3, Matrix4, MouseInputEvent, Node, Node2D, PI, PI_2, Path2D, PixelateEffect, PixelsTexture, Point, PointerInputEvent, Polygon, Projection2D, QuadGeometry, QuadUvGeometry, RAD_TO_DEG, Rectangle, Reference, RenderStack, Renderer, Resource, RoundedRectangle, SUPPORTS_AUDIO_CONTEXT, SUPPORTS_CLICK_EVENTS, SUPPORTS_CREATE_IMAGE_BITMAP, SUPPORTS_IMAGE_BITMAP, SUPPORTS_MOUSE_EVENTS, SUPPORTS_OFFLINE_AUDIO_CONTEXT, SUPPORTS_POINTER_EVENTS, SUPPORTS_RESIZE_OBSERVER, SUPPORTS_TOUCH_EVENTS, SUPPORTS_WEBGL2, SUPPORTS_WEBKIT_AUDIO_CONTEXT, SUPPORTS_WEBKIT_OFFLINE_AUDIO_CONTEXT, SUPPORTS_WEB_AUDIO, SUPPORTS_WHEEL_EVENTS, SVGPath, SceneTree, Star, Style2D, Style2DBackgroundModule, Style2DFilterModule, Style2DModule, Style2DTextModule, Style2DTransformModule, Text2D, TextLoader, Texture, TextureLoader, Ticker, TiltShiftEffect, Timer, Transform2D, Triangle, TwistEffect, UIInputEvent, UvGeometry, UvMaterial, Vector, Vector2, Vector3, Vector4, VertexAttribute, VertexBuffer, Video2D, VideoLoader, VideoTexture, Viewport, ViewportTexture, WebAudio, WebAudioContext, WebGLBatch2DModule, WebGLBlendMode, WebGLBufferModule, WebGLFramebufferModule, WebGLMaskModule, WebGLModule, WebGLProgramModule, WebGLRenderer, WebGLScissorModule, WebGLState, WebGLStateModule, WebGLStencilModule, WebGLTextureModule, WebGLVertexArrayModule, WebGLViewportModule, WebSound, WheelInputEvent, ZoomBlurEffect, _Object, assets, buildAdaptiveBezier, buildAdaptiveQuadratic, buildArc, buildArcTo, buildArcToSvg, buildCircle, buildLine, buildPolygon, buildRectangle, buildTriangle, clamp, closePointEps, createHTMLCanvas, createNode, crossOrigin, cubicBezier, curveEps, curves, customNode, customNodes, defaultOptions, defineProperty, determineCrossOrigin, ease, easeIn, easeInOut, easeOut, getDeclarations, getDefaultCssPropertyValue, isCanvasElement, isElementNode, isImageElement, isPow2, isVideoElement, isWebgl2, lerp, linear, log2, mapWebGLBlendModes, nextPow2, nextTick, parseCssFunctions, parseCssProperty, property, protectedProperty, render, squaredDistanceToLineSegment, timingFunctions, uid };
11532
+ export { Animation2D, Assets, Audio, AudioPipeline, AudioProcessor, AudioSpectrum, AudioWaveform, BlurEffect, CanvasContext, CanvasItem, Color, ColorAdjustEffect, ColorFilterEffect, ColorMatrix, ColorOverlayEffect, ColorRemoveEffect, ColorReplaceEffect, ColorTexture, DEG_TO_RAD, DEVICE_PIXEL_RATIO, Effect, EffectMaterial, EmbossEffect, Engine, EventEmitter, FontLoader, Geometry, GifLoader, GlitchEffect, GodrayEffect, Graphics2D, HTMLAudio, HTMLAudioContext, HTMLSound, IN_BROWSER, Image2D, Image2DResource, ImageTexture, IndexBuffer, Input, InternalMode, JsonLoader, KawaseEffect, LeftEraseEffect, Loader, Lottie2D, LottieLoader, MainLoop, MaskEffect, Material, Matrix, Matrix2, Matrix3, Matrix4, MouseInputEvent, Node, Node2D, PI, PI_2, PixelateEffect, PixelsTexture, PointerInputEvent, Projection2D, QuadGeometry, QuadUvGeometry, RAD_TO_DEG, Reference, RenderStack, Renderer, Resource, SUPPORTS_AUDIO_CONTEXT, SUPPORTS_CLICK_EVENTS, SUPPORTS_CREATE_IMAGE_BITMAP, SUPPORTS_IMAGE_BITMAP, SUPPORTS_MOUSE_EVENTS, SUPPORTS_OFFLINE_AUDIO_CONTEXT, SUPPORTS_POINTER_EVENTS, SUPPORTS_RESIZE_OBSERVER, SUPPORTS_TOUCH_EVENTS, SUPPORTS_WEBGL2, SUPPORTS_WEBKIT_AUDIO_CONTEXT, SUPPORTS_WEBKIT_OFFLINE_AUDIO_CONTEXT, SUPPORTS_WEB_AUDIO, SUPPORTS_WHEEL_EVENTS, SceneTree, Style2D, Style2DBackgroundModule, Style2DFilterModule, Style2DModule, Style2DTextModule, Style2DTransformModule, Text2D, TextLoader, Texture, TextureLoader, Ticker, TiltShiftEffect, Timer, Transform2D, TwistEffect, UIInputEvent, UvGeometry, UvMaterial, Vector, Vector2, Vector3, Vector4, VertexAttribute, VertexBuffer, Video2D, VideoLoader, VideoTexture, Viewport, ViewportTexture, WebAudio, WebAudioContext, WebGLBatch2DModule, WebGLBlendMode, WebGLBufferModule, WebGLFramebufferModule, WebGLMaskModule, WebGLModule, WebGLProgramModule, WebGLRenderer, WebGLScissorModule, WebGLState, WebGLStateModule, WebGLStencilModule, WebGLTextureModule, WebGLVertexArrayModule, WebGLViewportModule, WebSound, WheelInputEvent, ZoomBlurEffect, _Object, assets, clamp, createHTMLCanvas, createNode, crossOrigin, cubicBezier, curves, customNode, customNodes, defaultOptions, defineProperty, determineCrossOrigin, ease, easeIn, easeInOut, easeOut, getDeclarations, getDefaultCssPropertyValue, isCanvasElement, isElementNode, isImageElement, isPow2, isVideoElement, isWebgl2, lerp, linear, log2, mapWebGLBlendModes, nextPow2, nextTick, parseCssFunctions, parseCssProperty, property, protectedProperty, render, timingFunctions, uid };