jmgraph 3.2.22 → 3.2.25

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);
@@ -2727,7 +2742,8 @@ var jmGradient = /*#__PURE__*/function () {
2727
2742
 
2728
2743
  if (this.type === 'linear') {
2729
2744
  if (control.mode === 'webgl' && control.webglControl) {
2730
- gradient = control.webglControl.createLinearGradient(x1, y1, x2, y2, bounds);
2745
+ // WebGL 着色器中 v_text_coord 是绝对坐标,需要传递绝对坐标
2746
+ gradient = control.webglControl.createLinearGradient(sx1, sy1, sx2, sy2, bounds);
2731
2747
  gradient.key = this.toString();
2732
2748
  } else {
2733
2749
  context.createLinearGradient && (gradient = context.createLinearGradient(sx1, sy1, sx2, sy2));
@@ -2747,7 +2763,8 @@ var jmGradient = /*#__PURE__*/function () {
2747
2763
  }
2748
2764
 
2749
2765
  if (control.mode === 'webgl' && control.webglControl) {
2750
- 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);
2751
2768
  gradient.key = this.toString();
2752
2769
  } //offsetLine = Math.abs(r2 - r1);//二圆半径差
2753
2770
  else if (context.createRadialGradient) {
@@ -3068,9 +3085,8 @@ var jmGraph = /*#__PURE__*/function (_jmControl) {
3068
3085
  });
3069
3086
  } else {
3070
3087
  _this.context = canvas.getContext(_this.mode);
3071
- }
3088
+ } // webgl模式
3072
3089
 
3073
- _this.textureCanvas = option.textureCanvas || null; // webgl模式
3074
3090
 
3075
3091
  if (_this.mode === 'webgl') {
3076
3092
  _this.context.enable(_this.context.BLEND); // 开启混合功能:(注意,它不可和gl.DEPTH_TEST一起使用)
@@ -6193,11 +6209,17 @@ earcut.flatten = function (data) {
6193
6209
  Object.defineProperty(exports, "__esModule", {
6194
6210
  value: true
6195
6211
  });
6196
- 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;
6197
6219
 
6198
6220
  var _earcut = _interopRequireDefault(require("../earcut.js"));
6199
6221
 
6200
- var _gradient = _interopRequireDefault(require("./gradient.js"));
6222
+ var _gradient = _interopRequireWildcard(require("./gradient.js"));
6201
6223
 
6202
6224
  var _program = require("./core/program.js");
6203
6225
 
@@ -6205,9 +6227,13 @@ var _buffer = require("./core/buffer.js");
6205
6227
 
6206
6228
  var _texture = require("./core/texture.js");
6207
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
+
6208
6234
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
6209
6235
 
6210
- 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); }
6211
6237
 
6212
6238
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
6213
6239
 
@@ -6246,9 +6272,11 @@ var convertPointSource = "\n vec4 translatePosition(vec4 point, float x, floa
6246
6272
 
6247
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顶点着色器源码
6248
6274
 
6249
- 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 片段着色器源码
6250
6276
 
6251
- 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;
6252
6280
 
6253
6281
  var WeblBase = /*#__PURE__*/function () {
6254
6282
  function WeblBase(graph, option) {
@@ -6312,13 +6340,11 @@ var WeblBase = /*#__PURE__*/function () {
6312
6340
  var cos = Math.cos(angle);
6313
6341
  var sin = Math.sin(angle);
6314
6342
 
6315
- var _this$transformMatrix = _slicedToArray(this.transformMatrix, 6),
6343
+ var _this$transformMatrix = _slicedToArray(this.transformMatrix, 4),
6316
6344
  a = _this$transformMatrix[0],
6317
6345
  b = _this$transformMatrix[1],
6318
6346
  c = _this$transformMatrix[2],
6319
- d = _this$transformMatrix[3],
6320
- tx = _this$transformMatrix[4],
6321
- ty = _this$transformMatrix[5]; // 更新变换矩阵
6347
+ d = _this$transformMatrix[3]; // 更新变换矩阵
6322
6348
 
6323
6349
 
6324
6350
  this.transformMatrix[0] = a * cos - b * sin;
@@ -6362,28 +6388,24 @@ var WeblBase = /*#__PURE__*/function () {
6362
6388
  x: a * point.x + c * point.y + tx,
6363
6389
  y: b * point.x + d * point.y + ty
6364
6390
  };
6365
- } // 纹理绘制canvas
6391
+ } // 文本测量用的离屏 canvas context(1x1 单例缓存,不依赖 textureCanvas)
6366
6392
 
6367
6393
  }, {
6368
- key: "textureCanvas",
6394
+ key: "_measureCtx",
6369
6395
  get: function get() {
6370
- var canvas = this.graph.textureCanvas;
6371
-
6372
- if (!canvas) {
6373
- if (typeof document === 'undefined') return null;
6374
- 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
+ }
6375
6406
  }
6376
6407
 
6377
- return canvas;
6378
- } // 纹理绘制canvas ctx
6379
-
6380
- }, {
6381
- key: "textureContext",
6382
- get: function get() {
6383
- var ctx = this.textureCanvas.ctx || (this.textureCanvas.ctx = this.textureCanvas.getContext('2d', {
6384
- willReadFrequently: true
6385
- }));
6386
- return ctx;
6408
+ return this.__measureCtx;
6387
6409
  } // i当前程序
6388
6410
 
6389
6411
  }, {
@@ -6432,25 +6454,69 @@ var WeblBase = /*#__PURE__*/function () {
6432
6454
  key: "convertColor",
6433
6455
  value: function convertColor(color) {
6434
6456
  if (this.isGradient(color)) return color;
6435
- if (typeof color === 'string') color = this.graph.utils.hexToRGBA(color);
6436
- return this.graph.utils.rgbToDecimal(color);
6437
- }
6438
- }, {
6439
- key: "setTextureStyle",
6440
- value: function setTextureStyle(style) {
6441
- var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
6442
6457
 
6443
- if (typeof style === 'string') {
6444
- if (['fillStyle', 'strokeStyle', 'shadowColor'].indexOf(style) > -1) {
6445
- 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);
6446
6465
  }
6466
+ }
6447
6467
 
6448
- this.textureContext[style] = value;
6449
- } else {
6450
- for (var name in style) {
6451
- if (name === 'constructor') continue;
6452
- 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
+ };
6453
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
+ };
6454
6520
  }
6455
6521
  } // 创建程序
6456
6522
 
@@ -6669,84 +6735,29 @@ var WeblBase = /*#__PURE__*/function () {
6669
6735
  return obj && obj instanceof _gradient["default"];
6670
6736
  }
6671
6737
  /**
6672
- * 测试获取文本所占大小
6673
- *
6674
- * @method testSize
6675
- * @return {object} 含文本大小的对象
6676
- */
6738
+ * 测试获取文本所占大小
6739
+ *
6740
+ * @method testSize
6741
+ * @return {object} 含文本大小的对象
6742
+ */
6677
6743
 
6678
6744
  }, {
6679
6745
  key: "testSize",
6680
6746
  value: function testSize(text) {
6681
6747
  var style = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.style;
6682
- this.textureContext.save && this.textureContext.save(); // 修改字体,用来计算
6683
-
6684
- if (style.font || style.fontSize) this.textureContext.font = style.font || style.fontSize + 'px ' + style.fontFamily; //计算宽度
6685
-
6686
- 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) : {
6687
6756
  width: 15
6688
6757
  };
6689
- this.textureContext.restore && this.textureContext.restore();
6690
- size.height = this.style.fontSize ? this.style.fontSize : 15;
6758
+ ctx.restore && ctx.restore();
6759
+ size.height = style.fontSize ? parseInt(style.fontSize) : 15;
6691
6760
  return size;
6692
- } // 使用纹理canvas生成图,
6693
- // 填充可以是颜色或渐变对象
6694
- // 如果指定了points,则表明要绘制不规则的图形
6695
-
6696
- }, {
6697
- key: "toFillTexture",
6698
- value: function toFillTexture(fillStyle, bounds) {
6699
- var points = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
6700
- var canvas = this.textureCanvas;
6701
-
6702
- if (!canvas) {
6703
- return fillStyle;
6704
- }
6705
-
6706
- canvas.width = bounds.width;
6707
- canvas.height = bounds.height;
6708
-
6709
- if (!canvas.width || !canvas.height) {
6710
- return fillStyle;
6711
- }
6712
-
6713
- this.textureContext.clearRect(0, 0, canvas.width, canvas.height);
6714
- this.textureContext.fillStyle = fillStyle; // 规则图形用 fillRect,比 beginPath/lineTo/fill 快
6715
-
6716
- if (!points || !points.length) {
6717
- this.textureContext.fillRect(0, 0, bounds.width, bounds.height);
6718
- } else {
6719
- this.textureContext.beginPath();
6720
-
6721
- var _iterator = _createForOfIteratorHelper(points),
6722
- _step;
6723
-
6724
- try {
6725
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
6726
- var p = _step.value;
6727
-
6728
- //移至当前坐标
6729
- if (p.m) {
6730
- this.textureContext.moveTo(p.x - bounds.left, p.y - bounds.top);
6731
- } else {
6732
- this.textureContext.lineTo(p.x - bounds.left, p.y - bounds.top);
6733
- }
6734
- }
6735
- } catch (err) {
6736
- _iterator.e(err);
6737
- } finally {
6738
- _iterator.f();
6739
- }
6740
-
6741
- this.textureContext.closePath();
6742
- this.textureContext.fill();
6743
- }
6744
-
6745
- var data = this.textureContext.getImageData(0, 0, canvas.width, canvas.height);
6746
- return {
6747
- data: data,
6748
- points: points
6749
- };
6750
6761
  }
6751
6762
  }]);
6752
6763
 
@@ -7127,7 +7138,9 @@ function deleteTexture(gl, texture) {
7127
7138
  Object.defineProperty(exports, "__esModule", {
7128
7139
  value: true
7129
7140
  });
7130
- 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); }
7131
7144
 
7132
7145
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
7133
7146
 
@@ -7135,10 +7148,15 @@ function _defineProperties(target, props) { for (var i = 0; i < props.length; i+
7135
7148
 
7136
7149
  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
7137
7150
 
7138
- var WebglGradientTextureCache = {}; // 渐变
7151
+ var MAX_STOPS = 16;
7152
+ /**
7153
+ * WebGL 渐变对象
7154
+ * 支持 GLSL 着色器直接计算渐变色,无需 textureCanvas
7155
+ */
7156
+
7157
+ exports.MAX_STOPS = MAX_STOPS;
7139
7158
 
7140
7159
  var WebglGradient = /*#__PURE__*/function () {
7141
- // type:[linear= 线性渐变,radial=放射性渐变]
7142
7160
  function WebglGradient() {
7143
7161
  var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'linear';
7144
7162
  var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
@@ -7160,149 +7178,109 @@ var WebglGradient = /*#__PURE__*/function () {
7160
7178
  };
7161
7179
  this.control = params.control;
7162
7180
  this.stops = [];
7163
- this.init();
7181
+ this._sortedStops = null;
7182
+ this._paramsHash = null;
7164
7183
  }
7184
+ /**
7185
+ * 添加颜色断点
7186
+ */
7165
7187
 
7166
- _createClass(WebglGradient, [{
7167
- key: "init",
7168
- value: function init() {
7169
- var dx = this.x2 - this.x1;
7170
- var dy = this.y2 - this.y1;
7171
-
7172
- if (this.type === 'radial') {
7173
- this.length = this.r2 - this.r1;
7174
- } else if (dx === 0 && dy === 0) {
7175
- this.length = 0;
7176
- } else {
7177
- // 渐变中心的距离
7178
- this.length = Math.sqrt(Math.pow(dx, 2), Math.pow(dy, 2));
7179
- this.sin = dy / this.length;
7180
- this.cos = dx / this.length;
7181
- }
7182
- } // 渐变颜色
7183
7188
 
7184
- }, {
7189
+ _createClass(WebglGradient, [{
7185
7190
  key: "addColorStop",
7186
7191
  value: function addColorStop(offset, color) {
7187
7192
  this.stops.push({
7188
- offset: offset,
7193
+ offset: Math.max(0, Math.min(1, offset)),
7189
7194
  color: color
7190
7195
  });
7191
- } // 转为渐变为纹理
7196
+ this._sortedStops = null;
7197
+ this._paramsHash = null;
7198
+ }
7199
+ /**
7200
+ * 获取排序后的 stops(带解析后的颜色)
7201
+ */
7192
7202
 
7193
7203
  }, {
7194
- key: "toImageData",
7195
- value: function toImageData(control, bounds) {
7196
- var points = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
7197
- // 缓存基于渐变参数(不含 bounds,因为同一个渐变只是位置不同时纹理相同)
7198
- 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;
7199
7210
 
7200
- 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)) {
7201
- return this.__cachedData;
7202
- }
7211
+ if (utils && typeof c === 'string') {
7212
+ c = utils.hexToRGBA(c);
7213
+ }
7203
7214
 
7204
- if (!control.textureContext) {
7205
- return null;
7206
- }
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
+ }
7207
7227
 
7208
- 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
+ */
7209
7244
 
7210
- if (this.type === 'linear') {
7211
- gradient = control.textureContext.createLinearGradient(this.x1, this.y1, this.x2, this.y2);
7212
- } else {
7213
- 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;
7214
7261
  }
7215
7262
 
7216
- this.stops.forEach(function (s, i) {
7217
- var c = control.graph.utils.toColor(s.color);
7218
- gradient && gradient.addColorStop(s.offset, c);
7219
- });
7220
- var data = control.toFillTexture(gradient, bounds, points);
7221
- this.__cachedData = data;
7222
- this.__cacheKey = gradientKey;
7223
- return data;
7224
- } // 当渐变参数变化时使缓存失效
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
+ */
7225
7274
 
7226
7275
  }, {
7227
7276
  key: "invalidateCache",
7228
7277
  value: function invalidateCache() {
7229
- this.__cachedData = null;
7230
- this.__cacheKey = null;
7231
- } // 根据绘制图形的坐标计算出对应点的颜色
7232
-
7233
- /*
7234
- toPointColors(points) {
7235
- const stops = this.getStops();
7236
- const colors = [];
7237
- for(let i=0; i<points.length; i+=2) {
7238
- const p = {
7239
- x: points[i],
7240
- y: points[i+1]
7241
- }
7242
- if(this.type === 'radial') {
7243
- const dx = p.x - this.x1;
7244
- const dy = p.y - this.y1;
7245
- const len = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
7246
- const rang = this.getStopRange(len, stops);
7247
- if(!rang.start && rang.end) {
7248
- colors.push(rang.end.color);
7249
- }
7250
- else if(!rang.end && rang.start) {
7251
- colors.push(rang.start.color);
7252
- }
7253
- else {
7254
- const rangLength = rang.end.length - rang.start.length;
7255
- const offlen = len - rang.start.length;
7256
- const per = offlen / rangLength;
7257
- const color = {
7258
- r: rang.start.color.r + (rang.end.color.r - rang.start.color.r) * per,
7259
- g: rang.start.color.g + (rang.end.color.g - rang.start.color.g) * per,
7260
- b: rang.start.color.b + (rang.end.color.b - rang.start.color.b) * per,
7261
- a: rang.start.color.a + (rang.end.color.a - rang.start.color.a) * per,
7262
- };
7263
- colors.push(color);
7264
- }
7265
- }
7266
- }
7267
- return colors;
7278
+ this._sortedStops = null;
7279
+ this._paramsHash = null;
7268
7280
  }
7269
- */
7270
- // 根据起点距离获取边界stop
7271
-
7272
- /*
7273
- getStopRange(len, stops) {
7274
- const res = {};
7275
- for(const s of stops) {
7276
- if(s.length <= len) {
7277
- res.start = s;
7278
- }
7279
- else {
7280
- res.end = s;
7281
- }
7282
- }
7283
- return res;
7284
- }
7285
- // 根据stop计算offset长度
7286
- getStops() {
7287
- const stops = this.stops.sort((p1, p2) => p1.offset - p2.offset); // 渐变色排序从小于大
7288
- for(const s of stops) {
7289
-
7290
- const color = typeof s.color === 'string'? this.control.graph.utils.hexToRGBA(s.color) : s.color;
7291
- console.log(s, color);
7292
- s.color = this.control.graph.utils.rgbToDecimal(color);
7293
- s.length = s.offset * this.length;
7294
- }
7295
- return stops;
7296
- }
7297
- */
7298
-
7299
7281
  /**
7300
- * 转换为渐变的字符串表达
7301
- *
7302
- * @method toString
7303
- * @for jmGradient
7304
- * @return {string} linear-gradient(x1 y1 x2 y2, color1 step, color2 step, ...); //radial-gradient(x1 y1 r1 x2 y2 r2, color1 step,color2 step, ...);
7305
- */
7282
+ * 转换为渐变的字符串表达
7283
+ */
7306
7284
 
7307
7285
  }, {
7308
7286
  key: "toString",
@@ -7313,8 +7291,7 @@ var WebglGradient = /*#__PURE__*/function () {
7313
7291
  str += this.x1 + ' ' + this.y1 + ' ' + this.x2 + ' ' + this.y2;
7314
7292
  } else {
7315
7293
  str += this.x1 + ' ' + this.y1 + ' ' + this.r1 + ' ' + this.x2 + ' ' + this.y2 + ' ' + this.r2;
7316
- } //颜色渐变
7317
-
7294
+ }
7318
7295
 
7319
7296
  this.stops.forEach(function (s) {
7320
7297
  str += ',' + s.color + ' ' + s.offset;
@@ -7339,10 +7316,16 @@ Object.defineProperty(exports, "__esModule", {
7339
7316
  });
7340
7317
  exports["default"] = void 0;
7341
7318
 
7342
- var _base = _interopRequireDefault(require("./base.js"));
7319
+ var _base = _interopRequireWildcard(require("./base.js"));
7320
+
7321
+ var _earcut = _interopRequireDefault(require("../earcut.js"));
7343
7322
 
7344
7323
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
7345
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
+
7346
7329
  function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
7347
7330
 
7348
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."); }
@@ -7671,6 +7654,164 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
7671
7654
  key: "equalPoint",
7672
7655
  value: function equalPoint(p1, p2) {
7673
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);
7674
7815
  } // 把path坐标集合转为线段集
7675
7816
 
7676
7817
  }, {
@@ -7934,20 +8075,20 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
7934
8075
  var polygons = this.getPolygon(points);
7935
8076
 
7936
8077
  if (polygons.length) {
7937
- var _iterator4 = _createForOfIteratorHelper(polygons),
7938
- _step4;
8078
+ var _iterator6 = _createForOfIteratorHelper(polygons),
8079
+ _step6;
7939
8080
 
7940
8081
  try {
7941
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
7942
- var polygon = _step4.value;
8082
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
8083
+ var polygon = _step6.value;
7943
8084
  // 需要分割三角形,不然填充会有问题
7944
8085
  var triangles = this.earCutPointsToTriangles(polygon);
7945
8086
  res.push.apply(res, _toConsumableArray(triangles));
7946
8087
  }
7947
8088
  } catch (err) {
7948
- _iterator4.e(err);
8089
+ _iterator6.e(err);
7949
8090
  } finally {
7950
- _iterator4.f();
8091
+ _iterator6.f();
7951
8092
  }
7952
8093
  }
7953
8094
 
@@ -7982,9 +8123,56 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
7982
8123
 
7983
8124
  if (points && points.length) {
7984
8125
  var regular = lineWidth <= 1.2;
7985
- points = regular ? points : this.pathToPoints(points);
7986
- var buffer = this.writePoints(points);
7987
- 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
+
7988
8176
  }
7989
8177
 
7990
8178
  colorBuffer && this.disableVertexAttribArray(colorBuffer && colorBuffer.attr);
@@ -8017,10 +8205,9 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
8017
8205
  value: function fillColor(color, points, bounds) {
8018
8206
  var type = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
8019
8207
 
8020
- // 如果是渐变色,则需要计算偏移量的颜色
8208
+ // 如果是渐变色,使用 GLSL 着色器直接计算
8021
8209
  if (this.isGradient(color)) {
8022
- var imgData = color.toImageData(this, bounds, points);
8023
- return this.fillImage(imgData.data, imgData.points, bounds);
8210
+ return this.fillGradient(color, points, bounds);
8024
8211
  } // 标注为fill
8025
8212
 
8026
8213
 
@@ -8028,6 +8215,93 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
8028
8215
  var colorBuffer = this.setFragColor(color);
8029
8216
  this.fillPolygons(points);
8030
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);
8031
8305
  } // 区域填充图片
8032
8306
  // points绘制的图形顶点
8033
8307
  // 图片整体绘制区域
@@ -8086,7 +8360,7 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
8086
8360
  }, {
8087
8361
  key: "fillPolygons",
8088
8362
  value: function fillPolygons(points) {
8089
- var _this2 = this;
8363
+ var _this3 = this;
8090
8364
 
8091
8365
  var isTexture = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
8092
8366
 
@@ -8100,7 +8374,40 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
8100
8374
 
8101
8375
 
8102
8376
  if (this.isRegular) {
8103
- 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);
8104
8411
 
8105
8412
  var _coordBuffer = isTexture ? this.writePoints(points, this.program.attrs.a_text_coord) : null;
8106
8413
 
@@ -8115,40 +8422,40 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
8115
8422
  var allVertices = [];
8116
8423
  var allTexCoords = [];
8117
8424
 
8118
- var _iterator5 = _createForOfIteratorHelper(triangles),
8119
- _step5;
8425
+ var _iterator7 = _createForOfIteratorHelper(triangles),
8426
+ _step7;
8120
8427
 
8121
8428
  try {
8122
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
8123
- var triangle = _step5.value;
8429
+ for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
8430
+ var triangle = _step7.value;
8124
8431
 
8125
- var _iterator6 = _createForOfIteratorHelper(triangle),
8126
- _step6;
8432
+ var _iterator8 = _createForOfIteratorHelper(triangle),
8433
+ _step8;
8127
8434
 
8128
8435
  try {
8129
- for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
8130
- var p = _step6.value;
8436
+ for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
8437
+ var p = _step8.value;
8131
8438
  allVertices.push(p.x, p.y);
8132
8439
  if (isTexture) allTexCoords.push(p.x, p.y);
8133
8440
  }
8134
8441
  } catch (err) {
8135
- _iterator6.e(err);
8442
+ _iterator8.e(err);
8136
8443
  } finally {
8137
- _iterator6.f();
8444
+ _iterator8.f();
8138
8445
  }
8139
8446
  } // 一次性上传所有数据并绘制
8140
8447
 
8141
8448
  } catch (err) {
8142
- _iterator5.e(err);
8449
+ _iterator7.e(err);
8143
8450
  } finally {
8144
- _iterator5.f();
8451
+ _iterator7.f();
8145
8452
  }
8146
8453
 
8147
8454
  var vertexData = new Float32Array(allVertices);
8148
8455
  var gl = this.context; // 复用或创建 position buffer
8149
8456
 
8150
8457
  var posBuffer = this.__cachedBuffers.find(function (b) {
8151
- return b.attr === _this2.program.attrs.a_position;
8458
+ return b.attr === _this3.program.attrs.a_position;
8152
8459
  });
8153
8460
 
8154
8461
  if (!posBuffer) {
@@ -8167,7 +8474,7 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
8167
8474
  var texData = new Float32Array(allTexCoords);
8168
8475
 
8169
8476
  var texBuffer = this.__cachedBuffers.find(function (b) {
8170
- return b.attr === _this2.program.attrs.a_text_coord;
8477
+ return b.attr === _this3.program.attrs.a_text_coord;
8171
8478
  });
8172
8479
 
8173
8480
  if (!texBuffer) {
@@ -8205,44 +8512,78 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
8205
8512
  }, {
8206
8513
  key: "drawText",
8207
8514
  value: function drawText(text, x, y, bounds) {
8208
- 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;
8209
8520
 
8210
8521
  if (!canvas) {
8211
- return null;
8522
+ canvas = document.createElement('canvas');
8523
+ this.__textCanvas = canvas;
8212
8524
  }
8213
8525
 
8214
8526
  canvas.width = bounds.width;
8215
8527
  canvas.height = bounds.height;
8528
+ var ctx = canvas.getContext('2d', {
8529
+ willReadFrequently: true
8530
+ });
8531
+ ctx.clearRect(0, 0, canvas.width, canvas.height); // 修改字体
8216
8532
 
8217
- if (!canvas.width || !canvas.height) {
8218
- 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);
8219
8539
  }
8220
8540
 
8221
- 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
+ }
8222
8544
 
8223
- this.textureContext.font = this.style.font || this.style.fontSize + 'px ' + this.style.fontFamily;
8224
- x -= bounds.left;
8225
- y -= bounds.top;
8226
- this.setTextureStyle(this.style);
8545
+ if (this.style.shadowColor) {
8546
+ ctx.shadowColor = this.graph.utils.toColor(this.style.shadowColor);
8547
+ }
8548
+
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
+ }
8227
8568
 
8228
- if (this.style.fillStyle && this.textureContext.fillText) {
8569
+ if (this.style.fillStyle && ctx.fillText) {
8229
8570
  if (this.style.maxWidth) {
8230
- this.textureContext.fillText(text, x, y, this.style.maxWidth);
8571
+ ctx.fillText(text, x, y, this.style.maxWidth);
8231
8572
  } else {
8232
- this.textureContext.fillText(text, x, y);
8573
+ ctx.fillText(text, x, y);
8233
8574
  }
8234
8575
  }
8235
8576
 
8236
- if (this.textureContext.strokeText) {
8577
+ if (this.style.strokeStyle && ctx.strokeText) {
8237
8578
  if (this.style.maxWidth) {
8238
- this.textureContext.strokeText(text, x, y, this.style.maxWidth);
8579
+ ctx.strokeText(text, x, y, this.style.maxWidth);
8239
8580
  } else {
8240
- this.textureContext.strokeText(text, x, y);
8581
+ ctx.strokeText(text, x, y);
8241
8582
  }
8242
8583
  } // 用纹理图片代替文字
8243
8584
 
8244
8585
 
8245
- var data = this.textureContext.getImageData(0, 0, canvas.width, canvas.height);
8586
+ var data = ctx.getImageData(0, 0, canvas.width, canvas.height);
8246
8587
  this.fillImage(data, this.points, bounds);
8247
8588
  }
8248
8589
  }]);
@@ -8253,7 +8594,7 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
8253
8594
  var _default = WebglPath;
8254
8595
  exports["default"] = _default;
8255
8596
 
8256
- },{"./base.js":14}],23:[function(require,module,exports){
8597
+ },{"../earcut.js":13,"./base.js":14}],23:[function(require,module,exports){
8257
8598
  "use strict";
8258
8599
 
8259
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); }
@@ -9396,7 +9737,7 @@ var jmHArc = /*#__PURE__*/function (_jmArc) {
9396
9737
  maxps.reverse(); //大圆逆序
9397
9738
 
9398
9739
  if (!this.style || !this.style.close) {
9399
- maxps[0].m = true; //开始画大圆时表示为移动
9740
+ maxps[0].m = true; //非闭合时标记 moveTo,分隔内外两个子路径
9400
9741
  }
9401
9742
 
9402
9743
  this.points = minps.concat(maxps);