jmgraph 3.2.21 → 3.2.24

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/jmgraph.js CHANGED
@@ -176,6 +176,10 @@ function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _c
176
176
 
177
177
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
178
178
 
179
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
180
+
181
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
182
+
179
183
  function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
180
184
 
181
185
  function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
@@ -229,6 +233,17 @@ var jmGraphImpl = /*#__PURE__*/function (_jmGraphCore) {
229
233
  return _super.call(this, canvas, option, callback);
230
234
  }
231
235
 
236
+ _createClass(jmGraphImpl, null, [{
237
+ key: "create",
238
+ value: function create() {
239
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
240
+ args[_key] = arguments[_key];
241
+ }
242
+
243
+ return _construct(jmGraphImpl, args);
244
+ }
245
+ }]);
246
+
232
247
  return jmGraphImpl;
233
248
  }(_jmGraph.jmGraph); //创建实例,支持不加 new 直接调用
234
249
 
@@ -236,8 +251,8 @@ var jmGraphImpl = /*#__PURE__*/function (_jmGraphCore) {
236
251
  exports.jmGraph = jmGraphImpl;
237
252
 
238
253
  var createJmGraph = function createJmGraph() {
239
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
240
- args[_key] = arguments[_key];
254
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
255
+ args[_key2] = arguments[_key2];
241
256
  }
242
257
 
243
258
  return _construct(jmGraphImpl, args);
@@ -1598,7 +1613,16 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1598
1613
  args[_key] = arguments[_key];
1599
1614
  }
1600
1615
 
1601
- this.runEventHandle(args[0], args.slice(1));
1616
+ // 避免每帧 args.slice(1) 分配临时数组
1617
+ // runEventHandle 内部会把非数组参数包装成数组
1618
+ if (args.length > 2) {
1619
+ this.runEventHandle(args[0], args.slice(1));
1620
+ } else if (args.length === 2) {
1621
+ this.runEventHandle(args[0], [args[1]]);
1622
+ } else {
1623
+ this.runEventHandle(args[0], []);
1624
+ }
1625
+
1602
1626
  return this;
1603
1627
  }
1604
1628
  /**
@@ -2718,7 +2742,8 @@ var jmGradient = /*#__PURE__*/function () {
2718
2742
 
2719
2743
  if (this.type === 'linear') {
2720
2744
  if (control.mode === 'webgl' && control.webglControl) {
2721
- gradient = control.webglControl.createLinearGradient(x1, y1, x2, y2, bounds);
2745
+ // WebGL 着色器中 v_text_coord 是绝对坐标,需要传递绝对坐标
2746
+ gradient = control.webglControl.createLinearGradient(sx1, sy1, sx2, sy2, bounds);
2722
2747
  gradient.key = this.toString();
2723
2748
  } else {
2724
2749
  context.createLinearGradient && (gradient = context.createLinearGradient(sx1, sy1, sx2, sy2));
@@ -2738,7 +2763,8 @@ var jmGradient = /*#__PURE__*/function () {
2738
2763
  }
2739
2764
 
2740
2765
  if (control.mode === 'webgl' && control.webglControl) {
2741
- gradient = control.webglControl.createRadialGradient(x1, y1, r1, x2, y2, r2, bounds);
2766
+ // WebGL 着色器中 v_text_coord 是绝对坐标,需要传递绝对坐标
2767
+ gradient = control.webglControl.createRadialGradient(sx1, sy1, r1, sx2, sy2, r2, bounds);
2742
2768
  gradient.key = this.toString();
2743
2769
  } //offsetLine = Math.abs(r2 - r1);//二圆半径差
2744
2770
  else if (context.createRadialGradient) {
@@ -3059,9 +3085,8 @@ var jmGraph = /*#__PURE__*/function (_jmControl) {
3059
3085
  });
3060
3086
  } else {
3061
3087
  _this.context = canvas.getContext(_this.mode);
3062
- }
3088
+ } // webgl模式
3063
3089
 
3064
- _this.textureCanvas = option.textureCanvas || null; // webgl模式
3065
3090
 
3066
3091
  if (_this.mode === 'webgl') {
3067
3092
  _this.context.enable(_this.context.BLEND); // 开启混合功能:(注意,它不可和gl.DEPTH_TEST一起使用)
@@ -3430,13 +3455,22 @@ var jmGraph = /*#__PURE__*/function (_jmControl) {
3430
3455
 
3431
3456
  this.context.clearRect(0, 0, w, h);
3432
3457
  } else if (this.mode === 'webgl' && this.context.clear) {
3433
- var color = this.style && this.style.fill ? this.utils.hexToRGBA(this.style.fill) : {
3434
- r: 0,
3435
- g: 0,
3436
- b: 0,
3437
- a: 0
3438
- };
3439
- this.context.clearColor(color.r, color.g, color.b, color.a); // 设置清空颜色缓冲时的颜色值
3458
+ // 缓存 clearColor 对象,避免每帧创建
3459
+ if (this.style && this.style.fill) {
3460
+ var color = this.utils.hexToRGBA(this.style.fill);
3461
+ this.__lastClearColor = color;
3462
+ this.context.clearColor(color.r, color.g, color.b, color.a);
3463
+ } else if (!this.__lastClearColor) {
3464
+ this.__lastClearColor = {
3465
+ r: 0,
3466
+ g: 0,
3467
+ b: 0,
3468
+ a: 0
3469
+ };
3470
+ this.context.clearColor(0, 0, 0, 0);
3471
+ } else {
3472
+ this.context.clearColor(this.__lastClearColor.r, this.__lastClearColor.g, this.__lastClearColor.b, this.__lastClearColor.a);
3473
+ }
3440
3474
 
3441
3475
  this.context.clear(this.context.COLOR_BUFFER_BIT); // 清空颜色缓冲区,也就是清空画布
3442
3476
  }
@@ -3808,8 +3842,8 @@ var jmGraph = /*#__PURE__*/function (_jmControl) {
3808
3842
  if (self.needUpdate) self.redraw();
3809
3843
  var time = Date.now() - refreshStartTime; // 触发刷新事件
3810
3844
 
3811
- self.emit('update', time);
3812
- self.__requestAnimationFrameFunHandler && self.cancelAnimationFrame(self.__requestAnimationFrameFunHandler);
3845
+ self.emit('update', time); // 直接 requestAnimationFrame,无需先 cancel
3846
+
3813
3847
  self.__requestAnimationFrameFunHandler = self.requestAnimationFrame(update);
3814
3848
  if (callback) callback();
3815
3849
  }
@@ -6175,11 +6209,17 @@ earcut.flatten = function (data) {
6175
6209
  Object.defineProperty(exports, "__esModule", {
6176
6210
  value: true
6177
6211
  });
6178
- exports["default"] = void 0;
6212
+ Object.defineProperty(exports, "MAX_STOPS", {
6213
+ enumerable: true,
6214
+ get: function get() {
6215
+ return _gradient.MAX_STOPS;
6216
+ }
6217
+ });
6218
+ exports.pathFragmentSource = exports.pathVertexSource = exports["default"] = void 0;
6179
6219
 
6180
6220
  var _earcut = _interopRequireDefault(require("../earcut.js"));
6181
6221
 
6182
- var _gradient = _interopRequireDefault(require("./gradient.js"));
6222
+ var _gradient = _interopRequireWildcard(require("./gradient.js"));
6183
6223
 
6184
6224
  var _program = require("./core/program.js");
6185
6225
 
@@ -6187,9 +6227,13 @@ var _buffer = require("./core/buffer.js");
6187
6227
 
6188
6228
  var _texture = require("./core/texture.js");
6189
6229
 
6230
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
6231
+
6232
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
6233
+
6190
6234
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
6191
6235
 
6192
- function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
6236
+ function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
6193
6237
 
6194
6238
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
6195
6239
 
@@ -6228,9 +6272,11 @@ var convertPointSource = "\n vec4 translatePosition(vec4 point, float x, floa
6228
6272
 
6229
6273
  var convertTexturePosition = "\n vec2 translateTexturePosition(in vec2 point, vec4 bounds) {\n point.x = (point.x-bounds.x)/bounds.z; // \u79BB\u5DE6\u4E0A\u89D2\u4F4D\u7F6E\u7684X\u957F\u6BD4\u4E0A\u7EB9\u7406\u5BBD 0-1\n point.y = 1.0-(point.y-bounds.y)/bounds.w; // \u79BB\u5DE6\u4E0A\u89D2\u4F4D\u7F6E\u7684Y\u957F\u6BD4\u4E0A\u9AD8\uFF0C\u56E0\u4E3A\u7EB9\u7406\u5750\u6807\u662F\u5DE6\u4E0B\u89D2\u8D77\uFF0C\u6240\u4EE5\u8981\u75281-\n return point;\n }"; // path顶点着色器源码
6230
6274
 
6231
- var pathVertexSource = "\n attribute vec4 a_position;\n attribute vec4 a_color;\n attribute vec2 a_text_coord;\n uniform vec2 a_center_point; // \u5F53\u524Dcanvas\u7684\u4E2D\u5FC3\u4F4D\u7F6E\n uniform float a_point_size; // \u70B9\u7684\u5927\u5C0F\n uniform int a_type;\n varying vec4 v_color;\n varying vec2 v_text_coord;\n varying float v_type;\n\n ".concat(convertPointSource, "\n\n void main() {\n gl_PointSize = a_point_size == 0.0? 1.0 : a_point_size;\n v_type = float(a_type);\n vec4 pos = translatePosition(a_position, a_center_point.x, a_center_point.y);\n gl_Position = pos;\n v_color = a_color;\n if(a_type == 2) {\n v_text_coord = a_text_coord;\n }\n }\n"); // path 片段着色器源码
6275
+ var pathVertexSource = "\n attribute vec4 a_position;\n attribute vec4 a_color;\n attribute vec2 a_text_coord;\n uniform vec2 a_center_point; // \u5F53\u524Dcanvas\u7684\u4E2D\u5FC3\u4F4D\u7F6E\n uniform float a_point_size; // \u70B9\u7684\u5927\u5C0F\n uniform int a_type;\n varying vec4 v_color;\n varying vec2 v_text_coord;\n varying float v_type;\n\n ".concat(convertPointSource, "\n\n void main() {\n gl_PointSize = a_point_size == 0.0? 1.0 : a_point_size;\n v_type = float(a_type);\n vec4 pos = translatePosition(a_position, a_center_point.x, a_center_point.y);\n gl_Position = pos;\n v_color = a_color;\n if(a_type == 2 || a_type == 5) {\n v_text_coord = a_position.xy;\n }\n }\n"); // path 片段着色器源码
6232
6276
 
6233
- var pathFragmentSource = "\n precision mediump float;\n uniform sampler2D u_sample;\n uniform vec4 v_texture_bounds; // \u7EB9\u7406\u7684\u5DE6\u4E0A\u5750\u6807\u548C\u5927\u5C0F x,y,z,w\n uniform vec4 v_single_color;\n varying float v_type;\n varying vec4 v_color;\n varying vec2 v_text_coord;\n\n ".concat(convertTexturePosition, "\n\n void main() {\n // \u5982\u679C\u662Ffill\uFF0C\u5219\u76F4\u63A5\u586B\u5145\u989C\u8272\n if(v_type == 1.0) {\n gl_FragColor = v_single_color;\n }\n // \u6E10\u53D8\u8272\n else if(v_type == 3.0) {\n gl_FragColor = v_color;\n }\n else if(v_type == 2.0) {\n vec2 pos = translateTexturePosition(v_text_coord, v_texture_bounds);\n gl_FragColor = texture2D(u_sample, pos);\n }\n else {\n float r = distance(gl_PointCoord, vec2(0.5, 0.5));\n //\u6839\u636E\u8DDD\u79BB\u8BBE\u7F6E\u7247\u5143\n if(r <= 0.5){\n // \u65B9\u5F62\u533A\u57DF\u7247\u5143\u8DDD\u79BB\u51E0\u4F55\u4E2D\u5FC3\u534A\u5F84\u5C0F\u4E8E0.5\uFF0C\u50CF\u7D20\u989C\u8272\u8BBE\u7F6E\u7EA2\u8272\n gl_FragColor = v_single_color;\n }else {\n // \u65B9\u5F62\u533A\u57DF\u8DDD\u79BB\u51E0\u4F55\u4E2D\u5FC3\u534A\u5F84\u4E0D\u5C0F\u4E8E0.5\u7684\u7247\u5143\u526A\u88C1\u820D\u5F03\u6389\uFF1A\n discard;\n }\n }\n }\n");
6277
+ exports.pathVertexSource = pathVertexSource;
6278
+ var pathFragmentSource = "\n precision mediump float;\n uniform sampler2D u_sample;\n uniform vec4 v_texture_bounds; // \u7EB9\u7406\u7684\u5DE6\u4E0A\u5750\u6807\u548C\u5927\u5C0F x,y,z,w\n uniform vec4 v_single_color;\n // GLSL \u6E10\u53D8 uniforms\n uniform int u_gradient_type; // 0=\u65E0 1=\u7EBF\u6027 2=\u5F84\u5411\n uniform vec4 u_gradient_start; // \u7EBF\u6027:{x1,y1,0,0} \u5F84\u5411:{cx,cy,r1,0}\n uniform vec4 u_gradient_end; // \u7EBF\u6027:{x2,y2,0,0} \u5F84\u5411:{cx,cy,r2,0}\n uniform int u_gradient_stop_count;\n uniform float u_gradient_offsets[".concat(_gradient.MAX_STOPS, "];\n uniform vec4 u_gradient_colors[").concat(_gradient.MAX_STOPS, "]; // {r, g, b, a} 0~1 \u8303\u56F4\n varying float v_type;\n varying vec4 v_color;\n varying vec2 v_text_coord;\n\n ").concat(convertTexturePosition, "\n\n // \u5728 sorted stops \u4E2D\u6309 t \u503C\u91C7\u6837\u989C\u8272\n // \u517C\u5BB9 GLSL ES 1.0\uFF1A\u5FAA\u73AF\u4EC5\u4E0E\u5E38\u91CF\u6BD4\u8F83\uFF0C\u65E0 break/continue\n vec4 sampleGradient(float t) {\n t = clamp(t, 0.0, 1.0);\n // \u6B63\u5411\u626B\u63CF\uFF1A\u59CB\u7EC8\u904D\u5386 MAX_STOPS-1 \u6B21\uFF0C\u627E\u5230 t \u6240\u5728\u6BB5\u5E76\u8986\u76D6\u7ED3\u679C\n float localT = 0.0;\n vec4 c0 = u_gradient_colors[0];\n vec4 c1 = u_gradient_colors[0];\n for(int i = 0; i < ").concat(_gradient.MAX_STOPS - 1, "; i++) {\n float s0 = u_gradient_offsets[i];\n float s1 = u_gradient_offsets[i + 1];\n if(t >= s0) {\n float range = s1 - s0;\n localT = range > 0.0001 ? clamp((t - s0) / range, 0.0, 1.0) : 0.0;\n c0 = u_gradient_colors[i];\n c1 = u_gradient_colors[i + 1];\n }\n }\n return mix(c0, c1, localT);\n }\n\n void main() {\n // \u5982\u679C\u662Ffill\uFF0C\u5219\u76F4\u63A5\u586B\u5145\u989C\u8272\n if(v_type == 1.0) {\n gl_FragColor = v_single_color;\n }\n // \u6E10\u53D8\u8272 (\u65E7\u65B9\u5F0F\uFF0C\u9876\u70B9\u989C\u8272\u63D2\u503C)\n else if(v_type == 3.0) {\n gl_FragColor = v_color;\n }\n // GLSL \u6E10\u53D8\u586B\u5145 (type=5)\n else if(v_type == 5.0) {\n float t;\n if(u_gradient_type == 2) {\n // \u5F84\u5411\u6E10\u53D8\n vec2 d = v_text_coord - u_gradient_start.xy;\n float dist = length(d);\n float r1 = u_gradient_start.z;\n float r2 = u_gradient_end.z;\n float range = r2 - r1;\n t = range > 0.001 ? (dist - r1) / range : 0.0;\n } else {\n // \u7EBF\u6027\u6E10\u53D8\n vec2 dir = u_gradient_end.xy - u_gradient_start.xy;\n float lenSq = dot(dir, dir);\n if(lenSq > 0.001) {\n vec2 pos = v_text_coord - u_gradient_start.xy;\n t = dot(pos, dir) / lenSq;\n } else {\n t = 0.0;\n }\n }\n gl_FragColor = sampleGradient(t) * v_single_color.a;\n }\n else if(v_type == 2.0) {\n vec2 pos = translateTexturePosition(v_text_coord, v_texture_bounds);\n gl_FragColor = texture2D(u_sample, pos);\n }\n else {\n float r = distance(gl_PointCoord, vec2(0.5, 0.5));\n //\u6839\u636E\u8DDD\u79BB\u8BBE\u7F6E\u7247\u5143\n if(r <= 0.5){\n // \u65B9\u5F62\u533A\u57DF\u7247\u5143\u8DDD\u79BB\u51E0\u4F55\u4E2D\u5FC3\u534A\u5F84\u5C0F\u4E8E0.5\uFF0C\u50CF\u7D20\u989C\u8272\u8BBE\u7F6E\u7EA2\u8272\n gl_FragColor = v_single_color;\n }else {\n // \u65B9\u5F62\u533A\u57DF\u8DDD\u79BB\u51E0\u4F55\u4E2D\u5FC3\u534A\u5F84\u4E0D\u5C0F\u4E8E0.5\u7684\u7247\u5143\u526A\u88C1\u820D\u5F03\u6389\uFF1A\n discard;\n }\n }\n }\n");
6279
+ exports.pathFragmentSource = pathFragmentSource;
6234
6280
 
6235
6281
  var WeblBase = /*#__PURE__*/function () {
6236
6282
  function WeblBase(graph, option) {
@@ -6294,13 +6340,11 @@ var WeblBase = /*#__PURE__*/function () {
6294
6340
  var cos = Math.cos(angle);
6295
6341
  var sin = Math.sin(angle);
6296
6342
 
6297
- var _this$transformMatrix = _slicedToArray(this.transformMatrix, 6),
6343
+ var _this$transformMatrix = _slicedToArray(this.transformMatrix, 4),
6298
6344
  a = _this$transformMatrix[0],
6299
6345
  b = _this$transformMatrix[1],
6300
6346
  c = _this$transformMatrix[2],
6301
- d = _this$transformMatrix[3],
6302
- tx = _this$transformMatrix[4],
6303
- ty = _this$transformMatrix[5]; // 更新变换矩阵
6347
+ d = _this$transformMatrix[3]; // 更新变换矩阵
6304
6348
 
6305
6349
 
6306
6350
  this.transformMatrix[0] = a * cos - b * sin;
@@ -6344,28 +6388,24 @@ var WeblBase = /*#__PURE__*/function () {
6344
6388
  x: a * point.x + c * point.y + tx,
6345
6389
  y: b * point.x + d * point.y + ty
6346
6390
  };
6347
- } // 纹理绘制canvas
6391
+ } // 文本测量用的离屏 canvas context(1x1 单例缓存,不依赖 textureCanvas)
6348
6392
 
6349
6393
  }, {
6350
- key: "textureCanvas",
6394
+ key: "_measureCtx",
6351
6395
  get: function get() {
6352
- var canvas = this.graph.textureCanvas;
6353
-
6354
- if (!canvas) {
6355
- if (typeof document === 'undefined') return null;
6356
- canvas = this.graph.textureCanvas = document.createElement('canvas');
6396
+ if (!this.__measureCtx) {
6397
+ try {
6398
+ if (typeof document !== 'undefined') {
6399
+ var c = document.createElement('canvas');
6400
+ c.width = c.height = 1;
6401
+ this.__measureCtx = c.getContext('2d');
6402
+ }
6403
+ } catch (e) {
6404
+ this.__measureCtx = null;
6405
+ }
6357
6406
  }
6358
6407
 
6359
- return canvas;
6360
- } // 纹理绘制canvas ctx
6361
-
6362
- }, {
6363
- key: "textureContext",
6364
- get: function get() {
6365
- var ctx = this.textureCanvas.ctx || (this.textureCanvas.ctx = this.textureCanvas.getContext('2d', {
6366
- willReadFrequently: true
6367
- }));
6368
- return ctx;
6408
+ return this.__measureCtx;
6369
6409
  } // i当前程序
6370
6410
 
6371
6411
  }, {
@@ -6414,25 +6454,69 @@ var WeblBase = /*#__PURE__*/function () {
6414
6454
  key: "convertColor",
6415
6455
  value: function convertColor(color) {
6416
6456
  if (this.isGradient(color)) return color;
6417
- if (typeof color === 'string') color = this.graph.utils.hexToRGBA(color);
6418
- return this.graph.utils.rgbToDecimal(color);
6419
- }
6420
- }, {
6421
- key: "setTextureStyle",
6422
- value: function setTextureStyle(style) {
6423
- var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
6424
6457
 
6425
- if (typeof style === 'string') {
6426
- if (['fillStyle', 'strokeStyle', 'shadowColor'].indexOf(style) > -1) {
6427
- value = this.graph.utils.toColor(value);
6458
+ if (typeof color === 'string') {
6459
+ // 先尝试 hexToRGBA 解析
6460
+ color = this.graph.utils.hexToRGBA(color); // hexToRGBA 对无法识别的格式(如 hsl)会原样返回字符串
6461
+ // 利用离屏 canvas 将任意 CSS 颜色转为 rgba
6462
+
6463
+ if (typeof color === 'string') {
6464
+ color = this.__parseCSSColor(color);
6428
6465
  }
6466
+ }
6429
6467
 
6430
- this.textureContext[style] = value;
6431
- } else {
6432
- for (var name in style) {
6433
- if (name === 'constructor') continue;
6434
- this.setTextureStyle(name, style[name]);
6468
+ if (_typeof(color) === 'object' && color.r !== undefined) {
6469
+ return this.graph.utils.rgbToDecimal(color);
6470
+ }
6471
+
6472
+ return color;
6473
+ } // 利用离屏 canvas 解析任意 CSS 颜色(hsl/hsla/命名颜色等)
6474
+
6475
+ }, {
6476
+ key: "__parseCSSColor",
6477
+ value: function __parseCSSColor(colorStr) {
6478
+ var ctx = this._measureCtx;
6479
+ if (!ctx) return {
6480
+ r: 0,
6481
+ g: 0,
6482
+ b: 0,
6483
+ a: 0
6484
+ };
6485
+
6486
+ try {
6487
+ ctx.clearRect(0, 0, 1, 1);
6488
+ ctx.fillStyle = '#000000';
6489
+ ctx.fillStyle = colorStr;
6490
+ ctx.fillRect(0, 0, 1, 1);
6491
+
6492
+ var _ctx$getImageData$dat = _slicedToArray(ctx.getImageData(0, 0, 1, 1).data, 4),
6493
+ r = _ctx$getImageData$dat[0],
6494
+ g = _ctx$getImageData$dat[1],
6495
+ b = _ctx$getImageData$dat[2],
6496
+ a = _ctx$getImageData$dat[3];
6497
+
6498
+ if (ctx.fillStyle === '#000000' && colorStr !== '#000000' && colorStr !== 'black') {
6499
+ return {
6500
+ r: 0,
6501
+ g: 0,
6502
+ b: 0,
6503
+ a: 0
6504
+ };
6435
6505
  }
6506
+
6507
+ return {
6508
+ r: r,
6509
+ g: g,
6510
+ b: b,
6511
+ a: a / 255
6512
+ };
6513
+ } catch (e) {
6514
+ return {
6515
+ r: 0,
6516
+ g: 0,
6517
+ b: 0,
6518
+ a: 0
6519
+ };
6436
6520
  }
6437
6521
  } // 创建程序
6438
6522
 
@@ -6651,84 +6735,29 @@ var WeblBase = /*#__PURE__*/function () {
6651
6735
  return obj && obj instanceof _gradient["default"];
6652
6736
  }
6653
6737
  /**
6654
- * 测试获取文本所占大小
6655
- *
6656
- * @method testSize
6657
- * @return {object} 含文本大小的对象
6658
- */
6738
+ * 测试获取文本所占大小
6739
+ *
6740
+ * @method testSize
6741
+ * @return {object} 含文本大小的对象
6742
+ */
6659
6743
 
6660
6744
  }, {
6661
6745
  key: "testSize",
6662
6746
  value: function testSize(text) {
6663
6747
  var style = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.style;
6664
- this.textureContext.save && this.textureContext.save(); // 修改字体,用来计算
6665
-
6666
- if (style.font || style.fontSize) this.textureContext.font = style.font || style.fontSize + 'px ' + style.fontFamily; //计算宽度
6667
-
6668
- var size = this.textureContext.measureText ? this.textureContext.measureText(text) : {
6748
+ var ctx = this._measureCtx;
6749
+ if (!ctx) return {
6750
+ width: 15,
6751
+ height: style.fontSize || 15
6752
+ };
6753
+ ctx.save && ctx.save();
6754
+ if (style.font || style.fontSize) ctx.font = style.font || style.fontSize + 'px ' + style.fontFamily;
6755
+ var size = ctx.measureText ? ctx.measureText(text) : {
6669
6756
  width: 15
6670
6757
  };
6671
- this.textureContext.restore && this.textureContext.restore();
6672
- size.height = this.style.fontSize ? this.style.fontSize : 15;
6758
+ ctx.restore && ctx.restore();
6759
+ size.height = style.fontSize ? parseInt(style.fontSize) : 15;
6673
6760
  return size;
6674
- } // 使用纹理canvas生成图,
6675
- // 填充可以是颜色或渐变对象
6676
- // 如果指定了points,则表明要绘制不规则的图形
6677
-
6678
- }, {
6679
- key: "toFillTexture",
6680
- value: function toFillTexture(fillStyle, bounds) {
6681
- var points = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
6682
- var canvas = this.textureCanvas;
6683
-
6684
- if (!canvas) {
6685
- return fillStyle;
6686
- }
6687
-
6688
- canvas.width = bounds.width;
6689
- canvas.height = bounds.height;
6690
-
6691
- if (!canvas.width || !canvas.height) {
6692
- return fillStyle;
6693
- }
6694
-
6695
- this.textureContext.clearRect(0, 0, canvas.width, canvas.height);
6696
- this.textureContext.fillStyle = fillStyle; // 规则图形用 fillRect,比 beginPath/lineTo/fill 快
6697
-
6698
- if (!points || !points.length) {
6699
- this.textureContext.fillRect(0, 0, bounds.width, bounds.height);
6700
- } else {
6701
- this.textureContext.beginPath();
6702
-
6703
- var _iterator = _createForOfIteratorHelper(points),
6704
- _step;
6705
-
6706
- try {
6707
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
6708
- var p = _step.value;
6709
-
6710
- //移至当前坐标
6711
- if (p.m) {
6712
- this.textureContext.moveTo(p.x - bounds.left, p.y - bounds.top);
6713
- } else {
6714
- this.textureContext.lineTo(p.x - bounds.left, p.y - bounds.top);
6715
- }
6716
- }
6717
- } catch (err) {
6718
- _iterator.e(err);
6719
- } finally {
6720
- _iterator.f();
6721
- }
6722
-
6723
- this.textureContext.closePath();
6724
- this.textureContext.fill();
6725
- }
6726
-
6727
- var data = this.textureContext.getImageData(0, 0, canvas.width, canvas.height);
6728
- return {
6729
- data: data,
6730
- points: points
6731
- };
6732
6761
  }
6733
6762
  }]);
6734
6763
 
@@ -7109,7 +7138,9 @@ function deleteTexture(gl, texture) {
7109
7138
  Object.defineProperty(exports, "__esModule", {
7110
7139
  value: true
7111
7140
  });
7112
- exports["default"] = void 0;
7141
+ exports.MAX_STOPS = exports["default"] = void 0;
7142
+
7143
+ function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
7113
7144
 
7114
7145
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
7115
7146
 
@@ -7117,10 +7148,15 @@ function _defineProperties(target, props) { for (var i = 0; i < props.length; i+
7117
7148
 
7118
7149
  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
7119
7150
 
7120
- var WebglGradientTextureCache = {}; // 渐变
7151
+ var MAX_STOPS = 16;
7152
+ /**
7153
+ * WebGL 渐变对象
7154
+ * 支持 GLSL 着色器直接计算渐变色,无需 textureCanvas
7155
+ */
7156
+
7157
+ exports.MAX_STOPS = MAX_STOPS;
7121
7158
 
7122
7159
  var WebglGradient = /*#__PURE__*/function () {
7123
- // type:[linear= 线性渐变,radial=放射性渐变]
7124
7160
  function WebglGradient() {
7125
7161
  var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'linear';
7126
7162
  var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
@@ -7142,149 +7178,109 @@ var WebglGradient = /*#__PURE__*/function () {
7142
7178
  };
7143
7179
  this.control = params.control;
7144
7180
  this.stops = [];
7145
- this.init();
7181
+ this._sortedStops = null;
7182
+ this._paramsHash = null;
7146
7183
  }
7184
+ /**
7185
+ * 添加颜色断点
7186
+ */
7147
7187
 
7148
- _createClass(WebglGradient, [{
7149
- key: "init",
7150
- value: function init() {
7151
- var dx = this.x2 - this.x1;
7152
- var dy = this.y2 - this.y1;
7153
-
7154
- if (this.type === 'radial') {
7155
- this.length = this.r2 - this.r1;
7156
- } else if (dx === 0 && dy === 0) {
7157
- this.length = 0;
7158
- } else {
7159
- // 渐变中心的距离
7160
- this.length = Math.sqrt(Math.pow(dx, 2), Math.pow(dy, 2));
7161
- this.sin = dy / this.length;
7162
- this.cos = dx / this.length;
7163
- }
7164
- } // 渐变颜色
7165
7188
 
7166
- }, {
7189
+ _createClass(WebglGradient, [{
7167
7190
  key: "addColorStop",
7168
7191
  value: function addColorStop(offset, color) {
7169
7192
  this.stops.push({
7170
- offset: offset,
7193
+ offset: Math.max(0, Math.min(1, offset)),
7171
7194
  color: color
7172
7195
  });
7173
- } // 转为渐变为纹理
7196
+ this._sortedStops = null;
7197
+ this._paramsHash = null;
7198
+ }
7199
+ /**
7200
+ * 获取排序后的 stops(带解析后的颜色)
7201
+ */
7174
7202
 
7175
7203
  }, {
7176
- key: "toImageData",
7177
- value: function toImageData(control, bounds) {
7178
- var points = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
7179
- // 缓存基于渐变参数(不含 bounds,因为同一个渐变只是位置不同时纹理相同)
7180
- var gradientKey = this.toString();
7204
+ key: "_getSortedStops",
7205
+ value: function _getSortedStops() {
7206
+ if (this._sortedStops) return this._sortedStops;
7207
+ var utils = this.control && this.control.graph && this.control.graph.utils;
7208
+ this._sortedStops = this.stops.map(function (s) {
7209
+ var c = s.color;
7181
7210
 
7182
- if (this.__cachedData && this.__cacheKey === gradientKey && this.__cachedData.data && this.__cachedData.data.width === Math.ceil(bounds.width) && this.__cachedData.data.data && this.__cachedData.data.data.height === Math.ceil(bounds.height)) {
7183
- return this.__cachedData;
7184
- }
7211
+ if (utils && typeof c === 'string') {
7212
+ c = utils.hexToRGBA(c);
7213
+ }
7185
7214
 
7186
- if (!control.textureContext) {
7187
- return null;
7188
- }
7215
+ if (_typeof(c) === 'object' && c !== null) {
7216
+ // hexToRGBA 返回 r/g/b 为 0~255,a 为 0~1
7217
+ // 但如果已经是 0~1 范围(由 rgbToDecimal 处理过),需要检测
7218
+ var needNormalize = c.r > 1 || c.g > 1 || c.b > 1 ? 255 : 1;
7219
+ return {
7220
+ offset: s.offset,
7221
+ r: (c.r !== undefined ? c.r : 0) / needNormalize,
7222
+ g: (c.g !== undefined ? c.g : 0) / needNormalize,
7223
+ b: (c.b !== undefined ? c.b : 0) / needNormalize,
7224
+ a: c.a !== undefined ? c.a : 1
7225
+ };
7226
+ }
7189
7227
 
7190
- var gradient = null;
7228
+ return {
7229
+ offset: s.offset,
7230
+ r: 0,
7231
+ g: 0,
7232
+ b: 0,
7233
+ a: 1
7234
+ };
7235
+ }).sort(function (a, b) {
7236
+ return a.offset - b.offset;
7237
+ });
7238
+ return this._sortedStops;
7239
+ }
7240
+ /**
7241
+ * 将渐变参数以 uniform 形式传递给着色器
7242
+ * 返回 { type, start, end, stopCount, stops } 供着色器使用
7243
+ */
7191
7244
 
7192
- if (this.type === 'linear') {
7193
- gradient = control.textureContext.createLinearGradient(this.x1, this.y1, this.x2, this.y2);
7194
- } else {
7195
- gradient = control.textureContext.createRadialGradient(this.x1, this.y1, this.r1, this.x2, this.y2, this.r2);
7245
+ }, {
7246
+ key: "toUniformParams",
7247
+ value: function toUniformParams() {
7248
+ var stops = this._getSortedStops();
7249
+
7250
+ var count = Math.min(stops.length, MAX_STOPS); // 展平为 Float32Array: [offset, r, g, b, a, ...]
7251
+
7252
+ var flatStops = new Float32Array(count * 5);
7253
+
7254
+ for (var i = 0; i < count; i++) {
7255
+ var s = stops[i];
7256
+ flatStops[i * 5 + 0] = s.offset;
7257
+ flatStops[i * 5 + 1] = s.r;
7258
+ flatStops[i * 5 + 2] = s.g;
7259
+ flatStops[i * 5 + 3] = s.b;
7260
+ flatStops[i * 5 + 4] = s.a;
7196
7261
  }
7197
7262
 
7198
- this.stops.forEach(function (s, i) {
7199
- var c = control.graph.utils.toColor(s.color);
7200
- gradient && gradient.addColorStop(s.offset, c);
7201
- });
7202
- var data = control.toFillTexture(gradient, bounds, points);
7203
- this.__cachedData = data;
7204
- this.__cacheKey = gradientKey;
7205
- return data;
7206
- } // 当渐变参数变化时使缓存失效
7263
+ return {
7264
+ gradientType: this.type === 'radial' ? 2 : 1,
7265
+ gradientStart: new Float32Array([this.x1, this.y1, this.type === 'radial' ? Math.max(0, this.r1) : 0, 0]),
7266
+ gradientEnd: new Float32Array([this.x2, this.y2, this.type === 'radial' ? Math.max(0, this.r2) : 0, 0]),
7267
+ stopCount: count,
7268
+ stops: flatStops
7269
+ };
7270
+ }
7271
+ /**
7272
+ * 使缓存失效
7273
+ */
7207
7274
 
7208
7275
  }, {
7209
7276
  key: "invalidateCache",
7210
7277
  value: function invalidateCache() {
7211
- this.__cachedData = null;
7212
- this.__cacheKey = null;
7213
- } // 根据绘制图形的坐标计算出对应点的颜色
7214
-
7215
- /*
7216
- toPointColors(points) {
7217
- const stops = this.getStops();
7218
- const colors = [];
7219
- for(let i=0; i<points.length; i+=2) {
7220
- const p = {
7221
- x: points[i],
7222
- y: points[i+1]
7223
- }
7224
- if(this.type === 'radial') {
7225
- const dx = p.x - this.x1;
7226
- const dy = p.y - this.y1;
7227
- const len = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
7228
- const rang = this.getStopRange(len, stops);
7229
- if(!rang.start && rang.end) {
7230
- colors.push(rang.end.color);
7231
- }
7232
- else if(!rang.end && rang.start) {
7233
- colors.push(rang.start.color);
7234
- }
7235
- else {
7236
- const rangLength = rang.end.length - rang.start.length;
7237
- const offlen = len - rang.start.length;
7238
- const per = offlen / rangLength;
7239
- const color = {
7240
- r: rang.start.color.r + (rang.end.color.r - rang.start.color.r) * per,
7241
- g: rang.start.color.g + (rang.end.color.g - rang.start.color.g) * per,
7242
- b: rang.start.color.b + (rang.end.color.b - rang.start.color.b) * per,
7243
- a: rang.start.color.a + (rang.end.color.a - rang.start.color.a) * per,
7244
- };
7245
- colors.push(color);
7246
- }
7247
- }
7248
- }
7249
- return colors;
7278
+ this._sortedStops = null;
7279
+ this._paramsHash = null;
7250
7280
  }
7251
- */
7252
- // 根据起点距离获取边界stop
7253
-
7254
- /*
7255
- getStopRange(len, stops) {
7256
- const res = {};
7257
- for(const s of stops) {
7258
- if(s.length <= len) {
7259
- res.start = s;
7260
- }
7261
- else {
7262
- res.end = s;
7263
- }
7264
- }
7265
- return res;
7266
- }
7267
- // 根据stop计算offset长度
7268
- getStops() {
7269
- const stops = this.stops.sort((p1, p2) => p1.offset - p2.offset); // 渐变色排序从小于大
7270
- for(const s of stops) {
7271
-
7272
- const color = typeof s.color === 'string'? this.control.graph.utils.hexToRGBA(s.color) : s.color;
7273
- console.log(s, color);
7274
- s.color = this.control.graph.utils.rgbToDecimal(color);
7275
- s.length = s.offset * this.length;
7276
- }
7277
- return stops;
7278
- }
7279
- */
7280
-
7281
7281
  /**
7282
- * 转换为渐变的字符串表达
7283
- *
7284
- * @method toString
7285
- * @for jmGradient
7286
- * @return {string} linear-gradient(x1 y1 x2 y2, color1 step, color2 step, ...); //radial-gradient(x1 y1 r1 x2 y2 r2, color1 step,color2 step, ...);
7287
- */
7282
+ * 转换为渐变的字符串表达
7283
+ */
7288
7284
 
7289
7285
  }, {
7290
7286
  key: "toString",
@@ -7295,8 +7291,7 @@ var WebglGradient = /*#__PURE__*/function () {
7295
7291
  str += this.x1 + ' ' + this.y1 + ' ' + this.x2 + ' ' + this.y2;
7296
7292
  } else {
7297
7293
  str += this.x1 + ' ' + this.y1 + ' ' + this.r1 + ' ' + this.x2 + ' ' + this.y2 + ' ' + this.r2;
7298
- } //颜色渐变
7299
-
7294
+ }
7300
7295
 
7301
7296
  this.stops.forEach(function (s) {
7302
7297
  str += ',' + s.color + ' ' + s.offset;
@@ -7321,10 +7316,16 @@ Object.defineProperty(exports, "__esModule", {
7321
7316
  });
7322
7317
  exports["default"] = void 0;
7323
7318
 
7324
- var _base = _interopRequireDefault(require("./base.js"));
7319
+ var _base = _interopRequireWildcard(require("./base.js"));
7320
+
7321
+ var _earcut = _interopRequireDefault(require("../earcut.js"));
7325
7322
 
7326
7323
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
7327
7324
 
7325
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
7326
+
7327
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
7328
+
7328
7329
  function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
7329
7330
 
7330
7331
  function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -7456,9 +7457,16 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
7456
7457
  value: function setParentBounds() {
7457
7458
  var parentBounds = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.parentAbsoluteBounds;
7458
7459
  //this.useProgram();
7459
- if (parentBounds) this.parentAbsoluteBounds = parentBounds; // 写入当前canvas大小
7460
+ if (parentBounds) this.parentAbsoluteBounds = parentBounds; // 缓存中心点值,只在变化时才更新 uniform
7461
+
7462
+ var cx = this.graph.width / 2;
7463
+ var cy = this.graph.height / 2;
7460
7464
 
7461
- this.context.uniform2f(this.program.uniforms.a_center_point.location, this.graph.width / 2, this.graph.height / 2);
7465
+ if (this.__lastCenterX !== cx || this.__lastCenterY !== cy) {
7466
+ this.context.uniform2f(this.program.uniforms.a_center_point.location, cx, cy);
7467
+ this.__lastCenterX = cx;
7468
+ this.__lastCenterY = cy;
7469
+ }
7462
7470
  }
7463
7471
  }, {
7464
7472
  key: "setFragColor",
@@ -7646,6 +7654,164 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
7646
7654
  key: "equalPoint",
7647
7655
  value: function equalPoint(p1, p2) {
7648
7656
  return p1.x === p2.x && p1.y === p2.y;
7657
+ } // 将带 moveTo 标记的点集拆分为外轮廓和多个洞
7658
+
7659
+ }, {
7660
+ key: "splitSubPaths",
7661
+ value: function splitSubPaths(points) {
7662
+ var subPaths = [];
7663
+ var current = [];
7664
+
7665
+ for (var i = 0; i < points.length; i++) {
7666
+ var p = points[i];
7667
+
7668
+ if (p.m && current.length > 0) {
7669
+ subPaths.push(current);
7670
+ current = [];
7671
+ }
7672
+
7673
+ current.push(p);
7674
+ }
7675
+
7676
+ if (current.length > 0) subPaths.push(current); // 面积最大的作为外轮廓,其余作为洞
7677
+
7678
+ var maxArea = -1;
7679
+ var outerIdx = 0;
7680
+
7681
+ for (var _i2 = 0; _i2 < subPaths.length; _i2++) {
7682
+ var area = Math.abs(this.polygonArea(subPaths[_i2]));
7683
+
7684
+ if (area > maxArea) {
7685
+ maxArea = area;
7686
+ outerIdx = _i2;
7687
+ }
7688
+ }
7689
+
7690
+ var outerPoints = subPaths[outerIdx];
7691
+ var holes = [];
7692
+
7693
+ for (var _i3 = 0; _i3 < subPaths.length; _i3++) {
7694
+ if (_i3 !== outerIdx) holes.push(subPaths[_i3]);
7695
+ }
7696
+
7697
+ return {
7698
+ outerPoints: outerPoints,
7699
+ holes: holes
7700
+ };
7701
+ } // 计算多边形面积(Shoelace 公式)
7702
+
7703
+ }, {
7704
+ key: "polygonArea",
7705
+ value: function polygonArea(points) {
7706
+ var area = 0;
7707
+ var n = points.length;
7708
+
7709
+ for (var i = 0; i < n; i++) {
7710
+ var j = (i + 1) % n;
7711
+ area += points[i].x * points[j].y;
7712
+ area -= points[j].x * points[i].y;
7713
+ }
7714
+
7715
+ return area / 2;
7716
+ } // 使用 earcut 带 holes 填充多边形
7717
+
7718
+ }, {
7719
+ key: "fillWithHoles",
7720
+ value: function fillWithHoles(outerPoints, holes) {
7721
+ var _this2 = this;
7722
+
7723
+ var isTexture = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
7724
+
7725
+ // 将所有点合并:外轮廓 + 各个洞,并记录洞的起始索引
7726
+ var allPoints = _toConsumableArray(outerPoints);
7727
+
7728
+ var holeIndices = [];
7729
+
7730
+ var _iterator4 = _createForOfIteratorHelper(holes),
7731
+ _step4;
7732
+
7733
+ try {
7734
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
7735
+ var hole = _step4.value;
7736
+ holeIndices.push(allPoints.length);
7737
+ allPoints.push.apply(allPoints, _toConsumableArray(hole));
7738
+ }
7739
+ } catch (err) {
7740
+ _iterator4.e(err);
7741
+ } finally {
7742
+ _iterator4.f();
7743
+ }
7744
+
7745
+ var dim = 2;
7746
+ var vertexData = [];
7747
+
7748
+ var _iterator5 = _createForOfIteratorHelper(allPoints),
7749
+ _step5;
7750
+
7751
+ try {
7752
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
7753
+ var _p = _step5.value;
7754
+ vertexData.push(_p.x, _p.y);
7755
+ } // 用 earcut 进行带洞三角化
7756
+
7757
+ } catch (err) {
7758
+ _iterator5.e(err);
7759
+ } finally {
7760
+ _iterator5.f();
7761
+ }
7762
+
7763
+ var indices = (0, _earcut["default"])(vertexData, holeIndices, dim);
7764
+ if (!indices || indices.length < 3) return; // 构建 GPU 顶点数据
7765
+
7766
+ var allVertices = [];
7767
+ var allTexCoords = [];
7768
+
7769
+ for (var i = 0; i < indices.length; i++) {
7770
+ var p = allPoints[indices[i]];
7771
+ allVertices.push(p.x, p.y);
7772
+ if (isTexture) allTexCoords.push(p.x, p.y);
7773
+ }
7774
+
7775
+ var gl = this.context;
7776
+ var vertexArr = new Float32Array(allVertices);
7777
+
7778
+ var posBuffer = this.__cachedBuffers.find(function (b) {
7779
+ return b.attr === _this2.program.attrs.a_position;
7780
+ });
7781
+
7782
+ if (!posBuffer) {
7783
+ posBuffer = this.createFloat32Buffer(vertexArr, gl.ARRAY_BUFFER, gl.DYNAMIC_DRAW);
7784
+ posBuffer.attr = this.program.attrs.a_position;
7785
+
7786
+ this.__cachedBuffers.push(posBuffer);
7787
+ } else {
7788
+ gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer.buffer);
7789
+ gl.bufferData(gl.ARRAY_BUFFER, vertexArr, gl.DYNAMIC_DRAW);
7790
+ }
7791
+
7792
+ this.writeVertexAttrib(posBuffer, this.program.attrs.a_position, 2, 0, 0);
7793
+
7794
+ if (isTexture && allTexCoords.length) {
7795
+ var texData = new Float32Array(allTexCoords);
7796
+
7797
+ var texBuffer = this.__cachedBuffers.find(function (b) {
7798
+ return b.attr === _this2.program.attrs.a_text_coord;
7799
+ });
7800
+
7801
+ if (!texBuffer) {
7802
+ texBuffer = this.createFloat32Buffer(texData, gl.ARRAY_BUFFER, gl.DYNAMIC_DRAW);
7803
+ texBuffer.attr = this.program.attrs.a_text_coord;
7804
+
7805
+ this.__cachedBuffers.push(texBuffer);
7806
+ } else {
7807
+ gl.bindBuffer(gl.ARRAY_BUFFER, texBuffer.buffer);
7808
+ gl.bufferData(gl.ARRAY_BUFFER, texData, gl.DYNAMIC_DRAW);
7809
+ }
7810
+
7811
+ this.writeVertexAttrib(texBuffer, this.program.attrs.a_text_coord, 2, 0, 0);
7812
+ }
7813
+
7814
+ gl.drawArrays(gl.TRIANGLES, 0, allVertices.length / 2);
7649
7815
  } // 把path坐标集合转为线段集
7650
7816
 
7651
7817
  }, {
@@ -7909,20 +8075,20 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
7909
8075
  var polygons = this.getPolygon(points);
7910
8076
 
7911
8077
  if (polygons.length) {
7912
- var _iterator4 = _createForOfIteratorHelper(polygons),
7913
- _step4;
8078
+ var _iterator6 = _createForOfIteratorHelper(polygons),
8079
+ _step6;
7914
8080
 
7915
8081
  try {
7916
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
7917
- var polygon = _step4.value;
8082
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
8083
+ var polygon = _step6.value;
7918
8084
  // 需要分割三角形,不然填充会有问题
7919
8085
  var triangles = this.earCutPointsToTriangles(polygon);
7920
8086
  res.push.apply(res, _toConsumableArray(triangles));
7921
8087
  }
7922
8088
  } catch (err) {
7923
- _iterator4.e(err);
8089
+ _iterator6.e(err);
7924
8090
  } finally {
7925
- _iterator4.f();
8091
+ _iterator6.f();
7926
8092
  }
7927
8093
  }
7928
8094
 
@@ -7957,9 +8123,56 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
7957
8123
 
7958
8124
  if (points && points.length) {
7959
8125
  var regular = lineWidth <= 1.2;
7960
- points = regular ? points : this.pathToPoints(points);
7961
- var buffer = this.writePoints(points);
7962
- this.context.drawArrays(regular ? this.context.LINE_LOOP : this.context.POINTS, 0, points.length); // buffer 由 endDraw 统一清理
8126
+ var hasMoveTo = points.some && points.some(function (p) {
8127
+ return p.m;
8128
+ });
8129
+ var isRing = !hasMoveTo && this.needCut; // 空心形状(jmHArc close=true 时无 m 标记)
8130
+
8131
+ if (regular && (hasMoveTo || isRing)) {
8132
+ // 有 moveTo 标记或空心形状时,分段绘制每个子路径的 LINE_LOOP
8133
+ // 避免 LINE_LOOP 把不同子路径的点连起来产生拉扯线
8134
+ if (hasMoveTo) {
8135
+ var subPath = [];
8136
+
8137
+ for (var i = 0; i < points.length; i++) {
8138
+ if (points[i].m && subPath.length > 0) {
8139
+ var buffer = this.writePoints(subPath);
8140
+ this.context.drawArrays(this.context.LINE_LOOP, 0, subPath.length);
8141
+ subPath = [];
8142
+ }
8143
+
8144
+ subPath.push(points[i]);
8145
+ }
8146
+
8147
+ if (subPath.length > 1) {
8148
+ var _buffer = this.writePoints(subPath);
8149
+
8150
+ this.context.drawArrays(this.context.LINE_LOOP, 0, subPath.length);
8151
+ }
8152
+ } else if (isRing) {
8153
+ // 空心形状:前半段为内弧,后半段为外弧(反向),各自 LINE_LOOP
8154
+ var mid = Math.floor(points.length / 2);
8155
+ var inner = points.slice(0, mid);
8156
+ var outer = points.slice(mid);
8157
+
8158
+ if (inner.length > 1) {
8159
+ this.writePoints(inner);
8160
+ this.context.drawArrays(this.context.LINE_LOOP, 0, inner.length);
8161
+ }
8162
+
8163
+ if (outer.length > 1) {
8164
+ this.writePoints(outer);
8165
+ this.context.drawArrays(this.context.LINE_LOOP, 0, outer.length);
8166
+ }
8167
+ }
8168
+ } else {
8169
+ points = regular ? points : this.pathToPoints(points);
8170
+
8171
+ var _buffer2 = this.writePoints(points);
8172
+
8173
+ this.context.drawArrays(regular ? this.context.LINE_LOOP : this.context.POINTS, 0, points.length);
8174
+ } // buffer 由 endDraw 统一清理
8175
+
7963
8176
  }
7964
8177
 
7965
8178
  colorBuffer && this.disableVertexAttribArray(colorBuffer && colorBuffer.attr);
@@ -7992,10 +8205,9 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
7992
8205
  value: function fillColor(color, points, bounds) {
7993
8206
  var type = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
7994
8207
 
7995
- // 如果是渐变色,则需要计算偏移量的颜色
8208
+ // 如果是渐变色,使用 GLSL 着色器直接计算
7996
8209
  if (this.isGradient(color)) {
7997
- var imgData = color.toImageData(this, bounds, points);
7998
- return this.fillImage(imgData.data, imgData.points, bounds);
8210
+ return this.fillGradient(color, points, bounds);
7999
8211
  } // 标注为fill
8000
8212
 
8001
8213
 
@@ -8003,6 +8215,93 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
8003
8215
  var colorBuffer = this.setFragColor(color);
8004
8216
  this.fillPolygons(points);
8005
8217
  colorBuffer && this.disableVertexAttribArray(colorBuffer && colorBuffer.attr);
8218
+ }
8219
+ /**
8220
+ * 使用 GLSL 着色器渲染渐变填充
8221
+ * 无需 textureCanvas,直接通过 uniform 传递渐变参数给 GPU
8222
+ */
8223
+
8224
+ }, {
8225
+ key: "fillGradient",
8226
+ value: function fillGradient(gradient, points, bounds) {
8227
+ var params = gradient.toUniformParams();
8228
+ if (!params) return; // 标注为 GLSL 渐变 (type=5)
8229
+
8230
+ this.context.uniform1i(this.program.uniforms.a_type.location, 5); // 设置 globalAlpha(通过 v_single_color.a 传递给着色器)
8231
+
8232
+ this.context.uniform4f(this.program.uniforms.v_single_color.location, 1.0, 1.0, 1.0, this.style.globalAlpha); // 设置渐变类型
8233
+
8234
+ if (this.program.uniforms.u_gradient_type) {
8235
+ this.context.uniform1i(this.program.uniforms.u_gradient_type.location, params.gradientType);
8236
+ } // 设置渐变起点/终点
8237
+
8238
+
8239
+ if (this.program.uniforms.u_gradient_start) {
8240
+ this.context.uniform4fv(this.program.uniforms.u_gradient_start.location, params.gradientStart);
8241
+ }
8242
+
8243
+ if (this.program.uniforms.u_gradient_end) {
8244
+ this.context.uniform4fv(this.program.uniforms.u_gradient_end.location, params.gradientEnd);
8245
+ } // 设置颜色断点数量
8246
+
8247
+
8248
+ if (this.program.uniforms.u_gradient_stop_count) {
8249
+ this.context.uniform1i(this.program.uniforms.u_gradient_stop_count.location, params.stopCount);
8250
+ } // 设置每个 stop 的 offset
8251
+ // 关键:必须填充完整的 MAX_STOPS 长度数组,否则未初始化元素默认为 0
8252
+ // 会导致着色器循环中 t >= 0 始终为 true,返回黑色
8253
+
8254
+
8255
+ if (this.program.uniforms.u_gradient_offsets) {
8256
+ var offsets = new Float32Array(_base.MAX_STOPS);
8257
+
8258
+ for (var i = 0; i < params.stopCount; i++) {
8259
+ offsets[i] = params.stops[i * 5];
8260
+ } // 用 2.0 填充剩余项,使 t(0~1) >= 2.0 为 false,不会被匹配
8261
+
8262
+
8263
+ for (var _i4 = params.stopCount; _i4 < _base.MAX_STOPS; _i4++) {
8264
+ offsets[_i4] = 2.0;
8265
+ }
8266
+
8267
+ this.context.uniform1fv(this.program.uniforms.u_gradient_offsets.location, offsets);
8268
+ } // 设置每个 stop 的颜色 (rgba)
8269
+
8270
+
8271
+ if (this.program.uniforms.u_gradient_colors) {
8272
+ var colors = new Float32Array(_base.MAX_STOPS * 4);
8273
+
8274
+ for (var _i5 = 0; _i5 < params.stopCount; _i5++) {
8275
+ colors[_i5 * 4 + 0] = params.stops[_i5 * 5 + 1]; // r
8276
+
8277
+ colors[_i5 * 4 + 1] = params.stops[_i5 * 5 + 2]; // g
8278
+
8279
+ colors[_i5 * 4 + 2] = params.stops[_i5 * 5 + 3]; // b
8280
+
8281
+ colors[_i5 * 4 + 3] = params.stops[_i5 * 5 + 4]; // a
8282
+ } // 用最后一个 stop 的颜色填充剩余项,确保不会返回黑色
8283
+
8284
+
8285
+ if (params.stopCount > 0) {
8286
+ var lastR = params.stops[(params.stopCount - 1) * 5 + 1];
8287
+ var lastG = params.stops[(params.stopCount - 1) * 5 + 2];
8288
+ var lastB = params.stops[(params.stopCount - 1) * 5 + 3];
8289
+ var lastA = params.stops[(params.stopCount - 1) * 5 + 4];
8290
+
8291
+ for (var _i6 = params.stopCount; _i6 < _base.MAX_STOPS; _i6++) {
8292
+ colors[_i6 * 4 + 0] = lastR;
8293
+ colors[_i6 * 4 + 1] = lastG;
8294
+ colors[_i6 * 4 + 2] = lastB;
8295
+ colors[_i6 * 4 + 3] = lastA;
8296
+ }
8297
+ }
8298
+
8299
+ this.context.uniform4fv(this.program.uniforms.u_gradient_colors.location, colors);
8300
+ } // 填充多边形(需要纹理坐标来计算渐变位置)
8301
+
8302
+
8303
+ this.fillPolygons(points, true);
8304
+ this.disableVertexAttribArray(this.program.attrs.a_text_coord);
8006
8305
  } // 区域填充图片
8007
8306
  // points绘制的图形顶点
8008
8307
  // 图片整体绘制区域
@@ -8061,7 +8360,7 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
8061
8360
  }, {
8062
8361
  key: "fillPolygons",
8063
8362
  value: function fillPolygons(points) {
8064
- var _this2 = this;
8363
+ var _this3 = this;
8065
8364
 
8066
8365
  var isTexture = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
8067
8366
 
@@ -8075,7 +8374,40 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
8075
8374
 
8076
8375
 
8077
8376
  if (this.isRegular) {
8078
- var _buffer = this.writePoints(points);
8377
+ // 检查是否有 moveTo 标记,如果有说明路径包含多个子路径(如空心圆弧 jmHArc)
8378
+ var hasMoveTo = points.some && points.some(function (p) {
8379
+ return p.m;
8380
+ });
8381
+
8382
+ if (hasMoveTo) {
8383
+ // 有 m 标记:按 m 标记拆分子路径
8384
+ var _this$splitSubPaths = this.splitSubPaths(points),
8385
+ outerPoints = _this$splitSubPaths.outerPoints,
8386
+ holes = _this$splitSubPaths.holes;
8387
+
8388
+ this.fillWithHoles(outerPoints, holes, isTexture);
8389
+ return;
8390
+ } // 无 m 标记但 needCut=true 表示空心形状(如 jmHArc close=true)
8391
+ // 前半段为内弧,后半段为外弧(反向),按中点拆分
8392
+
8393
+
8394
+ if (this.needCut && points.length >= 6) {
8395
+ var mid = Math.floor(points.length / 2);
8396
+ var inner = points.slice(0, mid);
8397
+ var outer = points.slice(mid);
8398
+ var innerArea = Math.abs(this.polygonArea(inner));
8399
+ var outerArea = Math.abs(this.polygonArea(outer));
8400
+
8401
+ if (outerArea >= innerArea) {
8402
+ this.fillWithHoles(outer, [inner], isTexture);
8403
+ } else {
8404
+ this.fillWithHoles(inner, [outer], isTexture);
8405
+ }
8406
+
8407
+ return;
8408
+ }
8409
+
8410
+ var _buffer3 = this.writePoints(points);
8079
8411
 
8080
8412
  var _coordBuffer = isTexture ? this.writePoints(points, this.program.attrs.a_text_coord) : null;
8081
8413
 
@@ -8090,40 +8422,40 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
8090
8422
  var allVertices = [];
8091
8423
  var allTexCoords = [];
8092
8424
 
8093
- var _iterator5 = _createForOfIteratorHelper(triangles),
8094
- _step5;
8425
+ var _iterator7 = _createForOfIteratorHelper(triangles),
8426
+ _step7;
8095
8427
 
8096
8428
  try {
8097
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
8098
- var triangle = _step5.value;
8429
+ for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
8430
+ var triangle = _step7.value;
8099
8431
 
8100
- var _iterator6 = _createForOfIteratorHelper(triangle),
8101
- _step6;
8432
+ var _iterator8 = _createForOfIteratorHelper(triangle),
8433
+ _step8;
8102
8434
 
8103
8435
  try {
8104
- for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
8105
- var p = _step6.value;
8436
+ for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
8437
+ var p = _step8.value;
8106
8438
  allVertices.push(p.x, p.y);
8107
8439
  if (isTexture) allTexCoords.push(p.x, p.y);
8108
8440
  }
8109
8441
  } catch (err) {
8110
- _iterator6.e(err);
8442
+ _iterator8.e(err);
8111
8443
  } finally {
8112
- _iterator6.f();
8444
+ _iterator8.f();
8113
8445
  }
8114
8446
  } // 一次性上传所有数据并绘制
8115
8447
 
8116
8448
  } catch (err) {
8117
- _iterator5.e(err);
8449
+ _iterator7.e(err);
8118
8450
  } finally {
8119
- _iterator5.f();
8451
+ _iterator7.f();
8120
8452
  }
8121
8453
 
8122
8454
  var vertexData = new Float32Array(allVertices);
8123
8455
  var gl = this.context; // 复用或创建 position buffer
8124
8456
 
8125
8457
  var posBuffer = this.__cachedBuffers.find(function (b) {
8126
- return b.attr === _this2.program.attrs.a_position;
8458
+ return b.attr === _this3.program.attrs.a_position;
8127
8459
  });
8128
8460
 
8129
8461
  if (!posBuffer) {
@@ -8142,7 +8474,7 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
8142
8474
  var texData = new Float32Array(allTexCoords);
8143
8475
 
8144
8476
  var texBuffer = this.__cachedBuffers.find(function (b) {
8145
- return b.attr === _this2.program.attrs.a_text_coord;
8477
+ return b.attr === _this3.program.attrs.a_text_coord;
8146
8478
  });
8147
8479
 
8148
8480
  if (!texBuffer) {
@@ -8180,44 +8512,78 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
8180
8512
  }, {
8181
8513
  key: "drawText",
8182
8514
  value: function drawText(text, x, y, bounds) {
8183
- var canvas = this.textureCanvas;
8515
+ // 文本渲染仍需要 2D canvas 绘制字形,然后作为纹理上传
8516
+ // 使用临时 canvas,不依赖共享的 textureCanvas
8517
+ if (!bounds.width || !bounds.height) return null;
8518
+ if (typeof document === 'undefined') return null;
8519
+ var canvas = this.__textCanvas;
8184
8520
 
8185
8521
  if (!canvas) {
8186
- return null;
8522
+ canvas = document.createElement('canvas');
8523
+ this.__textCanvas = canvas;
8187
8524
  }
8188
8525
 
8189
8526
  canvas.width = bounds.width;
8190
8527
  canvas.height = bounds.height;
8528
+ var ctx = canvas.getContext('2d', {
8529
+ willReadFrequently: true
8530
+ });
8531
+ ctx.clearRect(0, 0, canvas.width, canvas.height); // 修改字体
8191
8532
 
8192
- if (!canvas.width || !canvas.height) {
8193
- return null;
8533
+ ctx.font = this.style.font || this.style.fontSize + 'px ' + this.style.fontFamily;
8534
+ x -= bounds.left;
8535
+ y -= bounds.top; // 设置文本样式
8536
+
8537
+ if (this.style.fillStyle) {
8538
+ ctx.fillStyle = this.graph.utils.toColor(this.style.fillStyle);
8194
8539
  }
8195
8540
 
8196
- this.textureContext.clearRect(0, 0, canvas.width, canvas.height); // 修改字体
8541
+ if (this.style.strokeStyle) {
8542
+ ctx.strokeStyle = this.graph.utils.toColor(this.style.strokeStyle);
8543
+ }
8197
8544
 
8198
- this.textureContext.font = this.style.font || this.style.fontSize + 'px ' + this.style.fontFamily;
8199
- x -= bounds.left;
8200
- y -= bounds.top;
8201
- this.setTextureStyle(this.style);
8545
+ if (this.style.shadowColor) {
8546
+ ctx.shadowColor = this.graph.utils.toColor(this.style.shadowColor);
8547
+ }
8202
8548
 
8203
- if (this.style.fillStyle && this.textureContext.fillText) {
8549
+ if (this.style.shadowBlur) {
8550
+ ctx.shadowBlur = this.style.shadowBlur;
8551
+ }
8552
+
8553
+ if (this.style.shadowOffsetX !== undefined) {
8554
+ ctx.shadowOffsetX = this.style.shadowOffsetX;
8555
+ }
8556
+
8557
+ if (this.style.shadowOffsetY !== undefined) {
8558
+ ctx.shadowOffsetY = this.style.shadowOffsetY;
8559
+ }
8560
+
8561
+ if (this.style.textAlign) {
8562
+ ctx.textAlign = this.style.textAlign;
8563
+ }
8564
+
8565
+ if (this.style.textBaseline) {
8566
+ ctx.textBaseline = this.style.textBaseline;
8567
+ }
8568
+
8569
+ if (this.style.fillStyle && ctx.fillText) {
8204
8570
  if (this.style.maxWidth) {
8205
- this.textureContext.fillText(text, x, y, this.style.maxWidth);
8571
+ ctx.fillText(text, x, y, this.style.maxWidth);
8206
8572
  } else {
8207
- this.textureContext.fillText(text, x, y);
8573
+ ctx.fillText(text, x, y);
8208
8574
  }
8209
8575
  }
8210
8576
 
8211
- if (this.textureContext.strokeText) {
8577
+ if (this.style.strokeStyle && ctx.strokeText) {
8212
8578
  if (this.style.maxWidth) {
8213
- this.textureContext.strokeText(text, x, y, this.style.maxWidth);
8579
+ ctx.strokeText(text, x, y, this.style.maxWidth);
8214
8580
  } else {
8215
- this.textureContext.strokeText(text, x, y);
8581
+ ctx.strokeText(text, x, y);
8216
8582
  }
8217
8583
  } // 用纹理图片代替文字
8218
8584
 
8219
8585
 
8220
- var data = this.textureContext.getImageData(0, 0, canvas.width, canvas.height);
8586
+ var data = ctx.getImageData(0, 0, canvas.width, canvas.height);
8221
8587
  this.fillImage(data, this.points, bounds);
8222
8588
  }
8223
8589
  }]);
@@ -8228,7 +8594,7 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
8228
8594
  var _default = WebglPath;
8229
8595
  exports["default"] = _default;
8230
8596
 
8231
- },{"./base.js":14}],23:[function(require,module,exports){
8597
+ },{"../earcut.js":13,"./base.js":14}],23:[function(require,module,exports){
8232
8598
  "use strict";
8233
8599
 
8234
8600
  function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
@@ -8403,7 +8769,6 @@ var jmArc = /*#__PURE__*/function (_jmPath) {
8403
8769
  var end = this.endAngle;
8404
8770
  if (mw == 0 && mh == 0 || start == end) return;
8405
8771
  var anticlockwise = this.anticlockwise;
8406
- this.points = [];
8407
8772
  var step = 1 / Math.max(mw, mh); //如果是逆时针绘制,则角度为负数,并且结束角为2Math.PI-end
8408
8773
 
8409
8774
  if (anticlockwise) {
@@ -8412,17 +8777,36 @@ var jmArc = /*#__PURE__*/function (_jmPath) {
8412
8777
  end = p2 - end;
8413
8778
  }
8414
8779
 
8415
- if (start > end) step = -step;
8416
- if (this.isFan) this.points.push(location.center); // 如果是扇形,则从中心开始画
8417
- //椭圆方程x=a*cos(r) ,y=b*sin(r)
8780
+ if (start > end) step = -step; // 预计算需要的点数量
8781
+
8782
+ var pointCount = Math.ceil(Math.abs(end - start) / Math.abs(step)) + 1;
8783
+ if (this.isFan) pointCount++; // 复用已有数组,避免每帧分配;大小变化时才重建
8784
+
8785
+ if (!this.points || this.points.length !== pointCount) {
8786
+ this.points = new Array(pointCount);
8787
+
8788
+ for (var i = 0; i < pointCount; i++) {
8789
+ this.points[i] = {
8790
+ x: 0,
8791
+ y: 0
8792
+ };
8793
+ }
8794
+ }
8795
+
8796
+ var idx = 0;
8797
+
8798
+ if (this.isFan) {
8799
+ this.points[idx].x = location.center.x;
8800
+ this.points[idx].y = location.center.y;
8801
+ idx++;
8802
+ } //椭圆方程x=a*cos(r) ,y=b*sin(r)
8803
+
8418
8804
 
8419
8805
  for (var r = start;; r += step) {
8420
8806
  if (step > 0 && r > end) r = end;else if (step < 0 && r < end) r = end;
8421
- var p = {
8422
- x: Math.cos(r) * mw + cx,
8423
- y: Math.sin(r) * mh + cy
8424
- };
8425
- this.points.push(p);
8807
+ this.points[idx].x = Math.cos(r) * mw + cx;
8808
+ this.points[idx].y = Math.sin(r) * mh + cy;
8809
+ idx++;
8426
8810
  if (r == end) break;
8427
8811
  }
8428
8812
 
@@ -9353,7 +9737,7 @@ var jmHArc = /*#__PURE__*/function (_jmArc) {
9353
9737
  maxps.reverse(); //大圆逆序
9354
9738
 
9355
9739
  if (!this.style || !this.style.close) {
9356
- maxps[0].m = true; //开始画大圆时表示为移动
9740
+ maxps[0].m = true; //非闭合时标记 moveTo,分隔内外两个子路径
9357
9741
  }
9358
9742
 
9359
9743
  this.points = minps.concat(maxps);