jmgraph 3.2.26 → 3.2.28

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.
Files changed (44) hide show
  1. package/README.md +188 -0
  2. package/dist/jmgraph.core.min.js +1 -1
  3. package/dist/jmgraph.core.min.js.map +1 -1
  4. package/dist/jmgraph.js +2713 -425
  5. package/dist/jmgraph.min.js +1 -1
  6. package/index.d.ts +142 -1
  7. package/package.json +1 -1
  8. package/src/core/jmControl.js +827 -127
  9. package/src/core/jmEvents.js +154 -0
  10. package/src/core/jmFilter.js +38 -1
  11. package/src/core/jmGradient.js +59 -8
  12. package/src/core/jmGraph.js +51 -7
  13. package/src/core/jmLayer.js +34 -2
  14. package/src/core/jmList.js +167 -0
  15. package/src/core/jmObject.js +128 -8
  16. package/src/core/jmPath.js +43 -5
  17. package/src/core/jmProperty.js +181 -2
  18. package/src/core/jmShadow.js +36 -7
  19. package/src/core/jmUtils.js +187 -14
  20. package/src/lib/webgl/base.js +211 -83
  21. package/src/lib/webgl/core/buffer.js +43 -12
  22. package/src/lib/webgl/core/mapSize.js +16 -7
  23. package/src/lib/webgl/core/mapType.js +41 -22
  24. package/src/lib/webgl/core/program.js +94 -54
  25. package/src/lib/webgl/core/shader.js +20 -8
  26. package/src/lib/webgl/core/texture.js +55 -32
  27. package/src/lib/webgl/gradient.js +49 -17
  28. package/src/lib/webgl/index.js +173 -24
  29. package/src/lib/webgl/path.js +61 -12
  30. package/src/shapes/jmArc.js +48 -2
  31. package/src/shapes/jmArrow.js +35 -2
  32. package/src/shapes/jmArrowLine.js +33 -2
  33. package/src/shapes/jmBezier.js +50 -4
  34. package/src/shapes/jmCircle.js +35 -2
  35. package/src/shapes/jmEllipse.js +29 -3
  36. package/src/shapes/jmHArc.js +39 -2
  37. package/src/shapes/jmImage.js +49 -3
  38. package/src/shapes/jmLabel.js +41 -2
  39. package/src/shapes/jmLine.js +42 -2
  40. package/src/shapes/jmPolygon.js +42 -3
  41. package/src/shapes/jmPrismatic.js +34 -2
  42. package/src/shapes/jmRect.js +45 -3
  43. package/src/shapes/jmResize.js +42 -4
  44. package/src/shapes/jmStar.js +38 -4
package/dist/jmgraph.js CHANGED
@@ -320,59 +320,192 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
320
320
 
321
321
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
322
322
 
323
+ /**
324
+ * 样式名称映射表
325
+ *
326
+ * 将简化的样式名称映射到 Canvas API 的标准属性名。
327
+ * 例如:'fill' -> 'fillStyle', 'stroke' -> 'strokeStyle'
328
+ *
329
+ * @constant {Object.<string, string>}
330
+ * @private
331
+ */
323
332
  var jmStyleMap = {
324
333
  'fill': 'fillStyle',
334
+ // 填充颜色
325
335
  'fillImage': 'fillImage',
336
+ // 填充图片
326
337
  'stroke': 'strokeStyle',
338
+ // 描边颜色
327
339
  'shadow.blur': 'shadowBlur',
340
+ // 阴影模糊度
328
341
  'shadow.x': 'shadowOffsetX',
342
+ // 阴影X偏移
329
343
  'shadow.y': 'shadowOffsetY',
344
+ // 阴影Y偏移
330
345
  'shadow.color': 'shadowColor',
346
+ // 阴影颜色
331
347
  'lineWidth': 'lineWidth',
348
+ // 线宽
332
349
  'miterLimit': 'miterLimit',
350
+ // 斜接限制
333
351
  'fillStyle': 'fillStyle',
352
+ // 填充样式
334
353
  'strokeStyle': 'strokeStyle',
354
+ // 描边样式
335
355
  'font': 'font',
356
+ // 字体
336
357
  'opacity': 'globalAlpha',
358
+ // 透明度
337
359
  'textAlign': 'textAlign',
360
+ // 文本对齐
338
361
  'textBaseline': 'textBaseline',
362
+ // 文本基线
339
363
  'shadowBlur': 'shadowBlur',
364
+ // 阴影模糊
340
365
  'shadowOffsetX': 'shadowOffsetX',
366
+ // 阴影X偏移
341
367
  'shadowOffsetY': 'shadowOffsetY',
368
+ // 阴影Y偏移
342
369
  'shadowColor': 'shadowColor',
370
+ // 阴影颜色
343
371
  'lineJoin': 'lineJoin',
372
+ // 线条连接样式
344
373
  'lineCap': 'lineCap',
374
+ // 线条端点样式
345
375
  'lineDashOffset': 'lineDashOffset',
346
- 'globalCompositeOperation': 'globalCompositeOperation'
376
+ // 虚线偏移
377
+ 'globalCompositeOperation': 'globalCompositeOperation' // 合成操作
378
+
347
379
  };
380
+ /**
381
+ * jmGraph 控件基类
382
+ *
383
+ * jmControl 是所有可视化图形控件的基类,提供了完整的图形渲染和交互能力。
384
+ *
385
+ * **核心功能:**
386
+ *
387
+ * 1. **样式系统**
388
+ * - 支持填充色、描边色、渐变、图片填充
389
+ * - 支持阴影、滤镜、混合模式
390
+ * - 支持虚线、线宽、线帽等线条样式
391
+ *
392
+ * 2. **变换系统**
393
+ * - 支持 translate(平移)
394
+ * - 支持 rotation(旋转)
395
+ * - 支持 transform(矩阵变换)
396
+ *
397
+ * 3. **事件系统**
398
+ * - 鼠标事件:mousedown, mouseup, mousemove, click, dblclick
399
+ * - 触摸事件:touchstart, touchmove, touchend
400
+ * - 焦点事件:mouseover, mouseleave, touchover, touchleave
401
+ * - 自定义事件:支持任意事件类型
402
+ *
403
+ * 4. **渲染系统**
404
+ * - 自动选择 Canvas 2D 或 WebGL 渲染器
405
+ * - 支持脏矩形优化
406
+ * - 支持层级排序(zIndex)
407
+ *
408
+ * 5. **碰撞检测**
409
+ * - 支持点在多边形内判断
410
+ * - 支持自定义命中区域
411
+ * - 支持旋转后的碰撞检测
412
+ *
413
+ * @class jmControl
414
+ * @extends jmProperty
415
+ *
416
+ * @example
417
+ * // 创建自定义控件
418
+ * class MyShape extends jmControl {
419
+ * constructor(params) {
420
+ * super(params, 'myShape');
421
+ * }
422
+ *
423
+ * // 重写绘制方法
424
+ * draw() {
425
+ * // 自定义绘制逻辑
426
+ * }
427
+ * }
428
+ *
429
+ * // 使用控件
430
+ * const shape = new MyShape({
431
+ * position: { x: 100, y: 100 },
432
+ * width: 50,
433
+ * height: 50,
434
+ * style: {
435
+ * fill: 'red',
436
+ * stroke: 'black',
437
+ * lineWidth: 2
438
+ * }
439
+ * });
440
+ * graph.children.add(shape);
441
+ */
348
442
 
349
443
  var jmControl = /*#__PURE__*/function (_jmProperty) {
350
444
  _inherits(jmControl, _jmProperty);
351
445
 
352
446
  var _super = _createSuper(jmControl);
353
447
 
448
+ /**
449
+ * 构造函数
450
+ *
451
+ * 创建一个新的控件实例。子类应该调用 super(params, 'typeName') 来设置类型名称。
452
+ *
453
+ * @constructor
454
+ * @param {Object} [params] - 控件初始化参数
455
+ * @param {Object} [params.style] - 样式对象,包含填充、描边等属性
456
+ * @param {number} [params.width=0] - 控件宽度
457
+ * @param {number} [params.height=0] - 控件高度
458
+ * @param {Object} [params.position] - 控件位置 {x, y}
459
+ * @param {jmGraph} [params.graph] - 所属画布实例
460
+ * @param {number} [params.zIndex=0] - 层级顺序
461
+ * @param {boolean} [params.interactive=false] - 是否响应交互事件
462
+ * @param {Object} [params.hitArea] - 自定义命中区域 {x, y, width, height}
463
+ * @param {boolean} [params.isRegular] - 是否为规则图形(WebGL优化)
464
+ * @param {boolean} [params.needCut] - 是否需要裁剪(WebGL)
465
+ * @param {string} [t] - 控件类型名称,默认使用类名
466
+ *
467
+ * @example
468
+ * // 创建矩形控件
469
+ * const rect = new jmControl({
470
+ * position: { x: 10, y: 10 },
471
+ * width: 100,
472
+ * height: 50,
473
+ * style: {
474
+ * fill: '#ff0000',
475
+ * stroke: '#000000',
476
+ * lineWidth: 2
477
+ * },
478
+ * interactive: true
479
+ * }, 'jmRect');
480
+ */
354
481
  function jmControl(params, t) {
355
482
  var _this2;
356
483
 
357
484
  _classCallCheck(this, jmControl);
358
485
 
359
486
  params = params || {};
360
- _this2 = _super.call(this, params);
487
+ _this2 = _super.call(this, params); // 设置控件类型标识
488
+
489
+ _this2.property('type', t || (this instanceof jmControl ? this.constructor : void 0).name); // 初始化样式对象
490
+
361
491
 
362
- _this2.property('type', t || (this instanceof jmControl ? this.constructor : void 0).name);
492
+ _this2.style = params && params.style ? params.style : {}; // 设置尺寸
363
493
 
364
- _this2.style = params && params.style ? params.style : {};
365
494
  _this2.width = params.width || 0;
366
- _this2.height = params.height || 0;
367
- _this2.hitArea = params.hitArea || null;
495
+ _this2.height = params.height || 0; // 自定义命中区域(用于点击测试)
496
+
497
+ _this2.hitArea = params.hitArea || null; // 设置位置
368
498
 
369
499
  if (params.position) {
370
500
  _this2.position = params.position;
371
- }
501
+ } // 关联画布
502
+
372
503
 
373
- _this2.graph = params.graph || null;
374
- _this2.zIndex = params.zIndex || 0;
375
- _this2.interactive = typeof params.interactive == 'undefined' ? false : params.interactive;
504
+ _this2.graph = params.graph || null; // 层级顺序(用于排序)
505
+
506
+ _this2.zIndex = params.zIndex || 0; // 是否响应交互事件
507
+
508
+ _this2.interactive = typeof params.interactive == 'undefined' ? false : params.interactive; // WebGL 模式下创建对应的渲染控制器
376
509
 
377
510
  if (_this2.mode === 'webgl') {
378
511
  _this2.webglControl = new _path["default"](_this2.graph, {
@@ -381,20 +514,52 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
381
514
  isRegular: params.isRegular,
382
515
  needCut: params.needCut
383
516
  });
384
- }
517
+ } // 执行初始化
385
518
 
386
- _this2.initializing();
387
519
 
388
- _this2.on = _this2.bind;
520
+ _this2.initializing(); // 别名:on 等同于 bind
521
+
522
+
523
+ _this2.on = _this2.bind; // 保存原始参数
524
+
389
525
  _this2.option = params;
390
526
  return _this2;
391
527
  }
528
+ /**
529
+ * 控件类型标识
530
+ *
531
+ * 用于类型检查和调试,由构造函数自动设置。
532
+ *
533
+ * @type {string}
534
+ * @readonly
535
+ *
536
+ * @example
537
+ * console.log(rect.type); // 'jmRect'
538
+ * if(control.type === 'jmCircle') { ... }
539
+ */
540
+
392
541
 
393
542
  _createClass(jmControl, [{
394
543
  key: "type",
395
544
  get: function get() {
396
545
  return this.property('type');
397
546
  }
547
+ /**
548
+ * 绘图上下文
549
+ *
550
+ * 获取当前控件的 Canvas 2D 或 WebGL 渲染上下文。
551
+ * 如果控件本身不是 jmGraph,会返回所属 graph 的上下文。
552
+ *
553
+ * @type {CanvasRenderingContext2D|WebGLRenderingContext}
554
+ * @readonly
555
+ *
556
+ * @example
557
+ * // 获取上下文并绘制
558
+ * const ctx = control.context;
559
+ * ctx.fillStyle = 'red';
560
+ * ctx.fillRect(0, 0, 100, 100);
561
+ */
562
+
398
563
  }, {
399
564
  key: "context",
400
565
  get: function get() {
@@ -409,6 +574,36 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
409
574
  set: function set(v) {
410
575
  return this.property('context', v);
411
576
  }
577
+ /**
578
+ * 样式对象
579
+ *
580
+ * 控件的视觉样式配置,包括:
581
+ * - fill: 填充颜色或渐变
582
+ * - stroke: 描边颜色
583
+ * - lineWidth: 线宽
584
+ * - shadow: 阴影配置
585
+ * - font: 字体(文本控件)
586
+ * - opacity: 透明度
587
+ *
588
+ * 设置新样式会触发 needUpdate。
589
+ *
590
+ * @type {Object}
591
+ *
592
+ * @example
593
+ * // 设置样式
594
+ * control.style = {
595
+ * fill: '#ff0000',
596
+ * stroke: '#000000',
597
+ * lineWidth: 2,
598
+ * shadow: {
599
+ * blur: 10,
600
+ * x: 5,
601
+ * y: 5,
602
+ * color: 'rgba(0,0,0,0.5)'
603
+ * }
604
+ * };
605
+ */
606
+
412
607
  }, {
413
608
  key: "style",
414
609
  get: function get() {
@@ -420,6 +615,23 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
420
615
  this.needUpdate = true;
421
616
  return this.property('style', v);
422
617
  }
618
+ /**
619
+ * 是否可见
620
+ *
621
+ * 控制控件是否参与渲染和事件响应。
622
+ * 不可见的控件不会被绘制,也不会响应鼠标/触摸事件。
623
+ *
624
+ * @type {boolean}
625
+ * @default true
626
+ *
627
+ * @example
628
+ * // 隐藏控件
629
+ * control.visible = false;
630
+ *
631
+ * // 显示控件
632
+ * control.visible = true;
633
+ */
634
+
423
635
  }, {
424
636
  key: "visible",
425
637
  get: function get() {
@@ -431,6 +643,23 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
431
643
  this.needUpdate = true;
432
644
  return this.property('visible', v);
433
645
  }
646
+ /**
647
+ * 是否响应交互事件
648
+ *
649
+ * 设置为 true 时,控件会响应鼠标和触摸事件。
650
+ * 设置为 false 时,事件会穿透到下层控件。
651
+ *
652
+ * @type {boolean}
653
+ * @default false
654
+ *
655
+ * @example
656
+ * // 启用交互
657
+ * control.interactive = true;
658
+ * control.bind('click', (evt) => {
659
+ * console.log('clicked!');
660
+ * });
661
+ */
662
+
434
663
  }, {
435
664
  key: "interactive",
436
665
  get: function get() {
@@ -440,6 +669,24 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
440
669
  set: function set(v) {
441
670
  return this.property('interactive', v);
442
671
  }
672
+ /**
673
+ * 自定义命中区域
674
+ *
675
+ * 用于点击测试的自定义区域,格式为 {x, y, width, height}。
676
+ * 如果设置,点击测试会使用此区域而非实际图形边界。
677
+ *
678
+ * @type {Object|null}
679
+ *
680
+ * @example
681
+ * // 设置更大的点击区域
682
+ * control.hitArea = {
683
+ * x: -10,
684
+ * y: -10,
685
+ * width: control.width + 20,
686
+ * height: control.height + 20
687
+ * };
688
+ */
689
+
443
690
  }, {
444
691
  key: "hitArea",
445
692
  get: function get() {
@@ -449,6 +696,27 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
449
696
  set: function set(v) {
450
697
  return this.property('hitArea', v);
451
698
  }
699
+ /**
700
+ * 子控件列表
701
+ *
702
+ * 当前控件的所有子控件。子控件会按 zIndex 排序后绘制。
703
+ * 添加子控件时会自动建立父子关系。
704
+ *
705
+ * @type {jmList}
706
+ *
707
+ * @example
708
+ * // 添加子控件
709
+ * parent.children.add(child);
710
+ *
711
+ * // 移除子控件
712
+ * parent.children.remove(child);
713
+ *
714
+ * // 遍历子控件
715
+ * parent.children.each((i, child) => {
716
+ * console.log(child);
717
+ * });
718
+ */
719
+
452
720
  }, {
453
721
  key: "children",
454
722
  get: function get() {
@@ -460,6 +728,22 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
460
728
  this.needUpdate = true;
461
729
  return this.property('children', v);
462
730
  }
731
+ /**
732
+ * 控件宽度
733
+ *
734
+ * 可以是具体数值或百分比字符串(如 '50%')。
735
+ * 百分比会相对于父容器宽度计算。
736
+ *
737
+ * @type {number|string}
738
+ *
739
+ * @example
740
+ * // 设置固定宽度
741
+ * control.width = 100;
742
+ *
743
+ * // 设置百分比宽度
744
+ * control.width = '50%';
745
+ */
746
+
463
747
  }, {
464
748
  key: "width",
465
749
  get: function get() {
@@ -471,6 +755,22 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
471
755
  this.needUpdate = true;
472
756
  return this.property('width', v);
473
757
  }
758
+ /**
759
+ * 控件高度
760
+ *
761
+ * 可以是具体数值或百分比字符串(如 '50%')。
762
+ * 百分比会相对于父容器高度计算。
763
+ *
764
+ * @type {number|string}
765
+ *
766
+ * @example
767
+ * // 设置固定高度
768
+ * control.height = 100;
769
+ *
770
+ * // 设置百分比高度
771
+ * control.height = '50%';
772
+ */
773
+
474
774
  }, {
475
775
  key: "height",
476
776
  get: function get() {
@@ -482,6 +782,23 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
482
782
  this.needUpdate = true;
483
783
  return this.property('height', v);
484
784
  }
785
+ /**
786
+ * 层级顺序
787
+ *
788
+ * 控制控件的绘制顺序,值越大越靠上。
789
+ * 设置 zIndex 会触发子控件重新排序。
790
+ *
791
+ * @type {number}
792
+ * @default 0
793
+ *
794
+ * @example
795
+ * // 将控件置于最上层
796
+ * control.zIndex = 100;
797
+ *
798
+ * // 将控件置于最下层
799
+ * control.zIndex = -1;
800
+ */
801
+
485
802
  }, {
486
803
  key: "zIndex",
487
804
  get: function get() {
@@ -495,6 +812,22 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
495
812
  this.needUpdate = true;
496
813
  return v;
497
814
  }
815
+ /**
816
+ * 鼠标样式
817
+ *
818
+ * 鼠标悬停在控件上时显示的光标样式。
819
+ * 常用值:'default', 'pointer', 'move', 'text', 'crosshair'
820
+ *
821
+ * @type {string}
822
+ *
823
+ * @example
824
+ * // 设置为手型指针
825
+ * control.cursor = 'pointer';
826
+ *
827
+ * // 设置为移动样式
828
+ * control.cursor = 'move';
829
+ */
830
+
498
831
  }, {
499
832
  key: "cursor",
500
833
  get: function get() {
@@ -503,7 +836,18 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
503
836
  if (graph) {
504
837
  return graph.css('cursor');
505
838
  }
506
- },
839
+ }
840
+ /**
841
+ * 初始化控件
842
+ *
843
+ * 在构造函数末尾调用,用于设置子控件管理逻辑。
844
+ * 重写了 children 的 add、remove、sort、clear 方法,
845
+ * 实现自动的父子关系维护和脏标记传播。
846
+ *
847
+ * @method initializing
848
+ * @protected
849
+ */
850
+ ,
507
851
  set: function set(cur) {
508
852
  var graph = this.graph;
509
853
 
@@ -517,14 +861,20 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
517
861
  var self = this;
518
862
  this.children = this.children || new _jmList.jmList();
519
863
  var oadd = this.children.add;
864
+ /**
865
+ * 重写 add 方法,自动建立父子关系
866
+ * @param {jmControl} obj - 要添加的子控件
867
+ * @returns {jmControl} 添加的子控件
868
+ */
520
869
 
521
870
  this.children.add = function (obj) {
522
871
  if (_typeof(obj) === 'object') {
872
+ // 如果对象已有父级,先从原父级移除
523
873
  if (obj.parent && obj.parent != self && obj.parent.children) {
524
874
  obj.parent.children.remove(obj);
525
875
  }
526
876
 
527
- obj.parent = self;
877
+ obj.parent = self; // 如果已存在,先移除再添加
528
878
 
529
879
  if (this.contain(obj)) {
530
880
  this.oremove(obj);
@@ -532,7 +882,8 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
532
882
 
533
883
  oadd.call(this, obj);
534
884
  obj.emit('add', obj);
535
- self.needUpdate = true;
885
+ self.needUpdate = true; // 传播 graph 引用
886
+
536
887
  if (self.graph) obj.graph = self.graph;
537
888
  this.sort();
538
889
  return obj;
@@ -540,6 +891,10 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
540
891
  };
541
892
 
542
893
  this.children.oremove = this.children.remove;
894
+ /**
895
+ * 重写 remove 方法,清理父子关系
896
+ * @param {jmControl} obj - 要移除的子控件
897
+ */
543
898
 
544
899
  this.children.remove = function (obj) {
545
900
  if (_typeof(obj) === 'object') {
@@ -550,6 +905,10 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
550
905
  self.needUpdate = true;
551
906
  }
552
907
  };
908
+ /**
909
+ * 按 zIndex 排序子控件
910
+ */
911
+
553
912
 
554
913
  this.children.sort = function () {
555
914
  var levelItems = {};
@@ -571,6 +930,10 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
571
930
  oadd.call(this, levelItems[index]);
572
931
  }
573
932
  };
933
+ /**
934
+ * 清空所有子控件
935
+ */
936
+
574
937
 
575
938
  this.children.clear = function () {
576
939
  this.each(function (i, obj) {
@@ -580,6 +943,39 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
580
943
 
581
944
  this.needUpdate = true;
582
945
  }
946
+ /**
947
+ * 设置控件样式到绘图上下文
948
+ *
949
+ * 将样式对象应用到 Canvas 上下文,支持:
950
+ * - 基础样式:fill, stroke, lineWidth, opacity 等
951
+ * - 阴影效果:shadow.blur, shadow.x, shadow.y, shadow.color
952
+ * - 渐变填充:支持线性渐变和径向渐变
953
+ * - 变换效果:rotation(旋转)、translate(平移)、transform(矩阵变换)
954
+ * - 高级效果:lineDash(虚线)、filter(滤镜)、clipPath(裁剪)、mask(遮罩)
955
+ *
956
+ * @method setStyle
957
+ * @param {Object} [style] - 要应用的样式对象,默认使用 this.style
958
+ *
959
+ * @example
960
+ * // 应用样式
961
+ * control.setStyle({
962
+ * fill: '#ff0000',
963
+ * stroke: '#000000',
964
+ * lineWidth: 2,
965
+ * shadow: {
966
+ * blur: 10,
967
+ * x: 5,
968
+ * y: 5,
969
+ * color: 'rgba(0,0,0,0.5)'
970
+ * }
971
+ * });
972
+ *
973
+ * // 使用渐变
974
+ * control.setStyle({
975
+ * fill: 'linear-gradient(0,0,100,0,#ff0000,#0000ff)'
976
+ * });
977
+ */
978
+
583
979
  }, {
584
980
  key: "setStyle",
585
981
  value: function setStyle(style) {
@@ -590,10 +986,17 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
590
986
  }
591
987
 
592
988
  if (!style) return;
989
+ /**
990
+ * 内部样式设置函数
991
+ * @param {*} styleValue - 样式值
992
+ * @param {string} name - 样式名称
993
+ * @param {string} [mpkey] - 映射键名
994
+ * @private
995
+ */
593
996
 
594
997
  var __setStyle = function __setStyle(style, name, mpkey) {
595
998
  if (style) {
596
- var styleValue = style;
999
+ var styleValue = style; // 支持函数形式的样式值
597
1000
 
598
1001
  if (typeof styleValue === 'function') {
599
1002
  try {
@@ -606,7 +1009,7 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
606
1009
 
607
1010
  var t = _typeof(styleValue);
608
1011
 
609
- var mpname = jmStyleMap[mpkey || name];
1012
+ var mpname = jmStyleMap[mpkey || name]; // 处理渐变
610
1013
 
611
1014
  if (styleValue instanceof _jmGradient.jmGradient || t == 'string' && styleValue.indexOf('-gradient') > -1) {
612
1015
  if (t == 'string' && styleValue.indexOf('-gradient') > -1) {
@@ -614,7 +1017,8 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
614
1017
  }
615
1018
 
616
1019
  __setStyle(styleValue.toGradient(_this3), mpname || name);
617
- } else if (mpname) {
1020
+ } // 处理标准样式映射
1021
+ else if (mpname) {
618
1022
  if (_this3.webglControl) {
619
1023
  _this3.webglControl.setStyle(mpname, styleValue);
620
1024
  } else {
@@ -624,8 +1028,10 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
624
1028
 
625
1029
  _this3.context[mpname] = styleValue;
626
1030
  }
627
- } else {
1031
+ } // 处理特殊样式
1032
+ else {
628
1033
  switch (name) {
1034
+ // 阴影样式
629
1035
  case 'shadow':
630
1036
  {
631
1037
  if (t == 'string') {
@@ -640,11 +1046,13 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
640
1046
 
641
1047
  break;
642
1048
  }
1049
+ // 平移变换
643
1050
 
644
1051
  case 'translate':
645
1052
  {
646
1053
  break;
647
1054
  }
1055
+ // 旋转变换
648
1056
 
649
1057
  case 'rotation':
650
1058
  {
@@ -659,6 +1067,7 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
659
1067
  _this3.context.translate && _this3.context.translate(-_this3.__translateAbsolutePosition.x, -_this3.__translateAbsolutePosition.y);
660
1068
  break;
661
1069
  }
1070
+ // 矩阵变换
662
1071
 
663
1072
  case 'transform':
664
1073
  {
@@ -672,6 +1081,7 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
672
1081
 
673
1082
  break;
674
1083
  }
1084
+ // 鼠标样式
675
1085
 
676
1086
  case 'cursor':
677
1087
  {
@@ -679,7 +1089,13 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
679
1089
  break;
680
1090
  }
681
1091
  // ===== 新增样式特性 =====
682
- // 虚线样式:支持自定义lineDash模式 (如 [5, 3, 2] 或 "5,3,2")
1092
+
1093
+ /**
1094
+ * 虚线样式
1095
+ * 支持数组格式 [5, 3, 2] 或字符串格式 "5,3,2"
1096
+ * @example
1097
+ * style: { lineDash: [5, 3] } // 5px实线,3px空白
1098
+ */
683
1099
 
684
1100
  case 'lineDash':
685
1101
  {
@@ -716,7 +1132,15 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
716
1132
  _this3.context.lineDashOffset = Number(styleValue) || 0;
717
1133
  break;
718
1134
  }
719
- // CSS滤镜效果 (blur, grayscale, sepia, brightness, contrast, saturate, hue-rotate, invert, opacity)
1135
+
1136
+ /**
1137
+ * CSS滤镜效果
1138
+ * 支持 blur, grayscale, sepia, brightness, contrast, saturate, hue-rotate, invert, opacity
1139
+ * @example
1140
+ * style: { filter: 'blur(5px) grayscale(50%)' }
1141
+ * // 或使用对象
1142
+ * style: { filter: { blur: 5, grayscale: 0.5 } }
1143
+ */
720
1144
 
721
1145
  case 'filter':
722
1146
  {
@@ -732,7 +1156,13 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
732
1156
 
733
1157
  break;
734
1158
  }
735
- // 混合模式 (source-over, multiply, screen, overlay, darken, lighten, etc.)
1159
+
1160
+ /**
1161
+ * 混合模式
1162
+ * 常用值:source-over, multiply, screen, overlay, darken, lighten
1163
+ * @example
1164
+ * style: { globalCompositeOperation: 'multiply' }
1165
+ */
736
1166
 
737
1167
  case 'globalCompositeOperation':
738
1168
  {
@@ -740,7 +1170,13 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
740
1170
  _this3.context.globalCompositeOperation = styleValue;
741
1171
  break;
742
1172
  }
743
- // 裁剪路径:通过canvas clip实现
1173
+
1174
+ /**
1175
+ * 裁剪路径
1176
+ * 通过 canvas clip 实现裁剪效果
1177
+ * @example
1178
+ * style: { clipPath: clipShape } // clipShape 是一个图形控件
1179
+ */
744
1180
 
745
1181
  case 'clipPath':
746
1182
  {
@@ -770,7 +1206,13 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
770
1206
 
771
1207
  break;
772
1208
  }
773
- // 遮罩效果:通过globalCompositeOperation + destination-in实现
1209
+
1210
+ /**
1211
+ * 遮罩效果
1212
+ * 通过 globalCompositeOperation + destination-in 实现
1213
+ * @example
1214
+ * style: { mask: maskShape } // maskShape 是一个图形控件
1215
+ */
774
1216
 
775
1217
  case 'mask':
776
1218
  {
@@ -780,7 +1222,7 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
780
1222
  _this3.__mask = styleValue;
781
1223
  break;
782
1224
  }
783
- // 图片阴影描边阴影(WebGL纹理canvas用)
1225
+ // 阴影相关样式(WebGL兼容)
784
1226
 
785
1227
  case 'shadowColor':
786
1228
  {
@@ -828,26 +1270,32 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
828
1270
  }
829
1271
  }
830
1272
  }
831
- };
1273
+ }; // 应用平移变换
1274
+
832
1275
 
833
1276
  if (this.translate) {
834
1277
  __setStyle(this.translate, 'translate');
835
- }
1278
+ } // 应用矩阵变换
1279
+
836
1280
 
837
1281
  if (this.transform) {
838
1282
  __setStyle(this.transform, 'transform');
839
- }
1283
+ } // 遍历应用所有样式
1284
+
840
1285
 
841
1286
  for (var k in style) {
842
1287
  if (k === 'constructor') continue;
843
1288
 
844
- var t = _typeof(style[k]);
1289
+ var t = _typeof(style[k]); // 自动转换渐变字符串
1290
+
845
1291
 
846
1292
  if (t == 'string' && style[k].indexOf('-gradient') > -1) {
847
1293
  style[k] = new _jmGradient.jmGradient(style[k]);
848
- } else if (t == 'string' && k == 'shadow') {
1294
+ } // 自动转换阴影字符串
1295
+ else if (t == 'string' && k == 'shadow') {
849
1296
  style[k] = new _jmShadow.jmShadow(style[k]);
850
- } else if (t == 'string' && k == 'filter') {
1297
+ } // 自动转换滤镜字符串
1298
+ else if (t == 'string' && k == 'filter') {
851
1299
  style[k] = new _jmFilter.jmFilter(style[k]);
852
1300
  }
853
1301
 
@@ -855,13 +1303,29 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
855
1303
  }
856
1304
  }
857
1305
  /**
858
- * 获取当前控件的边界
859
- * 通过分析控件的描点或位置加宽高得到为方形的边界
860
- *
1306
+ * 获取当前控件的边界矩形
1307
+ *
1308
+ * 通过分析控件的描点或位置加宽高得到边界矩形。
1309
+ * 对于 jmGraph,边界为画布尺寸。
1310
+ * 对于有 points 的控件,边界为所有点的最小包围矩形。
1311
+ *
861
1312
  * @method getBounds
862
- * @for jmControl
863
- * @param {boolean} [isReset=false] 是否强制重新计算
864
- * @return {object} 控件的边界描述对象(left,top,right,bottom,width,height)
1313
+ * @param {boolean} [isReset=false] - 是否强制重新计算(忽略缓存)
1314
+ * @returns {Object} 边界对象
1315
+ * @returns {number} returns.left - 左边界 X 坐标
1316
+ * @returns {number} returns.top - 上边界 Y 坐标
1317
+ * @returns {number} returns.right - 右边界 X 坐标
1318
+ * @returns {number} returns.bottom - 下边界 Y 坐标
1319
+ * @returns {number} returns.width - 宽度
1320
+ * @returns {number} returns.height - 高度
1321
+ *
1322
+ * @example
1323
+ * // 获取边界
1324
+ * const bounds = control.getBounds();
1325
+ * console.log(`宽: ${bounds.width}, 高: ${bounds.height}`);
1326
+ *
1327
+ * // 强制重新计算
1328
+ * const newBounds = control.getBounds(true);
865
1329
  */
866
1330
 
867
1331
  }, {
@@ -884,7 +1348,8 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
884
1348
  } else if (this.height) {
885
1349
  rect.bottom = this.height;
886
1350
  }
887
- } else if (this.points && this.points.length > 0) {
1351
+ } // 根据 points 计算边界
1352
+ else if (this.points && this.points.length > 0) {
888
1353
  var _iterator = _createForOfIteratorHelper(this.points),
889
1354
  _step;
890
1355
 
@@ -913,7 +1378,8 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
913
1378
  } finally {
914
1379
  _iterator.f();
915
1380
  }
916
- } else if (this.getLocation) {
1381
+ } // 根据位置和尺寸计算边界
1382
+ else if (this.getLocation) {
917
1383
  var _p = this.getLocation();
918
1384
 
919
1385
  if (_p) {
@@ -924,16 +1390,32 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
924
1390
  }
925
1391
  }
926
1392
 
927
- if (!rect.left) rect.left = 0;
928
- if (!rect.top) rect.top = 0;
929
- if (!rect.right) rect.right = 0;
930
- if (!rect.bottom) rect.bottom = 0;
1393
+ if (rect.left === undefined) rect.left = 0;
1394
+ if (rect.top === undefined) rect.top = 0;
1395
+ if (rect.right === undefined) rect.right = 0;
1396
+ if (rect.bottom === undefined) rect.bottom = 0;
931
1397
  rect.width = rect.right - rect.left;
932
1398
  rect.height = rect.bottom - rect.top;
933
1399
  return this.bounds = rect;
934
1400
  }
935
1401
  /**
936
- * 获取被旋转后的边界
1402
+ * 获取旋转后的边界矩形
1403
+ *
1404
+ * 计算控件旋转后的最小包围矩形。
1405
+ * 当控件有旋转变换时,实际占据的空间会发生变化。
1406
+ *
1407
+ * @method getRotationBounds
1408
+ * @param {Object} [rotation] - 旋转参数,默认使用 style.rotation
1409
+ * @param {number} rotation.x - 旋转中心 X(相对于控件)
1410
+ * @param {number} rotation.y - 旋转中心 Y(相对于控件)
1411
+ * @param {number} rotation.angle - 旋转角度(弧度)
1412
+ * @param {Object} [bounds] - 基础边界,默认使用 getBounds()
1413
+ * @returns {Object} 旋转后的边界对象
1414
+ *
1415
+ * @example
1416
+ * // 获取旋转后的边界
1417
+ * const bounds = control.getRotationBounds();
1418
+ * console.log(`旋转后宽度: ${bounds.width}`);
937
1419
  */
938
1420
 
939
1421
  }, {
@@ -1016,11 +1498,26 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1016
1498
  return rect;
1017
1499
  }
1018
1500
  /**
1019
- * 获取当前控件的位置相关参数
1020
- * 解析百分比和margin参数
1021
- *
1501
+ * 获取当前控件的位置参数
1502
+ *
1503
+ * 解析百分比和 margin 参数,返回标准化的位置信息。
1504
+ * 支持百分比定位(如 '50%')和 margin 偏移。
1505
+ *
1022
1506
  * @method getLocation
1023
- * @return {object} 当前控件位置参数,包括中心点坐标,右上角坐标,宽高
1507
+ * @returns {Object} 位置参数对象
1508
+ * @returns {number} returns.left - 左边距
1509
+ * @returns {number} returns.top - 上边距
1510
+ * @returns {number} returns.width - 宽度
1511
+ * @returns {number} returns.height - 高度
1512
+ * @returns {Object} [returns.position] - 位置对象 {x, y}
1513
+ * @returns {Object} [returns.center] - 中心点
1514
+ * @returns {Object} [returns.start] - 起点(线条类)
1515
+ * @returns {Object} [returns.end] - 终点(线条类)
1516
+ * @returns {number} [returns.radius] - 半径(圆形类)
1517
+ *
1518
+ * @example
1519
+ * const loc = control.getLocation();
1520
+ * console.log(`位置: (${loc.left}, ${loc.top})`);
1024
1521
  */
1025
1522
 
1026
1523
  }, {
@@ -1107,8 +1604,26 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1107
1604
  return local;
1108
1605
  }
1109
1606
  /**
1110
- * 获取当前控制的旋转信息
1111
- * @returns {object} 旋转中心和角度
1607
+ * 获取当前控件的旋转信息
1608
+ *
1609
+ * 解析旋转参数,支持百分比形式的旋转中心。
1610
+ * 如果控件本身没有旋转,会继承父级的旋转。
1611
+ *
1612
+ * @method getRotation
1613
+ * @param {Object} [rotation] - 旋转参数,默认使用 style.rotation
1614
+ * @param {Object} [bounds] - 基础边界
1615
+ * @returns {Object} 旋转信息
1616
+ * @returns {number} returns.x - 旋转中心 X(相对于控件)
1617
+ * @returns {number} returns.y - 旋转中心 Y(相对于控件)
1618
+ * @returns {number} returns.angle - 旋转角度(弧度)
1619
+ * @returns {Object} returns.bounds - 控件边界
1620
+ *
1621
+ * @example
1622
+ * // 获取旋转信息
1623
+ * const rot = control.getRotation();
1624
+ * if(rot.angle) {
1625
+ * console.log(`旋转角度: ${rot.angle} 弧度`);
1626
+ * }
1112
1627
  */
1113
1628
 
1114
1629
  }, {
@@ -1143,7 +1658,21 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1143
1658
  return _objectSpread(_objectSpread({}, rotation), {}, {
1144
1659
  bounds: bounds
1145
1660
  });
1146
- } // 计算位移偏移量
1661
+ }
1662
+ /**
1663
+ * 计算位移偏移量
1664
+ *
1665
+ * 解析 translate 样式,支持百分比形式。
1666
+ *
1667
+ * @method getTranslate
1668
+ * @param {Object} [translate] - 平移参数,默认使用 style.translate
1669
+ * @param {Object} [bounds] - 参考边界
1670
+ * @returns {Object} 平移信息 {x, y}
1671
+ *
1672
+ * @example
1673
+ * const trans = control.getTranslate();
1674
+ * console.log(`平移: (${trans.x}, ${trans.y})`);
1675
+ */
1147
1676
 
1148
1677
  }, {
1149
1678
  key: "getTranslate",
@@ -1173,9 +1702,15 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1173
1702
  }
1174
1703
  /**
1175
1704
  * 移除当前控件
1176
- * 如果是VML元素,则调用其删除元素
1177
- *
1178
- * @method remove
1705
+ *
1706
+ * 从父控件的子控件列表中移除当前控件。
1707
+ * 移除后会触发 needUpdate 重绘。
1708
+ *
1709
+ * @method remove
1710
+ *
1711
+ * @example
1712
+ * // 移除控件
1713
+ * control.remove();
1179
1714
  */
1180
1715
 
1181
1716
  }, {
@@ -1187,13 +1722,19 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1187
1722
  }
1188
1723
  /**
1189
1724
  * 对控件进行平移
1725
+ *
1190
1726
  * 遍历控件所有描点或位置,设置其偏移量。
1191
- *
1727
+ * 支持移动 position、center、start、end、points 等属性。
1728
+ *
1192
1729
  * @method offset
1193
- * @param {number} x x轴偏移量
1194
- * @param {number} y y轴偏移量
1195
- * @param {boolean} [trans] 是否传递,监听者可以通过此属性是否决定是否响应移动事件,默认=true
1196
- * @param {object} [evt] 如果是事件触发,则传递move事件参数
1730
+ * @param {number} x - X 轴偏移量
1731
+ * @param {number} y - Y 轴偏移量
1732
+ * @param {boolean} [trans=true] - 是否传递给监听者
1733
+ * @param {Object} [evt] - 如果是事件触发,传递 move 事件参数
1734
+ *
1735
+ * @example
1736
+ * // 向右移动 10px,向下移动 5px
1737
+ * control.offset(10, 5);
1197
1738
  */
1198
1739
 
1199
1740
  }, {
@@ -1266,11 +1807,17 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1266
1807
  this.needUpdate = true;
1267
1808
  }
1268
1809
  /**
1269
- * 获取控件相对于画布的绝对边界,
1270
- * 与getBounds不同的是:getBounds获取的是相对于父容器的边界.
1271
- *
1810
+ * 获取控件相对于画布的绝对边界
1811
+ *
1812
+ * 与 getBounds 不同的是:getBounds 获取的是相对于父容器的边界,
1813
+ * 而 getAbsoluteBounds 获取的是相对于画布的边界。
1814
+ *
1272
1815
  * @method getAbsoluteBounds
1273
- * @return {object} 边界对象(left,top,right,bottom,width,height)
1816
+ * @returns {Object} 绝对边界对象
1817
+ *
1818
+ * @example
1819
+ * const absBounds = control.getAbsoluteBounds();
1820
+ * console.log(`画布上的位置: (${absBounds.left}, ${absBounds.top})`);
1274
1821
  */
1275
1822
 
1276
1823
  }, {
@@ -1295,10 +1842,14 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1295
1842
  return rec;
1296
1843
  }
1297
1844
  /**
1298
- * 把当前控制内部坐标转为canvas绝对定位坐标
1845
+ * 把当前控件内部坐标转为画布绝对坐标
1299
1846
  *
1300
1847
  * @method toAbsolutePoint
1301
- * @param {x: number, y: number} 内部坐标
1848
+ * @param {Object} point - 内部坐标 {x, y}
1849
+ * @returns {Object} 绝对坐标
1850
+ *
1851
+ * @example
1852
+ * const absPoint = control.toAbsolutePoint({x: 10, y: 10});
1302
1853
  */
1303
1854
 
1304
1855
  }, {
@@ -1313,8 +1864,14 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1313
1864
  return point;
1314
1865
  }
1315
1866
  /**
1316
- * 把绝对定位坐标转为当前控件坐标系内
1317
- * @param {*} point
1867
+ * 把画布绝对坐标转为当前控件坐标系内
1868
+ *
1869
+ * @method toLocalPosition
1870
+ * @param {Object} point - 绝对坐标
1871
+ * @returns {Object|false} 相对坐标,如果无法转换返回 false
1872
+ *
1873
+ * @example
1874
+ * const localPoint = control.toLocalPosition({x: 100, y: 100});
1318
1875
  */
1319
1876
 
1320
1877
  }, {
@@ -1329,9 +1886,21 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1329
1886
  }
1330
1887
  /**
1331
1888
  * 画控件前初始化
1332
- * 执行beginPath开始控件的绘制
1889
+ *
1890
+ * 执行 beginPath 开始控件的绘制路径。
1891
+ * 重置位置信息缓存,确保使用最新的位置数据。
1333
1892
  *
1334
1893
  * @method beginDraw
1894
+ * @protected
1895
+ *
1896
+ * @example
1897
+ * // 子类重写时需要调用父类方法
1898
+ * class MyShape extends jmControl {
1899
+ * beginDraw() {
1900
+ * super.beginDraw();
1901
+ * // 自定义初始化逻辑
1902
+ * }
1903
+ * }
1335
1904
  */
1336
1905
 
1337
1906
  }, {
@@ -1344,8 +1913,18 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1344
1913
  }
1345
1914
  /**
1346
1915
  * 结束控件绘制
1347
- *
1916
+ *
1917
+ * 根据样式执行 fill 或 stroke 操作。
1918
+ * 如果设置了 close 样式,会先闭合路径。
1919
+ *
1348
1920
  * @method endDraw
1921
+ * @protected
1922
+ *
1923
+ * @example
1924
+ * // 绘制流程
1925
+ * control.beginDraw();
1926
+ * control.draw();
1927
+ * control.endDraw();
1349
1928
  */
1350
1929
 
1351
1930
  }, {
@@ -1388,10 +1967,24 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1388
1967
  this.needUpdate = false;
1389
1968
  }
1390
1969
  /**
1391
- * 绘制控件
1392
- * 在画布上描点
1970
+ * 绘制控件路径
1971
+ *
1972
+ * 在画布上绘制控件的路径点。
1973
+ * 子类应该重写此方法实现自定义绘制逻辑。
1393
1974
  *
1394
1975
  * @method draw
1976
+ * @protected
1977
+ *
1978
+ * @example
1979
+ * // 子类重写绘制方法
1980
+ * class MyShape extends jmControl {
1981
+ * draw() {
1982
+ * const ctx = this.context;
1983
+ * ctx.moveTo(0, 0);
1984
+ * ctx.lineTo(100, 100);
1985
+ * // ... 更多绘制逻辑
1986
+ * }
1987
+ * }
1395
1988
  */
1396
1989
 
1397
1990
  }, {
@@ -1421,10 +2014,23 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1421
2014
  }
1422
2015
  }
1423
2016
  /**
1424
- * 绘制当前控件
1425
- * 协调控件的绘制,先从其子控件开始绘制,再往上冒。
1426
- *
2017
+ * 绘制当前控件及其子控件
2018
+ *
2019
+ * 协调控件的绘制流程:
2020
+ * 1. 检查可见性
2021
+ * 2. 初始化点数据
2022
+ * 3. 计算边界
2023
+ * 4. 应用样式
2024
+ * 5. 绘制自身
2025
+ * 6. 绘制子控件
2026
+ * 7. 触发事件
2027
+ *
1427
2028
  * @method paint
2029
+ * @param {boolean} [v] - 是否可见,false 时跳过绘制
2030
+ *
2031
+ * @example
2032
+ * // 手动触发重绘
2033
+ * control.paint();
1428
2034
  */
1429
2035
 
1430
2036
  }, {
@@ -1498,12 +2104,19 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1498
2104
  }
1499
2105
  }
1500
2106
  /**
1501
- * 获取指定事件的集合
1502
- * 比如mousedown,mouseup等
1503
- *
2107
+ * 获取指定事件的监听器集合
2108
+ *
2109
+ * 返回绑定到指定事件名称的所有事件处理函数。
2110
+ *
1504
2111
  * @method getEvent
1505
- * @param {string} name 事件名称
1506
- * @return {list} 事件委托的集合
2112
+ * @param {string} name - 事件名称(如 'click', 'mousedown')
2113
+ * @returns {jmList|null} 事件处理函数集合,不存在则返回 null
2114
+ *
2115
+ * @example
2116
+ * const handlers = control.getEvent('click');
2117
+ * if(handlers) {
2118
+ * console.log(`有 ${handlers.count()} 个点击事件处理器`);
2119
+ * }
1507
2120
  */
1508
2121
 
1509
2122
  }, {
@@ -1512,11 +2125,31 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1512
2125
  return this.__events ? this.__events[name] : null;
1513
2126
  }
1514
2127
  /**
1515
- * 绑定控件的事件
1516
- *
2128
+ * 绑定控件事件
2129
+ *
2130
+ * 为控件添加事件监听器。支持同时绑定多个事件(用空格分隔)。
2131
+ * 同一个处理函数不会被重复添加。
2132
+ *
1517
2133
  * @method bind
1518
- * @param {string} name 事件名称
1519
- * @param {function} handle 事件委托
2134
+ * @param {string} name - 事件名称,多个事件用空格分隔
2135
+ * @param {Function} handle - 事件处理函数
2136
+ * @returns {void}
2137
+ *
2138
+ * @example
2139
+ * // 绑定单个事件
2140
+ * control.bind('click', (evt) => {
2141
+ * console.log('被点击了', evt);
2142
+ * });
2143
+ *
2144
+ * // 绑定多个事件
2145
+ * control.bind('mousedown mouseup', (evt) => {
2146
+ * console.log('鼠标事件', evt);
2147
+ * });
2148
+ *
2149
+ * // 使用 on 别名
2150
+ * control.on('mousemove', (evt) => {
2151
+ * console.log('鼠标移动', evt.position);
2152
+ * });
1520
2153
  */
1521
2154
 
1522
2155
  }, {
@@ -1561,11 +2194,23 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1561
2194
  }
1562
2195
  }
1563
2196
  /**
1564
- * 移除控件的事件
1565
- *
1566
- * @method unbind
1567
- * @param {string} name 事件名称
1568
- * @param {function} handle 从控件中移除事件的委托
2197
+ * 移除控件事件
2198
+ *
2199
+ * 移除已绑定的事件处理函数。如果不指定处理函数,则移除该事件的所有处理函数。
2200
+ *
2201
+ * @method unbind
2202
+ * @param {string} name - 事件名称,多个事件用空格分隔
2203
+ * @param {Function} [handle] - 要移除的事件处理函数,不指定则移除所有
2204
+ *
2205
+ * @example
2206
+ * // 移除特定处理函数
2207
+ * control.unbind('click', myHandler);
2208
+ *
2209
+ * // 移除所有点击事件
2210
+ * control.unbind('click');
2211
+ *
2212
+ * // 移除多个事件
2213
+ * control.unbind('mousedown mouseup');
1569
2214
  */
1570
2215
 
1571
2216
  }, {
@@ -1598,12 +2243,22 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1598
2243
  }
1599
2244
  }
1600
2245
  /**
1601
- * 执行监听回调
2246
+ * 触发事件
2247
+ *
2248
+ * 执行指定事件的所有监听器。
2249
+ * 支持传递多个参数给事件处理函数。
1602
2250
  *
1603
2251
  * @method emit
1604
- * @for jmControl
1605
- * @param {string} name 触发事件的名称
1606
- * @param {array} args 事件参数数组
2252
+ * @param {string} name - 事件名称
2253
+ * @param {...*} args - 传递给事件处理函数的参数
2254
+ * @returns {jmControl} 返回 this 以支持链式调用
2255
+ *
2256
+ * @example
2257
+ * // 触发自定义事件
2258
+ * control.emit('customEvent', { data: 'value' });
2259
+ *
2260
+ * // 触发带多个参数的事件
2261
+ * control.emit('dataChange', oldValue, newValue);
1607
2262
  */
1608
2263
 
1609
2264
  }, {
@@ -1626,11 +2281,16 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1626
2281
  return this;
1627
2282
  }
1628
2283
  /**
1629
- * 独立执行事件委托
1630
- *
2284
+ * 执行事件处理函数
2285
+ *
2286
+ * 内部方法,用于执行指定事件的所有监听器。
2287
+ * 如果任一处理函数返回 false,会设置 args.cancel = true。
2288
+ *
1631
2289
  * @method runEventHandle
1632
- * @param {string} 将执行的事件名称
1633
- * @param {object} 事件执行的参数,包括触发事件的对象和位置
2290
+ * @param {string} name - 事件名称
2291
+ * @param {Array|Object} args - 事件参数
2292
+ * @returns {boolean} 是否被取消
2293
+ * @protected
1634
2294
  */
1635
2295
 
1636
2296
  }, {
@@ -1639,6 +2299,10 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1639
2299
  var events = this.getEvent(name);
1640
2300
 
1641
2301
  if (events) {
2302
+ if (name === 'mousemove' && this.type == 'jmResize') {
2303
+ console.log('resize mousemove', args, events);
2304
+ }
2305
+
1642
2306
  var self = this;
1643
2307
  if (!Array.isArray(args)) args = [args];
1644
2308
  events.each(function (i, handle) {
@@ -1652,12 +2316,25 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1652
2316
  return args.cancel;
1653
2317
  }
1654
2318
  /**
1655
- * 检 查坐标是否落在当前控件区域中..true=在区域内
1656
- *
2319
+ * 检查坐标是否落在当前控件区域中
2320
+ *
2321
+ * 用于点击测试和碰撞检测。
2322
+ * 支持旋转后的碰撞检测,以及自定义命中区域。
2323
+ *
1657
2324
  * @method checkPoint
1658
- * @param {point} p 位置参数
1659
- * @param {number} [pad] 可选参数,表示线条多远内都算在线上
1660
- * @return {boolean} 当前位置如果在区域内则为true,否则为false。
2325
+ * @param {Object} p - 要检测的点坐标
2326
+ * @param {number} p.x - X 坐标
2327
+ * @param {number} p.y - Y 坐标
2328
+ * @param {number} [pad] - 容差范围,默认使用 lineWidth 或 1
2329
+ * @returns {boolean} 点是否在控件区域内
2330
+ *
2331
+ * @example
2332
+ * // 检查点击位置
2333
+ * graph.bind('click', (evt) => {
2334
+ * if(control.checkPoint(evt.position)) {
2335
+ * console.log('点击了控件');
2336
+ * }
2337
+ * });
1661
2338
  */
1662
2339
 
1663
2340
  }, {
@@ -1666,16 +2343,13 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1666
2343
  //jmGraph 需要判断dom位置
1667
2344
  if (this.type == 'jmGraph') {
1668
2345
  //获取dom位置
1669
- var position = this.getPosition(); // 由于高清屏会有放大坐标,所以这里用pagex就只能用真实的canvas大小
1670
-
1671
- var right = position.left + this.width;
1672
- var bottom = position.top + this.height;
2346
+ var position = this.getPosition();
1673
2347
 
1674
- if (p.x > right || p.x < position.left) {
2348
+ if (p.pageX > position.right || p.pageX < position.left) {
1675
2349
  return false;
1676
2350
  }
1677
2351
 
1678
- if (p.y > bottom || p.y < position.top) {
2352
+ if (p.pageY > position.bottom || p.pageY < position.top) {
1679
2353
  return false;
1680
2354
  }
1681
2355
 
@@ -1793,12 +2467,19 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1793
2467
  return true;
1794
2468
  }
1795
2469
  /**
1796
- * 触发控件事件,组合参数并按控件层级关系执行事件冒泡。
1797
- *
2470
+ * 触发控件事件并执行事件冒泡
2471
+ *
2472
+ * 组合事件参数,按控件层级关系执行事件冒泡。
2473
+ * 事件从最上层的子控件开始触发,向上冒泡到父控件。
2474
+ *
1798
2475
  * @method raiseEvent
1799
- * @param {string} name 事件名称
1800
- * @param {object} args 事件执行参数
1801
- * @return {boolean} 如果事件被组止冒泡则返回false,否则返回true
2476
+ * @param {string} name - 事件名称
2477
+ * @param {Object} args - 原生事件对象
2478
+ * @returns {boolean} 如果事件被阻止冒泡则返回 false,否则返回 true
2479
+ *
2480
+ * @example
2481
+ * // 通常由框架内部调用,用户一般不需要直接调用
2482
+ * // 框架会自动处理鼠标/触摸事件
1802
2483
  */
1803
2484
 
1804
2485
  }, {
@@ -1854,7 +2535,12 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1854
2535
  args.position.x = args.position.offsetX - abounds.left;
1855
2536
  args.position.y = args.position.offsetY - abounds.top; // 是否在当前控件内操作
1856
2537
 
1857
- var inpos = this.interactive !== false && this.checkPoint(args.position); //事件发生在边界内或健盘事件发生在画布中才触发
2538
+ var inpos = this.interactive !== false && this.checkPoint(args.position);
2539
+
2540
+ if (name === 'mousemove' && this.type == 'jmGraph' && !inpos) {
2541
+ console.log('mousemove out', args.position, abounds);
2542
+ } //事件发生在边界内或健盘事件发生在画布中才触发
2543
+
1858
2544
 
1859
2545
  if (inpos) {
1860
2546
  //如果没有指定触发对象,则认为当前为第一触发对象
@@ -1881,9 +2567,14 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1881
2567
  return args.cancel === false; //如果被阻止则返回false,否则返回true
1882
2568
  }
1883
2569
  /**
1884
- * 执行事件,并进行冒泡
1885
- * @param {string} name 事件名称
1886
- * @param {object} args 事件参数
2570
+ * 执行事件并进行冒泡
2571
+ *
2572
+ * 内部方法,用于执行事件处理并添加到事件路径。
2573
+ *
2574
+ * @method runEventAndPopEvent
2575
+ * @param {string} name - 事件名称
2576
+ * @param {Object} args - 事件参数
2577
+ * @protected
1887
2578
  */
1888
2579
 
1889
2580
  }, {
@@ -1908,9 +2599,15 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1908
2599
  }
1909
2600
  /**
1910
2601
  * 清空控件指定事件
1911
- *
2602
+ *
2603
+ * 移除指定事件名称下的所有事件处理函数。
2604
+ *
1912
2605
  * @method clearEvents
1913
- * @param {string} name 需要清除的事件名称
2606
+ * @param {string} name - 需要清除的事件名称
2607
+ *
2608
+ * @example
2609
+ * // 清除所有点击事件
2610
+ * control.clearEvents('click');
1914
2611
  */
1915
2612
 
1916
2613
  }, {
@@ -1919,15 +2616,24 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1919
2616
  var eventCollection = this.getEvent(name);
1920
2617
 
1921
2618
  if (eventCollection) {
1922
- eventCollection.clear;
2619
+ eventCollection.clear();
1923
2620
  }
1924
2621
  }
1925
2622
  /**
1926
- * 查找其父级类型为type的元素,直到找到指定的对象或到最顶级控件后返回空。
1927
- *
1928
- * @method findParent
1929
- * @param {object} 类型名称或类型对象
1930
- * @return {object} 指定类型的实例
2623
+ * 查找指定类型的父级控件
2624
+ *
2625
+ * 沿着父级链向上查找,直到找到指定类型的控件或到达最顶级。
2626
+ *
2627
+ * @method findParent
2628
+ * @param {string|Function} type - 类型名称(字符串)或类构造函数
2629
+ * @returns {jmControl|null} 找到的父级控件实例,未找到返回 null
2630
+ *
2631
+ * @example
2632
+ * // 查找 jmGraph 实例
2633
+ * const graph = control.findParent('jmGraph');
2634
+ *
2635
+ * // 查找特定类的实例
2636
+ * const parent = control.findParent(MyCustomControl);
1931
2637
  */
1932
2638
 
1933
2639
  }, {
@@ -1947,12 +2653,26 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
1947
2653
  return null;
1948
2654
  }
1949
2655
  /**
1950
- * 设定是否可以移动
1951
- * 此方法需指定jmgraph或在控件添加到jmgraph后再调用才能生效。
1952
- *
2656
+ * 设置控件是否可拖动
2657
+ *
2658
+ * 启用或禁用控件的拖动功能。
2659
+ * 拖动时会触发 movestart、move、moveend 事件。
2660
+ *
1953
2661
  * @method canMove
1954
- * @param {boolean} m true=可以移动,false=不可移动或清除移动。
1955
- * @param {jmGraph} [graph] 当前画布,如果为空的话必需是已加入画布的控件,否则得指定画布。
2662
+ * @param {boolean} m - true 启用拖动,false 禁用拖动
2663
+ * @param {jmGraph} [graph] - 画布实例,如果控件已添加到画布可省略
2664
+ * @returns {jmControl} 返回 this 以支持链式调用
2665
+ *
2666
+ * @example
2667
+ * // 启用拖动
2668
+ * control.canMove(true);
2669
+ *
2670
+ * // 禁用拖动
2671
+ * control.canMove(false);
2672
+ *
2673
+ * // 监听拖动事件
2674
+ * control.on('movestart', (evt) => console.log('开始拖动'));
2675
+ * control.on('moveend', (evt) => console.log('结束拖动'));
1956
2676
  */
1957
2677
 
1958
2678
  }, {
@@ -2022,7 +2742,7 @@ var jmControl = /*#__PURE__*/function (_jmProperty) {
2022
2742
  _this.offset(offsetx, offsety, true, evt);
2023
2743
 
2024
2744
  if (offsetx) _this.__mvMonitor.curposition.x = evt.position.offsetX;
2025
- if (offsety) _this.__mvMonitor.curposition.y = evt.position.offsetY; //console.log(offsetx + '.' + offsety);
2745
+ if (offsety) _this.__mvMonitor.curposition.y = evt.position.offsetY; //console.log('mouse move',offsetx + '.' + offsety);
2026
2746
  }
2027
2747
 
2028
2748
  return false;
@@ -2146,15 +2866,63 @@ function _defineProperties(target, props) { for (var i = 0; i < props.length; i+
2146
2866
 
2147
2867
  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
2148
2868
 
2869
+ /**
2870
+ * jmEvents 事件处理类
2871
+ *
2872
+ * 统一管理画布上的所有交互事件,包括鼠标、触摸和键盘事件。
2873
+ * 支持事件冒泡机制,可以将事件传递给子控件处理。
2874
+ *
2875
+ * @class jmEvents
2876
+ *
2877
+ * @param {jmGraph} container jmGraph 实例
2878
+ * @param {HTMLElement} target 事件目标元素(通常是 canvas 元素)
2879
+ *
2880
+ * @example
2881
+ * // 通常由 jmGraph 内部创建,不需要手动实例化
2882
+ * const events = new jmEvents(graph, canvasElement);
2883
+ */
2149
2884
  var jmEvents = /*#__PURE__*/function () {
2885
+ /**
2886
+ * 构造函数
2887
+ *
2888
+ * @param {jmGraph} container jmGraph 实例
2889
+ * @param {HTMLElement} target 事件目标元素
2890
+ */
2150
2891
  function jmEvents(container, target) {
2151
2892
  _classCallCheck(this, jmEvents);
2152
2893
 
2894
+ /**
2895
+ * jmGraph 实例
2896
+ * @type {jmGraph}
2897
+ */
2153
2898
  this.container = container;
2899
+ /**
2900
+ * 事件目标元素
2901
+ * @type {HTMLElement}
2902
+ */
2903
+
2154
2904
  this.target = target || container;
2905
+ /**
2906
+ * 鼠标事件处理器
2907
+ * @type {jmMouseEvent}
2908
+ */
2909
+
2155
2910
  this.mouseHandler = new jmMouseEvent(this, container, target);
2911
+ /**
2912
+ * 键盘事件处理器
2913
+ * @type {jmKeyEvent}
2914
+ */
2915
+
2156
2916
  this.keyHandler = new jmKeyEvent(this, container, target);
2157
2917
  }
2918
+ /**
2919
+ * 触摸开始事件处理
2920
+ *
2921
+ * @method touchStart
2922
+ * @param {TouchEvent} evt 触摸事件对象
2923
+ * @return {boolean} 如果事件目标为画布本身则返回 false
2924
+ */
2925
+
2158
2926
 
2159
2927
  _createClass(jmEvents, [{
2160
2928
  key: "touchStart",
@@ -2170,7 +2938,15 @@ var jmEvents = /*#__PURE__*/function () {
2170
2938
  }
2171
2939
  }, {
2172
2940
  key: "touchMove",
2173
- value: function touchMove(evt) {
2941
+ value:
2942
+ /**
2943
+ * 触摸移动事件处理
2944
+ *
2945
+ * @method touchMove
2946
+ * @param {TouchEvent} evt 触摸事件对象
2947
+ * @return {boolean} 如果事件目标为画布本身则返回 false
2948
+ */
2949
+ function touchMove(evt) {
2174
2950
  evt = evt || window.event;
2175
2951
  evt.eventName = 'touchmove';
2176
2952
  this.container.raiseEvent('touchmove', evt);
@@ -2182,7 +2958,15 @@ var jmEvents = /*#__PURE__*/function () {
2182
2958
  }
2183
2959
  }, {
2184
2960
  key: "touchEnd",
2185
- value: function touchEnd(evt) {
2961
+ value:
2962
+ /**
2963
+ * 触摸结束事件处理
2964
+ *
2965
+ * @method touchEnd
2966
+ * @param {TouchEvent} evt 触摸事件对象
2967
+ * @return {boolean} 如果事件目标为画布本身则返回 false
2968
+ */
2969
+ function touchEnd(evt) {
2186
2970
  evt = evt || window.event;
2187
2971
  evt.eventName = 'touchend';
2188
2972
  this.container.raiseEvent('touchend', evt);
@@ -2194,7 +2978,15 @@ var jmEvents = /*#__PURE__*/function () {
2194
2978
  }
2195
2979
  }, {
2196
2980
  key: "touchCancel",
2197
- value: function touchCancel(evt) {
2981
+ value:
2982
+ /**
2983
+ * 触摸取消事件处理
2984
+ *
2985
+ * @method touchCancel
2986
+ * @param {TouchEvent} evt 触摸事件对象
2987
+ * @return {boolean} 如果事件目标为画布本身则返回 false
2988
+ */
2989
+ function touchCancel(evt) {
2198
2990
  evt = evt || window.event;
2199
2991
  evt.eventName = 'touchcancel';
2200
2992
  this.container.raiseEvent('touchcancel', evt);
@@ -2206,7 +2998,15 @@ var jmEvents = /*#__PURE__*/function () {
2206
2998
  }
2207
2999
  }, {
2208
3000
  key: "tap",
2209
- value: function tap(evt) {
3001
+ value:
3002
+ /**
3003
+ * 轻触事件处理
3004
+ *
3005
+ * @method tap
3006
+ * @param {Event} evt 事件对象
3007
+ * @return {boolean} 如果事件目标为画布本身则返回 false
3008
+ */
3009
+ function tap(evt) {
2210
3010
  evt = evt || window.event;
2211
3011
  evt.eventName = 'tap';
2212
3012
  this.container.raiseEvent('tap', evt);
@@ -2218,7 +3018,15 @@ var jmEvents = /*#__PURE__*/function () {
2218
3018
  }
2219
3019
  }, {
2220
3020
  key: "destroy",
2221
- value: function destroy() {
3021
+ value:
3022
+ /**
3023
+ * 销毁事件处理器
3024
+ *
3025
+ * 移除所有绑定的事件监听器,释放资源。
3026
+ *
3027
+ * @method destroy
3028
+ */
3029
+ function destroy() {
2222
3030
  this.mouseHandler.destroy();
2223
3031
  this.keyHandler.destroy();
2224
3032
  }
@@ -2226,19 +3034,48 @@ var jmEvents = /*#__PURE__*/function () {
2226
3034
 
2227
3035
  return jmEvents;
2228
3036
  }();
3037
+ /**
3038
+ * 鼠标事件处理器
3039
+ *
3040
+ * @class jmMouseEvent
3041
+ * @private
3042
+ */
3043
+
2229
3044
 
2230
3045
  exports.jmEvents = exports["default"] = jmEvents;
2231
3046
 
2232
3047
  var jmMouseEvent = /*#__PURE__*/function () {
3048
+ /**
3049
+ * 构造函数
3050
+ *
3051
+ * @param {jmEvents} instance jmEvents 实例
3052
+ * @param {jmGraph} container jmGraph 实例
3053
+ * @param {HTMLElement} target 事件目标元素
3054
+ */
2233
3055
  function jmMouseEvent(instance, container, target) {
2234
3056
  _classCallCheck(this, jmMouseEvent);
2235
3057
 
2236
3058
  this.instance = instance;
2237
3059
  this.container = container;
2238
3060
  this.target = target || container;
3061
+ /**
3062
+ * 已绑定的事件映射表
3063
+ * @type {Object}
3064
+ */
3065
+
2239
3066
  this.eventEvents = {};
2240
3067
  this.init(instance, container, target);
2241
3068
  }
3069
+ /**
3070
+ * 初始化鼠标事件绑定
3071
+ *
3072
+ * @method init
3073
+ * @private
3074
+ * @param {jmEvents} instance jmEvents 实例
3075
+ * @param {jmGraph} container jmGraph 实例
3076
+ * @param {HTMLElement} target 事件目标元素
3077
+ */
3078
+
2242
3079
 
2243
3080
  _createClass(jmMouseEvent, [{
2244
3081
  key: "init",
@@ -2326,6 +3163,14 @@ var jmMouseEvent = /*#__PURE__*/function () {
2326
3163
  passive: false
2327
3164
  }));
2328
3165
  }
3166
+ /**
3167
+ * 销毁鼠标事件处理器
3168
+ *
3169
+ * 移除所有绑定的鼠标事件监听器。
3170
+ *
3171
+ * @method destroy
3172
+ */
3173
+
2329
3174
  }, {
2330
3175
  key: "destroy",
2331
3176
  value: function destroy() {
@@ -2340,17 +3185,45 @@ var jmMouseEvent = /*#__PURE__*/function () {
2340
3185
 
2341
3186
  return jmMouseEvent;
2342
3187
  }();
3188
+ /**
3189
+ * 键盘事件处理器
3190
+ *
3191
+ * @class jmKeyEvent
3192
+ * @private
3193
+ */
3194
+
2343
3195
 
2344
3196
  var jmKeyEvent = /*#__PURE__*/function () {
3197
+ /**
3198
+ * 构造函数
3199
+ *
3200
+ * @param {jmEvents} instance jmEvents 实例
3201
+ * @param {jmGraph} container jmGraph 实例
3202
+ * @param {HTMLElement} target 事件目标元素
3203
+ */
2345
3204
  function jmKeyEvent(instance, container, target) {
2346
3205
  _classCallCheck(this, jmKeyEvent);
2347
3206
 
2348
3207
  this.instance = instance;
2349
3208
  this.container = container;
2350
3209
  this.target = target || container;
3210
+ /**
3211
+ * 已绑定的事件映射表
3212
+ * @type {Object}
3213
+ */
3214
+
2351
3215
  this.eventEvents = {};
2352
3216
  this.init(container, target);
2353
3217
  }
3218
+ /**
3219
+ * 初始化键盘事件绑定
3220
+ *
3221
+ * @method init
3222
+ * @private
3223
+ * @param {jmGraph} container jmGraph 实例
3224
+ * @param {HTMLElement} target 事件目标元素
3225
+ */
3226
+
2354
3227
 
2355
3228
  _createClass(jmKeyEvent, [{
2356
3229
  key: "init",
@@ -2423,13 +3296,28 @@ function _defineProperties(target, props) { for (var i = 0; i < props.length; i+
2423
3296
  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
2424
3297
 
2425
3298
  /**
2426
- * CSS滤镜效果类
3299
+ * CSS 滤镜效果类
3300
+ *
2427
3301
  * 支持的滤镜: blur, grayscale, sepia, brightness, contrast, saturate, hue-rotate, invert, opacity
2428
3302
  *
2429
3303
  * @class jmFilter
2430
3304
  * @param {string|object} opt 滤镜参数
2431
3305
  * 字符串格式: "blur(2px) grayscale(50%) brightness(1.2)"
2432
3306
  * 对象格式: { blur: 2, grayscale: 0.5, brightness: 1.2 }
3307
+ *
3308
+ * @example
3309
+ * // 从字符串创建
3310
+ * const filter = new jmFilter('blur(2px) grayscale(50%)');
3311
+ *
3312
+ * // 从对象创建
3313
+ * const filter = new jmFilter({
3314
+ * blur: 2,
3315
+ * grayscale: 0.5,
3316
+ * brightness: 1.2
3317
+ * });
3318
+ *
3319
+ * // 应用到图形
3320
+ * shape.style.filter = filter;
2433
3321
  */
2434
3322
  var jmFilter = /*#__PURE__*/function () {
2435
3323
  function jmFilter(opt) {
@@ -2641,9 +3529,36 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
2641
3529
 
2642
3530
  /**
2643
3531
  * 渐变类
2644
- *
3532
+ *
3533
+ * 用于创建和管理线性渐变或径向渐变效果。
3534
+ * 支持 CSS 渐变字符串格式解析,可以转换为 Canvas 或 WebGL 兼容的渐变对象。
3535
+ *
2645
3536
  * @class jmGradient
2646
- * @param {object} op 渐变参数,type:[linear= 线性渐变,radial=放射性渐变]
3537
+ *
3538
+ * @param {Object|string} opt 渐变参数对象或 CSS 渐变字符串
3539
+ * @param {string} [opt.type='linear'] 渐变类型:'linear' 或 'radial'
3540
+ * @param {number|string} [opt.x1] 起点X坐标(支持百分比)
3541
+ * @param {number|string} [opt.y1] 起点Y坐标(支持百分比)
3542
+ * @param {number|string} [opt.x2] 终点X坐标(支持百分比)
3543
+ * @param {number|string} [opt.y2] 终点Y坐标(支持百分比)
3544
+ * @param {number|string} [opt.r1] 内圆半径(径向渐变)
3545
+ * @param {number|string} [opt.r2] 外圆半径(径向渐变)
3546
+ * @param {Array} [opt.stops] 颜色停止点数组 [{offset, color}, ...]
3547
+ *
3548
+ * @example
3549
+ * // 创建线性渐变
3550
+ * const gradient = new jmGradient({
3551
+ * type: 'linear',
3552
+ * x1: 0, y1: 0,
3553
+ * x2: '100%', y2: '100%',
3554
+ * stops: [
3555
+ * { offset: 0, color: '#ff0000' },
3556
+ * { offset: 1, color: '#0000ff' }
3557
+ * ]
3558
+ * });
3559
+ *
3560
+ * // 从 CSS 字符串创建
3561
+ * const gradient = new jmGradient('linear-gradient(180deg, #ff0000, #0000ff)');
2647
3562
  */
2648
3563
  var jmGradient = /*#__PURE__*/function () {
2649
3564
  function jmGradient(opt) {
@@ -2860,9 +3775,10 @@ var jmGradient = /*#__PURE__*/function () {
2860
3775
  if (!s) {
2861
3776
  console.warn('jmGradient: 渐变字符串为空');
2862
3777
  return;
2863
- }
3778
+ } // 使用 [\s\S] 匹配任意字符(包括换行符),支持多行渐变字符串
3779
+
2864
3780
 
2865
- var gradientMatch = s.match(/(linear|radial)-gradient\s*\(\s*(.+)\)/i);
3781
+ var gradientMatch = s.match(/(linear|radial)-gradient\s*\(\s*([\s\S]+)\)/i);
2866
3782
 
2867
3783
  if (!gradientMatch || gradientMatch.length < 3) {
2868
3784
  console.warn('jmGradient: 无效的渐变字符串格式: "' + s + '"');
@@ -3305,13 +4221,17 @@ var jmGradient = /*#__PURE__*/function () {
3305
4221
  value: function _isValidColor(color) {
3306
4222
  if (!color) return false;
3307
4223
  var hexPattern = /^#([a-fA-F0-9]{3,8})$/;
3308
- if (hexPattern.test(color)) return true;
3309
- var rgbPattern = /^rgba?\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*[\d.]+\s*)?\)$/i;
4224
+ if (hexPattern.test(color)) return true; // 支持 rgba(r,g,b,a) 和 rgba(r, g, b, a) 等各种空格格式
4225
+
4226
+ var rgbPattern = /^rgba?\s*\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*(,\s*[\d.]+\s*)?\)$/i;
3310
4227
  if (rgbPattern.test(color)) return true;
3311
- var hslPattern = /^hsla?\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})%?\s*,\s*(\d{1,3})%?\s*(,\s*[\d.]+\s*)?\)$/i;
3312
- if (hslPattern.test(color)) return true;
3313
- var namedColors = ['red', 'blue', 'green', 'yellow', 'orange', 'purple', 'pink', 'white', 'black', 'cyan', 'magenta', 'gray', 'grey', 'brown', 'navy', 'teal', 'olive', 'maroon', 'silver', 'lime', 'aqua', 'fuchsia', 'violet', 'indigo', 'gold', 'silver', 'transparent'];
3314
- if (namedColors.includes(color.toLowerCase())) return true;
4228
+ var hslPattern = /^hsla?\s*\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*(,\s*[\d.]+\s*)?\)$/i;
4229
+ if (hslPattern.test(color)) return true; // 使用 jmUtils 中的完整 CSS 颜色关键字表
4230
+
4231
+ if (_jmUtils.colorKeywords && _jmUtils.colorKeywords[color.toLowerCase()]) return true; // 宽松处理:符合 CSS 关键字命名规则的字符串也视为有效颜色
4232
+ // (纯字母,可能在运行时被浏览器或其他环境解析)
4233
+
4234
+ if (/^[a-zA-Z]+$/.test(color)) return true;
3315
4235
  return false;
3316
4236
  }
3317
4237
  /**
@@ -3667,15 +4587,39 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
3667
4587
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
3668
4588
 
3669
4589
  /**
3670
- * jmGraph画图类库
3671
- * 对canvas画图api进行二次封装,使其更易调用,省去很多重复的工作。
3672
- *
3673
- * @module jmGraph
4590
+ * jmGraph 画图类
4591
+ *
4592
+ * 对 Canvas 画图 API 进行二次封装,使其更易调用,省去很多重复的工作。
4593
+ * 支持多种图形的创建、渲染、交互和导出。
4594
+ *
3674
4595
  * @class jmGraph
3675
4596
  * @extends jmControl
3676
- * @param {element} canvas 标签canvas
3677
- * @param {object} option 参数:{width:宽,height:高}
3678
- * @param {function} callback 初始化后的回调
4597
+ *
4598
+ * @param {HTMLElement|string} canvas Canvas 元素或元素 ID
4599
+ * @param {Object} [option] 配置选项
4600
+ * @param {number} [option.width] 画布宽度
4601
+ * @param {number} [option.height] 画布高度
4602
+ * @param {string} [option.mode='2d'] 渲染模式:'2d' 或 'webgl'
4603
+ * @param {boolean} [option.autoRefresh=false] 是否自动刷新
4604
+ * @param {Object} [option.shapes] 自定义图形类型映射
4605
+ * @param {function} [callback] 初始化完成后的回调函数
4606
+ *
4607
+ * @example
4608
+ * // 创建画布实例
4609
+ * const graph = new jmGraph('canvasId', {
4610
+ * width: 800,
4611
+ * height: 600,
4612
+ * mode: '2d'
4613
+ * });
4614
+ *
4615
+ * // 创建一个矩形
4616
+ * const rect = graph.createShape('rect', {
4617
+ * x: 100, y: 100,
4618
+ * width: 200, height: 150,
4619
+ * style: { fill: '#ff0000' }
4620
+ * });
4621
+ * graph.children.add(rect);
4622
+ * graph.refresh();
3679
4623
  */
3680
4624
  var jmGraph = /*#__PURE__*/function (_jmControl) {
3681
4625
  _inherits(jmGraph, _jmControl);
@@ -4575,11 +5519,61 @@ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || func
4575
5519
 
4576
5520
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
4577
5521
 
5522
+ /**
5523
+ * @fileoverview jmList 列表类
5524
+ *
5525
+ * jmList 是 jmGraph 库的集合类,继承自原生 Array。
5526
+ * 提供了增强的列表操作方法,包括去重添加、条件查找、遍历等。
5527
+ *
5528
+ * 主要功能:
5529
+ * - 去重添加元素(add)
5530
+ * - 条件查找(get)
5531
+ * - 正向/反向遍历(each)
5532
+ * - 元素计数(count)
5533
+ * - 移除回调支持
5534
+ *
5535
+ * @module jmList
5536
+ * @author jmGraph Team
5537
+ * @license MIT
5538
+ */
5539
+
5540
+ /**
5541
+ * jmList 列表类
5542
+ *
5543
+ * 继承自 Array 的增强列表类,提供去重、遍历、查找等功能。
5544
+ * 主要用于管理图形对象的子元素集合。
5545
+ *
5546
+ * @class jmList
5547
+ * @extends Array
5548
+ *
5549
+ * @param {...*} arg 初始元素或数组
5550
+ *
5551
+ * @example
5552
+ * // 创建列表
5553
+ * const list = new jmList([1, 2, 3]);
5554
+ *
5555
+ * // 添加元素(自动去重)
5556
+ * list.add(4);
5557
+ * list.add([5, 6]);
5558
+ *
5559
+ * // 遍历
5560
+ * list.each((index, item) => {
5561
+ * console.log(index, item);
5562
+ * });
5563
+ *
5564
+ * // 条件查找
5565
+ * const found = list.get(item => item > 3);
5566
+ */
4578
5567
  var jmList = /*#__PURE__*/function (_Array) {
4579
5568
  _inherits(jmList, _Array);
4580
5569
 
4581
5570
  var _super = _createSuper(jmList);
4582
5571
 
5572
+ /**
5573
+ * 构造函数
5574
+ *
5575
+ * @param {...*} arg 初始元素或数组
5576
+ */
4583
5577
  function jmList() {
4584
5578
  var _this;
4585
5579
 
@@ -4600,11 +5594,37 @@ var jmList = /*#__PURE__*/function (_Array) {
4600
5594
  } else {
4601
5595
  _this = _super.call(this);
4602
5596
  }
5597
+ /**
5598
+ * 配置选项
5599
+ * @type {Object}
5600
+ * @property {function} removeHandler 元素移除时的回调函数
5601
+ */
5602
+
4603
5603
 
4604
5604
  _this.option = {};
5605
+ /**
5606
+ * 类型标识
5607
+ * @type {string}
5608
+ */
5609
+
4605
5610
  _this.type = 'jmList';
4606
5611
  return _possibleConstructorReturn(_this);
4607
5612
  }
5613
+ /**
5614
+ * 添加元素到列表
5615
+ *
5616
+ * 自动去重,如果元素已存在则不会重复添加。
5617
+ * 支持添加单个元素或数组。
5618
+ *
5619
+ * @method add
5620
+ * @param {*} obj 要添加的元素或数组
5621
+ * @returns {*} 添加的元素
5622
+ *
5623
+ * @example
5624
+ * list.add(1); // 添加单个元素
5625
+ * list.add([2, 3, 4]); // 添加数组
5626
+ */
5627
+
4608
5628
 
4609
5629
  _createClass(jmList, [{
4610
5630
  key: "add",
@@ -4621,6 +5641,18 @@ var jmList = /*#__PURE__*/function (_Array) {
4621
5641
  this.push(obj);
4622
5642
  return obj;
4623
5643
  }
5644
+ /**
5645
+ * 从列表中移除元素
5646
+ *
5647
+ * 移除所有匹配的元素,并触发移除回调。
5648
+ *
5649
+ * @method remove
5650
+ * @param {*} obj 要移除的元素
5651
+ *
5652
+ * @example
5653
+ * list.remove(item);
5654
+ */
5655
+
4624
5656
  }, {
4625
5657
  key: "remove",
4626
5658
  value: function remove(obj) {
@@ -4630,6 +5662,16 @@ var jmList = /*#__PURE__*/function (_Array) {
4630
5662
  }
4631
5663
  }
4632
5664
  }
5665
+ /**
5666
+ * 移除指定索引位置的元素
5667
+ *
5668
+ * @method removeAt
5669
+ * @param {number} index 要移除的元素索引
5670
+ *
5671
+ * @example
5672
+ * list.removeAt(0); // 移除第一个元素
5673
+ */
5674
+
4633
5675
  }, {
4634
5676
  key: "removeAt",
4635
5677
  value: function removeAt(index) {
@@ -4639,11 +5681,42 @@ var jmList = /*#__PURE__*/function (_Array) {
4639
5681
  if (this.option.removeHandler) this.option.removeHandler.call(this, obj, index);
4640
5682
  }
4641
5683
  }
5684
+ /**
5685
+ * 检查列表是否包含指定元素
5686
+ *
5687
+ * @method contain
5688
+ * @param {*} obj 要检查的元素
5689
+ * @returns {boolean} 如果包含返回 true,否则返回 false
5690
+ *
5691
+ * @example
5692
+ * if (list.contain(item)) {
5693
+ * console.log('元素存在');
5694
+ * }
5695
+ */
5696
+
4642
5697
  }, {
4643
5698
  key: "contain",
4644
5699
  value: function contain(obj) {
4645
5700
  return this.includes(obj);
4646
5701
  }
5702
+ /**
5703
+ * 获取元素
5704
+ *
5705
+ * 如果参数是函数,则返回第一个满足条件的元素;
5706
+ * 如果参数是数字,则返回指定索引的元素。
5707
+ *
5708
+ * @method get
5709
+ * @param {number|function} index 索引或条件函数
5710
+ * @returns {*} 找到的元素,如果未找到返回 undefined
5711
+ *
5712
+ * @example
5713
+ * // 按索引获取
5714
+ * const item = list.get(0);
5715
+ *
5716
+ * // 按条件查找
5717
+ * const found = list.get(item => item.id === 5);
5718
+ */
5719
+
4647
5720
  }, {
4648
5721
  key: "get",
4649
5722
  value: function get(index) {
@@ -4653,6 +5726,28 @@ var jmList = /*#__PURE__*/function (_Array) {
4653
5726
  return this[index];
4654
5727
  }
4655
5728
  }
5729
+ /**
5730
+ * 遍历列表
5731
+ *
5732
+ * 支持正向和反向遍历。在回调中返回 false 可以中断遍历。
5733
+ *
5734
+ * @method each
5735
+ * @param {function} cb 回调函数,参数为 (index, item)
5736
+ * @param {boolean} [inverse=false] 是否反向遍历
5737
+ *
5738
+ * @example
5739
+ * // 正向遍历
5740
+ * list.each((index, item) => {
5741
+ * console.log(index, item);
5742
+ * if (item.id === 3) return false; // 中断遍历
5743
+ * });
5744
+ *
5745
+ * // 反向遍历
5746
+ * list.each((index, item) => {
5747
+ * console.log(index, item);
5748
+ * }, true);
5749
+ */
5750
+
4656
5751
  }, {
4657
5752
  key: "each",
4658
5753
  value: function each(cb, inverse) {
@@ -4673,6 +5768,21 @@ var jmList = /*#__PURE__*/function (_Array) {
4673
5768
  }
4674
5769
  }
4675
5770
  }
5771
+ /**
5772
+ * 统计元素数量
5773
+ *
5774
+ * 如果提供了条件函数,返回满足条件的元素数量;
5775
+ * 否则返回列表总长度。
5776
+ *
5777
+ * @method count
5778
+ * @param {function} [handler] 条件函数
5779
+ * @returns {number} 元素数量
5780
+ *
5781
+ * @example
5782
+ * const total = list.count(); // 总数量
5783
+ * const matched = list.count(item => item.active); // 满足条件的数量
5784
+ */
5785
+
4676
5786
  }, {
4677
5787
  key: "count",
4678
5788
  value: function count(handler) {
@@ -4691,6 +5801,17 @@ var jmList = /*#__PURE__*/function (_Array) {
4691
5801
 
4692
5802
  return this.length;
4693
5803
  }
5804
+ /**
5805
+ * 清空列表
5806
+ *
5807
+ * 移除列表中的所有元素。
5808
+ *
5809
+ * @method clear
5810
+ *
5811
+ * @example
5812
+ * list.clear();
5813
+ */
5814
+
4694
5815
  }, {
4695
5816
  key: "clear",
4696
5817
  value: function clear() {
@@ -4719,91 +5840,197 @@ function _defineProperties(target, props) { for (var i = 0; i < props.length; i+
4719
5840
 
4720
5841
  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
4721
5842
 
5843
+ /**
5844
+ * 控件ID计数器
5845
+ * 用于为每个新创建的对象生成唯一标识符
5846
+ * @type {number}
5847
+ * @private
5848
+ */
4722
5849
  var control_id_counter = 0;
5850
+ /**
5851
+ * jmGraph 基础对象类
5852
+ *
5853
+ * 所有图形控件、属性对象、工具类的基类。
5854
+ * 提供了对象标识、类型检查和动画调度等核心功能。
5855
+ *
5856
+ * @class jmObject
5857
+ * @example
5858
+ * // 创建一个基础对象
5859
+ * const obj = new jmObject();
5860
+ * console.log(obj.id); // 输出唯一ID
5861
+ *
5862
+ * // 类型检查
5863
+ * obj.is('jmObject'); // true
5864
+ * obj.is(jmObject); // true
5865
+ */
4723
5866
 
4724
5867
  var jmObject = /*#__PURE__*/function () {
5868
+ /**
5869
+ * 构造函数
5870
+ *
5871
+ * 创建一个新的基础对象实例,自动分配唯一ID。
5872
+ * 如果传入的是 jmGraph 实例,则建立关联关系。
5873
+ *
5874
+ * @constructor
5875
+ * @param {jmGraph} [g] - 可选的 jmGraph 实例,用于建立对象与画布的关联
5876
+ *
5877
+ * @example
5878
+ * // 创建独立对象
5879
+ * const obj = new jmObject();
5880
+ *
5881
+ * // 创建关联画布的对象
5882
+ * const graph = new jmGraph(canvas);
5883
+ * const objWithGraph = new jmObject(graph);
5884
+ */
4725
5885
  function jmObject(g) {
4726
5886
  _classCallCheck(this, jmObject);
4727
5887
 
5888
+ // 如果传入的是 jmGraph 实例,则建立引用关系
4728
5889
  if (g && g.type == 'jmGraph') {
4729
5890
  this.graph = g;
4730
- }
5891
+ } // 生成唯一ID
5892
+
4731
5893
 
4732
5894
  this.id = ++control_id_counter;
4733
5895
  }
4734
5896
  /**
4735
- * 检 查对象是否为指定类型
5897
+ * 检查对象是否为指定类型
5898
+ *
5899
+ * 支持两种类型检查方式:
5900
+ * 1. 字符串方式:检查对象的 type 属性是否匹配
5901
+ * 2. 类构造函数方式:使用 instanceof 检查原型链
4736
5902
  *
4737
5903
  * @method is
4738
- * @param {class} type 判断的类型
4739
- * @for jmObject
4740
- * @return {boolean} true=表示当前对象为指定的类型type,false=表示不是
5904
+ * @param {string|Function} type - 要检查的类型名称(字符串)或类构造函数
5905
+ * @returns {boolean} 如果对象是指定类型则返回 true,否则返回 false
5906
+ *
5907
+ * @example
5908
+ * // 使用字符串检查
5909
+ * control.is('jmRect'); // 检查是否为矩形
5910
+ *
5911
+ * // 使用类构造函数检查
5912
+ * control.is(jmControl); // 检查是否为 jmControl 实例
5913
+ * control.is(jmPath); // 检查是否继承自 jmPath
4741
5914
  */
4742
5915
 
4743
5916
 
4744
5917
  _createClass(jmObject, [{
4745
5918
  key: "is",
4746
5919
  value: function is(type) {
5920
+ // 字符串类型:检查 type 属性
4747
5921
  if (typeof type == 'string') {
4748
5922
  return this.type == type;
4749
- }
5923
+ } // 类构造函数:使用 instanceof 检查原型链
5924
+
4750
5925
 
4751
5926
  return this instanceof type;
4752
5927
  }
5928
+ /**
5929
+ * 注册并执行动画帧回调
5930
+ *
5931
+ * 提供动画帧调度功能,支持:
5932
+ * - 按指定时间间隔执行回调
5933
+ * - 多个动画句柄并行执行
5934
+ * - 自动清理返回 false 的动画
5935
+ * - 错误自动移除异常动画
5936
+ *
5937
+ * 此方法通常由 jmGraph 实例调用,子控件会委托给所属的 graph 处理。
5938
+ *
5939
+ * @method animate
5940
+ * @param {Function} handle - 动画回调函数,返回 false 时自动移除
5941
+ * @param {number} [millisec=20] - 执行间隔(毫秒),默认 20ms
5942
+ * @param {...*} [params] - 传递给回调函数的额外参数
5943
+ *
5944
+ * @example
5945
+ * // 创建一个简单的动画
5946
+ * let x = 0;
5947
+ * graph.animate(function() {
5948
+ * x += 1;
5949
+ * rect.position.x = x;
5950
+ * graph.redraw();
5951
+ *
5952
+ * // 动画结束条件
5953
+ * if(x > 100) return false;
5954
+ * }, 16); // 约60fps
5955
+ *
5956
+ * // 带参数的动画
5957
+ * graph.animate(function(speed) {
5958
+ * x += speed;
5959
+ * // ...
5960
+ * }, 16, 5); // speed = 5
5961
+ */
5962
+
4753
5963
  }, {
4754
5964
  key: "animate",
4755
5965
  value: function animate() {
5966
+ // 只有 jmGraph 实例才真正处理动画调度
4756
5967
  if (this.is('jmGraph')) {
5968
+ // 注册新的动画句柄
4757
5969
  if (arguments.length > 1) {
4758
- if (!this.animateHandles) this.animateHandles = new _jmList.jmList();
5970
+ if (!this.animateHandles) this.animateHandles = new _jmList.jmList(); // 收集额外参数
5971
+
4759
5972
  var params = [];
4760
5973
 
4761
5974
  if (arguments.length > 2) {
4762
5975
  for (var i = 2; i < arguments.length; i++) {
4763
5976
  params.push(i < 0 || arguments.length <= i ? undefined : arguments[i]);
4764
5977
  }
4765
- }
5978
+ } // 添加动画句柄到列表
5979
+
4766
5980
 
4767
5981
  this.animateHandles.add({
4768
5982
  millisec: (arguments.length <= 1 ? undefined : arguments[1]) || 20,
5983
+ // 执行间隔
4769
5984
  handle: arguments.length <= 0 ? undefined : arguments[0],
4770
- params: params
5985
+ // 回调函数
5986
+ params: params // 额外参数
5987
+
4771
5988
  });
4772
- }
5989
+ } // 如果有动画句柄,启动调度循环
5990
+
4773
5991
 
4774
5992
  if (this.animateHandles) {
4775
5993
  if (this.animateHandles.count() > 0) {
4776
- var self = this;
5994
+ var self = this; // 使用 setTimeout 进行调度(避免 requestAnimationFrame 的固定帧率限制)
5995
+
4777
5996
  this.dispatcher = setTimeout(function (_this) {
4778
5997
  _this = _this || self;
4779
- var overduehandles = [];
4780
- var curTimes = Date.now();
5998
+ var overduehandles = []; // 需要移除的句柄
5999
+
6000
+ var curTimes = Date.now(); // 遍历执行所有动画句柄
4781
6001
 
4782
6002
  _this.animateHandles.each(function (i, ani) {
4783
6003
  try {
6004
+ // 检查是否到达执行时间
4784
6005
  if (ani && ani.handle && (!ani.times || curTimes - ani.times >= ani.millisec)) {
4785
- var r = ani.handle.apply(_this, ani.params);
6006
+ // 执行回调
6007
+ var r = ani.handle.apply(_this, ani.params); // 返回 false 表示动画结束
4786
6008
 
4787
6009
  if (r === false) {
4788
6010
  overduehandles.push(ani);
4789
- }
6011
+ } // 更新最后执行时间
6012
+
4790
6013
 
4791
6014
  ani.times = curTimes;
4792
6015
  }
4793
6016
  } catch (e) {
6017
+ // 出错的句柄自动移除
4794
6018
  if (ani) overduehandles.push(ani);
4795
6019
  }
4796
- });
6020
+ }); // 移除已完成的动画句柄
6021
+
4797
6022
 
4798
6023
  for (var _i in overduehandles) {
4799
6024
  _this.animateHandles.remove(overduehandles[_i]);
4800
- }
6025
+ } // 继续下一轮调度
6026
+
4801
6027
 
4802
6028
  _this.animate();
4803
6029
  }, 10, this);
4804
6030
  }
4805
6031
  }
4806
6032
  } else {
6033
+ // 非 jmGraph 对象委托给所属的 graph 处理
4807
6034
  var graph = this.graph;
4808
6035
 
4809
6036
  if (graph) {
@@ -4851,12 +6078,33 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
4851
6078
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
4852
6079
 
4853
6080
  /**
4854
- * 基础路径,大部分图型的基类
4855
- * 指定一系列点,画出图形
4856
- *
6081
+ * 基础路径类
6082
+ *
6083
+ * 大部分图形的基类,通过指定一系列点来画出图形。
6084
+ * 支持开放路径和闭合路径,支持 SVG 导出。
6085
+ *
4857
6086
  * @class jmPath
4858
6087
  * @extends jmControl
4859
- * @param {object} params 路径参数 points=所有描点
6088
+ *
6089
+ * @param {Object} params 路径参数
6090
+ * @param {Array<Object>} [params.points] 点序列,每个点格式:{x:0, y:0, m:false}
6091
+ * @param {string} [t='jmPath'] 类型标识
6092
+ *
6093
+ * @example
6094
+ * // 创建自定义路径
6095
+ * const path = new jmPath({
6096
+ * points: [
6097
+ * {x: 0, y: 0},
6098
+ * {x: 100, y: 0},
6099
+ * {x: 100, y: 100},
6100
+ * {x: 0, y: 100}
6101
+ * ],
6102
+ * style: {
6103
+ * fill: '#ff0000',
6104
+ * stroke: '#000000',
6105
+ * close: true // 闭合路径
6106
+ * }
6107
+ * });
4860
6108
  */
4861
6109
  var jmPath = /*#__PURE__*/function (_jmControl) {
4862
6110
  _inherits(jmPath, _jmControl);
@@ -4990,23 +6238,94 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
4990
6238
 
4991
6239
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
4992
6240
 
6241
+ /**
6242
+ * 属性存储的 Symbol 键
6243
+ * 使用 Symbol 确保属性存储的私有性和唯一性
6244
+ * @type {Symbol}
6245
+ * @private
6246
+ */
4993
6247
  var PROPERTY_KEY = Symbol("properties");
6248
+ /**
6249
+ * jmGraph 属性管理基类
6250
+ *
6251
+ * jmProperty 是 jmControl 的父类,为所有图形控件提供属性管理功能。
6252
+ * 采用 Symbol + WeakMap 模式实现真正的私有属性存储,避免属性名冲突。
6253
+ *
6254
+ * 核心特性:
6255
+ * 1. **私有属性存储**:使用 Symbol 键确保属性不被外部直接访问
6256
+ * 2. **属性变更通知**:设置属性时自动触发 'propertyChange' 事件
6257
+ * 3. **渲染模式继承**:子控件自动继承所属 graph 的渲染模式
6258
+ * 4. **脏标记传播**:子控件 needUpdate 会自动传播到 graph
6259
+ *
6260
+ * @class jmProperty
6261
+ * @extends jmObject
6262
+ *
6263
+ * @example
6264
+ * // 创建属性对象
6265
+ * const prop = new jmProperty({ mode: 'webgl' });
6266
+ *
6267
+ * // 设置和获取属性
6268
+ * prop.property('customValue', 100);
6269
+ * console.log(prop.property('customValue')); // 100
6270
+ *
6271
+ * // 监听属性变更
6272
+ * prop.on('propertyChange', (name, args) => {
6273
+ * console.log(`${name} changed from ${args.oldValue} to ${args.newValue}`);
6274
+ * });
6275
+ */
4994
6276
 
4995
6277
  var jmProperty = /*#__PURE__*/function (_jmObject) {
4996
6278
  _inherits(jmProperty, _jmObject);
4997
6279
 
4998
6280
  var _super = _createSuper(jmProperty);
4999
6281
 
6282
+ /**
6283
+ * 构造函数
6284
+ *
6285
+ * 初始化属性存储对象,并设置初始渲染模式。
6286
+ *
6287
+ * @constructor
6288
+ * @param {Object} [params] - 初始化参数
6289
+ * @param {'2d'|'webgl'} [params.mode] - 渲染模式,默认 '2d'
6290
+ *
6291
+ * @example
6292
+ * // 创建使用 WebGL 渲染的属性对象
6293
+ * const prop = new jmProperty({ mode: 'webgl' });
6294
+ */
5000
6295
  function jmProperty(params) {
5001
6296
  var _this;
5002
6297
 
5003
6298
  _classCallCheck(this, jmProperty);
5004
6299
 
5005
- _this = _super.call(this);
5006
- _this[PROPERTY_KEY] = {};
6300
+ _this = _super.call(this); // 初始化私有属性存储对象
6301
+
6302
+ _this[PROPERTY_KEY] = {}; // 设置渲染模式
6303
+
5007
6304
  if (params && params.mode) _this.mode = params.mode;
5008
6305
  return _this;
5009
6306
  }
6307
+ /**
6308
+ * 获取或设置属性值
6309
+ *
6310
+ * 这是属性系统的核心方法,所有属性的存取都通过此方法。
6311
+ * 设置属性时会自动触发 'propertyChange' 事件,便于实现响应式更新。
6312
+ *
6313
+ * @method property
6314
+ * @param {string} name - 属性名称
6315
+ * @param {*} [value] - 属性值(设置时提供)
6316
+ * @returns {*} 获取时返回属性值,设置时返回设置的值
6317
+ *
6318
+ * @example
6319
+ * // 获取属性
6320
+ * const value = obj.property('myProp');
6321
+ *
6322
+ * // 设置属性
6323
+ * obj.property('myProp', 'newValue');
6324
+ *
6325
+ * // 链式调用
6326
+ * obj.property('a', 1).property('b', 2);
6327
+ */
6328
+
5010
6329
 
5011
6330
  _createClass(jmProperty, [{
5012
6331
  key: "property",
@@ -5017,7 +6336,7 @@ var jmProperty = /*#__PURE__*/function (_jmObject) {
5017
6336
 
5018
6337
  if (pars) {
5019
6338
  var pros = this[PROPERTY_KEY];
5020
- var name = pars[0];
6339
+ var name = pars[0]; // 设置属性
5021
6340
 
5022
6341
  if (pars.length > 1) {
5023
6342
  var value = pars[1];
@@ -5025,51 +6344,149 @@ var jmProperty = /*#__PURE__*/function (_jmObject) {
5025
6344
  oldValue: pros[name],
5026
6345
  newValue: value
5027
6346
  };
5028
- pros[name] = pars[1];
6347
+ pros[name] = pars[1]; // 触发属性变更事件(如果对象支持事件)
6348
+
5029
6349
  if (this.emit) this.emit('propertyChange', name, args);
5030
6350
  return pars[1];
5031
- } else if (name) {
6351
+ } // 获取属性
6352
+ else if (name) {
5032
6353
  return pros[name];
5033
6354
  }
5034
6355
  }
5035
6356
  }
6357
+ /**
6358
+ * 是否需要重绘标记
6359
+ *
6360
+ * 当属性变化导致需要重新渲染时设置此标记。
6361
+ * 设置为 true 时,会自动将所属 graph 的 needUpdate 设为 true,
6362
+ * 从而触发画布重绘。
6363
+ *
6364
+ * @type {boolean}
6365
+ *
6366
+ * @example
6367
+ * // 标记需要重绘
6368
+ * control.needUpdate = true;
6369
+ *
6370
+ * // 检查是否需要重绘
6371
+ * if(control.needUpdate) {
6372
+ * control.redraw();
6373
+ * }
6374
+ */
6375
+
5036
6376
  }, {
5037
6377
  key: "needUpdate",
5038
6378
  get: function get() {
5039
6379
  return this.property('needUpdate');
5040
6380
  },
5041
6381
  set: function set(v) {
5042
- this.property('needUpdate', v);
6382
+ this.property('needUpdate', v); // 传播脏标记到 graph(避免 jmGraph 自身循环)
5043
6383
 
5044
6384
  if (v && !this.is('jmGraph') && this.graph) {
5045
6385
  this.graph.needUpdate = true;
5046
6386
  }
5047
6387
  }
6388
+ /**
6389
+ * 所属的画布实例
6390
+ *
6391
+ * 获取或设置当前对象所属的 jmGraph 实例。
6392
+ * 如果未显式设置,会自动向上查找父级链中的 jmGraph。
6393
+ *
6394
+ * @type {jmGraph}
6395
+ *
6396
+ * @example
6397
+ * // 获取所属画布
6398
+ * const graph = control.graph;
6399
+ *
6400
+ * // 设置所属画布(通常由框架内部调用)
6401
+ * control.graph = myGraph;
6402
+ */
6403
+
5048
6404
  }, {
5049
6405
  key: "graph",
5050
6406
  get: function get() {
5051
- var g = this.property('graph');
6407
+ var g = this.property('graph'); // 如果未设置,尝试从父级链查找
6408
+
5052
6409
  g = g || this.property('graph', this.findParent('jmGraph'));
5053
6410
  return g;
5054
6411
  },
5055
6412
  set: function set(v) {
5056
6413
  return this.property('graph', v);
5057
6414
  }
6415
+ /**
6416
+ * 渲染模式
6417
+ *
6418
+ * 获取当前渲染模式,支持 '2d' 和 'webgl' 两种模式。
6419
+ * 渲染模式的查找优先级:
6420
+ * 1. 当前对象设置的 mode
6421
+ * 2. 如果是 jmGraph,默认 '2d'
6422
+ * 3. 从所属 graph 继承 mode
6423
+ *
6424
+ * @type {'2d'|'webgl'}
6425
+ * @readonly
6426
+ *
6427
+ * @example
6428
+ * // 检查渲染模式
6429
+ * if(control.mode === 'webgl') {
6430
+ * // 使用 WebGL 特性
6431
+ * } else {
6432
+ * // 使用 Canvas 2D API
6433
+ * }
6434
+ */
6435
+
5058
6436
  }, {
5059
6437
  key: "mode",
5060
6438
  get: function get() {
6439
+ var _this$graph;
6440
+
5061
6441
  var m = this.property('mode');
5062
- if (m) return m;else if (this.is('jmGraph')) return this.property('mode');
5063
- return this.graph.mode;
6442
+ if (m) return m; // 如果当前对象是jmGraph且没有设置mode,返回默认值
6443
+
6444
+ if (this.is('jmGraph')) return this.property('mode') || '2d'; // 否则从所属的graph获取mode
6445
+
6446
+ return ((_this$graph = this.graph) === null || _this$graph === void 0 ? void 0 : _this$graph.mode) || '2d';
5064
6447
  },
5065
6448
  set: function set(v) {
5066
6449
  return this.property('mode', v);
5067
6450
  }
6451
+ /**
6452
+ * 请求动画帧
6453
+ *
6454
+ * 封装 requestAnimationFrame,支持在不同环境下工作。
6455
+ * 如果当前对象关联了 canvas,会使用 canvas 的 requestAnimationFrame。
6456
+ *
6457
+ * @method requestAnimationFrame
6458
+ * @param {Function} handler - 动画帧回调函数
6459
+ * @returns {number} 动画帧请求ID,用于取消
6460
+ *
6461
+ * @example
6462
+ * // 请求下一帧动画
6463
+ * const frameId = control.requestAnimationFrame(() => {
6464
+ * // 更新动画状态
6465
+ * control.redraw();
6466
+ * });
6467
+ *
6468
+ * // 取消动画帧
6469
+ * control.cancelAnimationFrame(frameId);
6470
+ */
6471
+
5068
6472
  }, {
5069
6473
  key: "requestAnimationFrame",
5070
6474
  value: function requestAnimationFrame(handler) {
5071
6475
  return _jmUtils.jmUtils.requestAnimationFrame(handler, this.graph ? this.graph.canvas : null);
5072
6476
  }
6477
+ /**
6478
+ * 取消动画帧请求
6479
+ *
6480
+ * 取消之前通过 requestAnimationFrame 注册的回调。
6481
+ *
6482
+ * @method cancelAnimationFrame
6483
+ * @param {number} handler - 动画帧请求ID
6484
+ *
6485
+ * @example
6486
+ * // 取消动画帧
6487
+ * control.cancelAnimationFrame(frameId);
6488
+ */
6489
+
5073
6490
  }, {
5074
6491
  key: "cancelAnimationFrame",
5075
6492
  value: function cancelAnimationFrame(handler) {
@@ -5099,13 +6516,26 @@ function _defineProperties(target, props) { for (var i = 0; i < props.length; i+
5099
6516
  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
5100
6517
 
5101
6518
  /**
5102
- * 画图阴影对象表示法
5103
- *
6519
+ * 阴影类
6520
+ *
6521
+ * 用于创建图形的阴影效果。阴影可以应用于任何图形控件。
6522
+ *
5104
6523
  * @class jmShadow
5105
- * @param {number} x 横坐标偏移量
5106
- * @param {number} y 纵坐标编移量
5107
- * @param {number} blur 模糊值
5108
- * @param {string} color 阴影的颜色
6524
+ *
6525
+ * @param {number|string} x 横坐标偏移量,或阴影字符串格式 'x,y,blur,color'
6526
+ * @param {number} [y] 纵坐标偏移量
6527
+ * @param {number} [blur] 模糊值
6528
+ * @param {string} [color] 阴影颜色
6529
+ *
6530
+ * @example
6531
+ * // 创建阴影
6532
+ * const shadow = new jmShadow(5, 5, 10, 'rgba(0,0,0,0.5)');
6533
+ *
6534
+ * // 从字符串创建
6535
+ * const shadow = new jmShadow('5, 5, 10, rgba(0,0,0,0.5)');
6536
+ *
6537
+ * // 应用到图形
6538
+ * rect.style.shadow = shadow;
5109
6539
  */
5110
6540
  var jmShadow = /*#__PURE__*/function () {
5111
6541
  function jmShadow(x, y, blur, color) {
@@ -5181,7 +6611,7 @@ exports.jmShadow = exports["default"] = jmShadow;
5181
6611
  Object.defineProperty(exports, "__esModule", {
5182
6612
  value: true
5183
6613
  });
5184
- exports.jmUtils = exports["default"] = void 0;
6614
+ exports.colorKeywords = exports.jmUtils = exports["default"] = void 0;
5185
6615
 
5186
6616
  var _jmList = require("./jmList.js");
5187
6617
 
@@ -5199,6 +6629,15 @@ function _defineProperties(target, props) { for (var i = 0; i < props.length; i+
5199
6629
 
5200
6630
  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
5201
6631
 
6632
+ /**
6633
+ * CSS 颜色关键字映射表
6634
+ *
6635
+ * 包含所有 CSS 标准颜色名称到十六进制值的映射。
6636
+ * 支持 147 种命名颜色 + CSS 系统颜色。
6637
+ *
6638
+ * @constant {Object.<string, string>}
6639
+ * @private
6640
+ */
5202
6641
  var colorKeywords = {
5203
6642
  aliceblue: "#f0f8ff",
5204
6643
  antiquewhite: "#faebd7",
@@ -5236,11 +6675,13 @@ var colorKeywords = {
5236
6675
  darkseagreen: "#8fbc8f",
5237
6676
  darkslateblue: "#483d8b",
5238
6677
  darkslategray: "#2f4f4f",
6678
+ darkslategrey: "#2f4f4f",
5239
6679
  darkturquoise: "#00ced1",
5240
6680
  darkviolet: "#9400d3",
5241
6681
  deeppink: "#ff1493",
5242
6682
  deepskyblue: "#00bfff",
5243
6683
  dimgray: "#696969",
6684
+ dimgrey: "#696969",
5244
6685
  dodgerblue: "#1e90ff",
5245
6686
  firebrick: "#b22222",
5246
6687
  floralwhite: "#fffaf0",
@@ -5275,6 +6716,7 @@ var colorKeywords = {
5275
6716
  lightseagreen: "#20b2aa",
5276
6717
  lightskyblue: "#87cefa",
5277
6718
  lightslategray: "#778899",
6719
+ lightslategrey: "#778899",
5278
6720
  lightsteelblue: "#b0c4de",
5279
6721
  lightyellow: "#ffffe0",
5280
6722
  lime: "#00ff00",
@@ -5315,6 +6757,7 @@ var colorKeywords = {
5315
6757
  powderblue: "#b0e0e6",
5316
6758
  purple: "#800080",
5317
6759
  red: "#ff0000",
6760
+ rebeccapurple: "#663399",
5318
6761
  rosybrown: "#bc8f8f",
5319
6762
  royalblue: "#4169e1",
5320
6763
  saddlebrown: "#8b4513",
@@ -5327,6 +6770,7 @@ var colorKeywords = {
5327
6770
  skyblue: "#87ceeb",
5328
6771
  slateblue: "#6a5acd",
5329
6772
  slategray: "#708090",
6773
+ slategrey: "#708090",
5330
6774
  snow: "#fffafa",
5331
6775
  springgreen: "#00ff7f",
5332
6776
  steelblue: "#4682b4",
@@ -5341,16 +6785,59 @@ var colorKeywords = {
5341
6785
  whitesmoke: "#f5f5f5",
5342
6786
  yellow: "#ffff00",
5343
6787
  yellowgreen: "#9acd32",
5344
- transparent: "rgba(0,0,0,0)"
6788
+ transparent: "rgba(0,0,0,0)",
6789
+ // grey 别名(已有 darkslategrey/lightslategrey/slategrey/dimgrey)
6790
+ // 以下为 CSS 系统颜色
6791
+ activeborder: "#bfcaca",
6792
+ activecaption: "#000080",
6793
+ appworkspace: "#ababab",
6794
+ background: "#636363",
6795
+ buttonface: "#c0c0c0",
6796
+ buttonhighlight: "#dedede",
6797
+ buttonshadow: "#808080",
6798
+ buttontext: "#000000",
6799
+ captiontext: "#000000",
6800
+ graytext: "#808080",
6801
+ highlight: "#b3d4fc",
6802
+ highlighttext: "#000000",
6803
+ inactiveborder: "#d4d0c8",
6804
+ inactivecaption: "#bfbbb0",
6805
+ inactivecaptiontext: "#545454",
6806
+ infobackground: "#fbfcc5",
6807
+ infotext: "#000000",
6808
+ menu: "#c0c0c0",
6809
+ menutext: "#000000",
6810
+ scrollbar: "#c0c0c0",
6811
+ threeddarkshadow: "#696969",
6812
+ threedface: "#c0c0c0",
6813
+ threedhighlight: "#dfdfdf",
6814
+ threedlightshadow: "#dcdcdc",
6815
+ threedshadow: "#808080",
6816
+ window: "#ffffff",
6817
+ windowframe: "#646464",
6818
+ windowtext: "#000000"
5345
6819
  };
5346
6820
  /**
5347
- * 画图基础对象
5348
- * 当前库的工具类
6821
+ * jmGraph 工具类
6822
+ *
6823
+ * 提供常用的静态工具方法,包括对象操作、事件处理、几何计算、颜色转换等。
5349
6824
  *
5350
6825
  * @class jmUtils
5351
6826
  * @static
6827
+ *
6828
+ * @example
6829
+ * // 克隆对象
6830
+ * const newObj = jmUtils.clone({ a: 1, b: 2 });
6831
+ *
6832
+ * // 绑定事件
6833
+ * jmUtils.bindEvent(element, 'click', handler);
6834
+ *
6835
+ * // 检查点是否在多边形内
6836
+ * const inside = jmUtils.pointInPolygon({x: 10, y: 10}, polygonPoints);
5352
6837
  */
5353
6838
 
6839
+ exports.colorKeywords = colorKeywords;
6840
+
5354
6841
  var jmUtils = /*#__PURE__*/function () {
5355
6842
  function jmUtils() {
5356
6843
  _classCallCheck(this, jmUtils);
@@ -5540,7 +7027,7 @@ var jmUtils = /*#__PURE__*/function () {
5540
7027
  }
5541
7028
  } else if (el.x) {
5542
7029
  pos.left += el.x;
5543
- } else if (el.x) {
7030
+ } else if (el.y) {
5544
7031
  pos.top += el.y;
5545
7032
  }
5546
7033
 
@@ -5675,6 +7162,31 @@ var jmUtils = /*#__PURE__*/function () {
5675
7162
 
5676
7163
  return this.rayCasting(pt, polygon, offset);
5677
7164
  }
7165
+ /**
7166
+ * 判断点是否在线段上
7167
+ *
7168
+ * 通过计算点到线段的垂直距离来判断点是否在线段上。
7169
+ * 同时检查点是否在线段的范围内(不仅仅是直线上)。
7170
+ *
7171
+ * @method pointOnLine
7172
+ * @static
7173
+ * @private
7174
+ * @param {Object} pt 待检测的点 {x, y}
7175
+ * @param {Object} p1 线段起点 {x, y}
7176
+ * @param {Object} p2 线段终点 {x, y}
7177
+ * @param {number} offset 允许的偏差值(像素)
7178
+ * @returns {number} 0=不在线段上, 1=在线段上
7179
+ *
7180
+ * @example
7181
+ * const onLine = jmUtils.pointOnLine(
7182
+ * {x: 5, y: 5}, // 待检测点
7183
+ * {x: 0, y: 0}, // 起点
7184
+ * {x: 10, y: 10}, // 终点
7185
+ * 2 // 允许偏差
7186
+ * );
7187
+ * // 返回 1,点在对角线上
7188
+ */
7189
+
5678
7190
  }, {
5679
7191
  key: "pointOnLine",
5680
7192
  value: function pointOnLine(pt, p1, p2, offset) {
@@ -5716,6 +7228,26 @@ var jmUtils = /*#__PURE__*/function () {
5716
7228
 
5717
7229
  return 0;
5718
7230
  }
7231
+ /**
7232
+ * 射线法判断点是否在多边形内部
7233
+ *
7234
+ * 从待测点向右发射一条水平射线,计算与多边形边界的交点数量。
7235
+ * - 交点数为奇数:点在多边形内部
7236
+ * - 交点数为偶数:点在多边形外部
7237
+ *
7238
+ * 这是判断点是否在任意多边形内的经典算法,时间复杂度 O(n)。
7239
+ *
7240
+ * @method rayCasting
7241
+ * @static
7242
+ * @private
7243
+ * @param {Object} pt 待检测的点 {x, y}
7244
+ * @param {Array<Object>} polygon 多边形顶点数组 [{x, y}, ...]
7245
+ * @param {number} offset 允许的偏差值(未使用)
7246
+ * @returns {number} 0=在多边形外部, 2=在多边形内部
7247
+ *
7248
+ * @see {@link https://en.wikipedia.org/wiki/Point_in_polygon Point in polygon - Wikipedia}
7249
+ */
7250
+
5719
7251
  }, {
5720
7252
  key: "rayCasting",
5721
7253
  value: function rayCasting(pt, polygon, offset) {
@@ -6124,8 +7656,19 @@ var jmUtils = /*#__PURE__*/function () {
6124
7656
  return this.__hexToRGBA_Cache[hex] = res;
6125
7657
  }
6126
7658
  /**
6127
- * 255的rgb值转为0-1的值
6128
- * @param {rgba} color 颜色
7659
+ * 将 RGB 颜色值从 0-255 范围转换为 0-1 范围
7660
+ *
7661
+ * WebGL 中的颜色值通常使用 0-1 的浮点数表示,
7662
+ * 此方法用于将标准 RGB 值转换为 WebGL 兼容格式。
7663
+ *
7664
+ * @method rgbToDecimal
7665
+ * @static
7666
+ * @param {Object} color 颜色对象 {r, g, b, a?}
7667
+ * @returns {Object} 转换后的颜色对象 {r, g, b, a?},其中 r/g/b 为 0-1 范围
7668
+ *
7669
+ * @example
7670
+ * const color = jmUtils.rgbToDecimal({ r: 255, g: 128, b: 64 });
7671
+ * // 返回 { r: 1, g: 0.502, b: 0.251 }
6129
7672
  */
6130
7673
 
6131
7674
  }, {
@@ -6136,7 +7679,16 @@ var jmUtils = /*#__PURE__*/function () {
6136
7679
  color.g = this.byteToDecimal(color.g);
6137
7680
  color.b = this.byteToDecimal(color.b);
6138
7681
  return color;
6139
- } //255值转为0-1的小数
7682
+ }
7683
+ /**
7684
+ * 将字节值(0-255)转换为小数(0-1)
7685
+ *
7686
+ * @method byteToDecimal
7687
+ * @static
7688
+ * @private
7689
+ * @param {number} b 字节值(0-255)
7690
+ * @returns {number} 小数值(0-1)
7691
+ */
6140
7692
 
6141
7693
  }, {
6142
7694
  key: "byteToDecimal",
@@ -6183,7 +7735,30 @@ var jmUtils = /*#__PURE__*/function () {
6183
7735
  }
6184
7736
 
6185
7737
  return r;
6186
- } // window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行
7738
+ }
7739
+ /**
7740
+ * 请求动画帧
7741
+ *
7742
+ * 封装浏览器原生的 requestAnimationFrame 方法,提供跨浏览器兼容性。
7743
+ * 在不支持 requestAnimationFrame 的环境中降级为 setTimeout。
7744
+ *
7745
+ * @method requestAnimationFrame
7746
+ * @static
7747
+ * @param {Function} callback 动画帧回调函数,接收时间戳参数
7748
+ * @param {Window} [win] 可选的窗口对象(用于多窗口环境)
7749
+ * @returns {number} 动画帧请求ID,用于取消
7750
+ *
7751
+ * @example
7752
+ * let animationId;
7753
+ * function animate(timestamp) {
7754
+ * // 更新动画
7755
+ * animationId = jmUtils.requestAnimationFrame(animate);
7756
+ * }
7757
+ * animationId = jmUtils.requestAnimationFrame(animate);
7758
+ *
7759
+ * // 取消动画
7760
+ * jmUtils.cancelAnimationFrame(animationId);
7761
+ */
6187
7762
 
6188
7763
  }, {
6189
7764
  key: "requestAnimationFrame",
@@ -6191,6 +7766,22 @@ var jmUtils = /*#__PURE__*/function () {
6191
7766
  var fun = win && win.requestAnimationFrame ? win.requestAnimationFrame : typeof window !== 'undefined' && window.requestAnimationFrame ? window.requestAnimationFrame : setTimeout;
6192
7767
  return fun(callback, 20);
6193
7768
  }
7769
+ /**
7770
+ * 取消动画帧请求
7771
+ *
7772
+ * 取消之前通过 requestAnimationFrame 注册的回调。
7773
+ * 在不支持 cancelAnimationFrame 的环境中降级为 clearTimeout。
7774
+ *
7775
+ * @method cancelAnimationFrame
7776
+ * @static
7777
+ * @param {number} handler requestAnimationFrame 返回的请求ID
7778
+ * @param {Window} [win] 可选的窗口对象(用于多窗口环境)
7779
+ *
7780
+ * @example
7781
+ * const animationId = jmUtils.requestAnimationFrame(animate);
7782
+ * jmUtils.cancelAnimationFrame(animationId);
7783
+ */
7784
+
6194
7785
  }, {
6195
7786
  key: "cancelAnimationFrame",
6196
7787
  value: function cancelAnimationFrame(handler, win) {
@@ -6940,9 +8531,24 @@ var pathVertexSource = "\n attribute vec4 a_position;\n attribute vec4 a_c
6940
8531
 
6941
8532
  exports.pathVertexSource = pathVertexSource;
6942
8533
  var pathFragmentSource = "\n precision mediump float;\n uniform sampler2D u_sample;\n uniform vec4 v_texture_bounds; // \u7EB9\u7406\u7684\u5DE6\u4E0A\u5750\u6807\u548C\u5927\u5C0F x,y,z,w\n uniform vec4 v_single_color;\n // GLSL \u6E10\u53D8 uniforms\n uniform int u_gradient_type; // 0=\u65E0 1=\u7EBF\u6027 2=\u5F84\u5411\n uniform vec4 u_gradient_start; // \u7EBF\u6027:{x1,y1,0,0} \u5F84\u5411:{cx,cy,r1,0}\n uniform vec4 u_gradient_end; // \u7EBF\u6027:{x2,y2,0,0} \u5F84\u5411:{cx,cy,r2,0}\n uniform int u_gradient_stop_count;\n uniform float u_gradient_offsets[".concat(_gradient.MAX_STOPS, "];\n uniform vec4 u_gradient_colors[").concat(_gradient.MAX_STOPS, "]; // {r, g, b, a} 0~1 \u8303\u56F4\n varying float v_type;\n varying vec4 v_color;\n varying vec2 v_text_coord;\n\n ").concat(convertTexturePosition, "\n\n // \u5728 sorted stops \u4E2D\u6309 t \u503C\u91C7\u6837\u989C\u8272\n // \u517C\u5BB9 GLSL ES 1.0\uFF1A\u5FAA\u73AF\u4EC5\u4E0E\u5E38\u91CF\u6BD4\u8F83\uFF0C\u65E0 break/continue\n vec4 sampleGradient(float t) {\n t = clamp(t, 0.0, 1.0);\n // \u6B63\u5411\u626B\u63CF\uFF1A\u59CB\u7EC8\u904D\u5386 MAX_STOPS-1 \u6B21\uFF0C\u627E\u5230 t \u6240\u5728\u6BB5\u5E76\u8986\u76D6\u7ED3\u679C\n float localT = 0.0;\n vec4 c0 = u_gradient_colors[0];\n vec4 c1 = u_gradient_colors[0];\n for(int i = 0; i < ").concat(_gradient.MAX_STOPS - 1, "; i++) {\n float s0 = u_gradient_offsets[i];\n float s1 = u_gradient_offsets[i + 1];\n if(t >= s0) {\n float range = s1 - s0;\n localT = range > 0.0001 ? clamp((t - s0) / range, 0.0, 1.0) : 0.0;\n c0 = u_gradient_colors[i];\n c1 = u_gradient_colors[i + 1];\n }\n }\n return mix(c0, c1, localT);\n }\n\n void main() {\n // \u5982\u679C\u662Ffill\uFF0C\u5219\u76F4\u63A5\u586B\u5145\u989C\u8272\n if(v_type == 1.0) {\n gl_FragColor = v_single_color;\n }\n // \u6E10\u53D8\u8272 (\u65E7\u65B9\u5F0F\uFF0C\u9876\u70B9\u989C\u8272\u63D2\u503C)\n else if(v_type == 3.0) {\n gl_FragColor = v_color;\n }\n // GLSL \u6E10\u53D8\u586B\u5145 (type=5)\n else if(v_type == 5.0) {\n float t;\n if(u_gradient_type == 2) {\n // \u5F84\u5411\u6E10\u53D8\n vec2 d = v_text_coord - u_gradient_start.xy;\n float dist = length(d);\n float r1 = u_gradient_start.z;\n float r2 = u_gradient_end.z;\n float range = r2 - r1;\n t = range > 0.001 ? (dist - r1) / range : 0.0;\n } else {\n // \u7EBF\u6027\u6E10\u53D8\n vec2 dir = u_gradient_end.xy - u_gradient_start.xy;\n float lenSq = dot(dir, dir);\n if(lenSq > 0.001) {\n vec2 pos = v_text_coord - u_gradient_start.xy;\n t = dot(pos, dir) / lenSq;\n } else {\n t = 0.0;\n }\n }\n gl_FragColor = sampleGradient(t) * v_single_color.a;\n }\n else if(v_type == 2.0) {\n vec2 pos = translateTexturePosition(v_text_coord, v_texture_bounds);\n gl_FragColor = texture2D(u_sample, pos);\n }\n else {\n float r = distance(gl_PointCoord, vec2(0.5, 0.5));\n //\u6839\u636E\u8DDD\u79BB\u8BBE\u7F6E\u7247\u5143\n if(r <= 0.5){\n // \u65B9\u5F62\u533A\u57DF\u7247\u5143\u8DDD\u79BB\u51E0\u4F55\u4E2D\u5FC3\u534A\u5F84\u5C0F\u4E8E0.5\uFF0C\u50CF\u7D20\u989C\u8272\u8BBE\u7F6E\u7EA2\u8272\n gl_FragColor = v_single_color;\n }else {\n // \u65B9\u5F62\u533A\u57DF\u8DDD\u79BB\u51E0\u4F55\u4E2D\u5FC3\u534A\u5F84\u4E0D\u5C0F\u4E8E0.5\u7684\u7247\u5143\u526A\u88C1\u820D\u5F03\u6389\uFF1A\n discard;\n }\n }\n }\n");
8534
+ /**
8535
+ * WebGL 基础渲染类
8536
+ * 提供 WebGL 渲染的核心功能,包括着色器、缓冲区、纹理管理等
8537
+ *
8538
+ * @class WeblBase
8539
+ * @example
8540
+ * const base = new WeblBase(graph, { mode: 'webgl' });
8541
+ * base.setStyle({ fillStyle: '#ff0000' });
8542
+ */
8543
+
6943
8544
  exports.pathFragmentSource = pathFragmentSource;
6944
8545
 
6945
8546
  var WeblBase = /*#__PURE__*/function () {
8547
+ /**
8548
+ * 构造函数
8549
+ * @param {jmGraph} graph jmGraph 实例
8550
+ * @param {Object} option 配置选项
8551
+ */
6946
8552
  function WeblBase(graph, option) {
6947
8553
  _classCallCheck(this, WeblBase);
6948
8554
 
@@ -6952,14 +8558,19 @@ var WeblBase = /*#__PURE__*/function () {
6952
8558
  globalAlpha: 1
6953
8559
  };
6954
8560
  this.stateStack = [];
6955
- this.transformMatrix = [1, 0, 0, 1, 0, 0]; // 2D 变换矩阵
8561
+ /** @type {number[]} 2D 变换矩阵 [a, b, c, d, tx, ty] */
8562
+
8563
+ this.transformMatrix = [1, 0, 0, 1, 0, 0];
6956
8564
  }
8565
+ /** @returns {WebGLRenderingContext} WebGL 渲染上下文 */
8566
+
6957
8567
 
6958
8568
  _createClass(WeblBase, [{
6959
8569
  key: "context",
6960
8570
  get: function get() {
6961
8571
  if (this.graph) return this.graph.context;
6962
- } // 保存当前状态
8572
+ }
8573
+ /** 保存当前状态到状态栈 */
6963
8574
 
6964
8575
  }, {
6965
8576
  key: "save",
@@ -6968,7 +8579,8 @@ var WeblBase = /*#__PURE__*/function () {
6968
8579
  transformMatrix: _toConsumableArray(this.transformMatrix),
6969
8580
  style: _objectSpread({}, this.style)
6970
8581
  });
6971
- } // 恢复上一个状态
8582
+ }
8583
+ /** 从状态栈恢复上一个状态 */
6972
8584
 
6973
8585
  }, {
6974
8586
  key: "restore",
@@ -6978,25 +8590,37 @@ var WeblBase = /*#__PURE__*/function () {
6978
8590
  this.transformMatrix = state.transformMatrix;
6979
8591
  this.style = state.style;
6980
8592
  }
6981
- } // 平移变换
8593
+ }
8594
+ /**
8595
+ * 平移变换
8596
+ * @param {number} x X 轴平移量
8597
+ * @param {number} y Y 轴平移量
8598
+ */
6982
8599
 
6983
8600
  }, {
6984
8601
  key: "translate",
6985
8602
  value: function translate(x, y) {
6986
- // 更新变换矩阵
6987
8603
  this.transformMatrix[4] += x * this.transformMatrix[0] + y * this.transformMatrix[2];
6988
8604
  this.transformMatrix[5] += x * this.transformMatrix[1] + y * this.transformMatrix[3];
6989
- } // 缩放变换
8605
+ }
8606
+ /**
8607
+ * 缩放变换
8608
+ * @param {number} sx X 轴缩放比例
8609
+ * @param {number} sy Y 轴缩放比例
8610
+ */
6990
8611
 
6991
8612
  }, {
6992
8613
  key: "scale",
6993
8614
  value: function scale(sx, sy) {
6994
- // 更新变换矩阵
6995
8615
  this.transformMatrix[0] *= sx;
6996
8616
  this.transformMatrix[1] *= sx;
6997
8617
  this.transformMatrix[2] *= sy;
6998
8618
  this.transformMatrix[3] *= sy;
6999
- } // 旋转变换
8619
+ }
8620
+ /**
8621
+ * 旋转变换
8622
+ * @param {number} angle 旋转角度(弧度)
8623
+ */
7000
8624
 
7001
8625
  }, {
7002
8626
  key: "rotate",
@@ -7008,14 +8632,22 @@ var WeblBase = /*#__PURE__*/function () {
7008
8632
  a = _this$transformMatrix[0],
7009
8633
  b = _this$transformMatrix[1],
7010
8634
  c = _this$transformMatrix[2],
7011
- d = _this$transformMatrix[3]; // 更新变换矩阵
7012
-
8635
+ d = _this$transformMatrix[3];
7013
8636
 
7014
8637
  this.transformMatrix[0] = a * cos - b * sin;
7015
8638
  this.transformMatrix[1] = a * sin + b * cos;
7016
8639
  this.transformMatrix[2] = c * cos - d * sin;
7017
8640
  this.transformMatrix[3] = c * sin + d * cos;
7018
- } // 矩阵变换
8641
+ }
8642
+ /**
8643
+ * 矩阵变换
8644
+ * @param {number} a 水平缩放
8645
+ * @param {number} b 垂直倾斜
8646
+ * @param {number} c 水平倾斜
8647
+ * @param {number} d 垂直缩放
8648
+ * @param {number} e 水平移动
8649
+ * @param {number} f 垂直移动
8650
+ */
7019
8651
 
7020
8652
  }, {
7021
8653
  key: "transform",
@@ -7026,8 +8658,7 @@ var WeblBase = /*#__PURE__*/function () {
7026
8658
  currentC = _this$transformMatrix2[2],
7027
8659
  currentD = _this$transformMatrix2[3],
7028
8660
  currentE = _this$transformMatrix2[4],
7029
- currentF = _this$transformMatrix2[5]; // 矩阵乘法
7030
-
8661
+ currentF = _this$transformMatrix2[5];
7031
8662
 
7032
8663
  this.transformMatrix[0] = a * currentA + b * currentC;
7033
8664
  this.transformMatrix[1] = a * currentB + b * currentD;
@@ -7035,7 +8666,12 @@ var WeblBase = /*#__PURE__*/function () {
7035
8666
  this.transformMatrix[3] = c * currentB + d * currentD;
7036
8667
  this.transformMatrix[4] = e * currentA + f * currentC + currentE;
7037
8668
  this.transformMatrix[5] = e * currentB + f * currentD + currentF;
7038
- } // 应用变换到点
8669
+ }
8670
+ /**
8671
+ * 应用变换到点
8672
+ * @param {Object} point 点坐标 {x, y}
8673
+ * @returns {Object} 变换后的点坐标 {x, y}
8674
+ */
7039
8675
 
7040
8676
  }, {
7041
8677
  key: "applyTransform",
@@ -7052,7 +8688,12 @@ var WeblBase = /*#__PURE__*/function () {
7052
8688
  x: a * point.x + c * point.y + tx,
7053
8689
  y: b * point.x + d * point.y + ty
7054
8690
  };
7055
- } // 文本测量用的离屏 canvas context(1x1 单例缓存,不依赖 textureCanvas)
8691
+ }
8692
+ /**
8693
+ * 文本测量用的离屏 canvas context
8694
+ * @private
8695
+ * @returns {CanvasRenderingContext2D|null}
8696
+ */
7056
8697
 
7057
8698
  }, {
7058
8699
  key: "_measureCtx",
@@ -7070,14 +8711,22 @@ var WeblBase = /*#__PURE__*/function () {
7070
8711
  }
7071
8712
 
7072
8713
  return this.__measureCtx;
7073
- } // i当前程序
8714
+ }
8715
+ /**
8716
+ * 获取当前着色器程序
8717
+ * @returns {Object} 着色器程序对象
8718
+ */
7074
8719
 
7075
8720
  }, {
7076
8721
  key: "program",
7077
8722
  get: function get() {
7078
- // 默认所有path用同一个编译好的program
7079
8723
  return this.graph.context.pathProgram || (this.graph.context.pathProgram = this.createProgram(pathVertexSource, pathFragmentSource));
7080
- } // 设置样式
8724
+ }
8725
+ /**
8726
+ * 设置样式
8727
+ * @param {Object|string} style 样式对象或样式属性名
8728
+ * @param {string} [value] 样式值(当 style 为字符串时使用)
8729
+ */
7081
8730
 
7082
8731
  }, {
7083
8732
  key: "setStyle",
@@ -7090,29 +8739,14 @@ var WeblBase = /*#__PURE__*/function () {
7090
8739
  obj[style] = value;
7091
8740
  style = obj;
7092
8741
  }
7093
- /*
7094
- // 设置线条颜色或填充色
7095
- if(style.strokeStyle) {
7096
- let color = style.strokeStyle;
7097
- if(typeof color === 'string') color = this.graph.utils.hexToRGBA(color);
7098
- this.style.strokeStyle = this.graph.utils.rgbToDecimal(color);
7099
- delete style.strokeStyle;
7100
- }
7101
- else if(style.fillStyle) {
7102
- let color = style.fillStyle;
7103
- if(this.isGradient(color)) {
7104
- this.style.fillStyle = color;
7105
- }
7106
- else {
7107
- if(typeof color === 'string') color = this.graph.utils.hexToRGBA(color);
7108
- this.style.fillStyle = this.graph.utils.rgbToDecimal(color);
7109
- }
7110
- delete style.fillStyle;
7111
- } */
7112
-
7113
8742
 
7114
8743
  this.style = _objectSpread(_objectSpread({}, this.style), style);
7115
- } // 把传统颜色转为webgl识别的
8744
+ }
8745
+ /**
8746
+ * 将颜色转换为 WebGL 可识别的格式
8747
+ * @param {string|Object} color 颜色值
8748
+ * @returns {Object} RGBA 对象 {r, g, b, a},范围 0-1
8749
+ */
7116
8750
 
7117
8751
  }, {
7118
8752
  key: "convertColor",
@@ -7120,9 +8754,7 @@ var WeblBase = /*#__PURE__*/function () {
7120
8754
  if (this.isGradient(color)) return color;
7121
8755
 
7122
8756
  if (typeof color === 'string') {
7123
- // 先尝试 hexToRGBA 解析
7124
- color = this.graph.utils.hexToRGBA(color); // hexToRGBA 对无法识别的格式(如 hsl)会原样返回字符串
7125
- // 利用离屏 canvas 将任意 CSS 颜色转为 rgba
8757
+ color = this.graph.utils.hexToRGBA(color);
7126
8758
 
7127
8759
  if (typeof color === 'string') {
7128
8760
  color = this.__parseCSSColor(color);
@@ -7134,7 +8766,13 @@ var WeblBase = /*#__PURE__*/function () {
7134
8766
  }
7135
8767
 
7136
8768
  return color;
7137
- } // 利用离屏 canvas 解析任意 CSS 颜色(hsl/hsla/命名颜色等)
8769
+ }
8770
+ /**
8771
+ * 利用离屏 canvas 解析任意 CSS 颜色
8772
+ * @private
8773
+ * @param {string} colorStr CSS 颜色字符串
8774
+ * @returns {Object} RGBA 对象 {r, g, b, a}
8775
+ */
7138
8776
 
7139
8777
  }, {
7140
8778
  key: "__parseCSSColor",
@@ -7182,13 +8820,24 @@ var WeblBase = /*#__PURE__*/function () {
7182
8820
  a: 0
7183
8821
  };
7184
8822
  }
7185
- } // 创建程序
8823
+ }
8824
+ /**
8825
+ * 创建着色器程序
8826
+ * @param {string} vertexSrc 顶点着色器源码
8827
+ * @param {string} fragmentSrc 片段着色器源码
8828
+ * @returns {Object} 着色器程序对象
8829
+ */
7186
8830
 
7187
8831
  }, {
7188
8832
  key: "createProgram",
7189
8833
  value: function createProgram(vertexSrc, fragmentSrc) {
7190
8834
  return (0, _program.createProgram)(this.context, vertexSrc, fragmentSrc);
7191
- } // 指定使用某个程序
8835
+ }
8836
+ /**
8837
+ * 使用指定的着色器程序
8838
+ * @param {Object} [program] 着色器程序,默认使用当前程序
8839
+ * @returns {Object} 着色器程序
8840
+ */
7192
8841
 
7193
8842
  }, {
7194
8843
  key: "useProgram",
@@ -7200,21 +8849,38 @@ var WeblBase = /*#__PURE__*/function () {
7200
8849
  this.context.__curent_program = program;
7201
8850
  return program;
7202
8851
  }
8852
+ /**
8853
+ * 获取属性位置
8854
+ * @param {string} name 属性名
8855
+ * @returns {number} 属性位置
8856
+ */
8857
+
7203
8858
  }, {
7204
8859
  key: "getAttribLocation",
7205
8860
  value: function getAttribLocation(name) {
7206
8861
  return this.context.getAttribLocation(this.program.program, name);
7207
8862
  }
8863
+ /**
8864
+ * 获取 uniform 位置
8865
+ * @param {string} name uniform 变量名
8866
+ * @returns {WebGLUniformLocation} uniform 位置
8867
+ */
8868
+
7208
8869
  }, {
7209
8870
  key: "getUniformLocation",
7210
8871
  value: function getUniformLocation(name) {
7211
8872
  return this.context.getUniformLocation(this.program.program, name);
7212
- } // 把缓冲区的值写入变量
7213
- // buffer: 缓冲区
7214
- // size: 组成数量,必须是1,2,3或4. 每个单元由多少个数组成
7215
- // strip: 步长 数组中一行长度,0 表示数据是紧密的没有空隙,让OpenGL决定具体步长
7216
- // offset: 字节偏移量,必须是类型的字节长度的倍数。
7217
- // dataType: 每个元素的数据类型
8873
+ }
8874
+ /**
8875
+ * 将缓冲区数据写入顶点属性
8876
+ * @param {Object} buffer 缓冲区对象
8877
+ * @param {Object} attr 属性对象
8878
+ * @param {number} [size=2] 每个顶点的分量数(1-4)
8879
+ * @param {number} [strip=0] 步长,0 表示紧密排列
8880
+ * @param {number} [offset=0] 字节偏移量
8881
+ * @param {number} [dataType=FLOAT] 数据类型
8882
+ * @returns {Object} 缓冲区对象
8883
+ */
7218
8884
 
7219
8885
  }, {
7220
8886
  key: "writeVertexAttrib",
@@ -7225,7 +8891,12 @@ var WeblBase = /*#__PURE__*/function () {
7225
8891
  var dataType = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : this.context.FLOAT;
7226
8892
  buffer.attr = attr;
7227
8893
  return (0, _program.writeVertexAttrib)(this.context, buffer, attr, size, strip, offset, dataType);
7228
- } // 禁用attri
8894
+ }
8895
+ /**
8896
+ * 禁用顶点属性数组
8897
+ * @param {Object} attr 属性对象
8898
+ * @returns {Object} 属性对象
8899
+ */
7229
8900
 
7230
8901
  }, {
7231
8902
  key: "disableVertexAttribArray",
@@ -7238,7 +8909,14 @@ var WeblBase = /*#__PURE__*/function () {
7238
8909
  }
7239
8910
 
7240
8911
  return attr;
7241
- } // 创建float32的buffer
8912
+ }
8913
+ /**
8914
+ * 创建 Float32 缓冲区
8915
+ * @param {Array} data 数据数组
8916
+ * @param {number} [type=ARRAY_BUFFER] 缓冲区类型
8917
+ * @param {number} [drawType=STATIC_DRAW] 绘制类型
8918
+ * @returns {Object} 缓冲区对象
8919
+ */
7242
8920
 
7243
8921
  }, {
7244
8922
  key: "createFloat32Buffer",
@@ -7250,6 +8928,14 @@ var WeblBase = /*#__PURE__*/function () {
7250
8928
  data: data
7251
8929
  }, buffer);
7252
8930
  }
8931
+ /**
8932
+ * 创建 Uint16 缓冲区
8933
+ * @param {Array} data 数据数组
8934
+ * @param {number} [type=ARRAY_BUFFER] 缓冲区类型
8935
+ * @param {number} [drawType=STATIC_DRAW] 绘制类型
8936
+ * @returns {Object} 缓冲区对象
8937
+ */
8938
+
7253
8939
  }, {
7254
8940
  key: "createUint16Buffer",
7255
8941
  value: function createUint16Buffer(data) {
@@ -7259,7 +8945,12 @@ var WeblBase = /*#__PURE__*/function () {
7259
8945
  return _objectSpread({
7260
8946
  data: data
7261
8947
  }, buffer);
7262
- } // 释放
8948
+ }
8949
+ /**
8950
+ * 删除缓冲区
8951
+ * @param {Object} buffer 缓冲区对象
8952
+ * @returns {Object} 缓冲区对象
8953
+ */
7263
8954
 
7264
8955
  }, {
7265
8956
  key: "deleteBuffer",
@@ -7274,25 +8965,41 @@ var WeblBase = /*#__PURE__*/function () {
7274
8965
  }
7275
8966
 
7276
8967
  return buffer;
7277
- } // 生成纹理
8968
+ }
8969
+ /** @returns {WebGLTexture} 2D 纹理对象 */
7278
8970
 
7279
8971
  }, {
7280
8972
  key: "create2DTexture",
7281
8973
  value: function create2DTexture() {
7282
8974
  return (0, _texture.create2DTexture)(this.context);
7283
- } // 创建图片纹理
8975
+ }
8976
+ /**
8977
+ * 创建图片纹理
8978
+ * @param {Image|HTMLImageElement} img 图像对象
8979
+ * @returns {Object} 纹理对象
8980
+ */
7284
8981
 
7285
8982
  }, {
7286
8983
  key: "createImgTexture",
7287
8984
  value: function createImgTexture(img) {
7288
8985
  return (0, _texture.createImgTexture)(this.context, img);
7289
- } // 根根像素值生成纹理
8986
+ }
8987
+ /**
8988
+ * 根据像素数据创建纹理
8989
+ * @param {ImageData|Uint8Array} data 像素数据
8990
+ * @returns {Object} 纹理对象
8991
+ */
7290
8992
 
7291
8993
  }, {
7292
8994
  key: "createDataTexture",
7293
8995
  value: function createDataTexture(data) {
7294
8996
  return (0, _texture.createDataTexture)(this.context, data);
7295
- } // 删除纹理
8997
+ }
8998
+ /**
8999
+ * 删除纹理
9000
+ * @param {Object} texture 纹理对象
9001
+ * @returns {Object} 纹理对象
9002
+ */
7296
9003
 
7297
9004
  }, {
7298
9005
  key: "deleteTexture",
@@ -7304,41 +9011,51 @@ var WeblBase = /*#__PURE__*/function () {
7304
9011
  }
7305
9012
 
7306
9013
  return texture;
7307
- } // 多边切割, 得到三角形顶点索引数组
7308
- // polygonIndices 顶点索引,
9014
+ }
9015
+ /**
9016
+ * 多边形三角化,得到三角形顶点索引数组
9017
+ * @param {Array<Object>} points 多边形顶点数组
9018
+ * @returns {Array<number>} 三角形顶点索引数组
9019
+ */
7309
9020
 
7310
9021
  }, {
7311
9022
  key: "earCutPoints",
7312
9023
  value: function earCutPoints(points) {
7313
9024
  var arr = this.pointsToArray(points);
7314
- var ps = (0, _earcut["default"])(arr); // 切割得到3角色顶点索引,
7315
-
9025
+ var ps = (0, _earcut["default"])(arr);
7316
9026
  return ps;
7317
- } // 多边切割, 得到三角形顶点
7318
- // polygonIndices 顶点索引,
9027
+ }
9028
+ /**
9029
+ * 多边形三角化,得到三角形顶点数组
9030
+ * @param {Array<Object>} points 多边形顶点数组
9031
+ * @returns {Array<Array<Object>>} 三角形数组,每个三角形包含3个顶点
9032
+ */
7319
9033
 
7320
9034
  }, {
7321
9035
  key: "earCutPointsToTriangles",
7322
9036
  value: function earCutPointsToTriangles(points) {
7323
- this.earCutCache = this.earCutCache || (this.earCutCache = {}); // 快速缓存 key:用长度和首尾点坐标
7324
-
9037
+ this.earCutCache = this.earCutCache || (this.earCutCache = {});
7325
9038
  var len = points.length;
7326
9039
  var key = len + '_' + points[0].x + '_' + points[0].y + '_' + points[len - 1].x + '_' + points[len - 1].y;
7327
9040
  if (this.earCutCache[key]) return this.earCutCache[key];
7328
- var ps = this.earCutPoints(points); // 切割得到3角色顶点索引,
7329
-
7330
- var triangles = []; // 用顶点索引再组合成坐标数组
9041
+ var ps = this.earCutPoints(points);
9042
+ var triangles = [];
7331
9043
 
7332
9044
  for (var i = 0; i < ps.length; i += 3) {
7333
9045
  var p1 = points[ps[i]];
7334
9046
  var p2 = points[ps[i + 1]];
7335
9047
  var p3 = points[ps[i + 2]];
7336
- triangles.push([p1, p2, p3]); // 每三个顶点构成一个三角
9048
+ triangles.push([p1, p2, p3]);
7337
9049
  }
7338
9050
 
7339
9051
  this.earCutCache[key] = triangles;
7340
9052
  return triangles;
7341
- } // 点坐标数组转为一维数组
9053
+ }
9054
+ /**
9055
+ * 点坐标数组转为一维数组
9056
+ * @param {Array<Object>} points 点数组 [{x, y}, ...]
9057
+ * @returns {Array<number>} 一维数组 [x1, y1, x2, y2, ...]
9058
+ */
7342
9059
 
7343
9060
  }, {
7344
9061
  key: "pointsToArray",
@@ -7347,8 +9064,13 @@ var WeblBase = /*#__PURE__*/function () {
7347
9064
 
7348
9065
  return (_ref = []).concat.apply(_ref, _toConsumableArray(points.map(function (p) {
7349
9066
  return [p.x, p.y];
7350
- }))); // 把x,y转为数组元素
7351
- } // 每2位表示坐标x,y转为坐标点对象
9067
+ })));
9068
+ }
9069
+ /**
9070
+ * 一维数组转为点坐标数组
9071
+ * @param {Array<number>} arr 一维数组 [x1, y1, x2, y2, ...]
9072
+ * @returns {Array<Object>} 点数组 [{x, y}, ...]
9073
+ */
7352
9074
 
7353
9075
  }, {
7354
9076
  key: "arrayToPoints",
@@ -7363,7 +9085,16 @@ var WeblBase = /*#__PURE__*/function () {
7363
9085
  }
7364
9086
 
7365
9087
  return points;
7366
- } // 创建线性渐变
9088
+ }
9089
+ /**
9090
+ * 创建线性渐变
9091
+ * @param {number} x1 起点X坐标
9092
+ * @param {number} y1 起点Y坐标
9093
+ * @param {number} x2 终点X坐标
9094
+ * @param {number} y2 终点Y坐标
9095
+ * @param {Object} bounds 渐变边界
9096
+ * @returns {WebglGradient} 渐变对象
9097
+ */
7367
9098
 
7368
9099
  }, {
7369
9100
  key: "createLinearGradient",
@@ -7376,7 +9107,18 @@ var WeblBase = /*#__PURE__*/function () {
7376
9107
  bounds: bounds,
7377
9108
  control: this
7378
9109
  });
7379
- } // 创建放射性渐变
9110
+ }
9111
+ /**
9112
+ * 创建径向渐变
9113
+ * @param {number} x1 内圆中心X坐标
9114
+ * @param {number} y1 内圆中心Y坐标
9115
+ * @param {number} r1 内圆半径
9116
+ * @param {number} x2 外圆中心X坐标
9117
+ * @param {number} y2 外圆中心Y坐标
9118
+ * @param {number} r2 外圆半径
9119
+ * @param {Object} bounds 渐变边界
9120
+ * @returns {WebglGradient} 渐变对象
9121
+ */
7380
9122
 
7381
9123
  }, {
7382
9124
  key: "createRadialGradient",
@@ -7391,7 +9133,12 @@ var WeblBase = /*#__PURE__*/function () {
7391
9133
  bounds: bounds,
7392
9134
  control: this
7393
9135
  });
7394
- } // 判断是否是一个渐变对象
9136
+ }
9137
+ /**
9138
+ * 判断是否为渐变对象
9139
+ * @param {Object} obj 待检测对象
9140
+ * @returns {boolean} 是否为渐变对象
9141
+ */
7395
9142
 
7396
9143
  }, {
7397
9144
  key: "isGradient",
@@ -7442,32 +9189,53 @@ exports.createUint16Buffer = createUint16Buffer;
7442
9189
  exports.createFloat32Buffer = createFloat32Buffer;
7443
9190
  exports.deleteBuffer = deleteBuffer;
7444
9191
 
7445
- // 创建缓冲区
9192
+ /**
9193
+ * @fileoverview WebGL 缓冲区管理模块
9194
+ *
9195
+ * 本模块提供了 WebGL 缓冲区的创建和管理功能,包括:
9196
+ * - 创建通用缓冲区
9197
+ * - 创建 Float32 类型缓冲区
9198
+ * - 创建 Uint16 类型缓冲区
9199
+ * - 删除缓冲区
9200
+ *
9201
+ * @module lib/webgl/core/buffer
9202
+ * @author jmGraph Team
9203
+ */
9204
+
9205
+ /**
9206
+ * 创建 WebGL 缓冲区
9207
+ * @param {WebGLRenderingContext} gl WebGL 渲染上下文
9208
+ * @param {Array|TypedArray} data 缓冲区数据
9209
+ * @param {number} [type=gl.ARRAY_BUFFER] 缓冲区类型
9210
+ * @param {number} [drawType=gl.STATIC_DRAW] 绘制类型
9211
+ * @returns {Object} 缓冲区对象 {type, drawType, buffer, unitSize}
9212
+ */
7446
9213
  function createBuffer(gl, data) {
7447
9214
  var type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : gl.ARRAY_BUFFER;
7448
9215
  var drawType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : gl.STATIC_DRAW;
7449
- //先创建一个缓存对象
7450
9216
  var buffer = gl.createBuffer();
7451
9217
 
7452
9218
  if (!buffer) {
7453
9219
  throw Error('创建缓冲区对象失败');
7454
- } //说明缓存对象保存的类型
7455
-
7456
-
7457
- gl.bindBuffer(type, buffer); //写入坐标数据
7458
- // 因为会将数据发送到 GPU,为了省去数据解析,这里使用 Float32Array 直接传送数据
7459
- // data.buffer这里要使用data.buffer,否则在edge下可能导至数据发生较大的改变
7460
-
7461
- gl.bufferData(type, data.buffer || data, drawType); // 表示缓冲区的内容不会经常更改
9220
+ }
7462
9221
 
9222
+ gl.bindBuffer(type, buffer);
9223
+ gl.bufferData(type, data.buffer || data, drawType);
7463
9224
  return {
7464
9225
  type: type,
7465
9226
  drawType: drawType,
7466
9227
  buffer: buffer,
7467
- // 获取到数组中单个元素的字节数
7468
9228
  unitSize: data.BYTES_PER_ELEMENT
7469
9229
  };
7470
- } // 创建float32的buffer
9230
+ }
9231
+ /**
9232
+ * 创建 Float32 类型缓冲区
9233
+ * @param {WebGLRenderingContext} gl WebGL 渲染上下文
9234
+ * @param {Array} data 数据数组
9235
+ * @param {number} [type=gl.ARRAY_BUFFER] 缓冲区类型
9236
+ * @param {number} [drawType=gl.STATIC_DRAW] 绘制类型
9237
+ * @returns {Object} 缓冲区对象
9238
+ */
7471
9239
 
7472
9240
 
7473
9241
  function createFloat32Buffer(gl, data) {
@@ -7476,7 +9244,15 @@ function createFloat32Buffer(gl, data) {
7476
9244
  var vertices = new Float32Array(data);
7477
9245
  var buffer = createBuffer(gl, vertices, type, drawType);
7478
9246
  return buffer;
7479
- } // 创建uint16的bugger
9247
+ }
9248
+ /**
9249
+ * 创建 Uint16 类型缓冲区
9250
+ * @param {WebGLRenderingContext} gl WebGL 渲染上下文
9251
+ * @param {Array} data 数据数组
9252
+ * @param {number} [type=gl.ARRAY_BUFFER] 缓冲区类型
9253
+ * @param {number} [drawType=gl.STATIC_DRAW] 绘制类型
9254
+ * @returns {Object} 缓冲区对象
9255
+ */
7480
9256
 
7481
9257
 
7482
9258
  function createUint16Buffer(gl, data) {
@@ -7485,7 +9261,12 @@ function createUint16Buffer(gl, data) {
7485
9261
  var vertices = new Uint16Array(data);
7486
9262
  var buffer = createBuffer(gl, vertices, type, drawType);
7487
9263
  return buffer;
7488
- } // 释放
9264
+ }
9265
+ /**
9266
+ * 删除缓冲区
9267
+ * @param {WebGLRenderingContext} gl WebGL 渲染上下文
9268
+ * @param {Object|WebGLBuffer} buffer 缓冲区对象或 WebGL 缓冲区
9269
+ */
7489
9270
 
7490
9271
 
7491
9272
  function deleteBuffer(gl, buffer) {
@@ -7499,6 +9280,20 @@ Object.defineProperty(exports, "__esModule", {
7499
9280
  value: true
7500
9281
  });
7501
9282
  exports.mapSize = void 0;
9283
+
9284
+ /**
9285
+ * @fileoverview GLSL 类型大小映射模块
9286
+ *
9287
+ * 本模块提供了 GLSL 类型到其元素数量的映射。
9288
+ *
9289
+ * @module lib/webgl/core/mapSize
9290
+ * @author jmGraph Team
9291
+ */
9292
+
9293
+ /**
9294
+ * GLSL 类型到元素数量的映射表
9295
+ * @constant {Object.<string, number>}
9296
+ */
7502
9297
  var GLSL_TO_SIZE = {
7503
9298
  'float': 1,
7504
9299
  'vec2': 2,
@@ -7518,10 +9313,9 @@ var GLSL_TO_SIZE = {
7518
9313
  'sampler2D': 1
7519
9314
  };
7520
9315
  /**
7521
- * @class
7522
- * @memberof PIXI.glCore.shader
7523
- * @param type {String}
7524
- * @return {Number}
9316
+ * 根据 GLSL 类型名获取元素数量
9317
+ * @param {string} type GLSL 类型名
9318
+ * @returns {number} 元素数量
7525
9319
  */
7526
9320
 
7527
9321
  var mapSize = function mapSize(type) {
@@ -7537,7 +9331,23 @@ Object.defineProperty(exports, "__esModule", {
7537
9331
  value: true
7538
9332
  });
7539
9333
  exports.mapType = void 0;
9334
+
9335
+ /**
9336
+ * @fileoverview WebGL 类型到 GLSL 类型映射模块
9337
+ *
9338
+ * 本模块提供了 WebGL 常量类型到 GLSL 类型名的映射。
9339
+ *
9340
+ * @module lib/webgl/core/mapType
9341
+ * @author jmGraph Team
9342
+ */
9343
+
9344
+ /** @type {Object.<number, string>|null} 缓存的类型映射表 */
7540
9345
  var GL_TABLE = null;
9346
+ /**
9347
+ * WebGL 常量到 GLSL 类型的映射表
9348
+ * @constant {Object.<string, string>}
9349
+ */
9350
+
7541
9351
  var GL_TO_GLSL_TYPES = {
7542
9352
  'FLOAT': 'float',
7543
9353
  'FLOAT_VEC2': 'vec2',
@@ -7556,6 +9366,12 @@ var GL_TO_GLSL_TYPES = {
7556
9366
  'FLOAT_MAT4': 'mat4',
7557
9367
  'SAMPLER_2D': 'sampler2D'
7558
9368
  };
9369
+ /**
9370
+ * 将 WebGL 类型常量映射为 GLSL 类型名
9371
+ * @param {WebGLRenderingContext} gl WebGL 渲染上下文
9372
+ * @param {number} type WebGL 类型常量
9373
+ * @returns {string} GLSL 类型名
9374
+ */
7559
9375
 
7560
9376
  var mapType = function mapType(gl, type) {
7561
9377
  if (!GL_TABLE) {
@@ -7594,25 +9410,37 @@ var _mapSize = require("./mapSize.js");
7594
9410
 
7595
9411
  var _mapType = require("./mapType.js");
7596
9412
 
7597
- // 创建程序
7598
- function createProgram(gl, vertexSrc, fragmentSrc) {
7599
- // 创建顶点着色器
7600
- var vertexShader = (0, _shader.createShader)(gl, gl.VERTEX_SHADER, vertexSrc); // 创建片段着色器
9413
+ /**
9414
+ * @fileoverview WebGL 着色器程序管理模块
9415
+ *
9416
+ * 本模块提供了 WebGL 着色器程序的创建和管理功能,包括:
9417
+ * - 创建着色器程序
9418
+ * - 提取属性和 uniform 变量
9419
+ * - 顶点属性绑定
9420
+ *
9421
+ * @module lib/webgl/core/program
9422
+ * @author jmGraph Team
9423
+ */
7601
9424
 
9425
+ /**
9426
+ * 创建着色器程序
9427
+ * @param {WebGLRenderingContext} gl WebGL 渲染上下文
9428
+ * @param {string} vertexSrc 顶点着色器源码
9429
+ * @param {string} fragmentSrc 片段着色器源码
9430
+ * @returns {Object} 程序对象 {program, attrs, uniforms}
9431
+ */
9432
+ function createProgram(gl, vertexSrc, fragmentSrc) {
9433
+ var vertexShader = (0, _shader.createShader)(gl, gl.VERTEX_SHADER, vertexSrc);
7602
9434
  var fragmentShader = (0, _shader.createShader)(gl, gl.FRAGMENT_SHADER, fragmentSrc);
7603
- var program = gl.createProgram(); // 创建一个程序
7604
-
7605
- gl.attachShader(program, vertexShader); // 添加顶点着色器
7606
-
7607
- gl.attachShader(program, fragmentShader); // 添加片元着色器
7608
-
7609
- gl.linkProgram(program); // 连接 program 中的着色器
7610
- // 检查程序链接状态
9435
+ var program = gl.createProgram();
9436
+ gl.attachShader(program, vertexShader);
9437
+ gl.attachShader(program, fragmentShader);
9438
+ gl.linkProgram(program);
7611
9439
 
7612
9440
  if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
7613
9441
  console.error('PError: Could not initialize shader.');
7614
9442
  console.error('gl.VALIDATE_STATUS', gl.getProgramParameter(program, gl.VALIDATE_STATUS));
7615
- console.error('gl.getError()', gl.getError()); // if there is a program info log, log it
9443
+ console.error('gl.getError()', gl.getError());
7616
9444
 
7617
9445
  if (gl.getProgramInfoLog(program) !== '') {
7618
9446
  console.warn('Warning: gl.getProgramInfoLog()', gl.getProgramInfoLog(program));
@@ -7621,8 +9449,7 @@ function createProgram(gl, vertexSrc, fragmentSrc) {
7621
9449
  gl.deleteProgram(program);
7622
9450
  }
7623
9451
 
7624
- useProgram(gl, program); // clean up some shaders
7625
-
9452
+ useProgram(gl, program);
7626
9453
  gl.deleteShader(vertexShader);
7627
9454
  gl.deleteShader(fragmentShader);
7628
9455
  var attrs = extractAttributes(gl, program);
@@ -7632,12 +9459,24 @@ function createProgram(gl, vertexSrc, fragmentSrc) {
7632
9459
  attrs: attrs,
7633
9460
  uniforms: uniforms
7634
9461
  };
7635
- } // 采用program
9462
+ }
9463
+ /**
9464
+ * 使用指定的着色器程序
9465
+ * @param {WebGLRenderingContext} gl WebGL 渲染上下文
9466
+ * @param {WebGLProgram} program 着色器程序
9467
+ */
7636
9468
 
7637
9469
 
7638
9470
  function useProgram(gl, program) {
7639
- return gl.useProgram(program); // 告诉 webgl 用这个 program 进行渲染
9471
+ return gl.useProgram(program);
7640
9472
  }
9473
+ /**
9474
+ * 提取着色器程序中的所有属性
9475
+ * @param {WebGLRenderingContext} gl WebGL 渲染上下文
9476
+ * @param {WebGLProgram} program 着色器程序
9477
+ * @returns {Object} 属性对象字典
9478
+ */
9479
+
7641
9480
 
7642
9481
  function extractAttributes(gl, program) {
7643
9482
  var attributes = {};
@@ -7656,6 +9495,13 @@ function extractAttributes(gl, program) {
7656
9495
 
7657
9496
  return attributes;
7658
9497
  }
9498
+ /**
9499
+ * 提取着色器程序中的所有 uniform 变量
9500
+ * @param {WebGLRenderingContext} gl WebGL 渲染上下文
9501
+ * @param {WebGLProgram} program 着色器程序
9502
+ * @returns {Object} uniform 变量对象字典
9503
+ */
9504
+
7659
9505
 
7660
9506
  function extractUniforms(gl, program) {
7661
9507
  var uniforms = {};
@@ -7675,12 +9521,18 @@ function extractUniforms(gl, program) {
7675
9521
 
7676
9522
  return uniforms;
7677
9523
  }
9524
+ /**
9525
+ * 将缓冲区数据写入顶点属性
9526
+ * @param {WebGLRenderingContext} gl WebGL 渲染上下文
9527
+ * @param {Object} buffer 缓冲区对象
9528
+ * @param {Object} attr 属性对象
9529
+ * @param {number} [size=2] 每个顶点的分量数(1-4)
9530
+ * @param {number} [strip=0] 步长,0 表示紧密排列
9531
+ * @param {number} [offset=0] 字节偏移量
9532
+ * @param {number} [dataType=gl.FLOAT] 数据类型
9533
+ * @returns {Object} 缓冲区对象
9534
+ */
7678
9535
 
7679
- ; // 把缓冲区的值写入变量
7680
- // size: 组成数量,必须是1,2,3或4. 每个单元由多少个数组成
7681
- // strip: 步长 数组中一行长度,0 表示数据是紧密的没有空隙,让OpenGL决定具体步长
7682
- // offset: 字节偏移量,必须是类型的字节长度的倍数。
7683
- // dataType: 每个元素的数据类型
7684
9536
 
7685
9537
  function writeVertexAttrib(gl, buffer, attr) {
7686
9538
  var size = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 2;
@@ -7688,22 +9540,40 @@ function writeVertexAttrib(gl, buffer, attr) {
7688
9540
  var offset = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;
7689
9541
  var dataType = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : gl.FLOAT;
7690
9542
  gl.bindBuffer(buffer.type, buffer.buffer);
7691
- gl.vertexAttribPointer( // 告诉 OpenGL 如何从 Buffer 中获取数据
7692
- attr.location, // 顶点属性的索引
7693
- size, // 组成数量,必须是1,2,3或4。我们只提供了 x 和 y
7694
- dataType, false, // 是否归一化到特定的范围,对 FLOAT 类型数据设置无效
7695
- strip * buffer.unitSize, offset);
9543
+ gl.vertexAttribPointer(attr.location, size, dataType, false, strip * buffer.unitSize, offset);
7696
9544
  gl.enableVertexAttribArray(attr.location);
7697
9545
  return buffer;
7698
9546
  }
9547
+ /**
9548
+ * 禁用顶点属性数组
9549
+ * @param {WebGLRenderingContext} gl WebGL 渲染上下文
9550
+ * @param {Object} attr 属性对象
9551
+ */
9552
+
7699
9553
 
7700
9554
  function disableVertexAttribArray(gl, attr) {
7701
9555
  return gl.disableVertexAttribArray(attr.location);
7702
9556
  }
9557
+ /**
9558
+ * 获取属性位置
9559
+ * @param {WebGLRenderingContext} gl WebGL 渲染上下文
9560
+ * @param {WebGLProgram} program 着色器程序
9561
+ * @param {string} name 属性名
9562
+ * @returns {number} 属性位置
9563
+ */
9564
+
7703
9565
 
7704
9566
  function getAttribLocation(gl, program, name) {
7705
9567
  return gl.getAttribLocation(program, name);
7706
9568
  }
9569
+ /**
9570
+ * 获取 uniform 位置
9571
+ * @param {WebGLRenderingContext} gl WebGL 渲染上下文
9572
+ * @param {WebGLProgram} program 着色器程序
9573
+ * @param {string} name uniform 变量名
9574
+ * @returns {WebGLUniformLocation} uniform 位置
9575
+ */
9576
+
7707
9577
 
7708
9578
  function getUniformLocation(gl, program, name) {
7709
9579
  return gl.getUniformLocation(program, name);
@@ -7717,16 +9587,26 @@ Object.defineProperty(exports, "__esModule", {
7717
9587
  });
7718
9588
  exports.createShader = createShader;
7719
9589
 
7720
- // 生成着色器
7721
- // type: gl.VERTEX_SHADER 顶点着色器 , gl.FRAGMENT_SHADER 片段着色器
7722
- // src: 着色器代码
7723
- function createShader(gl, type, src) {
7724
- var shader = gl.createShader(type); // 创建一个顶点着色器
7725
-
7726
- gl.shaderSource(shader, src); // 编写顶点着色器代码
7727
-
7728
- gl.compileShader(shader); // 编译着色器
9590
+ /**
9591
+ * @fileoverview WebGL 着色器管理模块
9592
+ *
9593
+ * 本模块提供了 WebGL 着色器的创建功能。
9594
+ *
9595
+ * @module lib/webgl/core/shader
9596
+ * @author jmGraph Team
9597
+ */
7729
9598
 
9599
+ /**
9600
+ * 创建 WebGL 着色器
9601
+ * @param {WebGLRenderingContext} gl WebGL 渲染上下文
9602
+ * @param {number} type 着色器类型:gl.VERTEX_SHADER 或 gl.FRAGMENT_SHADER
9603
+ * @param {string} src 着色器源码
9604
+ * @returns {WebGLShader} 编译后的着色器对象
9605
+ */
9606
+ function createShader(gl, type, src) {
9607
+ var shader = gl.createShader(type);
9608
+ gl.shaderSource(shader, src);
9609
+ gl.compileShader(shader);
7730
9610
  return shader;
7731
9611
  }
7732
9612
 
@@ -7741,55 +9621,71 @@ exports.createImgTexture = createImgTexture;
7741
9621
  exports.createDataTexture = createDataTexture;
7742
9622
  exports.deleteTexture = deleteTexture;
7743
9623
 
7744
- // 生成纹理
9624
+ /**
9625
+ * @fileoverview WebGL 纹理管理模块
9626
+ *
9627
+ * 本模块提供了 WebGL 纹理的创建和管理功能,包括:
9628
+ * - 创建 2D 纹理
9629
+ * - 创建图片纹理
9630
+ * - 创建数据纹理
9631
+ * - 删除纹理
9632
+ *
9633
+ * @module lib/webgl/core/texture
9634
+ * @author jmGraph Team
9635
+ */
9636
+
9637
+ /**
9638
+ * 创建 2D 纹理
9639
+ * @param {WebGLRenderingContext} gl WebGL 渲染上下文
9640
+ * @returns {WebGLTexture} 纹理对象
9641
+ */
7745
9642
  function create2DTexture(gl) {
7746
9643
  var texture = gl.createTexture();
7747
- gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); // 图像反转Y轴
7748
-
7749
- gl.activeTexture(gl.TEXTURE0); // 激活纹理单元
7750
-
7751
- gl.bindTexture(gl.TEXTURE_2D, texture); // 绑定纹理对象
7752
- //gl.generateMipmap(gl.TEXTURE_2D);
7753
-
7754
- gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); // 放大处理方式 // LINEAR / NEAREST
7755
-
7756
- gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); // 缩小处理方式
7757
-
7758
- gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); // 水平平铺方式
7759
-
7760
- gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); // 竖直平铺方式
7761
-
9644
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
9645
+ gl.activeTexture(gl.TEXTURE0);
9646
+ gl.bindTexture(gl.TEXTURE_2D, texture);
9647
+ gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
9648
+ gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
9649
+ gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
9650
+ gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
7762
9651
  return texture;
7763
- } // 创建图片纹理
9652
+ }
9653
+ /**
9654
+ * 创建图片纹理
9655
+ * @param {WebGLRenderingContext} gl WebGL 渲染上下文
9656
+ * @param {Image|HTMLImageElement} img 图像对象
9657
+ * @returns {Object} 纹理对象 {texture}
9658
+ */
7764
9659
 
7765
9660
 
7766
9661
  function createImgTexture(gl, img) {
7767
9662
  var texture = create2DTexture(gl);
7768
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img); // 配置纹理图像
7769
-
9663
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
7770
9664
  return {
7771
9665
  texture: texture
7772
9666
  };
7773
- } // 用像素值来绘制纹理
9667
+ }
9668
+ /**
9669
+ * 根据像素数据创建纹理
9670
+ * @param {WebGLRenderingContext} gl WebGL 渲染上下文
9671
+ * @param {ImageData|Object} pixels 像素数据 {data, width, height}
9672
+ * @returns {Object} 纹理对象 {texture}
9673
+ */
7774
9674
 
7775
9675
 
7776
9676
  function createDataTexture(gl, pixels) {
7777
9677
  var data = new Uint8Array(pixels.data || pixels);
7778
9678
  var texture = create2DTexture(gl);
7779
- gl.texImage2D(gl.TEXTURE_2D, // 纹理目标
7780
- 0, // 细节级别,指定详细级别。0 级是基本图像等级,n 级是第 n 个金字塔简化级。
7781
- gl.RGBA, // 纹理内部格式
7782
- pixels.width || 1, // 指定纹理的宽度
7783
- pixels.height || 1, // 指定纹理的高度
7784
- 0, // 指定纹理的边框宽度。必须为 0。
7785
- gl.RGBA, // 源图像数据格式
7786
- gl.UNSIGNED_BYTE, // 纹理数据类型
7787
- data // 数据
7788
- );
9679
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, pixels.width || 1, pixels.height || 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
7789
9680
  return {
7790
9681
  texture: texture
7791
9682
  };
7792
- } // 删除纹理
9683
+ }
9684
+ /**
9685
+ * 删除纹理
9686
+ * @param {WebGLRenderingContext} gl WebGL 渲染上下文
9687
+ * @param {WebGLTexture} texture 纹理对象
9688
+ */
7793
9689
 
7794
9690
 
7795
9691
  function deleteTexture(gl, texture) {
@@ -7812,21 +9708,56 @@ function _defineProperties(target, props) { for (var i = 0; i < props.length; i+
7812
9708
 
7813
9709
  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
7814
9710
 
9711
+ /**
9712
+ * @fileoverview WebGL 渐变对象
9713
+ *
9714
+ * 本模块提供了 WebGL 渐变功能,支持 GLSL 着色器直接计算渐变色,
9715
+ * 无需 textureCanvas,性能更优。
9716
+ *
9717
+ * 支持的渐变类型:
9718
+ * - 线性渐变 (linear)
9719
+ * - 径向渐变 (radial)
9720
+ *
9721
+ * @module lib/webgl/gradient
9722
+ * @author jmGraph Team
9723
+ */
9724
+
9725
+ /** @constant {number} 最大颜色断点数量 */
7815
9726
  var MAX_STOPS = 16;
7816
9727
  /**
7817
- * WebGL 渐变对象
7818
- * 支持 GLSL 着色器直接计算渐变色,无需 textureCanvas
9728
+ * WebGL 渐变类
9729
+ * 支持 GLSL 着色器直接计算渐变色
9730
+ *
9731
+ * @class WebglGradient
9732
+ * @example
9733
+ * const gradient = new WebglGradient('linear', { x1: 0, y1: 0, x2: 100, y2: 0 });
9734
+ * gradient.addColorStop(0, '#ff0000');
9735
+ * gradient.addColorStop(1, '#0000ff');
7819
9736
  */
7820
9737
 
7821
9738
  exports.MAX_STOPS = MAX_STOPS;
7822
9739
 
7823
9740
  var WebglGradient = /*#__PURE__*/function () {
9741
+ /**
9742
+ * 构造函数
9743
+ * @param {string} [type='linear'] 渐变类型:'linear' 或 'radial'
9744
+ * @param {Object} params 渐变参数
9745
+ * @param {number} [params.x1=0] 起点/内圆中心X坐标
9746
+ * @param {number} [params.y1=0] 起点/内圆中心Y坐标
9747
+ * @param {number} [params.r1=0] 内圆半径(径向渐变)
9748
+ * @param {number} [params.x2=0] 终点/外圆中心X坐标
9749
+ * @param {number} [params.y2=0] 终点/外圆中心Y坐标
9750
+ * @param {number} [params.r2=0] 外圆半径(径向渐变)
9751
+ * @param {Object} [params.bounds] 渐变边界
9752
+ * @param {Object} [params.control] 控制器对象
9753
+ */
7824
9754
  function WebglGradient() {
7825
9755
  var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'linear';
7826
9756
  var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7827
9757
 
7828
9758
  _classCallCheck(this, WebglGradient);
7829
9759
 
9760
+ /** @type {string} 渐变类型 */
7830
9761
  this.type = type || 'linear';
7831
9762
  this.x1 = params.x1 || 0;
7832
9763
  this.y1 = params.y1 || 0;
@@ -7834,6 +9765,8 @@ var WebglGradient = /*#__PURE__*/function () {
7834
9765
  this.x2 = params.x2 || 0;
7835
9766
  this.y2 = params.y2 || 0;
7836
9767
  this.r2 = params.r2 || 0;
9768
+ /** @type {Object} 渐变边界 */
9769
+
7837
9770
  this.bounds = params.bounds || {
7838
9771
  left: 0,
7839
9772
  top: 0,
@@ -7841,12 +9774,16 @@ var WebglGradient = /*#__PURE__*/function () {
7841
9774
  height: 0
7842
9775
  };
7843
9776
  this.control = params.control;
9777
+ /** @type {Array<{offset: number, color: string}>} 颜色断点数组 */
9778
+
7844
9779
  this.stops = [];
7845
9780
  this._sortedStops = null;
7846
9781
  this._paramsHash = null;
7847
9782
  }
7848
9783
  /**
7849
9784
  * 添加颜色断点
9785
+ * @param {number} offset 断点位置 (0-1)
9786
+ * @param {string} color 颜色值
7850
9787
  */
7851
9788
 
7852
9789
 
@@ -7861,7 +9798,9 @@ var WebglGradient = /*#__PURE__*/function () {
7861
9798
  this._paramsHash = null;
7862
9799
  }
7863
9800
  /**
7864
- * 获取排序后的 stops(带解析后的颜色)
9801
+ * 获取排序后的断点数组(带解析后的颜色)
9802
+ * @private
9803
+ * @returns {Array<{offset: number, r: number, g: number, b: number, a: number}>}
7865
9804
  */
7866
9805
 
7867
9806
  }, {
@@ -7877,8 +9816,6 @@ var WebglGradient = /*#__PURE__*/function () {
7877
9816
  }
7878
9817
 
7879
9818
  if (_typeof(c) === 'object' && c !== null) {
7880
- // hexToRGBA 返回 r/g/b 为 0~255,a 为 0~1
7881
- // 但如果已经是 0~1 范围(由 rgbToDecimal 处理过),需要检测
7882
9819
  var needNormalize = c.r > 1 || c.g > 1 || c.b > 1 ? 255 : 1;
7883
9820
  return {
7884
9821
  offset: s.offset,
@@ -7902,8 +9839,8 @@ var WebglGradient = /*#__PURE__*/function () {
7902
9839
  return this._sortedStops;
7903
9840
  }
7904
9841
  /**
7905
- * 将渐变参数以 uniform 形式传递给着色器
7906
- * 返回 { type, start, end, stopCount, stops } 供着色器使用
9842
+ * 将渐变参数转换为 uniform 格式,传递给着色器
9843
+ * @returns {Object} uniform 参数对象
7907
9844
  */
7908
9845
 
7909
9846
  }, {
@@ -7911,8 +9848,7 @@ var WebglGradient = /*#__PURE__*/function () {
7911
9848
  value: function toUniformParams() {
7912
9849
  var stops = this._getSortedStops();
7913
9850
 
7914
- var count = Math.min(stops.length, MAX_STOPS); // 展平为 Float32Array: [offset, r, g, b, a, ...]
7915
-
9851
+ var count = Math.min(stops.length, MAX_STOPS);
7916
9852
  var flatStops = new Float32Array(count * 5);
7917
9853
 
7918
9854
  for (var i = 0; i < count; i++) {
@@ -7932,9 +9868,7 @@ var WebglGradient = /*#__PURE__*/function () {
7932
9868
  stops: flatStops
7933
9869
  };
7934
9870
  }
7935
- /**
7936
- * 使缓存失效
7937
- */
9871
+ /** 使缓存失效 */
7938
9872
 
7939
9873
  }, {
7940
9874
  key: "invalidateCache",
@@ -7944,6 +9878,7 @@ var WebglGradient = /*#__PURE__*/function () {
7944
9878
  }
7945
9879
  /**
7946
9880
  * 转换为渐变的字符串表达
9881
+ * @returns {string} 渐变字符串
7947
9882
  */
7948
9883
 
7949
9884
  }, {
@@ -8036,29 +9971,58 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
8036
9971
 
8037
9972
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
8038
9973
 
8039
- // path 绘制类
9974
+ /**
9975
+ * WebGL 路径绘制类
9976
+ * 继承自 WeblBase,提供路径绘制功能
9977
+ *
9978
+ * @class WebglPath
9979
+ * @extends WeblBase
9980
+ * @example
9981
+ * const path = new WebglPath(graph, { isRegular: false, needCut: true });
9982
+ * path.draw(points);
9983
+ * path.stroke(points, '#ff0000', 2);
9984
+ */
8040
9985
  var WebglPath = /*#__PURE__*/function (_WebglBase) {
8041
9986
  _inherits(WebglPath, _WebglBase);
8042
9987
 
8043
9988
  var _super = _createSuper(WebglPath);
8044
9989
 
9990
+ /**
9991
+ * 构造函数
9992
+ * @param {jmGraph} graph jmGraph 实例
9993
+ * @param {Object} option 配置选项
9994
+ * @param {boolean} [option.isRegular=false] 是否为规则图形(凸多边形)
9995
+ * @param {boolean} [option.needCut=false] 是否需要切割处理
9996
+ * @param {Object} [option.control] 控制器对象
9997
+ */
8045
9998
  function WebglPath(graph, option) {
8046
9999
  var _this;
8047
10000
 
8048
10001
  _classCallCheck(this, WebglPath);
8049
10002
 
8050
- _this = _super.call(this, graph, option); // 是否是规则的,不规则的处理方式更为复杂和耗性能
10003
+ _this = _super.call(this, graph, option);
10004
+ /** @type {boolean} 是否为规则图形(凸多边形),规则图形处理更高效 */
8051
10005
 
8052
10006
  _this.isRegular = option.isRegular || false;
10007
+ /** @type {boolean} 是否需要切割处理 */
10008
+
8053
10009
  _this.needCut = option.needCut || false;
8054
10010
  _this.control = option.control;
8055
- _this.points = []; // 缓存 buffer 和纹理,避免每帧创建/销毁
10011
+ /** @type {Array<Object>} 路径点数组 */
10012
+
10013
+ _this.points = [];
10014
+ /** @type {Array} 缓存的缓冲区,避免每帧创建/销毁 */
8056
10015
 
8057
10016
  _this.__cachedBuffers = [];
10017
+ /** @type {Object} 缓存的纹理 */
10018
+
8058
10019
  _this.__cachedTexture = null;
10020
+ /** @type {string} 缓存纹理的 key */
10021
+
8059
10022
  _this.__cachedTextureKey = null;
8060
10023
  return _this;
8061
- } // 释放缓存的 WebGL 资源
10024
+ }
10025
+ /** 释放缓存的 WebGL 资源 */
8062
10026
 
8063
10027
 
8064
10028
  _createClass(WebglPath, [{
@@ -8085,7 +10049,13 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
8085
10049
  this.__cachedTexture = null;
8086
10050
  this.__cachedTextureKey = null;
8087
10051
  }
8088
- } // 获取或创建 buffer,优先复用缓存
10052
+ }
10053
+ /**
10054
+ * 获取或创建缓冲区,优先复用缓存
10055
+ * @param {Array} data 数据数组
10056
+ * @param {Object} attr 属性对象
10057
+ * @returns {Object} 缓冲区对象
10058
+ */
8089
10059
 
8090
10060
  }, {
8091
10061
  key: "getOrCreateBuffer",
@@ -8109,13 +10079,23 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
8109
10079
  this.__cachedBuffers.push(buffer);
8110
10080
 
8111
10081
  return buffer;
8112
- } // 应用变换到点
10082
+ }
10083
+ /**
10084
+ * 应用变换到点
10085
+ * @param {Object} point 点坐标 {x, y}
10086
+ * @returns {Object} 变换后的点坐标
10087
+ */
8113
10088
 
8114
10089
  }, {
8115
10090
  key: "applyTransform",
8116
10091
  value: function applyTransform(point) {
8117
10092
  return _get(_getPrototypeOf(WebglPath.prototype), "applyTransform", this).call(this, point);
8118
10093
  }
10094
+ /**
10095
+ * 设置父级边界
10096
+ * @param {Object} [parentBounds] 父级边界 {left, top, width, height}
10097
+ */
10098
+
8119
10099
  }, {
8120
10100
  key: "setParentBounds",
8121
10101
  value: function setParentBounds() {
@@ -8183,17 +10163,18 @@ var WebglPath = /*#__PURE__*/function (_WebglBase) {
8183
10163
  key: "endDraw",
8184
10164
  value: function endDraw() {
8185
10165
  if (this.points) delete this.points;
8186
- if (this.pathPoints) delete this.pathPoints; // 缓存的纹理保留到下次绘制(渐变可能不变)
8187
- } // 图形封闭
10166
+ if (this.pathPoints) delete this.pathPoints;
10167
+ this.needClose = false; // 缓存的纹理保留到下次绘制(渐变可能不变)
10168
+ }
10169
+ /**
10170
+ * 标记路径需要闭合(不修改原始 points 数组)
10171
+ * 闭合逻辑由 stroke/fill 绘制方法自行处理
10172
+ */
8188
10173
 
8189
10174
  }, {
8190
10175
  key: "closePath",
8191
10176
  value: function closePath() {
8192
- if (this.points && this.points.length > 2 && this.points[0] !== this.points[this.points.length - 1]) {
8193
- var start = this.points[0];
8194
- var end = this.points[this.points.length - 1];
8195
- if (start != end && !(start.x === end.x && start.y === end.y)) this.points.push(start);
8196
- }
10177
+ this.needClose = true;
8197
10178
  } // 绘制点数组(使用 DYNAMIC_DRAW 复用 buffer,避免每帧 create/delete)
8198
10179
 
8199
10180
  }, {
@@ -9291,11 +11272,40 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
9291
11272
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
9292
11273
 
9293
11274
  /**
9294
- * 圆弧图型 继承自jmPath
11275
+ * 圆弧类
11276
+ *
11277
+ * 绘制圆弧或扇形图形,继承自 jmPath。
11278
+ * 支持设置圆心、半径、起始角度和结束角度。
9295
11279
  *
9296
11280
  * @class jmArc
9297
11281
  * @extends jmPath
9298
- * @param {object} params center=当前圆弧中心,radius=圆弧半径,start=圆弧起始角度,end=圆弧结束角度,anticlockwise= false 顺时针,true 逆时针
11282
+ * @param {object} params 圆弧参数
11283
+ * @param {object} [params.center] 圆弧中心点 {x, y}
11284
+ * @param {number} [params.radius] 圆弧半径
11285
+ * @param {number} [params.start=0] 圆弧起始角度(弧度)
11286
+ * @param {number} [params.end=Math.PI*2] 圆弧结束角度(弧度)
11287
+ * @param {boolean} [params.anticlockwise=false] 绘制方向:false=顺时针,true=逆时针
11288
+ * @param {boolean} [params.isFan=false] 是否绘制为扇形
11289
+ *
11290
+ * @example
11291
+ * // 创建圆弧
11292
+ * const arc = graph.createShape('arc', {
11293
+ * center: {x: 200, y: 200},
11294
+ * radius: 50,
11295
+ * start: 0,
11296
+ * end: Math.PI,
11297
+ * style: { stroke: '#000' }
11298
+ * });
11299
+ *
11300
+ * // 创建扇形
11301
+ * const fan = graph.createShape('arc', {
11302
+ * center: {x: 200, y: 200},
11303
+ * radius: 50,
11304
+ * start: 0,
11305
+ * end: Math.PI / 2,
11306
+ * isFan: true,
11307
+ * style: { fill: '#ff0000' }
11308
+ * });
9299
11309
  */
9300
11310
  var jmArc = /*#__PURE__*/function (_jmPath) {
9301
11311
  _inherits(jmArc, _jmPath);
@@ -9518,11 +11528,27 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
9518
11528
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
9519
11529
 
9520
11530
  /**
9521
- * 画箭头,继承自jmPath
11531
+ * 箭头类
11532
+ *
11533
+ * 绘制箭头图形,支持空心和实心两种样式。
11534
+ * 箭头方向由起点和终点决定。
9522
11535
  *
9523
11536
  * @class jmArrow
9524
11537
  * @extends jmPath
9525
- * @param {object} 生成箭头所需的参数
11538
+ * @param {object} params 箭头参数
11539
+ * @param {object} [params.start] 箭头起始点 {x, y}
11540
+ * @param {object} [params.end] 箭头终点(箭头尖端){x, y}
11541
+ * @param {number} [params.angle] 箭头角度(弧度),不指定则自动计算
11542
+ * @param {number} [params.offsetX=5] 箭头X方向偏移量
11543
+ * @param {number} [params.offsetY=8] 箭头Y方向偏移量
11544
+ *
11545
+ * @example
11546
+ * // 创建箭头
11547
+ * const arrow = graph.createShape('arrow', {
11548
+ * start: {x: 100, y: 100},
11549
+ * end: {x: 200, y: 100},
11550
+ * style: { fill: '#ff0000', stroke: '#000' }
11551
+ * });
9526
11552
  */
9527
11553
  var jmArrow = /*#__PURE__*/function (_jmPath) {
9528
11554
  _inherits(jmArrow, _jmPath);
@@ -9746,11 +11772,25 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
9746
11772
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
9747
11773
 
9748
11774
  /**
9749
- * 带箭头的直线,继承jmPath
11775
+ * 带箭头的直线类
11776
+ *
11777
+ * 绘制带箭头的直线,继承自 jmLine。
11778
+ * 箭头位于直线的末端。
9750
11779
  *
9751
11780
  * @class jmArrowLine
9752
11781
  * @extends jmLine
9753
- * @param {object} params 生成当前直线的参数对象,(style=当前线条样式,start=直线起始点,end=直线终结点)
11782
+ * @param {object} params 直线参数
11783
+ * @param {object} [params.start] 直线起始点 {x, y}
11784
+ * @param {object} [params.end] 直线终结点 {x, y}
11785
+ * @param {boolean} [params.arrowVisible=true] 是否显示箭头
11786
+ *
11787
+ * @example
11788
+ * // 创建带箭头的直线
11789
+ * const arrowLine = graph.createShape('arrowLine', {
11790
+ * start: {x: 100, y: 100},
11791
+ * end: {x: 200, y: 100},
11792
+ * style: { stroke: '#000', lineWidth: 2 }
11793
+ * });
9754
11794
  */
9755
11795
  var jmArrowLine = /*#__PURE__*/function (_jmLine) {
9756
11796
  _inherits(jmArrowLine, _jmLine);
@@ -9834,12 +11874,37 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
9834
11874
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
9835
11875
 
9836
11876
  /**
9837
- * 贝塞尔曲线,继承jmPath
9838
- * N阶,参数points中为控制点
11877
+ * 贝塞尔曲线类
11878
+ *
11879
+ * 绘制 N 阶贝塞尔曲线,参数 points 中为控制点。
11880
+ * 支持 2 阶(二次贝塞尔)、3 阶(三次贝塞尔)及更高阶曲线。
9839
11881
  *
9840
11882
  * @class jmBezier
9841
11883
  * @extends jmPath
9842
11884
  * @param {object} params 参数
11885
+ * @param {array} [params.points] 控制点数组 [{x, y}, ...]
11886
+ *
11887
+ * @example
11888
+ * // 创建二次贝塞尔曲线(3个控制点)
11889
+ * const quadBezier = graph.createShape('bezier', {
11890
+ * points: [
11891
+ * {x: 100, y: 100}, // 起点
11892
+ * {x: 200, y: 50}, // 控制点
11893
+ * {x: 300, y: 100} // 终点
11894
+ * ],
11895
+ * style: { stroke: '#000', lineWidth: 2 }
11896
+ * });
11897
+ *
11898
+ * // 创建三次贝塞尔曲线(4个控制点)
11899
+ * const cubicBezier = graph.createShape('bezier', {
11900
+ * points: [
11901
+ * {x: 100, y: 100}, // 起点
11902
+ * {x: 150, y: 50}, // 控制点1
11903
+ * {x: 250, y: 50}, // 控制点2
11904
+ * {x: 300, y: 100} // 终点
11905
+ * ],
11906
+ * style: { stroke: '#ff0000' }
11907
+ * });
9843
11908
  */
9844
11909
  var jmBezier = /*#__PURE__*/function (_jmPath) {
9845
11910
  _inherits(jmBezier, _jmPath);
@@ -9853,8 +11918,12 @@ var jmBezier = /*#__PURE__*/function (_jmPath) {
9853
11918
 
9854
11919
  _classCallCheck(this, jmBezier);
9855
11920
 
9856
- // 典线默认不封闭
9857
- if (params.style && typeof params.style.close !== true) {
11921
+ // 参数初始化
11922
+ params = params || {}; // 曲线默认不封闭
11923
+
11924
+ if (!params.style) params.style = {};
11925
+
11926
+ if (typeof params.style.close !== true) {
9858
11927
  params.style.close = false;
9859
11928
  }
9860
11929
 
@@ -10010,11 +12079,27 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
10010
12079
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
10011
12080
 
10012
12081
  /**
10013
- * 画规则的圆弧
12082
+ * 圆形类
12083
+ *
12084
+ * 绘制圆形图形,继承自 jmArc。
12085
+ * 可以通过 center 和 radius 指定圆心和半径,
12086
+ * 也可以通过 width 和 height 指定圆的尺寸。
10014
12087
  *
10015
12088
  * @class jmCircle
10016
12089
  * @extends jmArc
10017
- * @param {object} params 圆的参数:center=圆中心,radius=圆半径,优先取此属性,如果没有则取宽和高,width=圆宽,height=圆高
12090
+ * @param {object} params 圆的参数
12091
+ * @param {object} [params.center] 圆心坐标 {x, y}
12092
+ * @param {number} [params.radius] 圆半径(优先使用)
12093
+ * @param {number} [params.width] 圆宽度(无 radius 时使用)
12094
+ * @param {number} [params.height] 圆高度(无 radius 时使用)
12095
+ *
12096
+ * @example
12097
+ * // 创建圆形
12098
+ * const circle = graph.createShape('circle', {
12099
+ * center: {x: 200, y: 200},
12100
+ * radius: 50,
12101
+ * style: { fill: '#ff0000', stroke: '#000' }
12102
+ * });
10018
12103
  */
10019
12104
  var jmCircle = /*#__PURE__*/function (_jmArc) {
10020
12105
  _inherits(jmCircle, _jmArc);
@@ -10140,9 +12225,10 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
10140
12225
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
10141
12226
 
10142
12227
  /**
10143
- * 画椭圆
10144
- * 椭圆是通过缩放圆形来实现的,支持完整的椭圆和椭圆弧
10145
- * 可以指定起始角度和结束角度来绘制椭圆弧
12228
+ * 椭圆类
12229
+ *
12230
+ * 绘制椭圆图形,继承自 jmArc。
12231
+ * 可以指定起始角度和结束角度来绘制椭圆弧。
10146
12232
  *
10147
12233
  * @class jmEllipse
10148
12234
  * @extends jmArc
@@ -10153,6 +12239,15 @@ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.g
10153
12239
  * @param {number} [params.startAngle=0] 起始角度(弧度)
10154
12240
  * @param {number} [params.endAngle=Math.PI*2] 结束角度(弧度)
10155
12241
  * @param {boolean} [params.anticlockwise=false] 是否逆时针绘制
12242
+ *
12243
+ * @example
12244
+ * // 创建椭圆
12245
+ * const ellipse = graph.createShape('ellipse', {
12246
+ * center: {x: 200, y: 200},
12247
+ * width: 200,
12248
+ * height: 100,
12249
+ * style: { fill: '#ff0000', stroke: '#000' }
12250
+ * });
10156
12251
  */
10157
12252
  var jmEllipse = /*#__PURE__*/function (_jmArc) {
10158
12253
  _inherits(jmEllipse, _jmArc);
@@ -10286,11 +12381,31 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
10286
12381
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
10287
12382
 
10288
12383
  /**
10289
- * 画空心圆弧,继承自jmPath
12384
+ * 空心圆弧类
12385
+ *
12386
+ * 绘制空心圆弧(圆环弧),继承自 jmArc。
12387
+ * 由内圆半径和外圆半径定义环形区域。
10290
12388
  *
10291
12389
  * @class jmHArc
10292
12390
  * @extends jmArc
10293
- * @param {object} params 空心圆参数:minRadius=中心小圆半径,maxRadius=大圆半径,start=起始角度,end=结束角度,anticlockwise=false 顺时针,true 逆时针
12391
+ * @param {object} params 空心圆弧参数
12392
+ * @param {object} [params.center] 圆弧中心点 {x, y}
12393
+ * @param {number} [params.minRadius] 内圆半径
12394
+ * @param {number} [params.maxRadius] 外圆半径
12395
+ * @param {number} [params.start=0] 起始角度(弧度)
12396
+ * @param {number} [params.end=Math.PI*2] 结束角度(弧度)
12397
+ * @param {boolean} [params.anticlockwise=false] 是否逆时针绘制
12398
+ *
12399
+ * @example
12400
+ * // 创建空心圆弧
12401
+ * const hArc = graph.createShape('hArc', {
12402
+ * center: {x: 200, y: 200},
12403
+ * minRadius: 30,
12404
+ * maxRadius: 50,
12405
+ * start: 0,
12406
+ * end: Math.PI,
12407
+ * style: { fill: '#ff0000' }
12408
+ * });
10294
12409
  */
10295
12410
  var jmHArc = /*#__PURE__*/function (_jmArc) {
10296
12411
  _inherits(jmHArc, _jmArc);
@@ -10450,13 +12565,41 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
10450
12565
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
10451
12566
 
10452
12567
  /**
10453
- * 图片控件,继承自jmControl
10454
- * params参数中image为指定的图片源地址或图片img对象,
10455
- * postion=当前控件的位置,width=其宽度,height=高度,sourcePosition=从当前图片中展示的位置,sourceWidth=从图片中截取的宽度,sourceHeight=从图片中截取的高度。
12568
+ * 图片类
10456
12569
  *
12570
+ * 显示图片控件,支持从 URL 或 Image 对象加载图片。
12571
+ * 支持图片裁剪和缩放功能。
12572
+ *
10457
12573
  * @class jmImage
10458
12574
  * @extends jmControl
10459
12575
  * @param {object} params 控件参数
12576
+ * @param {string|HTMLImageElement} [params.image] 图片源地址或图片对象
12577
+ * @param {object} [params.position] 图片位置 {x, y}
12578
+ * @param {number} [params.width] 图片显示宽度
12579
+ * @param {number} [params.height] 图片显示高度
12580
+ * @param {object} [params.sourcePosition] 图片裁剪起始位置 {x, y}
12581
+ * @param {number} [params.sourceWidth] 图片裁剪宽度
12582
+ * @param {number} [params.sourceHeight] 图片裁剪高度
12583
+ *
12584
+ * @example
12585
+ * // 从 URL 加载图片
12586
+ * const img = graph.createShape('image', {
12587
+ * image: 'path/to/image.png',
12588
+ * position: {x: 100, y: 100},
12589
+ * width: 200,
12590
+ * height: 150
12591
+ * });
12592
+ *
12593
+ * // 裁剪图片
12594
+ * const croppedImg = graph.createShape('image', {
12595
+ * image: 'path/to/sprite.png',
12596
+ * position: {x: 100, y: 100},
12597
+ * sourcePosition: {x: 0, y: 0},
12598
+ * sourceWidth: 50,
12599
+ * sourceHeight: 50,
12600
+ * width: 100,
12601
+ * height: 100
12602
+ * });
10460
12603
  */
10461
12604
  var jmImage = /*#__PURE__*/function (_jmControl) {
10462
12605
  _inherits(jmImage, _jmControl);
@@ -10758,11 +12901,32 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
10758
12901
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
10759
12902
 
10760
12903
  /**
10761
- * 显示文字控件
12904
+ * 文本标签类
12905
+ *
12906
+ * 显示文字控件,支持多种文本样式和对齐方式。
10762
12907
  *
10763
12908
  * @class jmLabel
10764
12909
  * @extends jmControl
10765
- * @param {object} params params参数:style=样式,value=显示的文字
12910
+ * @param {object} params 参数
12911
+ * @param {string} [params.text=''] 显示的文字内容
12912
+ * @param {object} [params.center] 文本中心点坐标
12913
+ * @param {object} [params.style] 样式对象
12914
+ * @param {string} [params.style.font] 字体样式
12915
+ * @param {string} [params.style.textAlign='left'] 水平对齐方式
12916
+ * @param {string} [params.style.textBaseline='middle'] 垂直对齐方式
12917
+ * @param {number} [params.style.maxWidth] 最大宽度(用于自动换行)
12918
+ *
12919
+ * @example
12920
+ * // 创建文本标签
12921
+ * const label = graph.createShape('label', {
12922
+ * position: {x: 100, y: 100},
12923
+ * text: 'Hello World',
12924
+ * style: {
12925
+ * fill: '#000',
12926
+ * font: '20px Arial',
12927
+ * textAlign: 'center'
12928
+ * }
12929
+ * });
10766
12930
  */
10767
12931
  var jmLabel = /*#__PURE__*/function (_jmControl) {
10768
12932
  _inherits(jmLabel, _jmControl);
@@ -11168,11 +13332,34 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
11168
13332
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
11169
13333
 
11170
13334
  /**
11171
- * 画一条直线
13335
+ * 直线类
13336
+ *
13337
+ * 绘制从起点到终点的直线,支持实线和虚线两种模式。
11172
13338
  *
11173
13339
  * @class jmLine
11174
13340
  * @extends jmPath
11175
- * @param {object} params 直线参数:start=起始点,end=结束点,lineType=线类型(solid=实线,dotted=虚线),dashLength=虚线间隔(=4)
13341
+ * @param {object} params 直线参数
13342
+ * @param {object} [params.start] 起始点 {x, y}
13343
+ * @param {object} [params.end] 结束点 {x, y}
13344
+ * @param {string} [params.lineType='solid'] 线类型:'solid'=实线,'dotted'=虚线
13345
+ * @param {number} [params.dashLength=4] 虚线间隔长度
13346
+ *
13347
+ * @example
13348
+ * // 创建实线
13349
+ * const line = graph.createShape('line', {
13350
+ * start: {x: 0, y: 0},
13351
+ * end: {x: 100, y: 100},
13352
+ * style: { stroke: '#000', lineWidth: 2 }
13353
+ * });
13354
+ *
13355
+ * // 创建虚线
13356
+ * const dottedLine = graph.createShape('line', {
13357
+ * start: {x: 0, y: 0},
13358
+ * end: {x: 100, y: 100},
13359
+ * lineType: 'dotted',
13360
+ * dashLength: 5,
13361
+ * style: { stroke: '#000' }
13362
+ * });
11176
13363
  */
11177
13364
  var jmLine = /*#__PURE__*/function (_jmPath) {
11178
13365
  _inherits(jmLine, _jmPath);
@@ -11323,9 +13510,11 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
11323
13510
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
11324
13511
 
11325
13512
  /**
11326
- * 画多边形
11327
- * 支持规则多边形(正多边形)和自定义多边形
11328
- * 规则多边形通过边数和半径自动计算顶点,自定义多边形通过顶点数组定义
13513
+ * 多边形类
13514
+ *
13515
+ * 绘制多边形图形,支持规则多边形和自定义多边形。
13516
+ * 规则多边形通过边数和半径自动计算顶点,
13517
+ * 自定义多边形通过顶点数组定义。
11329
13518
  *
11330
13519
  * @class jmPolygon
11331
13520
  * @extends jmPath
@@ -11334,6 +13523,27 @@ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.g
11334
13523
  * @param {number} [params.sides=3] 多边形边数(3-100)
11335
13524
  * @param {number} [params.radius=50] 多边形半径(像素)
11336
13525
  * @param {object} [params.center={x:0,y:0}] 多边形中心点坐标
13526
+ *
13527
+ * @example
13528
+ * // 创建正六边形
13529
+ * const hexagon = graph.createShape('polygon', {
13530
+ * center: {x: 200, y: 200},
13531
+ * sides: 6,
13532
+ * radius: 50,
13533
+ * style: { fill: '#ff0000', stroke: '#000' }
13534
+ * });
13535
+ *
13536
+ * // 创建自定义多边形
13537
+ * const polygon = graph.createShape('polygon', {
13538
+ * points: [
13539
+ * {x: 100, y: 100},
13540
+ * {x: 200, y: 50},
13541
+ * {x: 300, y: 100},
13542
+ * {x: 250, y: 200},
13543
+ * {x: 150, y: 200}
13544
+ * ],
13545
+ * style: { fill: '#00ff00' }
13546
+ * });
11337
13547
  */
11338
13548
  var jmPolygon = /*#__PURE__*/function (_jmPath) {
11339
13549
  _inherits(jmPolygon, _jmPath);
@@ -11519,11 +13729,26 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
11519
13729
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
11520
13730
 
11521
13731
  /**
11522
- * 画棱形
13732
+ * 棱形类
13733
+ *
13734
+ * 绘制棱形(菱形)图形,继承自 jmPath。
13735
+ * 棱形由中心点、宽度和高度定义。
11523
13736
  *
11524
13737
  * @class jmPrismatic
11525
13738
  * @extends jmPath
11526
- * @param {object} params 参数 center=棱形中心点,width=棱形宽,height=棱形高
13739
+ * @param {object} params 参数
13740
+ * @param {object} [params.center] 棱形中心点 {x, y}
13741
+ * @param {number} [params.width] 棱形宽度
13742
+ * @param {number} [params.height] 棱形高度
13743
+ *
13744
+ * @example
13745
+ * // 创建棱形
13746
+ * const prismatic = graph.createShape('prismatic', {
13747
+ * center: {x: 200, y: 200},
13748
+ * width: 100,
13749
+ * height: 80,
13750
+ * style: { fill: '#ff0000', stroke: '#000' }
13751
+ * });
11527
13752
  */
11528
13753
  var jmPrismatic = /*#__PURE__*/function (_jmPath) {
11529
13754
  _inherits(jmPrismatic, _jmPath);
@@ -11643,12 +13868,37 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
11643
13868
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
11644
13869
 
11645
13870
  /**
11646
- * 画矩形
13871
+ * 矩形类
13872
+ *
13873
+ * 绘制矩形图形,支持圆角和虚线边框。
13874
+ * 圆角可以统一设置或四角独立设置。
11647
13875
  *
11648
13876
  * @class jmRect
11649
13877
  * @extends jmPath
11650
- * @param {object} params 参数 position=矩形左上角顶点坐标,width=宽,height=高,radius=边角弧度
11651
- * radius支持数字(四角相同)或对象 { topLeft, topRight, bottomRight, bottomLeft }
13878
+ * @param {object} params 参数
13879
+ * @param {object} [params.position] 矩形左上角顶点坐标 {x, y}
13880
+ * @param {number} [params.width] 矩形宽度
13881
+ * @param {number} [params.height] 矩形高度
13882
+ * @param {number|object} [params.radius] 边角弧度,支持数字(四角相同)或对象 { topLeft, topRight, bottomRight, bottomLeft }
13883
+ *
13884
+ * @example
13885
+ * // 创建普通矩形
13886
+ * const rect = graph.createShape('rect', {
13887
+ * position: {x: 100, y: 100},
13888
+ * width: 200,
13889
+ * height: 150,
13890
+ * style: { fill: '#ff0000', stroke: '#000' }
13891
+ * });
13892
+ *
13893
+ * // 创建圆角矩形
13894
+ * const roundedRect = graph.createShape('rect', {
13895
+ * position: {x: 100, y: 100},
13896
+ * width: 200,
13897
+ * height: 150,
13898
+ * radius: 10, // 四角统一圆角
13899
+ * // 或 radius: { topLeft: 5, topRight: 10, bottomRight: 15, bottomLeft: 20 }
13900
+ * style: { fill: '#00ff00' }
13901
+ * });
11652
13902
  */
11653
13903
  var jmRect = /*#__PURE__*/function (_jmPath) {
11654
13904
  _inherits(jmRect, _jmPath);
@@ -12004,12 +14254,32 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
12004
14254
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
12005
14255
 
12006
14256
  /**
12007
- * 可拉伸的缩放控件
12008
- * 继承jmRect
12009
- * 如果此控件加入到了当前控制的对象的子控件中,请在参数中加入movable:false,否则导致当前控件会偏离被控制的控件。
14257
+ * 可缩放控件类
14258
+ *
14259
+ * 继承自 jmRect,在矩形四边和四角添加可拖拽的控制点。
14260
+ * 用于实现图形的缩放和调整功能。
12010
14261
  *
12011
14262
  * @class jmResize
12012
14263
  * @extends jmRect
14264
+ * @param {object} params 控件参数
14265
+ * @param {boolean} [params.resizable=true] 是否可缩放
14266
+ * @param {boolean} [params.movable] 是否可移动
14267
+ * @param {number} [params.rectSize=8] 控制点大小
14268
+ *
14269
+ * @example
14270
+ * // 创建可缩放矩形
14271
+ * const resize = graph.createShape('resize', {
14272
+ * position: {x: 100, y: 100},
14273
+ * width: 200,
14274
+ * height: 150,
14275
+ * resizable: true,
14276
+ * movable: true
14277
+ * });
14278
+ *
14279
+ * // 监听缩放事件
14280
+ * resize.on('resize', (px, py, dx, dy) => {
14281
+ * console.log('缩放中', px, py, dx, dy);
14282
+ * });
12013
14283
  */
12014
14284
  var jmResize = /*#__PURE__*/function (_jmRect) {
12015
14285
  _inherits(jmResize, _jmRect);
@@ -12348,7 +14618,7 @@ var jmResize = /*#__PURE__*/function (_jmRect) {
12348
14618
 
12349
14619
  case 6:
12350
14620
  {
12351
- r.position.x = (newLocation.width - r.height) / 2;
14621
+ r.position.x = (newLocation.width - r.width) / 2;
12352
14622
  r.position.y = newLocation.height - r.height / 2;
12353
14623
  break;
12354
14624
  }
@@ -12404,18 +14674,36 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
12404
14674
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
12405
14675
 
12406
14676
  /**
12407
- * 画星形
12408
- * 支持自定义顶点数和内外半径,创建各种星形图案
12409
- * 星形由交替的外半径和内半径顶点组成
14677
+ * 星形类
14678
+ *
14679
+ * 绘制星形图形,支持自定义顶点数和内外半径。
14680
+ * 星形由交替的外半径和内半径顶点组成。
12410
14681
  *
12411
14682
  * @class jmStar
12412
14683
  * @extends jmPath
12413
14684
  * @param {object} params 星形的参数
12414
- * @param {array} [params.points] 自定义顶点数组,如果提供则忽略其他参数
12415
14685
  * @param {number} [params.points=5] 星形顶点数(角数,3-50)
12416
14686
  * @param {number} [params.radius=50] 星形外半径(从中心到尖角的距离)
12417
14687
  * @param {number} [params.innerRadius=25] 星形内半径(从中心到凹陷处的距离)
12418
14688
  * @param {object} [params.center={x:0,y:0}] 星形中心点坐标
14689
+ *
14690
+ * @example
14691
+ * // 创建五角星
14692
+ * const star = graph.createShape('star', {
14693
+ * center: {x: 200, y: 200},
14694
+ * points: 5,
14695
+ * radius: 50,
14696
+ * innerRadius: 25,
14697
+ * style: { fill: '#ff0000', stroke: '#000' }
14698
+ * });
14699
+ *
14700
+ * // 创建六角星
14701
+ * const hexStar = graph.createShape('star', {
14702
+ * center: {x: 200, y: 200},
14703
+ * points: 6,
14704
+ * radius: 60,
14705
+ * innerRadius: 30
14706
+ * });
12419
14707
  */
12420
14708
  var jmStar = /*#__PURE__*/function (_jmPath) {
12421
14709
  _inherits(jmStar, _jmPath);