@vvfx/sdk 0.2.2-alpha.1 → 0.2.2-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -3,7 +3,7 @@
3
3
  * Description: TODO
4
4
  * Author: Ant Group CO., Ltd.
5
5
  * Contributors: 赤芍,何即,不择,意绮
6
- * Version: v0.2.2-alpha.1
6
+ * Version: v0.2.2-alpha.2
7
7
  */
8
8
 
9
9
  'use strict';
@@ -56603,6 +56603,10 @@ var cursorMap = {
56603
56603
  type: 'preset',
56604
56604
  content: 'crosshair'
56605
56605
  },
56606
+ 'box-select': {
56607
+ type: 'preset',
56608
+ content: 'crosshair'
56609
+ },
56606
56610
  'text-rotation': {
56607
56611
  type: 'svg',
56608
56612
  content: 'default',
@@ -60971,7 +60975,7 @@ var PageDataUtils = /*#__PURE__*/ function() {
60971
60975
  * @description 更新 PlayerItem 的 Property 属性
60972
60976
  */ _proto.updatePlayerItemPropertyAttribute = function updatePlayerItemPropertyAttribute(playerItem, targetItem, propertyName, propertyValue) {
60973
60977
  return _async_to_generator(function() {
60974
- var _this, _playerItem_getComponent, _playerItem_getComponent1, color, _array_, array, family, textComponent, textComponent1, lineCount, textHeight, _playerItem_getComponent2, textComponent2, textHeight1, textComponent3, outlineColor, textComponent4, textComponent5, textComponent6, originFontSize, lineCount1, textHeight2, textComponent7, textHeight3, viewSize, worldSizeX, originSize, originChildBoxes, originBox, worldScaleX, originScale, originWidth, currentWidth, ratio, originScale1, textComponent8, originChildBoxes1, originBox1, worldScaleY, originScale2, originHeight, currentHeight, ratio1, originScale3, viewSize1, worldSizeY, originSize1, textComponent9, textHeight4, _playerItem_getComponent3, _, _playerItem_getComponent4, _1, _propertyValue_compositions_find, _ref, subCompositionItem, compositionId, mainComposition, effectsSize, viewSize2, worldSize, compositionItem, component, videoComponent, videoComponent1, videoComponent2, pixelTranslation, viewTranslation, translation, rotation, currentScale, scaleRatio, frameComponent, _SDK_config_itemConfig_frameConfig, freeLayoutBackgroundColor, autoLayoutBackgroundColor, color1, childrenItem, time;
60978
+ var _this, _playerItem_getComponent, _playerItem_getComponent1, color, _array_, array, family, textComponent, textComponent1, lineCount, textHeight, _playerItem_getComponent2, textComponent2, textHeight1, textComponent3, outlineColor, textComponent4, textComponent5, textComponent6, originFontSize, lineCount1, textHeight2, textComponent7, textHeight3, viewSize, worldSizeX, originSize, originChildBoxes, originBox, worldScaleX, originScale, originWidth, currentWidth, ratio, originScale1, textComponent8, originChildBoxes1, originBox1, worldScaleY, originScale2, originHeight, currentHeight, ratio1, originScale3, viewSize1, worldSizeY, originSize1, textComponent9, textHeight4, _playerItem_getComponent3, _, _playerItem_getComponent4, _1, _propertyValue_compositions_find, _ref, subCompositionItem, compositionId, mainComposition, effectsSize, viewSize2, worldSize, compositionItem, component, videoPlayStates, videoComponent, videoComponent1, videoComponent2, pixelTranslation, viewTranslation, translation, rotation, currentScale, scaleRatio, frameComponent, _SDK_config_itemConfig_frameConfig, freeLayoutBackgroundColor, autoLayoutBackgroundColor, color1, childrenItem, time, videoPlayStates1;
60975
60979
  return _ts_generator(this, function(_state) {
60976
60980
  switch(_state.label){
60977
60981
  case 0:
@@ -61459,7 +61463,10 @@ var PageDataUtils = /*#__PURE__*/ function() {
61459
61463
  compositionItem.parentId = playerItem.getInstanceId();
61460
61464
  component = compositionItem.components[0];
61461
61465
  component == null ? void 0 : component.pause();
61466
+ // 刷新前快照视频播放态,刷新后恢复,避免更换特效导致全量视频被自动播放
61467
+ videoPlayStates = this.snapshotVideoPlayStates();
61462
61468
  this.sdk.player.gotoAndPlay(0);
61469
+ this.restoreVideoPlayStates(videoPlayStates);
61463
61470
  _state.label = 28;
61464
61471
  case 28:
61465
61472
  return [
@@ -61609,11 +61616,14 @@ var PageDataUtils = /*#__PURE__*/ function() {
61609
61616
  'size'
61610
61617
  ].includes(propertyName)) {
61611
61618
  time = this.sdk.pageData.time;
61619
+ // 刷新前快照视频播放态,刷新后恢复,避免设置属性导致全量视频被自动播放
61620
+ videoPlayStates1 = this.snapshotVideoPlayStates();
61612
61621
  if (SDK.config.mode === 'editor') {
61613
61622
  this.player.gotoAndPlay(time);
61614
61623
  } else {
61615
61624
  this.player.gotoAndStop(time);
61616
61625
  }
61626
+ this.restoreVideoPlayStates(videoPlayStates1);
61617
61627
  }
61618
61628
  return [
61619
61629
  2
@@ -65628,6 +65638,51 @@ var PageDataUtils = /*#__PURE__*/ function() {
65628
65638
  var result = box.clone().scale(scale, center).translate(translation);
65629
65639
  return result;
65630
65640
  };
65641
+ /**
65642
+ * @description 快照当前所有视频元素的播放状态(播放/暂停 + 当前播放进度),用于属性刷新后恢复,
65643
+ * 避免设置属性导致全量视频被自动播放或进度被重置回 0s
65644
+ */ _proto.snapshotVideoPlayStates = function snapshotVideoPlayStates() {
65645
+ var states = new Map();
65646
+ var composition = this.getCurrentComposition();
65647
+ for(var _iterator = _create_for_of_iterator_helper_loose(composition.items), _step; !(_step = _iterator()).done;){
65648
+ var item = _step.value;
65649
+ if (item.type === EFFECTS.spec.ItemType.video) {
65650
+ var videoComponent = item.getComponent(VideoComponent);
65651
+ if (!videoComponent) {
65652
+ continue;
65653
+ }
65654
+ //@ts-expect-error @赤芍 played 字段未在类型中声明,参见 rebuildCompositionItems 处用法
65655
+ var played = !!videoComponent.played;
65656
+ var time = videoComponent.getCurrentTime();
65657
+ states.set(item.getInstanceId(), {
65658
+ played: played,
65659
+ time: time
65660
+ });
65661
+ }
65662
+ }
65663
+ return states;
65664
+ };
65665
+ /**
65666
+ * @description 按快照恢复视频元素的播放状态(先 pause 再 seek,最后按原状态 play/pause,避免进度抖动)
65667
+ */ _proto.restoreVideoPlayStates = function restoreVideoPlayStates(states) {
65668
+ for(var _iterator = _create_for_of_iterator_helper_loose(states), _step; !(_step = _iterator()).done;){
65669
+ var _step_value = _step.value, id = _step_value[0], _step_value_ = _step_value[1], played = _step_value_.played, time = _step_value_.time;
65670
+ var playerItem = this.getPlayerItemById(id);
65671
+ if ((playerItem == null ? void 0 : playerItem.type) !== EFFECTS.spec.ItemType.video) {
65672
+ continue;
65673
+ }
65674
+ var videoComponent = playerItem.getComponent(VideoComponent);
65675
+ if (!videoComponent) {
65676
+ continue;
65677
+ }
65678
+ // 先暂停再 seek,避免播放状态下 seek 导致画面抖动
65679
+ videoComponent.pauseVideo();
65680
+ videoComponent.setCurrentTime(time);
65681
+ if (played) {
65682
+ videoComponent.playVideo();
65683
+ }
65684
+ }
65685
+ };
65631
65686
  _proto.playVideoItem = function playVideoItem(id) {
65632
65687
  var playerItem = this.getPlayerItemById(id);
65633
65688
  if ((playerItem == null ? void 0 : playerItem.type) !== EFFECTS.spec.ItemType.video) {
@@ -67193,7 +67248,7 @@ var PageDataUtils = /*#__PURE__*/ function() {
67193
67248
  };
67194
67249
  _proto.autoLayoutPage = function autoLayoutPage() {
67195
67250
  return _async_to_generator(function(param) {
67196
- var _this, pageData, _param_mode, mode, ids, _param_focus, focus, _param_gap, gap, isPartialLayout, targetItems, layoutElements, moveInfos, anchor, _iterator, _step, moveInfo, sdkItem;
67251
+ var _this, pageData, _param_mode, mode, ids, _param_focus, focus, _param_gap, gap, shift, isPartialLayout, targetItems, layoutElements, moveInfos, anchor, _iterator, _step, moveInfo, sdkItem;
67197
67252
  return _ts_generator(this, function(_state) {
67198
67253
  switch(_state.label){
67199
67254
  case 0:
@@ -67208,7 +67263,7 @@ var PageDataUtils = /*#__PURE__*/ function() {
67208
67263
  2
67209
67264
  ];
67210
67265
  }
67211
- _param_mode = param.mode, mode = _param_mode === void 0 ? SDK.config.pageConfig.autoLayoutDefaultMode : _param_mode, ids = param.ids, _param_focus = param.focus, focus = _param_focus === void 0 ? true : _param_focus, _param_gap = param.gap, gap = _param_gap === void 0 ? SDK.config.pageConfig.autoLayoutDefaultGap : _param_gap;
67266
+ _param_mode = param.mode, mode = _param_mode === void 0 ? SDK.config.pageConfig.autoLayoutDefaultMode : _param_mode, ids = param.ids, _param_focus = param.focus, focus = _param_focus === void 0 ? true : _param_focus, _param_gap = param.gap, gap = _param_gap === void 0 ? SDK.config.pageConfig.autoLayoutDefaultGap : _param_gap, shift = param.shift;
67212
67267
  isPartialLayout = !!(ids == null ? void 0 : ids.length);
67213
67268
  // 1. 确定参与排布的顶层元素(过滤子元素)
67214
67269
  targetItems = pageData.items.filter(function(item) {
@@ -67237,7 +67292,7 @@ var PageDataUtils = /*#__PURE__*/ function() {
67237
67292
  // 4. 计算锚点偏移
67238
67293
  // - 选中元素排布:以原始包围盒左上角为锚点
67239
67294
  // - 全量排布:以视口中心为锚点
67240
- anchor = isPartialLayout ? this.getPartialLayoutAnchor(layoutElements, moveInfos.boundingBox) : this.getGlobalLayoutAnchor(moveInfos.boundingBox);
67295
+ anchor = isPartialLayout ? this.getPartialLayoutAnchor(layoutElements, moveInfos.boundingBox) : this.getGlobalLayoutAnchor(moveInfos.boundingBox, shift);
67241
67296
  _iterator = _create_for_of_iterator_helper_loose(moveInfos.items);
67242
67297
  _state.label = 1;
67243
67298
  case 1:
@@ -67280,7 +67335,7 @@ var PageDataUtils = /*#__PURE__*/ function() {
67280
67335
  if (focus) {
67281
67336
  this.setPageZoom(1, undefined, true);
67282
67337
  this.setPageMove(new Vector2());
67283
- this.viewportFit(undefined, moveInfos.boundingBox.translate(anchor));
67338
+ this.viewportFit(shift, moveInfos.boundingBox.translate(anchor));
67284
67339
  }
67285
67340
  return [
67286
67341
  2
@@ -67304,8 +67359,9 @@ var PageDataUtils = /*#__PURE__*/ function() {
67304
67359
  /**
67305
67360
  * @description 计算全量排布的锚点偏移:以视口中心为锚点
67306
67361
  * @param layoutBoundingBox 排布算法输出的包围盒
67307
- */ _proto.getGlobalLayoutAnchor = function getGlobalLayoutAnchor(layoutBoundingBox) {
67308
- var viewCenter = new Vector2(this.sdk._container.offsetWidth / 2, this.sdk._container.offsetHeight / 2);
67362
+ */ _proto.getGlobalLayoutAnchor = function getGlobalLayoutAnchor(layoutBoundingBox, shift) {
67363
+ var _ref = shift != null ? shift : {}, _ref_top = _ref.top, top = _ref_top === void 0 ? 0 : _ref_top, _ref_bottom = _ref.bottom, bottom = _ref_bottom === void 0 ? 0 : _ref_bottom, _ref_left = _ref.left, left = _ref_left === void 0 ? 0 : _ref_left, _ref_right = _ref.right, right = _ref_right === void 0 ? 0 : _ref_right;
67364
+ var viewCenter = new Vector2(this.sdk._container.offsetWidth / 2 + left - right, this.sdk._container.offsetHeight / 2 + top - bottom);
67309
67365
  var boundCenter = layoutBoundingBox.getCenter();
67310
67366
  return new Vector2(viewCenter.x - boundCenter.x, viewCenter.y - boundCenter.y);
67311
67367
  };
@@ -68907,6 +68963,8 @@ var MaskGizmo = /*#__PURE__*/ function(Gizmo) {
68907
68963
  */ _this.maskSprite = null, _this._config = {}, _this.boxGraphics = new Graphics(), _this.type = 'mask', _this.mode = 'paint', /**
68908
68964
  * 蒙版工具独立的撤销重做实例
68909
68965
  */ _this._undoRedo = new GizmoUndoRedo(), /**
68966
+ * 框选擦除进行中标记(按下到松开之间),用于实时选框描边的显示控制
68967
+ */ _this._isBoxErasing = false, /**
68910
68968
  * 鼠标状态绘制结果
68911
68969
  */ _this.cursorResult = {
68912
68970
  type: 'normal',
@@ -68923,10 +68981,22 @@ var MaskGizmo = /*#__PURE__*/ function(Gizmo) {
68923
68981
  var _proto = MaskGizmo.prototype;
68924
68982
  /**
68925
68983
  * 设置模式
68926
- * @param mode 模式类型:'paint' 表示涂抹,'erase' 表示擦除
68984
+ * @param mode 模式类型:'paint' 笔刷涂抹、'erase' 笔刷逐笔擦除、'box-erase' 框选擦除、'box-paint' 框选涂抹
68927
68985
  */ _proto.setMode = function setMode(mode) {
68928
68986
  this.mode = mode;
68929
68987
  };
68988
+ /**
68989
+ * @description 判断点是否在包围盒内
68990
+ */ _proto._isPointInBox = function _isPointInBox(p, box) {
68991
+ return p.x >= box.min.x && p.x <= box.max.x && p.y >= box.min.y && p.y <= box.max.y;
68992
+ };
68993
+ /**
68994
+ * @description 将屏幕坐标转换为包围盒内的归一化坐标 [0,1](钳制在范围内)
68995
+ */ _proto._toNormalized = function _toNormalized(p, box) {
68996
+ var x = Math.max(0, Math.min(1, (p.x - box.min.x) / (box.max.x - box.min.x)));
68997
+ var y = Math.max(0, Math.min(1, (p.y - box.min.y) / (box.max.y - box.min.y)));
68998
+ return new Vector2(x, y);
68999
+ };
68930
69000
  _proto.initialize = function initialize() {};
68931
69001
  _proto.preparationAction = function preparationAction(event) {
68932
69002
  if (!this.interactive) {
@@ -68945,6 +69015,26 @@ var MaskGizmo = /*#__PURE__*/ function(Gizmo) {
68945
69015
  };
68946
69016
  // 更新鼠标位置
68947
69017
  this.result.point = new Vector2(event.offsetX, event.offsetY);
69018
+ // 框选模式(框选擦除 / 框选涂抹):仅在元素包围盒内按下才触发
69019
+ if (this.mode === 'box-erase' || this.mode === 'box-paint') {
69020
+ var box = this.result.box;
69021
+ if (!box || !this._isPointInBox(this.result.point, box)) {
69022
+ // 包围盒外按下:不触发框选,交由其它 gizmo
69023
+ return undefined;
69024
+ }
69025
+ var start = this._toNormalized(this.result.point, box);
69026
+ this.result.lines.push({
69027
+ type: this.mode === 'box-paint' ? 'paint' : 'erase',
69028
+ shape: 'rect',
69029
+ brushSize: 0,
69030
+ points: [
69031
+ start,
69032
+ start.clone()
69033
+ ]
69034
+ });
69035
+ this._isBoxErasing = true;
69036
+ return this.type;
69037
+ }
68948
69038
  // 开启新画笔
68949
69039
  this.result.lines.push({
68950
69040
  type: this.mode,
@@ -68954,32 +69044,61 @@ var MaskGizmo = /*#__PURE__*/ function(Gizmo) {
68954
69044
  return this.type;
68955
69045
  };
68956
69046
  _proto.action = function action(event) {
68957
- var // 记录鼠标划线位置
68958
- _this_result_lines_;
68959
69047
  if (!this.interactive || this.result.status === 'init') {
68960
69048
  return;
68961
69049
  }
68962
69050
  // 更新鼠标位置
68963
69051
  var box = this.result.box;
68964
- var point = new Vector2((event.offsetX - box.min.x) / (box.max.x - box.min.x), (event.offsetY - box.min.y) / (box.max.y - box.min.y));
68965
- (_this_result_lines_ = this.result.lines[this.result.lines.length - 1]) == null ? void 0 : _this_result_lines_.points.push(point);
69052
+ var point = new Vector2(event.offsetX, event.offsetY);
69053
+ this.result.point = point;
69054
+ var lastLine = this.result.lines[this.result.lines.length - 1];
69055
+ // 框选擦除:更新框选终点(钳制到包围盒内)
69056
+ if ((lastLine == null ? void 0 : lastLine.shape) === 'rect') {
69057
+ lastLine.points[1] = this._toNormalized(point, box);
69058
+ return;
69059
+ }
69060
+ // 记录鼠标划线位置(笔刷模式)
69061
+ var np = new Vector2((event.offsetX - box.min.x) / (box.max.x - box.min.x), (event.offsetY - box.min.y) / (box.max.y - box.min.y));
69062
+ lastLine == null ? void 0 : lastLine.points.push(np);
68966
69063
  };
68967
69064
  _proto.endAction = function endAction() {
68968
69065
  if (!this.interactive) {
68969
69066
  return undefined;
68970
69067
  }
68971
- // 记录操作到 undoRedo(仅当画线有实际点时才记录)
68972
69068
  var lastLine = this.result.lines[this.result.lines.length - 1];
69069
+ // 框选擦除:起点==终点视为空框选,移除;否则提交 undoRedo
69070
+ if ((lastLine == null ? void 0 : lastLine.shape) === 'rect') {
69071
+ this._isBoxErasing = false;
69072
+ var _lastLine_points = lastLine.points, a = _lastLine_points[0], b = _lastLine_points[1];
69073
+ var isEmpty = !!a && !!b && a.x === b.x && a.y === b.y;
69074
+ if (this._oldLines && !isEmpty) {
69075
+ var operation = {
69076
+ type: 'update',
69077
+ oldData: this._oldLines,
69078
+ newData: {
69079
+ lines: JSON.parse(JSON.stringify(this.result.lines))
69080
+ }
69081
+ };
69082
+ this._undoRedo.push(operation);
69083
+ this._eventEmitter.emit('maskGizmoUndoRedoChange', operation);
69084
+ } else {
69085
+ // 空框选移除
69086
+ this.result.lines.pop();
69087
+ }
69088
+ this._oldLines = undefined;
69089
+ return this.type;
69090
+ }
69091
+ // 记录操作到 undoRedo(仅当画线有实际点时才记录)
68973
69092
  if (this._oldLines && lastLine && lastLine.points.length > 0) {
68974
- var operation = {
69093
+ var operation1 = {
68975
69094
  type: 'update',
68976
69095
  oldData: this._oldLines,
68977
69096
  newData: {
68978
69097
  lines: JSON.parse(JSON.stringify(this.result.lines))
68979
69098
  }
68980
69099
  };
68981
- this._undoRedo.push(operation);
68982
- this._eventEmitter.emit('maskGizmoUndoRedoChange', operation);
69100
+ this._undoRedo.push(operation1);
69101
+ this._eventEmitter.emit('maskGizmoUndoRedoChange', operation1);
68983
69102
  } else if ((lastLine == null ? void 0 : lastLine.points.length) === 0) {
68984
69103
  // 如果没有实际绘制点,移除空的线条
68985
69104
  this.result.lines.pop();
@@ -69104,6 +69223,17 @@ var MaskGizmo = /*#__PURE__*/ function(Gizmo) {
69104
69223
  this.boxGraphics.lineStyle(boxLineWidth, boxLineColor, boxLineAlpha);
69105
69224
  this.boxGraphics.drawBox(box);
69106
69225
  this.boxGraphics.endFill();
69226
+ // 框选擦除进行中:叠加当前拖动矩形的可视描边
69227
+ var lastLine = this.result.lines[this.result.lines.length - 1];
69228
+ if (this._isBoxErasing && (lastLine == null ? void 0 : lastLine.shape) === 'rect' && lastLine.points.length >= 2) {
69229
+ var _lastLine_points = lastLine.points, a = _lastLine_points[0], b = _lastLine_points[1];
69230
+ if (a && b) {
69231
+ var selBox = new Box2(new Vector2(box.min.x + Math.min(a.x, b.x) * (box.max.x - box.min.x), box.min.y + Math.min(a.y, b.y) * (box.max.y - box.min.y)), new Vector2(box.min.x + Math.max(a.x, b.x) * (box.max.x - box.min.x), box.min.y + Math.max(a.y, b.y) * (box.max.y - box.min.y)));
69232
+ this.boxGraphics.lineStyle(boxLineWidth, boxLineColor, boxLineAlpha);
69233
+ this.boxGraphics.drawBox(selBox);
69234
+ this.boxGraphics.endFill();
69235
+ }
69236
+ }
69107
69237
  // 1. 画线形(只用于遮罩,不直接显示
69108
69238
  for(var _iterator = _create_for_of_iterator_helper_loose(this.result.lines), _step; !(_step = _iterator()).done;){
69109
69239
  var line = _step.value;
@@ -69111,6 +69241,32 @@ var MaskGizmo = /*#__PURE__*/ function(Gizmo) {
69111
69241
  continue;
69112
69242
  }
69113
69243
  var lineGraphics = new Graphics();
69244
+ // 矩形框选:填充矩形,paint 用 NORMAL 叠加,erase 用 DST_OUT 抠除
69245
+ if (line.shape === 'rect') {
69246
+ var a1 = line.points[0];
69247
+ var b1 = line.points[1];
69248
+ if (a1 && b1) {
69249
+ var w = box.max.x - box.min.x;
69250
+ var h = box.max.y - box.min.y;
69251
+ var x0 = Math.min(a1.x, b1.x) * w;
69252
+ var y0 = Math.min(a1.y, b1.y) * h;
69253
+ var x1 = Math.max(a1.x, b1.x) * w;
69254
+ var y1 = Math.max(a1.y, b1.y) * h;
69255
+ // 太小(纯点击)不渲染,避免 1px 擦除/涂抹点
69256
+ if (x1 - x0 > 0.5 || y1 - y0 > 0.5) {
69257
+ lineGraphics.beginFill(brushColor);
69258
+ lineGraphics.drawRect(x0, y0, x1 - x0, y1 - y0);
69259
+ lineGraphics.endFill();
69260
+ lineGraphics.blendMode = line.type === 'paint' ? BLEND_MODES.NORMAL : BLEND_MODES.DST_OUT;
69261
+ this._app.renderer.render(lineGraphics, {
69262
+ renderTexture: this.maskRenderTexture,
69263
+ clear: false
69264
+ });
69265
+ }
69266
+ }
69267
+ lineGraphics.destroy();
69268
+ continue;
69269
+ }
69114
69270
  lineGraphics.blendMode = line.type === 'paint' ? BLEND_MODES.NORMAL : BLEND_MODES.DST_OUT;
69115
69271
  lineGraphics.lineStyle({
69116
69272
  width: line.brushSize * viewportParam.scale,
@@ -69154,14 +69310,24 @@ var MaskGizmo = /*#__PURE__*/ function(Gizmo) {
69154
69310
  if (!point || !box) {
69155
69311
  return;
69156
69312
  }
69157
- if (point.x >= box.min.x && point.x <= box.max.x && point.y >= box.min.y && point.y <= box.max.y) {
69158
- var viewportParam = this._pageDataUtils.interactionUtils.viewportParam;
69313
+ var inside = point.x >= box.min.x && point.x <= box.max.x && point.y >= box.min.y && point.y <= box.max.y;
69314
+ if (!inside) {
69315
+ return;
69316
+ }
69317
+ // 框选模式(框选擦除 / 框选涂抹):crosshair
69318
+ if (this.mode === 'box-erase' || this.mode === 'box-paint') {
69159
69319
  this.cursorResult = {
69160
- type: 'circle',
69161
- angle: 0,
69162
- radius: this.config.brushSize * viewportParam.scale / 2
69320
+ type: 'box-select',
69321
+ angle: 0
69163
69322
  };
69323
+ return;
69164
69324
  }
69325
+ var viewportParam = this._pageDataUtils.interactionUtils.viewportParam;
69326
+ this.cursorResult = {
69327
+ type: 'circle',
69328
+ angle: 0,
69329
+ radius: this.config.brushSize * viewportParam.scale / 2
69330
+ };
69165
69331
  };
69166
69332
  _proto.close = function close() {
69167
69333
  this._config.maskImage = undefined;
@@ -69309,6 +69475,21 @@ var MaskGizmo = /*#__PURE__*/ function(Gizmo) {
69309
69475
  if (!line || line.points.length === 0) {
69310
69476
  continue;
69311
69477
  }
69478
+ // 矩形框选:填充矩形
69479
+ if (line.shape === 'rect') {
69480
+ var _line_points = line.points, a = _line_points[0], b1 = _line_points[1];
69481
+ if (!a || !b1) {
69482
+ continue;
69483
+ }
69484
+ var x0 = Math.min(a.x, b1.x) * width;
69485
+ var y0 = Math.min(a.y, b1.y) * height;
69486
+ var x1 = Math.max(a.x, b1.x) * width;
69487
+ var y1 = Math.max(a.y, b1.y) * height;
69488
+ ctx.globalCompositeOperation = 'source-over';
69489
+ ctx.fillStyle = line.type === 'paint' ? maskHexColor : maskBackgroundHexColor;
69490
+ ctx.fillRect(x0, y0, Math.max(1, x1 - x0), Math.max(1, y1 - y0));
69491
+ continue;
69492
+ }
69312
69493
  ctx.lineWidth = line.brushSize * scale;
69313
69494
  ctx.lineCap = 'round';
69314
69495
  ctx.lineJoin = 'round';
@@ -71314,7 +71495,8 @@ var GestureHandler = /*#__PURE__*/ function() {
71314
71495
  'active-hand',
71315
71496
  'pointer',
71316
71497
  'text-create',
71317
- 'frame-create'
71498
+ 'frame-create',
71499
+ 'box-select'
71318
71500
  ].includes(result.type)) {
71319
71501
  var cursor = cursorMap[result.type];
71320
71502
  if (cursor.type === 'svg') {
@@ -71486,6 +71668,7 @@ var GestureHandler = /*#__PURE__*/ function() {
71486
71668
  return;
71487
71669
  }
71488
71670
  this.maskGizmo.setMode(mode);
71671
+ this.render();
71489
71672
  };
71490
71673
  _proto.openLoadingGizmo = function openLoadingGizmo(id, options) {
71491
71674
  var _this__emitter;
@@ -94780,7 +94963,7 @@ var SDK = /*#__PURE__*/ function() {
94780
94963
  };
94781
94964
  /**
94782
94965
  * @description 设置蒙版工具模式
94783
- * @param mode 模式类型:'paint' 表示涂抹,'erase' 表示擦除
94966
+ * @param mode 模式类型:'paint' 笔刷涂抹、'erase' 笔刷逐笔擦除、'box-erase' 框选擦除、'box-paint' 框选涂抹
94784
94967
  */ _proto.setMaskGizmoMode = function setMaskGizmoMode(mode) {
94785
94968
  this._gestureHandler.setMaskGizmoMode(mode);
94786
94969
  };