jmgraph 3.2.20 → 3.2.22

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
@@ -120,22 +120,22 @@ Object.defineProperty(exports, "jmGradient", {
120
120
  return _jmGraph.jmGradient;
121
121
  }
122
122
  });
123
- Object.defineProperty(exports, "jmControl", {
123
+ Object.defineProperty(exports, "jmFilter", {
124
124
  enumerable: true,
125
125
  get: function get() {
126
- return _jmGraph.jmControl;
126
+ return _jmGraph.jmFilter;
127
127
  }
128
128
  });
129
- Object.defineProperty(exports, "jmPath", {
129
+ Object.defineProperty(exports, "jmControl", {
130
130
  enumerable: true,
131
131
  get: function get() {
132
- return _jmGraph.jmPath;
132
+ return _jmGraph.jmControl;
133
133
  }
134
134
  });
135
- Object.defineProperty(exports, "jmLayer", {
135
+ Object.defineProperty(exports, "jmPath", {
136
136
  enumerable: true,
137
137
  get: function get() {
138
- return _jmGraph.jmLayer;
138
+ return _jmGraph.jmPath;
139
139
  }
140
140
  });
141
141
  exports.create = exports.jmGraph = exports["default"] = void 0;
@@ -176,10 +176,6 @@ 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
-
183
179
  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); }
184
180
 
185
181
  function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
@@ -213,27 +209,17 @@ var shapes = {
213
209
  "star": _jmStar.jmStar
214
210
  };
215
211
 
216
- var jmGraph = /*#__PURE__*/function (_jmGraphCore) {
217
- _inherits(jmGraph, _jmGraphCore);
212
+ var jmGraphImpl = /*#__PURE__*/function (_jmGraphCore) {
213
+ _inherits(jmGraphImpl, _jmGraphCore);
218
214
 
219
- var _super = _createSuper(jmGraph);
215
+ var _super = _createSuper(jmGraphImpl);
220
216
 
221
- function jmGraph(canvas, option, callback) {
222
- var _this;
223
-
224
- _classCallCheck(this, jmGraph);
225
-
226
- var targetType = this instanceof jmGraph ? this.constructor : void 0; // 合并shapes
217
+ function jmGraphImpl(canvas, option, callback) {
218
+ _classCallCheck(this, jmGraphImpl);
227
219
 
220
+ // 合并shapes
228
221
  option = Object.assign({}, option);
229
- option.shapes = Object.assign(shapes, option.shapes || {}); //不是用new实例化的话,返回一个promise
230
-
231
- if (!targetType || !(targetType.prototype instanceof _jmGraph.jmGraph)) {
232
- return _possibleConstructorReturn(_this, new Promise(function (resolve, reject) {
233
- var g = new jmGraph(canvas, option, callback);
234
- if (resolve) resolve(g);
235
- }));
236
- }
222
+ option.shapes = Object.assign(shapes, option.shapes || {});
237
223
 
238
224
  if (typeof option == 'function') {
239
225
  callback = option;
@@ -243,30 +229,25 @@ var jmGraph = /*#__PURE__*/function (_jmGraphCore) {
243
229
  return _super.call(this, canvas, option, callback);
244
230
  }
245
231
 
246
- _createClass(jmGraph, null, [{
247
- key: "create",
248
- value: function create() {
249
- return createJmGraph.apply(void 0, arguments);
250
- }
251
- }]);
252
-
253
- return jmGraph;
254
- }(_jmGraph.jmGraph); //创建实例
232
+ return jmGraphImpl;
233
+ }(_jmGraph.jmGraph); //创建实例,支持不加 new 直接调用
255
234
 
256
235
 
257
- exports.jmGraph = exports["default"] = jmGraph;
236
+ exports.jmGraph = jmGraphImpl;
258
237
 
259
238
  var createJmGraph = function createJmGraph() {
260
239
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
261
240
  args[_key] = arguments[_key];
262
241
  }
263
242
 
264
- return _construct(jmGraph, args);
243
+ return _construct(jmGraphImpl, args);
265
244
  };
266
245
 
267
246
  exports.create = createJmGraph;
247
+ var _default = jmGraphImpl;
248
+ exports["default"] = _default;
268
249
 
269
- },{"./src/core/jmGraph.js":5,"./src/shapes/jmArc.js":23,"./src/shapes/jmArrow.js":24,"./src/shapes/jmArrowLine.js":25,"./src/shapes/jmBezier.js":26,"./src/shapes/jmCircle.js":27,"./src/shapes/jmEllipse.js":28,"./src/shapes/jmHArc.js":29,"./src/shapes/jmImage.js":30,"./src/shapes/jmLabel.js":31,"./src/shapes/jmLine.js":32,"./src/shapes/jmPolygon.js":33,"./src/shapes/jmPrismatic.js":34,"./src/shapes/jmRect.js":35,"./src/shapes/jmResize.js":36,"./src/shapes/jmStar.js":37}],2:[function(require,module,exports){
250
+ },{"./src/core/jmGraph.js":6,"./src/shapes/jmArc.js":23,"./src/shapes/jmArrow.js":24,"./src/shapes/jmArrowLine.js":25,"./src/shapes/jmBezier.js":26,"./src/shapes/jmCircle.js":27,"./src/shapes/jmEllipse.js":28,"./src/shapes/jmHArc.js":29,"./src/shapes/jmImage.js":30,"./src/shapes/jmLabel.js":31,"./src/shapes/jmLine.js":32,"./src/shapes/jmPolygon.js":33,"./src/shapes/jmPrismatic.js":34,"./src/shapes/jmRect.js":35,"./src/shapes/jmResize.js":36,"./src/shapes/jmStar.js":37}],2:[function(require,module,exports){
270
251
  "use strict";
271
252
 
272
253
  Object.defineProperty(exports, "__esModule", {
@@ -282,20 +263,14 @@ var _jmGradient = require("./jmGradient.js");
282
263
 
283
264
  var _jmShadow = require("./jmShadow.js");
284
265
 
266
+ var _jmFilter = require("./jmFilter.js");
267
+
285
268
  var _jmProperty2 = require("./jmProperty.js");
286
269
 
287
270
  var _path = _interopRequireDefault(require("../lib/webgl/path.js"));
288
271
 
289
272
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
290
273
 
291
- function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
292
-
293
- 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."); }
294
-
295
- function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
296
-
297
- function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
298
-
299
274
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
300
275
 
301
276
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
@@ -351,7 +326,9 @@ var jmStyleMap = {
351
326
  'shadowOffsetY': 'shadowOffsetY',
352
327
  'shadowColor': 'shadowColor',
353
328
  'lineJoin': 'lineJoin',
354
- 'lineCap': 'lineCap'
329
+ 'lineCap': 'lineCap',
330
+ 'lineDashOffset': 'lineDashOffset',
331
+ 'globalCompositeOperation': 'globalCompositeOperation'
355
332
  };
356
333
 
357
334
  var jmControl = /*#__PURE__*/function (_jmProperty) {
@@ -593,7 +570,10 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
593
570
  value: function setStyle(style) {
594
571
  var _this3 = this;
595
572
 
596
- style = style || _jmUtils.jmUtils.clone(this.style, true);
573
+ if (!style) {
574
+ style = this.style;
575
+ }
576
+
597
577
  if (!style) return;
598
578
 
599
579
  var __setStyle = function __setStyle(style, name, mpkey) {
@@ -681,6 +661,153 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
681
661
  case 'cursor':
682
662
  {
683
663
  _this3.cursor = styleValue;
664
+ break;
665
+ }
666
+ // ===== 新增样式特性 =====
667
+ // 虚线样式:支持自定义lineDash模式 (如 [5, 3, 2] 或 "5,3,2")
668
+
669
+ case 'lineDash':
670
+ {
671
+ if (!_this3.context.setLineDash) break;
672
+ var dash;
673
+
674
+ if (typeof styleValue === 'string') {
675
+ dash = styleValue.split(',').map(function (v) {
676
+ return parseFloat(v.trim());
677
+ }).filter(function (v) {
678
+ return !isNaN(v);
679
+ });
680
+ } else if (Array.isArray(styleValue)) {
681
+ dash = styleValue.map(function (v) {
682
+ return parseFloat(v);
683
+ }).filter(function (v) {
684
+ return !isNaN(v);
685
+ });
686
+ }
687
+
688
+ if (dash && dash.length) {
689
+ _this3.context.setLineDash(dash);
690
+ } else {
691
+ _this3.context.setLineDash([]);
692
+ }
693
+
694
+ break;
695
+ }
696
+ // 虚线偏移量
697
+
698
+ case 'lineDashOffset':
699
+ {
700
+ if (!_this3.context.setLineDash) break;
701
+ _this3.context.lineDashOffset = Number(styleValue) || 0;
702
+ break;
703
+ }
704
+ // CSS滤镜效果 (blur, grayscale, sepia, brightness, contrast, saturate, hue-rotate, invert, opacity)
705
+
706
+ case 'filter':
707
+ {
708
+ if (_this3.context.filter === undefined) break;
709
+
710
+ if (styleValue instanceof _jmFilter.jmFilter) {
711
+ _this3.context.filter = styleValue.toCanvasFilter();
712
+ } else if (typeof styleValue === 'string') {
713
+ _this3.context.filter = styleValue || 'none';
714
+ } else if (_typeof(styleValue) === 'object') {
715
+ _this3.context.filter = new _jmFilter.jmFilter(styleValue).toCanvasFilter();
716
+ }
717
+
718
+ break;
719
+ }
720
+ // 混合模式 (source-over, multiply, screen, overlay, darken, lighten, etc.)
721
+
722
+ case 'globalCompositeOperation':
723
+ {
724
+ if (!_this3.context.globalCompositeOperation) break;
725
+ _this3.context.globalCompositeOperation = styleValue;
726
+ break;
727
+ }
728
+ // 裁剪路径:通过canvas clip实现
729
+
730
+ case 'clipPath':
731
+ {
732
+ if (!_this3.context.clip) break; // clipPath可以是一个图形控件实例
733
+
734
+ if (styleValue && styleValue.points && styleValue.points.length > 0) {
735
+ var bounds = _this3.parent && _this3.parent.absoluteBounds ? _this3.parent.absoluteBounds : _this3.absoluteBounds;
736
+
737
+ _this3.context.beginPath();
738
+
739
+ _this3.context.moveTo(styleValue.points[0].x + (bounds ? bounds.left : 0), styleValue.points[0].y + (bounds ? bounds.top : 0));
740
+
741
+ for (var i = 1; i < styleValue.points.length; i++) {
742
+ if (styleValue.points[i].m) {
743
+ _this3.context.moveTo(styleValue.points[i].x + (bounds ? bounds.left : 0), styleValue.points[i].y + (bounds ? bounds.top : 0));
744
+ } else {
745
+ _this3.context.lineTo(styleValue.points[i].x + (bounds ? bounds.left : 0), styleValue.points[i].y + (bounds ? bounds.top : 0));
746
+ }
747
+ }
748
+
749
+ if (styleValue.style && styleValue.style.close) {
750
+ _this3.context.closePath();
751
+ }
752
+
753
+ _this3.context.clip();
754
+ }
755
+
756
+ break;
757
+ }
758
+ // 遮罩效果:通过globalCompositeOperation + destination-in实现
759
+
760
+ case 'mask':
761
+ {
762
+ if (!_this3.context.globalCompositeOperation) break; // mask是一个图形控件实例,在绘制前需要先应用mask
763
+ // 这里只是标记,实际绘制在paint流程中处理
764
+
765
+ _this3.__mask = styleValue;
766
+ break;
767
+ }
768
+ // 图片阴影描边阴影(WebGL纹理canvas用)
769
+
770
+ case 'shadowColor':
771
+ {
772
+ if (_this3.webglControl) {
773
+ _this3.webglControl.setStyle('shadowColor', styleValue);
774
+ } else {
775
+ _this3.context.shadowColor = _jmUtils.jmUtils.toColor(styleValue);
776
+ }
777
+
778
+ break;
779
+ }
780
+
781
+ case 'shadowBlur':
782
+ {
783
+ if (_this3.webglControl) {
784
+ _this3.webglControl.setStyle('shadowBlur', styleValue);
785
+ } else {
786
+ _this3.context.shadowBlur = Number(styleValue) || 0;
787
+ }
788
+
789
+ break;
790
+ }
791
+
792
+ case 'shadowOffsetX':
793
+ {
794
+ if (_this3.webglControl) {
795
+ _this3.webglControl.setStyle('shadowOffsetX', styleValue);
796
+ } else {
797
+ _this3.context.shadowOffsetX = Number(styleValue) || 0;
798
+ }
799
+
800
+ break;
801
+ }
802
+
803
+ case 'shadowOffsetY':
804
+ {
805
+ if (_this3.webglControl) {
806
+ _this3.webglControl.setStyle('shadowOffsetY', styleValue);
807
+ } else {
808
+ _this3.context.shadowOffsetY = Number(styleValue) || 0;
809
+ }
810
+
684
811
  break;
685
812
  }
686
813
  }
@@ -705,6 +832,8 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
705
832
  style[k] = new _jmGradient.jmGradient(style[k]);
706
833
  } else if (t == 'string' && k == 'shadow') {
707
834
  style[k] = new _jmShadow.jmShadow(style[k]);
835
+ } else if (t == 'string' && k == 'filter') {
836
+ style[k] = new _jmFilter.jmFilter(style[k]);
708
837
  }
709
838
 
710
839
  __setStyle(style[k], k);
@@ -882,7 +1011,6 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
882
1011
  }, {
883
1012
  key: "getLocation",
884
1013
  value: function getLocation() {
885
- var clone = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
886
1014
  //如果已经计算过则直接返回
887
1015
  //在开画之前会清空此对象
888
1016
  //if(reset !== true && this.location) return this.location;
@@ -891,32 +1019,34 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
891
1019
  top: 0,
892
1020
  width: 0,
893
1021
  height: 0
894
- };
895
- local.position = typeof this.position == 'function' ? this.position() : _jmUtils.jmUtils.clone(this.position);
896
- local.center = this.center && typeof this.center === 'function' ? this.center() : _jmUtils.jmUtils.clone(this.center); //中心
1022
+ }; // 检查是否有百分比参数需要解析,没有则直接引用避免克隆开销
1023
+
1024
+ var needResolve = this.parent && (_jmUtils.jmUtils.checkPercent(this.width) || _jmUtils.jmUtils.checkPercent(this.height) || this.position && _jmUtils.jmUtils.checkPercent(this.position.x) || this.position && _jmUtils.jmUtils.checkPercent(this.position.y));
1025
+
1026
+ local.position = typeof this.position == 'function' ? this.position() : needResolve ? _jmUtils.jmUtils.clone(this.position) : this.position;
1027
+ local.center = this.center && typeof this.center === 'function' ? this.center() : needResolve ? _jmUtils.jmUtils.clone(this.center) : this.center; //中心
897
1028
 
898
- local.start = this.start && typeof this.start === 'function' ? this.start() : _jmUtils.jmUtils.clone(this.start); //起点
1029
+ local.start = this.start && typeof this.start === 'function' ? this.start() : needResolve ? _jmUtils.jmUtils.clone(this.start) : this.start; //起点
899
1030
 
900
- local.end = this.end && typeof this.end === 'function' ? this.end() : _jmUtils.jmUtils.clone(this.end); //起点
1031
+ local.end = this.end && typeof this.end === 'function' ? this.end() : needResolve ? _jmUtils.jmUtils.clone(this.end) : this.end; //起点
901
1032
 
902
1033
  local.radius = this.radius; //半径
903
1034
 
904
1035
  local.width = this.width;
905
1036
  local.height = this.height;
906
-
907
- var margin = _jmUtils.jmUtils.clone(this.style.margin, {});
908
-
909
- margin.left = margin.left || 0;
910
- margin.top = margin.top || 0;
911
- margin.right = margin.right || 0;
912
- margin.bottom = margin.bottom || 0; //如果没有指定位置,但指定了margin。则位置取margin偏移量
1037
+ var margin = this.style.margin;
1038
+ var marginObj = needResolve && margin ? _jmUtils.jmUtils.clone(margin, {}) : margin || {};
1039
+ marginObj.left = marginObj.left || 0;
1040
+ marginObj.top = marginObj.top || 0;
1041
+ marginObj.right = marginObj.right || 0;
1042
+ marginObj.bottom = marginObj.bottom || 0; //如果没有指定位置,但指定了margin。则位置取margin偏移量
913
1043
 
914
1044
  if (local.position) {
915
1045
  local.left = local.position.x;
916
1046
  local.top = local.position.y;
917
1047
  } else {
918
- local.left = margin.left;
919
- local.top = margin.top;
1048
+ local.left = marginObj.left;
1049
+ local.top = marginObj.top;
920
1050
  }
921
1051
 
922
1052
  if (this.parent) {
@@ -1210,25 +1340,36 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1210
1340
  if (this.style.close) {
1211
1341
  if (this.webglControl) this.webglControl.closePath();
1212
1342
  this.context.closePath && this.context.closePath();
1213
- }
1343
+ } // 根据渲染模式选择不同的绘制路径
1214
1344
 
1215
- var fill = this.style['fill'] || this.style['fillStyle'];
1216
1345
 
1217
- if (fill) {
1218
- if (this.webglControl) {
1346
+ if (this.webglControl) {
1347
+ // WebGL 模式:使用 WebGL 绘制
1348
+ var fill = this.style['fill'] || this.style['fillStyle'];
1349
+
1350
+ if (fill) {
1219
1351
  var bounds = this.getBounds();
1220
1352
  this.webglControl.fill(bounds);
1221
1353
  }
1222
1354
 
1223
- this.context.fill && this.context.fill();
1224
- }
1355
+ if (this.style['stroke'] || !fill && !this.is('jmGraph')) {
1356
+ this.webglControl.stroke();
1357
+ }
1358
+
1359
+ if (this.webglControl.endDraw) this.webglControl.endDraw();
1360
+ } else {
1361
+ // 2D 模式:使用 Canvas 2D API 绘制
1362
+ var _fill = this.style['fill'] || this.style['fillStyle'];
1363
+
1364
+ if (_fill) {
1365
+ this.context.fill && this.context.fill();
1366
+ }
1225
1367
 
1226
- if (this.style['stroke'] || !fill && !this.is('jmGraph')) {
1227
- if (this.webglControl) this.webglControl.stroke();
1228
- this.context.stroke && this.context.stroke();
1368
+ if (this.style['stroke'] || !_fill && !this.is('jmGraph')) {
1369
+ this.context.stroke && this.context.stroke();
1370
+ }
1229
1371
  }
1230
1372
 
1231
- if (this.webglControl && this.webglControl.endDraw) this.webglControl.endDraw();
1232
1373
  this.needUpdate = false;
1233
1374
  }
1234
1375
  /**
@@ -1247,7 +1388,7 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1247
1388
 
1248
1389
  if (this.webglControl) {
1249
1390
  this.webglControl.setParentBounds(bounds);
1250
- this.webglControl.draw(_toConsumableArray(this.points));
1391
+ this.webglControl.draw(this.points);
1251
1392
  } else if (this.context && this.context.moveTo) {
1252
1393
  this.context.moveTo(this.points[0].x + bounds.left, this.points[0].y + bounds.top);
1253
1394
  var len = this.points.length;
@@ -1288,10 +1429,47 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1288
1429
  this.context.save && this.context.save();
1289
1430
  this.emit('beginDraw', this);
1290
1431
  this.setStyle(); //设定样式
1432
+ // 应用mask遮罩效果:在mask区域内绘制当前控件
1433
+ // 使用 destination-in 合成模式,只保留mask区域内的内容
1434
+
1435
+ var maskStyle = this.style.mask || this.__mask;
1436
+
1437
+ if (maskStyle && maskStyle.points && this.context.globalCompositeOperation) {
1438
+ // 先绘制当前控件
1439
+ if (needDraw && this.beginDraw) this.beginDraw();
1440
+ if (needDraw && this.draw) this.draw();
1441
+ if (needDraw && this.endDraw) this.endDraw(); // 再应用mask裁剪
1291
1442
 
1292
- if (needDraw && this.beginDraw) this.beginDraw();
1293
- if (needDraw && this.draw) this.draw();
1294
- if (needDraw && this.endDraw) this.endDraw();
1443
+ this.context.globalCompositeOperation = 'destination-in';
1444
+ if (maskStyle.initPoints) maskStyle.initPoints();
1445
+ var mBounds = maskStyle.parent && maskStyle.parent.absoluteBounds ? maskStyle.parent.absoluteBounds : this.absoluteBounds;
1446
+ this.context.beginPath();
1447
+
1448
+ if (maskStyle.points && maskStyle.points.length > 0) {
1449
+ this.context.moveTo(maskStyle.points[0].x + (mBounds ? mBounds.left : 0), maskStyle.points[0].y + (mBounds ? mBounds.top : 0));
1450
+
1451
+ for (var i = 1; i < maskStyle.points.length; i++) {
1452
+ if (maskStyle.points[i].m) {
1453
+ this.context.moveTo(maskStyle.points[i].x + (mBounds ? mBounds.left : 0), maskStyle.points[i].y + (mBounds ? mBounds.top : 0));
1454
+ } else {
1455
+ this.context.lineTo(maskStyle.points[i].x + (mBounds ? mBounds.left : 0), maskStyle.points[i].y + (mBounds ? mBounds.top : 0));
1456
+ }
1457
+ }
1458
+
1459
+ if (maskStyle.style && maskStyle.style.close) {
1460
+ this.context.closePath();
1461
+ }
1462
+ }
1463
+
1464
+ this.context.fillStyle = '#ffffff';
1465
+ this.context.fill(); // 恢复合成模式
1466
+
1467
+ this.context.globalCompositeOperation = 'source-over';
1468
+ } else {
1469
+ if (needDraw && this.beginDraw) this.beginDraw();
1470
+ if (needDraw && this.draw) this.draw();
1471
+ if (needDraw && this.endDraw) this.endDraw();
1472
+ }
1295
1473
 
1296
1474
  if (this.children) {
1297
1475
  this.children.each(function (i, item) {
@@ -1420,7 +1598,16 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1420
1598
  args[_key] = arguments[_key];
1421
1599
  }
1422
1600
 
1423
- this.runEventHandle(args[0], args.slice(1));
1601
+ // 避免每帧 args.slice(1) 分配临时数组
1602
+ // runEventHandle 内部会把非数组参数包装成数组
1603
+ if (args.length > 2) {
1604
+ this.runEventHandle(args[0], args.slice(1));
1605
+ } else if (args.length === 2) {
1606
+ this.runEventHandle(args[0], [args[1]]);
1607
+ } else {
1608
+ this.runEventHandle(args[0], []);
1609
+ }
1610
+
1424
1611
  return this;
1425
1612
  }
1426
1613
  /**
@@ -1928,7 +2115,7 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1928
2115
  exports.jmControl = exports["default"] = jmControl;
1929
2116
  ;
1930
2117
 
1931
- },{"../lib/webgl/path.js":22,"./jmGradient.js":4,"./jmList.js":7,"./jmProperty.js":10,"./jmShadow.js":11,"./jmUtils.js":12}],3:[function(require,module,exports){
2118
+ },{"../lib/webgl/path.js":22,"./jmFilter.js":4,"./jmGradient.js":5,"./jmList.js":7,"./jmProperty.js":10,"./jmShadow.js":11,"./jmUtils.js":12}],3:[function(require,module,exports){
1932
2119
  "use strict";
1933
2120
 
1934
2121
  Object.defineProperty(exports, "__esModule", {
@@ -2205,6 +2392,209 @@ var jmKeyEvent = /*#__PURE__*/function () {
2205
2392
  },{"./jmUtils.js":12}],4:[function(require,module,exports){
2206
2393
  "use strict";
2207
2394
 
2395
+ Object.defineProperty(exports, "__esModule", {
2396
+ value: true
2397
+ });
2398
+ exports.jmFilter = exports["default"] = void 0;
2399
+
2400
+ var _jmUtils = require("./jmUtils.js");
2401
+
2402
+ 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); }
2403
+
2404
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2405
+
2406
+ 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); } }
2407
+
2408
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
2409
+
2410
+ /**
2411
+ * CSS滤镜效果类
2412
+ * 支持的滤镜: blur, grayscale, sepia, brightness, contrast, saturate, hue-rotate, invert, opacity
2413
+ *
2414
+ * @class jmFilter
2415
+ * @param {string|object} opt 滤镜参数
2416
+ * 字符串格式: "blur(2px) grayscale(50%) brightness(1.2)"
2417
+ * 对象格式: { blur: 2, grayscale: 0.5, brightness: 1.2 }
2418
+ */
2419
+ var jmFilter = /*#__PURE__*/function () {
2420
+ function jmFilter(opt) {
2421
+ _classCallCheck(this, jmFilter);
2422
+
2423
+ this.filters = [];
2424
+
2425
+ if (typeof opt === 'string') {
2426
+ this.fromString(opt);
2427
+ } else if (opt && _typeof(opt) === 'object') {
2428
+ for (var k in opt) {
2429
+ if (k === 'constructor' || k === 'filters') continue;
2430
+ this.addFilter(k, opt[k]);
2431
+ }
2432
+ }
2433
+ }
2434
+ /**
2435
+ * 添加单个滤镜
2436
+ * @param {string} name 滤镜名称 (blur, grayscale, sepia, brightness, contrast, saturate, hue-rotate, invert, opacity)
2437
+ * @param {number|string} value 滤镜值
2438
+ */
2439
+
2440
+
2441
+ _createClass(jmFilter, [{
2442
+ key: "addFilter",
2443
+ value: function addFilter(name, value) {
2444
+ name = name.toLowerCase().trim();
2445
+
2446
+ if (typeof value === 'string') {
2447
+ value = parseFloat(value);
2448
+ }
2449
+
2450
+ if (isNaN(value)) return; // 规范化滤镜名称
2451
+
2452
+ var normalized = {
2453
+ 'blur': 'blur',
2454
+ 'grayscale': 'grayscale',
2455
+ 'greyscale': 'grayscale',
2456
+ 'sepia': 'sepia',
2457
+ 'brightness': 'brightness',
2458
+ 'contrast': 'contrast',
2459
+ 'saturate': 'saturate',
2460
+ 'hue-rotate': 'hueRotate',
2461
+ 'hueRotate': 'hueRotate',
2462
+ 'invert': 'invert',
2463
+ 'opacity': 'opacity'
2464
+ }[name];
2465
+ if (!normalized) return; // 检查是否已有同名滤镜,有则更新
2466
+
2467
+ var existing = this.filters.find(function (f) {
2468
+ return f.name === normalized;
2469
+ });
2470
+
2471
+ if (existing) {
2472
+ existing.value = value;
2473
+ } else {
2474
+ this.filters.push({
2475
+ name: normalized,
2476
+ value: value
2477
+ });
2478
+ }
2479
+ }
2480
+ /**
2481
+ * 从字符串格式解析滤镜
2482
+ * 格式: "blur(2px) grayscale(50%) brightness(1.2)"
2483
+ * @param {string} s 滤镜字符串
2484
+ */
2485
+
2486
+ }, {
2487
+ key: "fromString",
2488
+ value: function fromString(s) {
2489
+ if (!s || typeof s !== 'string') return; // 匹配 filterName(value) 模式
2490
+
2491
+ var regex = /([a-zA-Z-]+)\s*\(\s*([^)]+)\s*\)/g;
2492
+ var match;
2493
+
2494
+ while ((match = regex.exec(s)) !== null) {
2495
+ var name = match[1];
2496
+ var valueStr = match[2].replace(/[a-z%]+$/i, '').trim();
2497
+ var value = parseFloat(valueStr);
2498
+
2499
+ if (!isNaN(value)) {
2500
+ this.addFilter(name, value);
2501
+ }
2502
+ }
2503
+ }
2504
+ /**
2505
+ * 转换为CSS filter字符串格式
2506
+ * @returns {string}
2507
+ */
2508
+
2509
+ }, {
2510
+ key: "toString",
2511
+ value: function toString() {
2512
+ return this.filters.map(function (f) {
2513
+ switch (f.name) {
2514
+ case 'blur':
2515
+ return "blur(".concat(f.value, "px)");
2516
+
2517
+ case 'hueRotate':
2518
+ return "hue-rotate(".concat(f.value, "deg)");
2519
+
2520
+ default:
2521
+ return "".concat(f.name, "(").concat(f.value, ")");
2522
+ }
2523
+ }).join(' ');
2524
+ }
2525
+ /**
2526
+ * 转换为Canvas context.filter可用的字符串
2527
+ * @returns {string}
2528
+ */
2529
+
2530
+ }, {
2531
+ key: "toCanvasFilter",
2532
+ value: function toCanvasFilter() {
2533
+ if (this.filters.length === 0) return 'none';
2534
+ return this.toString();
2535
+ }
2536
+ /**
2537
+ * 检查是否有指定名称的滤镜
2538
+ * @param {string} name 滤镜名称
2539
+ * @returns {boolean}
2540
+ */
2541
+
2542
+ }, {
2543
+ key: "has",
2544
+ value: function has(name) {
2545
+ return this.filters.some(function (f) {
2546
+ return f.name === name;
2547
+ });
2548
+ }
2549
+ /**
2550
+ * 获取指定滤镜的值
2551
+ * @param {string} name 滤镜名称
2552
+ * @returns {number|undefined}
2553
+ */
2554
+
2555
+ }, {
2556
+ key: "get",
2557
+ value: function get(name) {
2558
+ var f = this.filters.find(function (f) {
2559
+ return f.name === name;
2560
+ });
2561
+ return f ? f.value : undefined;
2562
+ }
2563
+ /**
2564
+ * 移除指定滤镜
2565
+ * @param {string} name 滤镜名称
2566
+ */
2567
+
2568
+ }, {
2569
+ key: "remove",
2570
+ value: function remove(name) {
2571
+ var index = this.filters.findIndex(function (f) {
2572
+ return f.name === name;
2573
+ });
2574
+
2575
+ if (index > -1) {
2576
+ this.filters.splice(index, 1);
2577
+ }
2578
+ }
2579
+ /**
2580
+ * 清空所有滤镜
2581
+ */
2582
+
2583
+ }, {
2584
+ key: "clear",
2585
+ value: function clear() {
2586
+ this.filters = [];
2587
+ }
2588
+ }]);
2589
+
2590
+ return jmFilter;
2591
+ }();
2592
+
2593
+ exports.jmFilter = exports["default"] = jmFilter;
2594
+
2595
+ },{"./jmUtils.js":12}],5:[function(require,module,exports){
2596
+ "use strict";
2597
+
2208
2598
  Object.defineProperty(exports, "__esModule", {
2209
2599
  value: true
2210
2600
  });
@@ -2485,7 +2875,7 @@ var jmGradient = /*#__PURE__*/function () {
2485
2875
 
2486
2876
  exports.jmGradient = exports["default"] = jmGradient;
2487
2877
 
2488
- },{"./jmList.js":7,"./jmUtils.js":12}],5:[function(require,module,exports){
2878
+ },{"./jmList.js":7,"./jmUtils.js":12}],6:[function(require,module,exports){
2489
2879
  "use strict";
2490
2880
 
2491
2881
  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); }
@@ -2523,6 +2913,12 @@ Object.defineProperty(exports, "jmGradient", {
2523
2913
  return _jmGradient.jmGradient;
2524
2914
  }
2525
2915
  });
2916
+ Object.defineProperty(exports, "jmFilter", {
2917
+ enumerable: true,
2918
+ get: function get() {
2919
+ return _jmFilter.jmFilter;
2920
+ }
2921
+ });
2526
2922
  Object.defineProperty(exports, "jmEvents", {
2527
2923
  enumerable: true,
2528
2924
  get: function get() {
@@ -2541,12 +2937,6 @@ Object.defineProperty(exports, "jmPath", {
2541
2937
  return _jmPath.jmPath;
2542
2938
  }
2543
2939
  });
2544
- Object.defineProperty(exports, "jmLayer", {
2545
- enumerable: true,
2546
- get: function get() {
2547
- return _jmLayer.jmLayer;
2548
- }
2549
- });
2550
2940
  exports.jmGraph = exports["default"] = void 0;
2551
2941
 
2552
2942
  var _jmUtils = require("./jmUtils.js");
@@ -2559,14 +2949,14 @@ var _jmShadow = require("./jmShadow.js");
2559
2949
 
2560
2950
  var _jmGradient = require("./jmGradient.js");
2561
2951
 
2952
+ var _jmFilter = require("./jmFilter.js");
2953
+
2562
2954
  var _jmEvents = require("./jmEvents.js");
2563
2955
 
2564
2956
  var _jmControl2 = require("./jmControl.js");
2565
2957
 
2566
2958
  var _jmPath = require("./jmPath.js");
2567
2959
 
2568
- var _jmLayer = require("./jmLayer.js");
2569
-
2570
2960
  function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }
2571
2961
 
2572
2962
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
@@ -2902,9 +3292,7 @@ var jmGraph = /*#__PURE__*/function (_jmControl) {
2902
3292
  if (shape) {
2903
3293
  if (!args) args = {};
2904
3294
  args.graph = this;
2905
- var obj = new shape(args); // 添加到活动图层
2906
-
2907
- this.addShapeToLayer(obj);
3295
+ var obj = new shape(args);
2908
3296
  return obj;
2909
3297
  }
2910
3298
  }
@@ -3051,13 +3439,22 @@ var jmGraph = /*#__PURE__*/function (_jmControl) {
3051
3439
 
3052
3440
  this.context.clearRect(0, 0, w, h);
3053
3441
  } else if (this.mode === 'webgl' && this.context.clear) {
3054
- var color = this.style && this.style.fill ? this.utils.hexToRGBA(this.style.fill) : {
3055
- r: 0,
3056
- g: 0,
3057
- b: 0,
3058
- a: 0
3059
- };
3060
- this.context.clearColor(color.r, color.g, color.b, color.a); // 设置清空颜色缓冲时的颜色值
3442
+ // 缓存 clearColor 对象,避免每帧创建
3443
+ if (this.style && this.style.fill) {
3444
+ var color = this.utils.hexToRGBA(this.style.fill);
3445
+ this.__lastClearColor = color;
3446
+ this.context.clearColor(color.r, color.g, color.b, color.a);
3447
+ } else if (!this.__lastClearColor) {
3448
+ this.__lastClearColor = {
3449
+ r: 0,
3450
+ g: 0,
3451
+ b: 0,
3452
+ a: 0
3453
+ };
3454
+ this.context.clearColor(0, 0, 0, 0);
3455
+ } else {
3456
+ this.context.clearColor(this.__lastClearColor.r, this.__lastClearColor.g, this.__lastClearColor.b, this.__lastClearColor.a);
3457
+ }
3061
3458
 
3062
3459
  this.context.clear(this.context.COLOR_BUFFER_BIT); // 清空颜色缓冲区,也就是清空画布
3063
3460
  }
@@ -3214,306 +3611,65 @@ var jmGraph = /*#__PURE__*/function (_jmControl) {
3214
3611
 
3215
3612
  zoom = Math.max(minZoom, Math.min(maxZoom, zoom));
3216
3613
 
3217
- if (x !== undefined && y !== undefined) {
3218
- // 计算缩放前后的坐标偏移
3219
- // 保持缩放中心点在屏幕上的位置不变
3220
- var oldZoom = this.scaleFactor;
3221
- var newZoom = zoom; // 调整平移量以保持缩放中心位置不变
3222
-
3223
- this.translation.x = x - (x - this.translation.x) * (newZoom / oldZoom);
3224
- this.translation.y = y - (y - this.translation.y) * (newZoom / oldZoom);
3225
- }
3226
-
3227
- this.scaleFactor = zoom;
3228
- this.needUpdate = true;
3229
- this.redraw();
3230
- return this; // 支持链式调用
3231
- }
3232
- /**
3233
- * 平移画布
3234
- * 移动画布视图,改变可视区域
3235
- *
3236
- * @method pan
3237
- * @param {number} dx X轴平移量(像素)
3238
- * @param {number} dy Y轴平移量(像素)
3239
- * @return {jmGraph} 返回当前实例,支持链式调用
3240
- */
3241
-
3242
- }, {
3243
- key: "pan",
3244
- value: function pan(dx, dy) {
3245
- // 参数验证
3246
- if (typeof dx !== 'number' || typeof dy !== 'number' || isNaN(dx) || isNaN(dy)) {
3247
- console.warn('jmGraph: pan - 无效的平移参数');
3248
- return this;
3249
- }
3250
-
3251
- this.translation.x += dx;
3252
- this.translation.y += dy;
3253
- this.needUpdate = true;
3254
- this.redraw();
3255
- return this; // 支持链式调用
3256
- }
3257
- /**
3258
- * 重置缩放和平移
3259
- * 恢复画布到初始状态(缩放为1,平移为0)
3260
- *
3261
- * @method resetTransform
3262
- * @return {jmGraph} 返回当前实例,支持链式调用
3263
- */
3264
-
3265
- }, {
3266
- key: "resetTransform",
3267
- value: function resetTransform() {
3268
- this.scaleFactor = 1;
3269
- this.translation = {
3270
- x: 0,
3271
- y: 0
3272
- };
3273
- this.needUpdate = true;
3274
- this.redraw();
3275
- return this; // 支持链式调用
3276
- }
3277
- /**
3278
- * 初始化图层系统
3279
- * 创建图层管理的基础结构,包括默认图层
3280
- *
3281
- * @method initLayers
3282
- * @private
3283
- */
3284
-
3285
- }, {
3286
- key: "initLayers",
3287
- value: function initLayers() {
3288
- if (!this.layers) {
3289
- this.layers = new _jmList.jmList(); // 创建默认图层
3290
-
3291
- var defaultLayer = this.createLayer('Default Layer');
3292
- this.activeLayer = defaultLayer;
3293
- }
3294
- }
3295
- /**
3296
- * 创建新图层
3297
- * 图层用于组织和管理图形对象,支持可见性和锁定控制
3298
- *
3299
- * @method createLayer
3300
- * @param {string} name 图层名称(必须唯一)
3301
- * @param {object} [options] 图层选项
3302
- * @param {boolean} [options.visible=true] 图层是否可见
3303
- * @param {boolean} [options.locked=false] 图层是否锁定(锁定后不可交互)
3304
- * @return {jmLayer} 新创建的图层
3305
- */
3306
-
3307
- }, {
3308
- key: "createLayer",
3309
- value: function createLayer(name) {
3310
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
3311
-
3312
- // 参数验证
3313
- if (!name || typeof name !== 'string') {
3314
- console.warn('jmGraph: createLayer - 图层名称必须是非空字符串');
3315
- name = "Layer_".concat(Date.now());
3316
- }
3317
-
3318
- this.initLayers(); // 检查图层名称是否已存在
3319
-
3320
- var existingLayer = this.getLayer(name);
3321
-
3322
- if (existingLayer) {
3323
- console.warn("jmGraph: \u56FE\u5C42 \"".concat(name, "\" \u5DF2\u5B58\u5728\uFF0C\u5C06\u8FD4\u56DE\u73B0\u6709\u56FE\u5C42"));
3324
- return existingLayer;
3325
- }
3326
-
3327
- var layer = new _jmLayer.jmLayer(_objectSpread({
3328
- name: name,
3329
- graph: this
3330
- }, options));
3331
- this.layers.add(layer);
3332
- this.children.add(layer);
3333
- this.needUpdate = true;
3334
- return layer;
3335
- }
3336
- /**
3337
- * 获取所有图层
3338
- *
3339
- * @method getLayers
3340
- * @return {jmList} 图层列表
3341
- */
3342
-
3343
- }, {
3344
- key: "getLayers",
3345
- value: function getLayers() {
3346
- this.initLayers();
3347
- return this.layers;
3348
- }
3349
- /**
3350
- * 根据名称获取图层
3351
- *
3352
- * @method getLayer
3353
- * @param {string} name 图层名称
3354
- * @return {jmLayer|null} 图层对象,如果不存在则返回null
3355
- */
3356
-
3357
- }, {
3358
- key: "getLayer",
3359
- value: function getLayer(name) {
3360
- this.initLayers();
3361
- if (!name) return null;
3362
- var result = null;
3363
- this.layers.each(function (i, layer) {
3364
- if (layer.name === name) {
3365
- result = layer;
3366
- return false; // 找到后停止遍历
3367
- }
3368
- });
3369
- return result;
3370
- }
3371
- /**
3372
- * 设置活动图层
3373
- * 新创建的图形将自动添加到活动图层
3374
- *
3375
- * @method setActiveLayer
3376
- * @param {string|jmLayer} layer 图层名称或图层对象
3377
- * @return {jmGraph} 返回当前实例,支持链式调用
3378
- */
3379
-
3380
- }, {
3381
- key: "setActiveLayer",
3382
- value: function setActiveLayer(layer) {
3383
- this.initLayers(); // 支持传入图层名称或图层对象
3384
-
3385
- if (typeof layer === 'string') {
3386
- layer = this.getLayer(layer);
3387
- }
3388
-
3389
- if (!layer || !(layer instanceof _jmLayer.jmLayer)) {
3390
- console.warn('jmGraph: setActiveLayer - 无效的图层');
3391
- return this;
3392
- }
3393
-
3394
- this.activeLayer = layer;
3395
- return this;
3396
- }
3397
- /**
3398
- * 获取当前活动图层
3399
- * 活动图层是新创建图形的默认容器
3400
- *
3401
- * @method getActiveLayer
3402
- * @return {jmLayer} 当前活动图层
3403
- */
3404
-
3405
- }, {
3406
- key: "getActiveLayer",
3407
- value: function getActiveLayer() {
3408
- this.initLayers();
3409
- return this.activeLayer;
3410
- }
3411
- /**
3412
- * 移除图层
3413
- * 删除指定图层及其包含的所有图形
3414
- * 注意:默认图层不可删除
3415
- *
3416
- * @method removeLayer
3417
- * @param {string|jmLayer} layer 图层名称或图层对象
3418
- * @return {boolean} 是否成功删除
3419
- */
3420
-
3421
- }, {
3422
- key: "removeLayer",
3423
- value: function removeLayer(layer) {
3424
- this.initLayers(); // 支持传入图层名称或图层对象
3425
-
3426
- if (typeof layer === 'string') {
3427
- layer = this.getLayer(layer);
3428
- }
3429
-
3430
- if (!layer) {
3431
- console.warn('jmGraph: removeLayer - 图层不存在');
3432
- return false;
3433
- } // 禁止删除默认图层
3434
-
3435
-
3436
- if (layer.name === 'Default Layer') {
3437
- console.warn('jmGraph: 不能删除默认图层');
3438
- return false;
3439
- } // 如果删除的是当前活动图层,切换到默认图层
3440
-
3614
+ if (x !== undefined && y !== undefined) {
3615
+ // 计算缩放前后的坐标偏移
3616
+ // 保持缩放中心点在屏幕上的位置不变
3617
+ var oldZoom = this.scaleFactor;
3618
+ var newZoom = zoom; // 调整平移量以保持缩放中心位置不变
3441
3619
 
3442
- if (this.activeLayer === layer) {
3443
- this.activeLayer = this.getLayer('Default Layer');
3620
+ this.translation.x = x - (x - this.translation.x) * (newZoom / oldZoom);
3621
+ this.translation.y = y - (y - this.translation.y) * (newZoom / oldZoom);
3444
3622
  }
3445
3623
 
3446
- this.layers.remove(layer);
3447
- this.children.remove(layer);
3624
+ this.scaleFactor = zoom;
3448
3625
  this.needUpdate = true;
3449
- return true;
3626
+ this.redraw();
3627
+ return this; // 支持链式调用
3450
3628
  }
3451
3629
  /**
3452
- * 将形状添加到指定图层
3453
- * 如果未指定图层,则添加到当前活动图层
3630
+ * 平移画布
3631
+ * 移动画布视图,改变可视区域
3454
3632
  *
3455
- * @method addShapeToLayer
3456
- * @param {jmControl} shape 要添加的形状对象
3457
- * @param {string|jmLayer} [layer] 图层名称或图层对象,默认为当前活动图层
3633
+ * @method pan
3634
+ * @param {number} dx X轴平移量(像素)
3635
+ * @param {number} dy Y轴平移量(像素)
3458
3636
  * @return {jmGraph} 返回当前实例,支持链式调用
3459
3637
  */
3460
3638
 
3461
3639
  }, {
3462
- key: "addShapeToLayer",
3463
- value: function addShapeToLayer(shape, layer) {
3464
- this.initLayers(); // 参数验证
3465
-
3466
- if (!shape) {
3467
- console.warn('jmGraph: addShapeToLayer - 无效的形状对象');
3468
- return this;
3469
- } // 确定目标图层
3470
-
3471
-
3472
- if (!layer) {
3473
- layer = this.activeLayer;
3474
- } else if (typeof layer === 'string') {
3475
- layer = this.getLayer(layer);
3476
- }
3477
-
3478
- if (!layer) {
3479
- console.warn('jmGraph: addShapeToLayer - 图层不存在');
3640
+ key: "pan",
3641
+ value: function pan(dx, dy) {
3642
+ // 参数验证
3643
+ if (typeof dx !== 'number' || typeof dy !== 'number' || isNaN(dx) || isNaN(dy)) {
3644
+ console.warn('jmGraph: pan - 无效的平移参数');
3480
3645
  return this;
3481
3646
  }
3482
3647
 
3483
- layer.children.add(shape);
3648
+ this.translation.x += dx;
3649
+ this.translation.y += dy;
3484
3650
  this.needUpdate = true;
3485
- return this;
3651
+ this.redraw();
3652
+ return this; // 支持链式调用
3486
3653
  }
3487
3654
  /**
3488
- * 从图层中移除形状
3655
+ * 重置缩放和平移
3656
+ * 恢复画布到初始状态(缩放为1,平移为0)
3489
3657
  *
3490
- * @method removeShapeFromLayer
3491
- * @param {jmControl} shape 要移除的形状对象
3658
+ * @method resetTransform
3492
3659
  * @return {jmGraph} 返回当前实例,支持链式调用
3493
3660
  */
3494
3661
 
3495
3662
  }, {
3496
- key: "removeShapeFromLayer",
3497
- value: function removeShapeFromLayer(shape) {
3498
- var _this2 = this;
3499
-
3500
- if (!shape) {
3501
- console.warn('jmGraph: removeShapeFromLayer - 无效的形状对象');
3502
- return this;
3503
- } // 从所有图层中查找并移除
3504
-
3505
-
3506
- if (this.layers) {
3507
- this.layers.each(function (i, layer) {
3508
- if (layer.children.contains(shape)) {
3509
- layer.children.remove(shape);
3510
- _this2.needUpdate = true;
3511
- return false; // 找到后停止遍历
3512
- }
3513
- });
3514
- }
3515
-
3516
- return this;
3663
+ key: "resetTransform",
3664
+ value: function resetTransform() {
3665
+ this.scaleFactor = 1;
3666
+ this.translation = {
3667
+ x: 0,
3668
+ y: 0
3669
+ };
3670
+ this.needUpdate = true;
3671
+ this.redraw();
3672
+ return this; // 支持链式调用
3517
3673
  }
3518
3674
  /**
3519
3675
  * 保存为base64图形数据
@@ -3599,9 +3755,8 @@ var jmGraph = /*#__PURE__*/function (_jmControl) {
3599
3755
  }
3600
3756
  }
3601
3757
  /**
3602
- * 转换为SVG字符串
3603
- * 遍历所有图层和形状,生成SVG标记
3604
- *
3758
+ * 遍历所有形状,生成SVG标记
3759
+ *
3605
3760
  * @method toSVG
3606
3761
  * @return {string} SVG字符串
3607
3762
  */
@@ -3614,32 +3769,14 @@ var jmGraph = /*#__PURE__*/function (_jmControl) {
3614
3769
 
3615
3770
  if (this.style && this.style.fill) {
3616
3771
  svg += "<rect width=\"100%\" height=\"100%\" fill=\"".concat(this.style.fill, "\"/>");
3617
- } // 遍历所有图层
3618
-
3772
+ } // 遍历所有直接添加的形状
3619
3773
 
3620
- if (this.layers) {
3621
- this.layers.each(function (i, layer) {
3622
- if (layer.visible) {
3623
- // 添加图层组,方便管理
3624
- svg += "<g id=\"".concat(layer.name, "\" opacity=\"").concat(layer.opacity || 1, "\">"); // 遍历图层中的所有形状
3625
-
3626
- layer.children.each(function (j, shape) {
3627
- if (shape.toSVG) {
3628
- svg += shape.toSVG();
3629
- }
3630
- });
3631
- svg += '</g>';
3632
- }
3633
- });
3634
- } else {
3635
- // 遍历直接添加的形状(兼容没有图层系统的情况)
3636
- this.children.each(function (i, shape) {
3637
- if (shape.toSVG) {
3638
- svg += shape.toSVG();
3639
- }
3640
- });
3641
- }
3642
3774
 
3775
+ this.children.each(function (i, shape) {
3776
+ if (shape.toSVG) {
3777
+ svg += shape.toSVG();
3778
+ }
3779
+ });
3643
3780
  svg += '</svg>';
3644
3781
  return svg;
3645
3782
  }
@@ -3689,8 +3826,8 @@ var jmGraph = /*#__PURE__*/function (_jmControl) {
3689
3826
  if (self.needUpdate) self.redraw();
3690
3827
  var time = Date.now() - refreshStartTime; // 触发刷新事件
3691
3828
 
3692
- self.emit('update', time);
3693
- self.__requestAnimationFrameFunHandler && self.cancelAnimationFrame(self.__requestAnimationFrameFunHandler);
3829
+ self.emit('update', time); // 直接 requestAnimationFrame,无需先 cancel
3830
+
3694
3831
  self.__requestAnimationFrameFunHandler = self.requestAnimationFrame(update);
3695
3832
  if (callback) callback();
3696
3833
  }
@@ -3722,215 +3859,7 @@ var jmGraph = /*#__PURE__*/function (_jmControl) {
3722
3859
 
3723
3860
  exports.jmGraph = exports["default"] = jmGraph;
3724
3861
 
3725
- },{"./jmControl.js":2,"./jmEvents.js":3,"./jmGradient.js":4,"./jmLayer.js":6,"./jmList.js":7,"./jmPath.js":9,"./jmProperty.js":10,"./jmShadow.js":11,"./jmUtils.js":12}],6:[function(require,module,exports){
3726
- "use strict";
3727
-
3728
- 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); }
3729
-
3730
- Object.defineProperty(exports, "__esModule", {
3731
- value: true
3732
- });
3733
- exports.jmLayer = exports["default"] = void 0;
3734
-
3735
- var _jmControl2 = require("./jmControl.js");
3736
-
3737
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3738
-
3739
- 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); } }
3740
-
3741
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
3742
-
3743
- function _get(target, property, receiver) { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); }
3744
-
3745
- function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; }
3746
-
3747
- 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); }
3748
-
3749
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
3750
-
3751
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
3752
-
3753
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
3754
-
3755
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
3756
-
3757
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
3758
-
3759
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
3760
-
3761
- /**
3762
- * 图层类
3763
- * 用于组织和管理图形对象,支持可见性和锁定控制
3764
- * 图层可以包含多个图形对象,并控制它们的显示和交互
3765
- *
3766
- * @class jmLayer
3767
- * @extends jmControl
3768
- * @param {object} params 图层参数
3769
- * @param {string} [params.name] 图层名称,默认为 'Layer_${timestamp}'
3770
- * @param {boolean} [params.visible=true] 图层是否可见
3771
- * @param {boolean} [params.locked=false] 图层是否锁定(锁定后不可交互)
3772
- * @param {jmGraph} [params.graph] 所属的画布对象
3773
- */
3774
- var jmLayer = /*#__PURE__*/function (_jmControl) {
3775
- _inherits(jmLayer, _jmControl);
3776
-
3777
- var _super = _createSuper(jmLayer);
3778
-
3779
- function jmLayer(params) {
3780
- var _this;
3781
-
3782
- var t = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'jmLayer';
3783
-
3784
- _classCallCheck(this, jmLayer);
3785
-
3786
- params = params || {};
3787
- params.interactive = false; // 图层本身不响应交互事件
3788
-
3789
- _this = _super.call(this, params, t);
3790
- _this.name = params.name || "Layer_".concat(Date.now());
3791
- _this.visible = params.visible !== false;
3792
- _this.locked = params.locked || false;
3793
- return _this;
3794
- }
3795
- /**
3796
- * 图层名称
3797
- * 图层的唯一标识符,用于查找和管理图层
3798
- *
3799
- * @property name
3800
- * @type {string}
3801
- */
3802
-
3803
-
3804
- _createClass(jmLayer, [{
3805
- key: "name",
3806
- get: function get() {
3807
- return this.property('name');
3808
- },
3809
- set: function set(v) {
3810
- if (!v || typeof v !== 'string') {
3811
- console.warn('jmLayer: name must be a non-empty string');
3812
- return;
3813
- }
3814
-
3815
- return this.property('name', v);
3816
- }
3817
- /**
3818
- * 图层是否可见
3819
- * 不可见的图层不会被渲染,但仍然存在于图层列表中
3820
- *
3821
- * @property visible
3822
- * @type {boolean}
3823
- */
3824
-
3825
- }, {
3826
- key: "visible",
3827
- get: function get() {
3828
- return this.property('visible');
3829
- },
3830
- set: function set(v) {
3831
- this.needUpdate = true;
3832
- return this.property('visible', v);
3833
- }
3834
- /**
3835
- * 图层是否锁定
3836
- * 锁定的图层中的图形不可被选中或移动,但仍然可见
3837
- * 适用于背景图层或参考图层
3838
- *
3839
- * @property locked
3840
- * @type {boolean}
3841
- */
3842
-
3843
- }, {
3844
- key: "locked",
3845
- get: function get() {
3846
- return this.property('locked');
3847
- },
3848
- set: function set(v) {
3849
- return this.property('locked', v);
3850
- }
3851
- /**
3852
- * 绘制图层
3853
- * 只有可见的图层才会被绘制
3854
- *
3855
- * @method paint
3856
- * @param {boolean} v 是否需要重绘
3857
- */
3858
-
3859
- }, {
3860
- key: "paint",
3861
- value: function paint(v) {
3862
- if (this.visible !== false) {
3863
- _get(_getPrototypeOf(jmLayer.prototype), "paint", this).call(this, v);
3864
- }
3865
- }
3866
- /**
3867
- * 检查点是否在图层内
3868
- * 锁定的图层不会响应鼠标事件
3869
- *
3870
- * @method checkPoint
3871
- * @param {object} p 坐标点 {x, y}
3872
- * @param {number} [pad] padding,额外的检测范围
3873
- * @return {boolean} 是否在图层内
3874
- */
3875
-
3876
- }, {
3877
- key: "checkPoint",
3878
- value: function checkPoint(p, pad) {
3879
- // 锁定的图层不响应交互
3880
- if (this.locked) return false;
3881
- return _get(_getPrototypeOf(jmLayer.prototype), "checkPoint", this).call(this, p, pad);
3882
- }
3883
- /**
3884
- * 清空图层
3885
- * 移除图层中的所有图形对象
3886
- *
3887
- * @method clear
3888
- */
3889
-
3890
- }, {
3891
- key: "clear",
3892
- value: function clear() {
3893
- this.children.clear();
3894
- this.needUpdate = true;
3895
- }
3896
- /**
3897
- * 获取图层中的图形数量
3898
- *
3899
- * @method getShapeCount
3900
- * @return {number} 图形数量
3901
- */
3902
-
3903
- }, {
3904
- key: "getShapeCount",
3905
- value: function getShapeCount() {
3906
- return this.children.length;
3907
- }
3908
- /**
3909
- * 获取图层信息
3910
- * 返回图层的基本信息,用于调试和日志
3911
- *
3912
- * @method getInfo
3913
- * @return {object} 图层信息对象
3914
- */
3915
-
3916
- }, {
3917
- key: "getInfo",
3918
- value: function getInfo() {
3919
- return {
3920
- name: this.name,
3921
- visible: this.visible,
3922
- locked: this.locked,
3923
- shapeCount: this.getShapeCount()
3924
- };
3925
- }
3926
- }]);
3927
-
3928
- return jmLayer;
3929
- }(_jmControl2.jmControl);
3930
-
3931
- exports.jmLayer = exports["default"] = jmLayer;
3932
-
3933
- },{"./jmControl.js":2}],7:[function(require,module,exports){
3862
+ },{"./jmControl.js":2,"./jmEvents.js":3,"./jmFilter.js":4,"./jmGradient.js":5,"./jmList.js":7,"./jmPath.js":9,"./jmProperty.js":10,"./jmShadow.js":11,"./jmUtils.js":12}],7:[function(require,module,exports){
3934
3863
  "use strict";
3935
3864
 
3936
3865
  Object.defineProperty(exports, "__esModule", {
@@ -4576,6 +4505,12 @@ exports.jmUtils = exports["default"] = void 0;
4576
4505
 
4577
4506
  var _jmList = require("./jmList.js");
4578
4507
 
4508
+ 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(_e) { throw _e; }, 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(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
4509
+
4510
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4511
+
4512
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
4513
+
4579
4514
  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); }
4580
4515
 
4581
4516
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
@@ -4759,68 +4694,89 @@ var jmUtils = /*#__PURE__*/function () {
4759
4694
  var deep = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
4760
4695
  var copyHandler = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
4761
4696
  var deepIndex = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
4697
+ var cloned = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : null;
4762
4698
 
4763
4699
  // 如果有指定回调,则用回调处理,否则走后面的复制逻辑
4764
4700
  if (typeof copyHandler === 'function') {
4765
4701
  var obj = copyHandler(source, deep, deepIndex);
4766
4702
  if (obj) return obj;
4767
- }
4703
+ } // 首次调用时初始化克隆映射表(用于处理循环引用)
4768
4704
 
4769
- deepIndex++; // 每执行一次,需要判断最大拷贝深度
4705
+
4706
+ if (!cloned) cloned = new WeakMap();
4770
4707
 
4771
4708
  if (typeof target === 'boolean') {
4772
4709
  deep = target;
4773
4710
  target = undefined;
4774
- } // 超过100拷贝深度,直接返回
4711
+ } // 非对象直接返回
4775
4712
 
4776
4713
 
4777
- if (deepIndex > 100) {
4778
- return target;
4779
- }
4714
+ if (!source || _typeof(source) !== 'object') {
4715
+ return typeof target !== 'undefined' ? target : source;
4716
+ } // 如果source已经被克隆过,直接返回之前的克隆对象,打破循环引用
4780
4717
 
4781
- if (source && _typeof(source) === 'object') {
4782
- target = target || {}; //如果为当前泛型,则直接new
4783
4718
 
4719
+ if (cloned.has(source)) return cloned.get(source); // 数组处理
4720
+
4721
+ if (Array.isArray(source)) {
4722
+ //如果为当前泛型,则直接new
4784
4723
  if (this.isType(source, _jmList.jmList)) {
4785
4724
  return new _jmList.jmList(source);
4786
- } else if (Array.isArray(source)) {
4787
- //如果是深度复,则拷贝每个对象
4788
- if (deep) {
4789
- var dest = [];
4725
+ }
4790
4726
 
4791
- for (var i = 0; i < source.length; i++) {
4792
- dest.push(this.clone(source[i], target[i], deep, copyHandler, deepIndex));
4793
- }
4727
+ if (deep) {
4728
+ var dest = [];
4729
+ cloned.set(source, dest);
4794
4730
 
4795
- return dest;
4731
+ for (var i = 0; i < source.length; i++) {
4732
+ dest.push(this.clone(source[i], undefined, deep, copyHandler, deepIndex + 1, cloned));
4796
4733
  }
4797
4734
 
4798
- return source.slice(0);
4735
+ return dest;
4799
4736
  }
4800
4737
 
4801
- if (source.__proto__) target.__proto__ = source.__proto__;
4738
+ return source.slice(0);
4739
+ } // 不复制页面元素和class对象(如jmControl实例等复杂对象保持引用)
4740
+
4802
4741
 
4803
- for (var k in source) {
4742
+ if (source.tagName || source.getContext || source.emit) {
4743
+ return source;
4744
+ } // 普通对象处理
4745
+
4746
+
4747
+ target = target || {};
4748
+ cloned.set(source, target); // 保持原型链一致
4749
+
4750
+ if (source.__proto__) target.__proto__ = source.__proto__; // 遍历自身可枚举属性(字符串键 + Symbol键),避免触发原型链上宿主对象的getter
4751
+
4752
+ var keys = Object.keys(source).concat(Object.getOwnPropertySymbols(source));
4753
+
4754
+ var _iterator = _createForOfIteratorHelper(keys),
4755
+ _step;
4756
+
4757
+ try {
4758
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
4759
+ var k = _step.value;
4804
4760
  if (k === 'constructor') continue;
4805
4761
  var v = source[k]; // 不复制页面元素和class对象
4806
4762
 
4807
- if (v && (v.tagName || v.getContext)) {
4763
+ if (v && (v.tagName || v.getContext || v.emit)) {
4808
4764
  target[k] = v;
4809
4765
  continue;
4810
4766
  } // 如果不是对象和空,则采用target的属性
4811
4767
 
4812
4768
 
4813
4769
  if (_typeof(target[k]) === 'object' || typeof target[k] === 'undefined') {
4814
- target[k] = this.clone(v, target[k], deep, copyHandler, deepIndex);
4770
+ target[k] = this.clone(v, target[k], deep, copyHandler, deepIndex + 1, cloned);
4815
4771
  }
4816
4772
  }
4817
-
4818
- return target;
4819
- } else if (typeof target != 'undefined') {
4820
- return target;
4773
+ } catch (err) {
4774
+ _iterator.e(err);
4775
+ } finally {
4776
+ _iterator.f();
4821
4777
  }
4822
4778
 
4823
- return source;
4779
+ return target;
4824
4780
  }
4825
4781
  /**
4826
4782
  * 绑定事件到html对象
@@ -6501,7 +6457,6 @@ var WeblBase = /*#__PURE__*/function () {
6501
6457
  }, {
6502
6458
  key: "createProgram",
6503
6459
  value: function createProgram(vertexSrc, fragmentSrc) {
6504
- this.context.lineWidth(1);
6505
6460
  return (0, _program.createProgram)(this.context, vertexSrc, fragmentSrc);
6506
6461
  } // 指定使用某个程序
6507
6462
 
@@ -6635,8 +6590,10 @@ var WeblBase = /*#__PURE__*/function () {
6635
6590
  }, {
6636
6591
  key: "earCutPointsToTriangles",
6637
6592
  value: function earCutPointsToTriangles(points) {
6638
- this.earCutCache = this.earCutCache || (this.earCutCache = {});
6639
- var key = JSON.stringify(points);
6593
+ this.earCutCache = this.earCutCache || (this.earCutCache = {}); // 快速缓存 key:用长度和首尾点坐标
6594
+
6595
+ var len = points.length;
6596
+ var key = len + '_' + points[0].x + '_' + points[0].y + '_' + points[len - 1].x + '_' + points[len - 1].y;
6640
6597
  if (this.earCutCache[key]) return this.earCutCache[key];
6641
6598
  var ps = this.earCutPoints(points); // 切割得到3角色顶点索引,
6642
6599
 
@@ -6754,34 +6711,13 @@ var WeblBase = /*#__PURE__*/function () {
6754
6711
  }
6755
6712
 
6756
6713
  this.textureContext.clearRect(0, 0, canvas.width, canvas.height);
6757
- this.textureContext.fillStyle = fillStyle;
6758
- this.textureContext.beginPath();
6714
+ this.textureContext.fillStyle = fillStyle; // 规则图形用 fillRect,比 beginPath/lineTo/fill 快
6759
6715
 
6760
6716
  if (!points || !points.length) {
6761
- points = [];
6762
- points.push({
6763
- x: bounds.left,
6764
- y: bounds.top
6765
- });
6766
- points.push({
6767
- x: bounds.left + bounds.width,
6768
- y: bounds.top
6769
- });
6770
- points.push({
6771
- x: bounds.left + bounds.width,
6772
- y: bounds.top + bounds.height
6773
- });
6774
- points.push({
6775
- x: bounds.left,
6776
- y: bounds.top + bounds.height
6777
- });
6778
- points.push({
6779
- x: bounds.left,
6780
- y: bounds.top
6781
- });
6782
- }
6717
+ this.textureContext.fillRect(0, 0, bounds.width, bounds.height);
6718
+ } else {
6719
+ this.textureContext.beginPath();
6783
6720
 
6784
- if (points && points.length) {
6785
6721
  var _iterator = _createForOfIteratorHelper(points),
6786
6722
  _step;
6787
6723
 
@@ -6801,16 +6737,11 @@ var WeblBase = /*#__PURE__*/function () {
6801
6737
  } finally {
6802
6738
  _iterator.f();
6803
6739
  }
6804
- } else {
6805
- this.textureContext.moveTo(0, 0);
6806
- this.textureContext.lineTo(bounds.width, 0);
6807
- this.textureContext.lineTo(bounds.width, bounds.height);
6808
- this.textureContext.lineTo(0, bounds.height);
6809
- this.textureContext.lineTo(0, 0);
6740
+
6741
+ this.textureContext.closePath();
6742
+ this.textureContext.fill();
6810
6743
  }
6811
6744
 
6812
- this.textureContext.closePath();
6813
- this.textureContext.fill();
6814
6745
  var data = this.textureContext.getImageData(0, 0, canvas.width, canvas.height);
6815
6746
  return {
6816
6747
  data: data,
@@ -7263,9 +7194,13 @@ var WebglGradient = /*#__PURE__*/function () {
7263
7194
  key: "toImageData",
7264
7195
  value: function toImageData(control, bounds) {
7265
7196
  var points = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
7197
+ // 缓存基于渐变参数(不含 bounds,因为同一个渐变只是位置不同时纹理相同)
7198
+ var gradientKey = this.toString();
7199
+
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
+ }
7266
7203
 
7267
- //const key = this.key || this.toString();
7268
- //if(WebglGradientTextureCache[key]) return WebglGradientTextureCache[key];
7269
7204
  if (!control.textureContext) {
7270
7205
  return null;
7271
7206
  }
@@ -7282,9 +7217,17 @@ var WebglGradient = /*#__PURE__*/function () {
7282
7217
  var c = control.graph.utils.toColor(s.color);
7283
7218
  gradient && gradient.addColorStop(s.offset, c);
7284
7219
  });
7285
- var data = control.toFillTexture(gradient, bounds, points); //WebglGradientTextureCache[key] = data;
7286
-
7220
+ var data = control.toFillTexture(gradient, bounds, points);
7221
+ this.__cachedData = data;
7222
+ this.__cacheKey = gradientKey;
7287
7223
  return data;
7224
+ } // 当渐变参数变化时使缓存失效
7225
+
7226
+ }, {
7227
+ key: "invalidateCache",
7228
+ value: function invalidateCache() {
7229
+ this.__cachedData = null;
7230
+ this.__cacheKey = null;
7288
7231
  } // 根据绘制图形的坐标计算出对应点的颜色
7289
7232
 
7290
7233
  /*
@@ -7408,7 +7351,15 @@ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symb
7408
7351
 
7409
7352
  function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
7410
7353
 
7411
- 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(_e) { throw _e; }, 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(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
7354
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
7355
+
7356
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
7357
+
7358
+ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
7359
+
7360
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7361
+
7362
+ 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; } } }; }
7412
7363
 
7413
7364
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
7414
7365
 
@@ -7454,12 +7405,66 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
7454
7405
  _this.isRegular = option.isRegular || false;
7455
7406
  _this.needCut = option.needCut || false;
7456
7407
  _this.control = option.control;
7457
- _this.points = [];
7408
+ _this.points = []; // 缓存 buffer 和纹理,避免每帧创建/销毁
7409
+
7410
+ _this.__cachedBuffers = [];
7411
+ _this.__cachedTexture = null;
7412
+ _this.__cachedTextureKey = null;
7458
7413
  return _this;
7459
- } // 应用变换到点
7414
+ } // 释放缓存的 WebGL 资源
7460
7415
 
7461
7416
 
7462
7417
  _createClass(WebglPath, [{
7418
+ key: "dispose",
7419
+ value: function dispose() {
7420
+ var _iterator = _createForOfIteratorHelper(this.__cachedBuffers),
7421
+ _step;
7422
+
7423
+ try {
7424
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
7425
+ var buf = _step.value;
7426
+ this.deleteBuffer(buf);
7427
+ }
7428
+ } catch (err) {
7429
+ _iterator.e(err);
7430
+ } finally {
7431
+ _iterator.f();
7432
+ }
7433
+
7434
+ this.__cachedBuffers = [];
7435
+
7436
+ if (this.__cachedTexture) {
7437
+ this.deleteTexture(this.__cachedTexture);
7438
+ this.__cachedTexture = null;
7439
+ this.__cachedTextureKey = null;
7440
+ }
7441
+ } // 获取或创建 buffer,优先复用缓存
7442
+
7443
+ }, {
7444
+ key: "getOrCreateBuffer",
7445
+ value: function getOrCreateBuffer(data, attr) {
7446
+ var buffer = this.__cachedBuffers.find(function (b) {
7447
+ return b.attr === attr;
7448
+ });
7449
+
7450
+ if (buffer) {
7451
+ var gl = this.context;
7452
+ var float32 = new Float32Array(data);
7453
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer.buffer);
7454
+ gl.bufferData(gl.ARRAY_BUFFER, float32, gl.DYNAMIC_DRAW);
7455
+ buffer.data = data;
7456
+ return buffer;
7457
+ }
7458
+
7459
+ buffer = this.createFloat32Buffer(data);
7460
+ buffer.attr = attr;
7461
+
7462
+ this.__cachedBuffers.push(buffer);
7463
+
7464
+ return buffer;
7465
+ } // 应用变换到点
7466
+
7467
+ }, {
7463
7468
  key: "applyTransform",
7464
7469
  value: function applyTransform(point) {
7465
7470
  return _get(_getPrototypeOf(WebglPath.prototype), "applyTransform", this).call(this, point);
@@ -7469,9 +7474,16 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
7469
7474
  value: function setParentBounds() {
7470
7475
  var parentBounds = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.parentAbsoluteBounds;
7471
7476
  //this.useProgram();
7472
- if (parentBounds) this.parentAbsoluteBounds = parentBounds; // 写入当前canvas大小
7477
+ if (parentBounds) this.parentAbsoluteBounds = parentBounds; // 缓存中心点值,只在变化时才更新 uniform
7478
+
7479
+ var cx = this.graph.width / 2;
7480
+ var cy = this.graph.height / 2;
7473
7481
 
7474
- this.context.uniform2f(this.program.uniforms.a_center_point.location, this.graph.width / 2, this.graph.height / 2);
7482
+ if (this.__lastCenterX !== cx || this.__lastCenterY !== cy) {
7483
+ this.context.uniform2f(this.program.uniforms.a_center_point.location, cx, cy);
7484
+ this.__lastCenterX = cx;
7485
+ this.__lastCenterY = cy;
7486
+ }
7475
7487
  }
7476
7488
  }, {
7477
7489
  key: "setFragColor",
@@ -7485,20 +7497,20 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
7485
7497
 
7486
7498
  var colorData = [];
7487
7499
 
7488
- var _iterator = _createForOfIteratorHelper(color),
7489
- _step;
7500
+ var _iterator2 = _createForOfIteratorHelper(color),
7501
+ _step2;
7490
7502
 
7491
7503
  try {
7492
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
7493
- var c = _step.value;
7504
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
7505
+ var c = _step2.value;
7494
7506
  c = this.convertColor(c);
7495
7507
  if (typeof c.a === 'undefined') c.a = 1;
7496
7508
  colorData.push(c.r, c.g, c.b, c.a * this.style.globalAlpha);
7497
7509
  }
7498
7510
  } catch (err) {
7499
- _iterator.e(err);
7511
+ _iterator2.e(err);
7500
7512
  } finally {
7501
- _iterator.f();
7513
+ _iterator2.f();
7502
7514
  }
7503
7515
 
7504
7516
  var colorBuffer = this.createFloat32Buffer(colorData);
@@ -7524,7 +7536,7 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
7524
7536
  key: "endDraw",
7525
7537
  value: function endDraw() {
7526
7538
  if (this.points) delete this.points;
7527
- if (this.pathPoints) delete this.pathPoints;
7539
+ if (this.pathPoints) delete this.pathPoints; // 缓存的纹理保留到下次绘制(渐变可能不变)
7528
7540
  } // 图形封闭
7529
7541
 
7530
7542
  }, {
@@ -7535,7 +7547,7 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
7535
7547
  var end = this.points[this.points.length - 1];
7536
7548
  if (start != end && !(start.x === end.x && start.y === end.y)) this.points.push(start);
7537
7549
  }
7538
- } // 绘制点数组
7550
+ } // 绘制点数组(使用 DYNAMIC_DRAW 复用 buffer,避免每帧 create/delete)
7539
7551
 
7540
7552
  }, {
7541
7553
  key: "writePoints",
@@ -7543,25 +7555,64 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
7543
7555
  var attr = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.program.attrs.a_position;
7544
7556
  var fixedPoints = [];
7545
7557
 
7546
- var _iterator2 = _createForOfIteratorHelper(points),
7547
- _step2;
7558
+ var _this$transformMatrix = _slicedToArray(this.transformMatrix, 6),
7559
+ a = _this$transformMatrix[0],
7560
+ b = _this$transformMatrix[1],
7561
+ c = _this$transformMatrix[2],
7562
+ d = _this$transformMatrix[3],
7563
+ tx = _this$transformMatrix[4],
7564
+ ty = _this$transformMatrix[5];
7548
7565
 
7549
- try {
7550
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
7551
- var p = _step2.value;
7552
- // 应用变换矩阵
7553
- var transformedPoint = this.applyTransform(p);
7554
- fixedPoints.push(transformedPoint.x + this.parentAbsoluteBounds.left, transformedPoint.y + this.parentAbsoluteBounds.top);
7566
+ var isIdentity = a === 1 && b === 0 && c === 0 && d === 1 && tx === 0 && ty === 0;
7567
+ var offsetLeft = this.parentAbsoluteBounds.left;
7568
+ var offsetTop = this.parentAbsoluteBounds.top;
7569
+
7570
+ if (isIdentity) {
7571
+ // 单位矩阵时直接加偏移,避免逐点调用 applyTransform
7572
+ for (var i = 0; i < points.length; i++) {
7573
+ fixedPoints.push(points[i].x + offsetLeft, points[i].y + offsetTop);
7574
+ }
7575
+ } else {
7576
+ var _iterator3 = _createForOfIteratorHelper(points),
7577
+ _step3;
7578
+
7579
+ try {
7580
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
7581
+ var p = _step3.value;
7582
+ var transformedPoint = this.applyTransform(p);
7583
+ fixedPoints.push(transformedPoint.x + offsetLeft, transformedPoint.y + offsetTop);
7584
+ }
7585
+ } catch (err) {
7586
+ _iterator3.e(err);
7587
+ } finally {
7588
+ _iterator3.f();
7589
+ }
7590
+ }
7591
+
7592
+ var float32 = new Float32Array(fixedPoints);
7593
+ var gl = this.context; // 复用已有 buffer 或创建新的
7594
+
7595
+ if (this.__cachedBuffers.length > 0) {
7596
+ // 找一个同 attr 的 buffer 复用
7597
+ var buffer = this.__cachedBuffers.find(function (b) {
7598
+ return b.attr === attr;
7599
+ });
7600
+
7601
+ if (buffer) {
7602
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer.buffer);
7603
+ gl.bufferData(gl.ARRAY_BUFFER, float32, gl.DYNAMIC_DRAW);
7604
+ buffer.data = fixedPoints;
7605
+ this.writeVertexAttrib(buffer, attr, 2, 0, 0);
7606
+ return buffer;
7555
7607
  }
7556
- } catch (err) {
7557
- _iterator2.e(err);
7558
- } finally {
7559
- _iterator2.f();
7560
7608
  }
7561
7609
 
7562
- var vertexBuffer = this.createFloat32Buffer(fixedPoints);
7610
+ var vertexBuffer = this.createFloat32Buffer(float32, gl.ARRAY_BUFFER, gl.DYNAMIC_DRAW);
7563
7611
  this.writeVertexAttrib(vertexBuffer, attr, 2, 0, 0);
7564
7612
  vertexBuffer.attr = attr;
7613
+
7614
+ this.__cachedBuffers.push(vertexBuffer);
7615
+
7565
7616
  return vertexBuffer;
7566
7617
  } // 连接二个点
7567
7618
 
@@ -7874,27 +7925,29 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
7874
7925
  }, {
7875
7926
  key: "getTriangles",
7876
7927
  value: function getTriangles(points) {
7877
- this.trianglesCache = this.trianglesCache || (this.trianglesCache = {});
7878
- var key = JSON.stringify(points);
7928
+ this.trianglesCache = this.trianglesCache || (this.trianglesCache = {}); // 快速缓存 key:用长度和首尾点坐标(比 JSON.stringify 快几个数量级)
7929
+
7930
+ var len = points.length;
7931
+ var key = len + '_' + points[0].x + '_' + points[0].y + '_' + points[len - 1].x + '_' + points[len - 1].y;
7879
7932
  if (this.trianglesCache[key]) return this.trianglesCache[key];
7880
7933
  var res = [];
7881
7934
  var polygons = this.getPolygon(points);
7882
7935
 
7883
7936
  if (polygons.length) {
7884
- var _iterator3 = _createForOfIteratorHelper(polygons),
7885
- _step3;
7937
+ var _iterator4 = _createForOfIteratorHelper(polygons),
7938
+ _step4;
7886
7939
 
7887
7940
  try {
7888
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
7889
- var polygon = _step3.value;
7941
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
7942
+ var polygon = _step4.value;
7890
7943
  // 需要分割三角形,不然填充会有问题
7891
7944
  var triangles = this.earCutPointsToTriangles(polygon);
7892
7945
  res.push.apply(res, _toConsumableArray(triangles));
7893
7946
  }
7894
7947
  } catch (err) {
7895
- _iterator3.e(err);
7948
+ _iterator4.e(err);
7896
7949
  } finally {
7897
- _iterator3.f();
7950
+ _iterator4.f();
7898
7951
  }
7899
7952
  }
7900
7953
 
@@ -7931,12 +7984,10 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
7931
7984
  var regular = lineWidth <= 1.2;
7932
7985
  points = regular ? points : this.pathToPoints(points);
7933
7986
  var buffer = this.writePoints(points);
7934
- this.context.drawArrays(regular ? this.context.LINE_LOOP : this.context.POINTS, 0, points.length);
7935
- this.deleteBuffer(buffer);
7987
+ this.context.drawArrays(regular ? this.context.LINE_LOOP : this.context.POINTS, 0, points.length); // buffer 由 endDraw 统一清理
7936
7988
  }
7937
7989
 
7938
- colorBuffer && this.deleteBuffer(colorBuffer);
7939
- colorBuffer && this.disableVertexAttribArray(colorBuffer.attr);
7990
+ colorBuffer && this.disableVertexAttribArray(colorBuffer && colorBuffer.attr);
7940
7991
  } // 填充图形
7941
7992
 
7942
7993
  }, {
@@ -7976,8 +8027,7 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
7976
8027
  this.context.uniform1i(this.program.uniforms.a_type.location, type);
7977
8028
  var colorBuffer = this.setFragColor(color);
7978
8029
  this.fillPolygons(points);
7979
- colorBuffer && this.deleteBuffer(colorBuffer);
7980
- colorBuffer && this.disableVertexAttribArray(colorBuffer.attr);
8030
+ colorBuffer && this.disableVertexAttribArray(colorBuffer && colorBuffer.attr);
7981
8031
  } // 区域填充图片
7982
8032
  // points绘制的图形顶点
7983
8033
  // 图片整体绘制区域
@@ -7985,16 +8035,39 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
7985
8035
  }, {
7986
8036
  key: "fillImage",
7987
8037
  value: function fillImage(img, points, bounds) {
7988
- if (!img) return; // 设置纹理
8038
+ if (!img) return; // 对于 ImageData,生成缓存 key(基于渐变参数或 bounds),复用纹理
8039
+
8040
+ var texture = null;
8041
+
8042
+ if (img instanceof ImageData) {
8043
+ var key = "".concat(img.width, "_").concat(img.height, "_").concat(bounds.width, "_").concat(bounds.height, "_").concat(bounds.left, "_").concat(bounds.top);
8044
+
8045
+ if (this.__cachedTexture && this.__cachedTextureKey === key) {
8046
+ texture = this.__cachedTexture;
8047
+ } else {
8048
+ texture = this.createDataTexture(img); // 释放旧纹理
8049
+
8050
+ if (this.__cachedTexture) {
8051
+ this.deleteTexture(this.__cachedTexture);
8052
+ }
8053
+
8054
+ this.__cachedTexture = texture;
8055
+ this.__cachedTextureKey = key;
8056
+ }
8057
+ } else {
8058
+ texture = this.createImgTexture(img);
8059
+ }
7989
8060
 
7990
- var texture = img instanceof ImageData ? this.createDataTexture(img) : this.createImgTexture(img);
7991
8061
  this.context.uniform1i(this.program.uniforms.u_sample.location, 0); // 纹理单元传递给着色器
7992
8062
  // 指定纹理区域尺寸
7993
8063
 
7994
8064
  this.context.uniform4f(this.program.uniforms.v_texture_bounds.location, bounds.left + this.parentAbsoluteBounds.left, bounds.top + this.parentAbsoluteBounds.top, bounds.width, bounds.height); // 纹理单元传递给着色器
7995
8065
 
7996
- this.fillTexture(points);
7997
- this.deleteTexture(texture);
8066
+ this.fillTexture(points); // 仅对非缓存纹理(非 ImageData)立即删除
8067
+
8068
+ if (!(img instanceof ImageData)) {
8069
+ this.deleteTexture(texture);
8070
+ }
7998
8071
  }
7999
8072
  }, {
8000
8073
  key: "fillTexture",
@@ -8013,34 +8086,104 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
8013
8086
  }, {
8014
8087
  key: "fillPolygons",
8015
8088
  value: function fillPolygons(points) {
8089
+ var _this2 = this;
8090
+
8016
8091
  var isTexture = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
8017
8092
 
8018
- if (points.length > 3) {
8019
- var triangles = this.needCut ? this.earCutPointsToTriangles(points) : this.getTriangles(points);
8093
+ if (points.length <= 3) {
8094
+ // 3个点以下的三角形直接画
8095
+ var buffer = this.writePoints(points);
8096
+ var coordBuffer = isTexture ? this.writePoints(points, this.program.attrs.a_text_coord) : null;
8097
+ this.context.drawArrays(this.context.TRIANGLE_FAN, 0, points.length);
8098
+ return;
8099
+ } // 规则图形(凸多边形,如圆):直接用 TRIANGLE_FAN 一次性绘制,无需 earcut
8100
+
8020
8101
 
8021
- if (triangles.length) {
8022
- var _iterator4 = _createForOfIteratorHelper(triangles),
8023
- _step4;
8102
+ if (this.isRegular) {
8103
+ var _buffer = this.writePoints(points);
8104
+
8105
+ var _coordBuffer = isTexture ? this.writePoints(points, this.program.attrs.a_text_coord) : null;
8106
+
8107
+ this.context.drawArrays(this.context.TRIANGLE_FAN, 0, points.length);
8108
+ return;
8109
+ } // 不规则图形:需要 earcut 三角化后,合并为一个大的顶点缓冲区,单次 drawArrays
8110
+
8111
+
8112
+ var triangles = this.needCut ? this.earCutPointsToTriangles(points) : this.getTriangles(points);
8113
+ if (!triangles.length) return; // 合并所有三角形的顶点到一个数组
8114
+
8115
+ var allVertices = [];
8116
+ var allTexCoords = [];
8117
+
8118
+ var _iterator5 = _createForOfIteratorHelper(triangles),
8119
+ _step5;
8120
+
8121
+ try {
8122
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
8123
+ var triangle = _step5.value;
8124
+
8125
+ var _iterator6 = _createForOfIteratorHelper(triangle),
8126
+ _step6;
8024
8127
 
8025
8128
  try {
8026
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
8027
- var triangle = _step4.value;
8028
- this.fillPolygons(triangle, isTexture); // 这里就变成了规则的图形了
8129
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
8130
+ var p = _step6.value;
8131
+ allVertices.push(p.x, p.y);
8132
+ if (isTexture) allTexCoords.push(p.x, p.y);
8029
8133
  }
8030
8134
  } catch (err) {
8031
- _iterator4.e(err);
8135
+ _iterator6.e(err);
8032
8136
  } finally {
8033
- _iterator4.f();
8137
+ _iterator6.f();
8034
8138
  }
8035
- }
8139
+ } // 一次性上传所有数据并绘制
8140
+
8141
+ } catch (err) {
8142
+ _iterator5.e(err);
8143
+ } finally {
8144
+ _iterator5.f();
8145
+ }
8146
+
8147
+ var vertexData = new Float32Array(allVertices);
8148
+ var gl = this.context; // 复用或创建 position buffer
8149
+
8150
+ var posBuffer = this.__cachedBuffers.find(function (b) {
8151
+ return b.attr === _this2.program.attrs.a_position;
8152
+ });
8153
+
8154
+ if (!posBuffer) {
8155
+ posBuffer = this.createFloat32Buffer(vertexData, gl.ARRAY_BUFFER, gl.DYNAMIC_DRAW);
8156
+ posBuffer.attr = this.program.attrs.a_position;
8157
+
8158
+ this.__cachedBuffers.push(posBuffer);
8036
8159
  } else {
8037
- var buffer = this.writePoints(points); // 纹理坐标
8160
+ gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer.buffer);
8161
+ gl.bufferData(gl.ARRAY_BUFFER, vertexData, gl.DYNAMIC_DRAW);
8162
+ }
8038
8163
 
8039
- var coordBuffer = isTexture ? this.writePoints(points, this.program.attrs.a_text_coord) : null;
8040
- this.context.drawArrays(this.context.TRIANGLE_FAN, 0, points.length);
8041
- this.deleteBuffer(buffer);
8042
- coordBuffer && this.deleteBuffer(coordBuffer);
8164
+ this.writeVertexAttrib(posBuffer, this.program.attrs.a_position, 2, 0, 0);
8165
+
8166
+ if (isTexture && allTexCoords.length) {
8167
+ var texData = new Float32Array(allTexCoords);
8168
+
8169
+ var texBuffer = this.__cachedBuffers.find(function (b) {
8170
+ return b.attr === _this2.program.attrs.a_text_coord;
8171
+ });
8172
+
8173
+ if (!texBuffer) {
8174
+ texBuffer = this.createFloat32Buffer(texData, gl.ARRAY_BUFFER, gl.DYNAMIC_DRAW);
8175
+ texBuffer.attr = this.program.attrs.a_text_coord;
8176
+
8177
+ this.__cachedBuffers.push(texBuffer);
8178
+ } else {
8179
+ gl.bindBuffer(gl.ARRAY_BUFFER, texBuffer.buffer);
8180
+ gl.bufferData(gl.ARRAY_BUFFER, texData, gl.DYNAMIC_DRAW);
8181
+ }
8182
+
8183
+ this.writeVertexAttrib(texBuffer, this.program.attrs.a_text_coord, 2, 0, 0);
8043
8184
  }
8185
+
8186
+ gl.drawArrays(gl.TRIANGLES, 0, allVertices.length / 2);
8044
8187
  } // 填充图形
8045
8188
 
8046
8189
  }, {
@@ -8285,7 +8428,6 @@ var jmArc = /*#__PURE__*/function (_jmPath) {
8285
8428
  var end = this.endAngle;
8286
8429
  if (mw == 0 && mh == 0 || start == end) return;
8287
8430
  var anticlockwise = this.anticlockwise;
8288
- this.points = [];
8289
8431
  var step = 1 / Math.max(mw, mh); //如果是逆时针绘制,则角度为负数,并且结束角为2Math.PI-end
8290
8432
 
8291
8433
  if (anticlockwise) {
@@ -8294,17 +8436,36 @@ var jmArc = /*#__PURE__*/function (_jmPath) {
8294
8436
  end = p2 - end;
8295
8437
  }
8296
8438
 
8297
- if (start > end) step = -step;
8298
- if (this.isFan) this.points.push(location.center); // 如果是扇形,则从中心开始画
8299
- //椭圆方程x=a*cos(r) ,y=b*sin(r)
8439
+ if (start > end) step = -step; // 预计算需要的点数量
8440
+
8441
+ var pointCount = Math.ceil(Math.abs(end - start) / Math.abs(step)) + 1;
8442
+ if (this.isFan) pointCount++; // 复用已有数组,避免每帧分配;大小变化时才重建
8443
+
8444
+ if (!this.points || this.points.length !== pointCount) {
8445
+ this.points = new Array(pointCount);
8446
+
8447
+ for (var i = 0; i < pointCount; i++) {
8448
+ this.points[i] = {
8449
+ x: 0,
8450
+ y: 0
8451
+ };
8452
+ }
8453
+ }
8454
+
8455
+ var idx = 0;
8456
+
8457
+ if (this.isFan) {
8458
+ this.points[idx].x = location.center.x;
8459
+ this.points[idx].y = location.center.y;
8460
+ idx++;
8461
+ } //椭圆方程x=a*cos(r) ,y=b*sin(r)
8462
+
8300
8463
 
8301
8464
  for (var r = start;; r += step) {
8302
8465
  if (step > 0 && r > end) r = end;else if (step < 0 && r < end) r = end;
8303
- var p = {
8304
- x: Math.cos(r) * mw + cx,
8305
- y: Math.sin(r) * mh + cy
8306
- };
8307
- this.points.push(p);
8466
+ this.points[idx].x = Math.cos(r) * mw + cx;
8467
+ this.points[idx].y = Math.sin(r) * mh + cy;
8468
+ idx++;
8308
8469
  if (r == end) break;
8309
8470
  }
8310
8471
 
@@ -9561,12 +9722,6 @@ exports.jmLabel = exports["default"] = void 0;
9561
9722
 
9562
9723
  var _jmControl2 = require("../core/jmControl.js");
9563
9724
 
9564
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
9565
-
9566
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
9567
-
9568
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
9569
-
9570
9725
  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(_e) { throw _e; }, 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(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
9571
9726
 
9572
9727
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
@@ -9626,7 +9781,7 @@ var jmLabel = /*#__PURE__*/function (_jmControl) {
9626
9781
  _this.style.textAlign = _this.style.textAlign || 'left'; //文字垂直对齐
9627
9782
 
9628
9783
  _this.style.textBaseline = _this.style.textBaseline || 'middle';
9629
- _this.text = params.text || '';
9784
+ _this.text = params.text || params.value || '';
9630
9785
  _this.center = params.center || null;
9631
9786
  return _this;
9632
9787
  }
@@ -9959,68 +10114,6 @@ var jmLabel = /*#__PURE__*/function (_jmControl) {
9959
10114
  this.context.strokeText(txt, x, y);
9960
10115
  }
9961
10116
  }
9962
- } //如果有指定边框,则画出边框
9963
-
9964
-
9965
- if (this.style.border) {
9966
- //如果指定了边框样式
9967
- if (this.style.border.style) {
9968
- this.context.save && this.context.save();
9969
- this.setStyle(this.style.border.style);
9970
- }
9971
-
9972
- if (this.mode === '2d') {
9973
- this.context.moveTo(this.points[0].x + bounds.left, this.points[0].y + bounds.top);
9974
-
9975
- if (this.style.border.top) {
9976
- this.context.lineTo(this.points[1].x + bounds.left, this.points[1].y + bounds.top);
9977
- }
9978
-
9979
- if (this.style.border.right) {
9980
- this.context.moveTo(this.points[1].x + bounds.left, this.points[1].y + bounds.top);
9981
- this.context.lineTo(this.points[2].x + bounds.left, this.points[2].y + bounds.top);
9982
- }
9983
-
9984
- if (this.style.border.bottom) {
9985
- this.context.moveTo(this.points[2].x + bounds.left, this.points[2].y + bounds.top);
9986
- this.context.lineTo(this.points[3].x + bounds.left, this.points[3].y + bounds.top);
9987
- }
9988
-
9989
- if (this.style.border.left) {
9990
- this.context.moveTo(this.points[3].x + bounds.left, this.points[3].y + bounds.top);
9991
- this.context.lineTo(this.points[0].x + bounds.left, this.points[0].y + bounds.top);
9992
- }
9993
- } else {
9994
- var points = [];
9995
-
9996
- if (this.style.border.top) {
9997
- points.push(this.points[0]);
9998
- points.push(this.points[1]);
9999
- }
10000
-
10001
- if (this.style.border.right) {
10002
- points.push(_objectSpread(_objectSpread({}, this.points[1]), {}, {
10003
- m: true
10004
- }));
10005
- points.push(this.points[2]);
10006
- }
10007
-
10008
- if (this.style.border.bottom) {
10009
- points.push(_objectSpread(_objectSpread({}, this.points[2]), {}, {
10010
- m: true
10011
- }));
10012
- points.push(this.points[3]);
10013
- }
10014
-
10015
- if (this.style.border.left) {
10016
- points.push(_objectSpread(_objectSpread({}, this.points[3]), {}, {
10017
- m: true
10018
- }));
10019
- points.push(this.points[0]);
10020
- }
10021
-
10022
- points.length && this.webglControl && this.webglControl.stroke(points);
10023
- }
10024
10117
  }
10025
10118
  }
10026
10119
  }, {
@@ -10511,8 +10604,6 @@ exports.jmPrismatic = exports["default"] = jmPrismatic;
10511
10604
  },{"../core/jmPath.js":9}],35:[function(require,module,exports){
10512
10605
  "use strict";
10513
10606
 
10514
- 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); }
10515
-
10516
10607
  Object.defineProperty(exports, "__esModule", {
10517
10608
  value: true
10518
10609
  });
@@ -10524,6 +10615,8 @@ var _jmArc = require("./jmArc.js");
10524
10615
 
10525
10616
  var _jmLine = require("./jmLine.js");
10526
10617
 
10618
+ 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); }
10619
+
10527
10620
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
10528
10621
 
10529
10622
  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); } }
@@ -10550,6 +10643,7 @@ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.g
10550
10643
  * @class jmRect
10551
10644
  * @extends jmPath
10552
10645
  * @param {object} params 参数 position=矩形左上角顶点坐标,width=宽,height=高,radius=边角弧度
10646
+ * radius支持数字(四角相同)或对象 { topLeft, topRight, bottomRight, bottomLeft }
10553
10647
  */
10554
10648
  var jmRect = /*#__PURE__*/function (_jmPath) {
10555
10649
  _inherits(jmRect, _jmPath);
@@ -10568,13 +10662,26 @@ var jmRect = /*#__PURE__*/function (_jmPath) {
10568
10662
 
10569
10663
  _this = _super.call(this, params, t);
10570
10664
  _this.style.close = true;
10571
- _this.radius = params.radius || _this.style.radius || 0;
10665
+ var r = params.radius || _this.style.radius || _this.style.borderRadius || 0;
10666
+
10667
+ if (_typeof(r) === 'object' && r !== null) {
10668
+ // 四角独立圆角
10669
+ _this.radius = {
10670
+ topLeft: Number(r.topLeft) || 0,
10671
+ topRight: Number(r.topRight) || 0,
10672
+ bottomRight: Number(r.bottomRight) || 0,
10673
+ bottomLeft: Number(r.bottomLeft) || 0
10674
+ };
10675
+ } else {
10676
+ _this.radius = r;
10677
+ }
10678
+
10572
10679
  return _this;
10573
10680
  }
10574
10681
  /**
10575
- * 圆角半径
10682
+ * 圆角半径,支持数字或四角独立对象
10576
10683
  * @property radius
10577
- * @type {number}
10684
+ * @type {number|object}
10578
10685
  */
10579
10686
 
10580
10687
 
@@ -10587,6 +10694,53 @@ var jmRect = /*#__PURE__*/function (_jmPath) {
10587
10694
  this.needUpdate = true;
10588
10695
  return this.property('radius', v);
10589
10696
  }
10697
+ /**
10698
+ * 获取规范化的圆角值(四角独立)
10699
+ * @returns {object} { topLeft, topRight, bottomRight, bottomLeft }
10700
+ */
10701
+
10702
+ }, {
10703
+ key: "getNormalizedRadius",
10704
+ value: function getNormalizedRadius() {
10705
+ var r = this.radius;
10706
+
10707
+ if (typeof r === 'number') {
10708
+ var v = Math.max(0, r);
10709
+ return {
10710
+ topLeft: v,
10711
+ topRight: v,
10712
+ bottomRight: v,
10713
+ bottomLeft: v
10714
+ };
10715
+ }
10716
+
10717
+ if (_typeof(r) === 'object' && r !== null) {
10718
+ return {
10719
+ topLeft: Math.max(0, Number(r.topLeft) || 0),
10720
+ topRight: Math.max(0, Number(r.topRight) || 0),
10721
+ bottomRight: Math.max(0, Number(r.bottomRight) || 0),
10722
+ bottomLeft: Math.max(0, Number(r.bottomLeft) || 0)
10723
+ };
10724
+ }
10725
+
10726
+ return {
10727
+ topLeft: 0,
10728
+ topRight: 0,
10729
+ bottomRight: 0,
10730
+ bottomLeft: 0
10731
+ };
10732
+ }
10733
+ /**
10734
+ * 检查是否有圆角
10735
+ * @returns {boolean}
10736
+ */
10737
+
10738
+ }, {
10739
+ key: "hasRadius",
10740
+ value: function hasRadius() {
10741
+ var nr = this.getNormalizedRadius();
10742
+ return nr.topLeft > 0 || nr.topRight > 0 || nr.bottomRight > 0 || nr.bottomLeft > 0;
10743
+ }
10590
10744
  /**
10591
10745
  * 当前位置左上角
10592
10746
  * @property position
@@ -10649,7 +10803,7 @@ var jmRect = /*#__PURE__*/function (_jmPath) {
10649
10803
 
10650
10804
  /**
10651
10805
  * 初始化图形点
10652
- * 如果有边角弧度则类型圆绝计算其描点
10806
+ * 支持四角独立圆角,借助圆弧对象计算描点
10653
10807
  *
10654
10808
  * @method initPoints
10655
10809
  * @private
@@ -10680,55 +10834,93 @@ var jmRect = /*#__PURE__*/function (_jmPath) {
10680
10834
  this.dottedLine = this.graph.createShape(_jmLine.jmLine, {
10681
10835
  style: this.style
10682
10836
  });
10683
- } //如果有边界弧度则借助圆弧对象计算描点
10837
+ }
10684
10838
 
10839
+ var nr = this.getNormalizedRadius();
10840
+ var hasRadius = this.hasRadius(); // 如果有圆角(支持四角独立),借助圆弧对象计算描点
10841
+
10842
+ if (hasRadius) {
10843
+ var q = Math.PI / 2; // 限制圆角不超过短边的一半
10844
+
10845
+ var maxR = Math.min(location.width / 2, location.height / 2);
10846
+ var rtl = Math.min(nr.topLeft, maxR);
10847
+ var rtr = Math.min(nr.topRight, maxR);
10848
+ var rbr = Math.min(nr.bottomRight, maxR);
10849
+ var rbl = Math.min(nr.bottomLeft, maxR); // 左上角圆弧
10850
+
10851
+ if (rtl > 0) {
10852
+ var arc = this.graph.createShape(_jmArc.jmArc, {
10853
+ radius: rtl,
10854
+ anticlockwise: false
10855
+ });
10856
+ arc.center = {
10857
+ x: location.left + rtl,
10858
+ y: location.top + rtl
10859
+ };
10860
+ arc.startAngle = Math.PI;
10861
+ arc.endAngle = Math.PI + q;
10862
+ var ps1 = arc.initPoints();
10863
+ } else {
10864
+ var ps1 = [p1];
10865
+ } // 右上角圆弧
10866
+
10867
+
10868
+ if (rtr > 0) {
10869
+ var _arc = this.graph.createShape(_jmArc.jmArc, {
10870
+ radius: rtr,
10871
+ anticlockwise: false
10872
+ });
10873
+
10874
+ _arc.center = {
10875
+ x: p2.x - rtr,
10876
+ y: p2.y + rtr
10877
+ };
10878
+ _arc.startAngle = Math.PI + q;
10879
+ _arc.endAngle = Math.PI * 2;
10880
+
10881
+ var ps2 = _arc.initPoints();
10882
+ } else {
10883
+ var ps2 = [p2];
10884
+ } // 右下角圆弧
10885
+
10886
+
10887
+ if (rbr > 0) {
10888
+ var _arc2 = this.graph.createShape(_jmArc.jmArc, {
10889
+ radius: rbr,
10890
+ anticlockwise: false
10891
+ });
10892
+
10893
+ _arc2.center = {
10894
+ x: p3.x - rbr,
10895
+ y: p3.y - rbr
10896
+ };
10897
+ _arc2.startAngle = 0;
10898
+ _arc2.endAngle = q;
10899
+
10900
+ var ps3 = _arc2.initPoints();
10901
+ } else {
10902
+ var ps3 = [p3];
10903
+ } // 左下角圆弧
10904
+
10905
+
10906
+ if (rbl > 0) {
10907
+ var _arc3 = this.graph.createShape(_jmArc.jmArc, {
10908
+ radius: rbl,
10909
+ anticlockwise: false
10910
+ });
10911
+
10912
+ _arc3.center = {
10913
+ x: p4.x + rbl,
10914
+ y: p4.y - rbl
10915
+ };
10916
+ _arc3.startAngle = q;
10917
+ _arc3.endAngle = Math.PI;
10918
+
10919
+ var ps4 = _arc3.initPoints();
10920
+ } else {
10921
+ var ps4 = [p4];
10922
+ }
10685
10923
 
10686
- if (location.radius && location.radius < location.width / 2 && location.radius < location.height / 2) {
10687
- var q = Math.PI / 2;
10688
- var arc = this.graph.createShape(_jmArc.jmArc, {
10689
- radius: location.radius,
10690
- anticlockwise: false
10691
- });
10692
- arc.center = {
10693
- x: location.left + location.radius,
10694
- y: location.top + location.radius
10695
- };
10696
- arc.startAngle = Math.PI;
10697
- arc.endAngle = Math.PI + q;
10698
- var ps1 = arc.initPoints();
10699
- arc = this.graph.createShape(_jmArc.jmArc, {
10700
- radius: location.radius,
10701
- anticlockwise: false
10702
- });
10703
- arc.center = {
10704
- x: p2.x - location.radius,
10705
- y: p2.y + location.radius
10706
- };
10707
- arc.startAngle = Math.PI + q;
10708
- arc.endAngle = Math.PI * 2;
10709
- var ps2 = arc.initPoints();
10710
- arc = this.graph.createShape(_jmArc.jmArc, {
10711
- radius: location.radius,
10712
- anticlockwise: false
10713
- });
10714
- arc.center = {
10715
- x: p3.x - location.radius,
10716
- y: p3.y - location.radius
10717
- };
10718
- arc.startAngle = 0;
10719
- arc.endAngle = q;
10720
- var ps3 = arc.initPoints();
10721
- arc = this.graph.createShape(_jmArc.jmArc, {
10722
- radius: location.radius,
10723
- anticlockwise: false
10724
- });
10725
- arc.center = {
10726
- x: p4.x + location.radius,
10727
- y: p4.y - location.radius
10728
- };
10729
- arc.startAngle = q;
10730
- arc.endAngle = Math.PI;
10731
- var ps4 = arc.initPoints();
10732
10924
  this.points = ps1.concat(ps2, ps3, ps4);
10733
10925
  } else {
10734
10926
  this.points = [];