@galacean/effects-core 2.9.0-alpha.1 → 2.9.0-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.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * Description: Galacean Effects runtime core for the web
4
4
  * Author: Ant Group CO., Ltd.
5
5
  * Contributors: 燃然,飂兮,十弦,云垣,茂安,意绮
6
- * Version: v2.9.0-alpha.1
6
+ * Version: v2.9.0-alpha.2
7
7
  */
8
8
 
9
9
  'use strict';
@@ -43,11 +43,6 @@ function _instanceof1(left, right) {
43
43
  } else return _instanceof1(left, right);
44
44
  }
45
45
 
46
- function _type_of(obj) {
47
- "@swc/helpers - typeof";
48
- return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
49
- }
50
-
51
46
  function __decorate(decorators, target, key, desc) {
52
47
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
53
48
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -4097,7 +4092,7 @@ function getDirectStore(target) {
4097
4092
  function EffectsObject(engine) {
4098
4093
  this.engine = engine;
4099
4094
  this.guid = generateGUID();
4100
- this.defination = {};
4095
+ this.definition = {};
4101
4096
  this.engine.addInstance(this);
4102
4097
  }
4103
4098
  var _proto = EffectsObject.prototype;
@@ -7001,6 +6996,11 @@ function _create_class(Constructor, protoProps, staticProps) {
7001
6996
  // OVERRIDE
7002
6997
  };
7003
6998
  /**
6999
+ * 当父级或间接父级发生改变时调用
7000
+ */ _proto.onParentChanged = function onParentChanged() {
7001
+ // OVERRIDE
7002
+ };
7003
+ /**
7004
7004
  * @internal
7005
7005
  */ _proto.enable = function enable() {
7006
7006
  if (this.item.composition) {
@@ -9231,7 +9231,6 @@ exports.MaterialRenderType = void 0;
9231
9231
  for(var _iterator4 = _create_for_of_iterator_helper_loose(frameClipMasks), _step4; !(_step4 = _iterator4()).done;){
9232
9232
  var frameClipMask1 = _step4.value;
9233
9233
  this.removeMaskReference(frameClipMask1);
9234
- maskedComponent.frameClipMasks = [];
9235
9234
  }
9236
9235
  };
9237
9236
  /**
@@ -10669,7 +10668,6 @@ BoundingBox.tempVector2 = new Vector3();
10669
10668
  _this.materials = [];
10670
10669
  /**
10671
10670
  * @hidden
10672
- * @internal
10673
10671
  * Internal utility.
10674
10672
  * Not part of the public API — do not rely on this in your code.
10675
10673
  */ _this.frameClipMasks = [];
@@ -10693,6 +10691,9 @@ BoundingBox.tempVector2 = new Vector3();
10693
10691
  var _this_item_composition;
10694
10692
  (_this_item_composition = this.item.composition) == null ? void 0 : _this_item_composition.renderFrame.removeMeshFromDefaultRenderPass(this);
10695
10693
  };
10694
+ _proto.onParentChanged = function onParentChanged() {
10695
+ this.frameClipMasks = [];
10696
+ };
10696
10697
  /**
10697
10698
  * 获取包围盒信息
10698
10699
  */ _proto.getBoundingBoxInfo = function getBoundingBoxInfo() {
@@ -13211,6 +13212,7 @@ exports.VFXItem = /*#__PURE__*/ function(EffectsObject) {
13211
13212
  if (!this.composition && vfxItem.composition) {
13212
13213
  this.composition = vfxItem.composition;
13213
13214
  }
13215
+ this.onParentChanged();
13214
13216
  if (!this.isDuringPlay && vfxItem.isDuringPlay) {
13215
13217
  this.awake();
13216
13218
  this.beginPlay();
@@ -13343,6 +13345,122 @@ exports.VFXItem = /*#__PURE__*/ function(EffectsObject) {
13343
13345
  // OVERRIDE
13344
13346
  };
13345
13347
  /**
13348
+ * 对当前元素及其子节点进行射线命中测试
13349
+ *
13350
+ * @param ray - 射线
13351
+ * @param x - 归一化屏幕坐标 x
13352
+ * @param y - 归一化屏幕坐标 y
13353
+ * @param regions - 命中结果收集数组
13354
+ * @param hitPositions - 共享的命中位置数组,所有 region 共享同一引用
13355
+ * @param force - 是否强制测试无交互信息的元素
13356
+ * @param options - 额外选项(maxCount、stop、skip)
13357
+ * @returns 是否有任何命中
13358
+ */ _proto.hitTest = function hitTest(ray, x, y, regions, hitPositions, force, options) {
13359
+ var _this_composition;
13360
+ if (!this.isActive) {
13361
+ return false;
13362
+ }
13363
+ var hitTestSuccess = false;
13364
+ var maxCount = options == null ? void 0 : options.maxCount;
13365
+ var hitParams = this.getHitTestParams(force);
13366
+ // 1. 测试自身
13367
+ if (hitParams) {
13368
+ var clipMasks = hitParams.clipMasks;
13369
+ var clipPassed = true;
13370
+ if (clipMasks.length > 0 && !hitTestMask(ray, clipMasks)) {
13371
+ clipPassed = false;
13372
+ }
13373
+ if (clipPassed) {
13374
+ var success = false;
13375
+ var intersectPoint = new Vector3();
13376
+ if (hitParams.type === exports.HitTestType.triangle) {
13377
+ var triangles = hitParams.triangles, backfaceCulling = hitParams.backfaceCulling;
13378
+ for(var j = 0; j < triangles.length; j++){
13379
+ if (ray.intersectTriangle(triangles[j], intersectPoint, backfaceCulling)) {
13380
+ success = true;
13381
+ hitPositions.push(intersectPoint);
13382
+ break;
13383
+ }
13384
+ }
13385
+ } else if (hitParams.type === exports.HitTestType.box) {
13386
+ var center = hitParams.center, size = hitParams.size;
13387
+ var boxMin = center.clone().addScaledVector(size, 0.5);
13388
+ var boxMax = center.clone().addScaledVector(size, -0.5);
13389
+ if (ray.intersectBox({
13390
+ min: boxMin,
13391
+ max: boxMax
13392
+ }, intersectPoint)) {
13393
+ success = true;
13394
+ hitPositions.push(intersectPoint);
13395
+ }
13396
+ } else if (hitParams.type === exports.HitTestType.sphere) {
13397
+ var center1 = hitParams.center, radius = hitParams.radius;
13398
+ if (ray.intersectSphere({
13399
+ center: center1,
13400
+ radius: radius
13401
+ }, intersectPoint)) {
13402
+ success = true;
13403
+ hitPositions.push(intersectPoint);
13404
+ }
13405
+ } else if (hitParams.type === exports.HitTestType.custom) {
13406
+ var tempPosition = hitParams.collect(ray, new Vector2(x, y));
13407
+ if (tempPosition && tempPosition.length > 0) {
13408
+ tempPosition.forEach(function(pos) {
13409
+ hitPositions.push(pos);
13410
+ });
13411
+ success = true;
13412
+ }
13413
+ }
13414
+ if (success) {
13415
+ var _options_stop;
13416
+ var region = {
13417
+ id: this.getInstanceId(),
13418
+ name: this.name,
13419
+ position: hitPositions[hitPositions.length - 1],
13420
+ parentId: this.parentId,
13421
+ hitPositions: hitPositions,
13422
+ behavior: hitParams.behavior,
13423
+ item: this,
13424
+ composition: this.composition
13425
+ };
13426
+ regions.push(region);
13427
+ hitTestSuccess = true;
13428
+ if (options == null ? void 0 : (_options_stop = options.stop) == null ? void 0 : _options_stop.call(options, region)) {
13429
+ return true;
13430
+ }
13431
+ }
13432
+ }
13433
+ }
13434
+ // 2. 递归测试子节点
13435
+ for(var _iterator = _create_for_of_iterator_helper_loose(this.children), _step; !(_step = _iterator()).done;){
13436
+ var child = _step.value;
13437
+ var _options_skip;
13438
+ if (maxCount !== undefined && regions.length >= maxCount) {
13439
+ break;
13440
+ }
13441
+ if (options == null ? void 0 : (_options_skip = options.skip) == null ? void 0 : _options_skip.call(options, child)) {
13442
+ continue;
13443
+ }
13444
+ if (child.hitTest(ray, x, y, regions, hitPositions, force, options)) {
13445
+ hitTestSuccess = true;
13446
+ }
13447
+ }
13448
+ // 3. composition 元素:子元素命中时,将自身也加入结果(根元素除外)
13449
+ if (VFXItem.isComposition(this) && hitTestSuccess && this !== ((_this_composition = this.composition) == null ? void 0 : _this_composition.rootItem)) {
13450
+ regions.push({
13451
+ id: this.getInstanceId(),
13452
+ name: this.name,
13453
+ position: hitPositions[hitPositions.length - 1],
13454
+ parentId: this.parentId,
13455
+ hitPositions: hitPositions,
13456
+ behavior: InteractBehavior.NONE,
13457
+ item: this,
13458
+ composition: this.composition
13459
+ });
13460
+ }
13461
+ return hitTestSuccess;
13462
+ };
13463
+ /**
13346
13464
  * 获取元素当前世界坐标
13347
13465
  */ _proto.getCurrentPosition = function getCurrentPosition() {
13348
13466
  var pos = new Vector3();
@@ -13378,7 +13496,7 @@ exports.VFXItem = /*#__PURE__*/ function(EffectsObject) {
13378
13496
  // 重新设置当前元素和组件的 ID 以及子元素和子元素组件的 ID,避免实例化新的对象时产生碰撞
13379
13497
  this.refreshGUIDRecursive();
13380
13498
  var newItem = this.engine.findObject({
13381
- id: this.defination.id
13499
+ id: this.definition.id
13382
13500
  });
13383
13501
  newItem.refreshGUIDRecursive();
13384
13502
  this.refreshGUIDRecursive(previousObjectIDMap);
@@ -13454,6 +13572,16 @@ exports.VFXItem = /*#__PURE__*/ function(EffectsObject) {
13454
13572
  }
13455
13573
  }
13456
13574
  };
13575
+ _proto.onParentChanged = function onParentChanged() {
13576
+ for(var _iterator = _create_for_of_iterator_helper_loose(this.components), _step; !(_step = _iterator()).done;){
13577
+ var component = _step.value;
13578
+ component.onParentChanged();
13579
+ }
13580
+ for(var _iterator1 = _create_for_of_iterator_helper_loose(this.children), _step1; !(_step1 = _iterator1()).done;){
13581
+ var child = _step1.value;
13582
+ child.onParentChanged();
13583
+ }
13584
+ };
13457
13585
  /**
13458
13586
  * @internal
13459
13587
  */ _proto.setRendererComponentOrder = function setRendererComponentOrder(renderOrder) {
@@ -13473,7 +13601,7 @@ exports.VFXItem = /*#__PURE__*/ function(EffectsObject) {
13473
13601
  this.parentId = parentId;
13474
13602
  this.components.length = 0;
13475
13603
  if (VFXItem.isComposition(this)) {
13476
- var refId = this.defination.content.options.refId;
13604
+ var refId = this.definition.content.options.refId;
13477
13605
  var compositionData = this.engine.findEffectsObjectData(refId);
13478
13606
  if (!compositionData) {
13479
13607
  throw new Error("Referenced precomposition with Id: " + refId + " does not exist.");
@@ -13520,24 +13648,24 @@ exports.VFXItem = /*#__PURE__*/ function(EffectsObject) {
13520
13648
  };
13521
13649
  _proto.toData = function toData() {
13522
13650
  var _this_parent;
13523
- this.defination.id = this.guid;
13524
- this.defination.transform = this.transform.toData();
13525
- this.defination.dataType = DataType.VFXItemData;
13651
+ this.definition.id = this.guid;
13652
+ this.definition.transform = this.transform.toData();
13653
+ this.definition.dataType = DataType.VFXItemData;
13526
13654
  if (((_this_parent = this.parent) == null ? void 0 : _this_parent.name) !== "rootItem") {
13527
13655
  var _this_parent1;
13528
- this.defination.parentId = (_this_parent1 = this.parent) == null ? void 0 : _this_parent1.guid;
13656
+ this.definition.parentId = (_this_parent1 = this.parent) == null ? void 0 : _this_parent1.guid;
13529
13657
  }
13530
13658
  // TODO 统一 sprite 等其他组件的序列化逻辑
13531
- if (!this.defination.components) {
13532
- this.defination.components = [];
13659
+ if (!this.definition.components) {
13660
+ this.definition.components = [];
13533
13661
  for(var _iterator = _create_for_of_iterator_helper_loose(this.components), _step; !(_step = _iterator()).done;){
13534
13662
  var component = _step.value;
13535
13663
  if (_instanceof1(component, exports.EffectComponent)) {
13536
- this.defination.components.push(component);
13664
+ this.definition.components.push(component);
13537
13665
  }
13538
13666
  }
13539
13667
  }
13540
- this.defination.content = {};
13668
+ this.definition.content = {};
13541
13669
  };
13542
13670
  /**
13543
13671
  * 销毁元素
@@ -13794,6 +13922,47 @@ exports.Item = void 0;
13794
13922
  }
13795
13923
  Item.isNull = isNull;
13796
13924
  })(exports.Item || (exports.Item = {}));
13925
+ /**
13926
+ * 遮罩命中测试:检查射线是否通过所有遮罩区域
13927
+ * 根据每个遮罩的 transform(size、scale、position、rotation、anchor)构建世界空间矩形,
13928
+ * 然后检测射线是否与该矩形相交。所有遮罩都必须通过才算测试通过。
13929
+ * @param ray - 射线
13930
+ * @param clipMasks - 遮罩列表
13931
+ * @returns 射线是否通过所有遮罩测试
13932
+ */ function hitTestMask(ray, clipMasks) {
13933
+ for(var _iterator = _create_for_of_iterator_helper_loose(clipMasks), _step; !(_step = _iterator()).done;){
13934
+ var mask = _step.value;
13935
+ var item = mask.item;
13936
+ if (!item.isActive || !item.transform.getValid()) {
13937
+ continue;
13938
+ }
13939
+ var transform = item.transform;
13940
+ var worldMatrix = transform.getWorldMatrix();
13941
+ var sx = transform.size.x;
13942
+ var sy = transform.size.y;
13943
+ // 将遮罩矩形的四个顶点从本地空间变换到世界空间
13944
+ // 本地空间顶点为单位矩形 (-0.5, -0.5) 到 (0.5, 0.5),按 size 缩放
13945
+ var p0 = new Vector3(-0.5 * sx, 0.5 * sy, 0).applyMatrix(worldMatrix);
13946
+ var p1 = new Vector3(-0.5 * sx, -0.5 * sy, 0).applyMatrix(worldMatrix);
13947
+ var p2 = new Vector3(0.5 * sx, 0.5 * sy, 0).applyMatrix(worldMatrix);
13948
+ var p3 = new Vector3(0.5 * sx, -0.5 * sy, 0).applyMatrix(worldMatrix);
13949
+ // 矩形由两个三角形组成,检测射线与任一三角形的相交
13950
+ var triangle1 = {
13951
+ p0: p0,
13952
+ p1: p1,
13953
+ p2: p2
13954
+ };
13955
+ var triangle2 = {
13956
+ p0: p2,
13957
+ p1: p1,
13958
+ p2: p3
13959
+ };
13960
+ if (!ray.intersectTriangle(triangle1) && !ray.intersectTriangle(triangle2)) {
13961
+ return false;
13962
+ }
13963
+ }
13964
+ return true;
13965
+ }
13797
13966
 
13798
13967
  var toHalf = function() {
13799
13968
  var floatView = new Float32Array(1);
@@ -17401,7 +17570,7 @@ function triangulate(contours) {
17401
17570
  */ _proto.getY = function getY() {
17402
17571
  return this.points[this.points.length - 1];
17403
17572
  };
17404
- _proto.build = function build(points) {
17573
+ _proto.build = function build(points, screenScale) {
17405
17574
  for(var i = 0; i < this.points.length; i++){
17406
17575
  points[i] = this.points[i];
17407
17576
  }
@@ -17503,11 +17672,10 @@ var RECURSION_LIMIT = 8;
17503
17672
  var FLT_EPSILON = 1.19209290e-7;
17504
17673
  var PATH_DISTANCE_EPSILON = 1.0;
17505
17674
  var defaultBezierSmoothness = 0.5;
17506
- function buildAdaptiveBezier(points, sX, sY, cp1x, cp1y, cp2x, cp2y, eX, eY, smoothness) {
17507
- // TODO expose as a parameter
17508
- var scale = 5;
17675
+ function buildAdaptiveBezier(points, sX, sY, cp1x, cp1y, cp2x, cp2y, eX, eY, smoothness, scale) {
17676
+ var s = scale != null ? scale : 1;
17509
17677
  var smoothing = Math.min(0.99, Math.max(0, smoothness != null ? smoothness : defaultBezierSmoothness));
17510
- var distanceTolerance = (PATH_DISTANCE_EPSILON - smoothing) / scale;
17678
+ var distanceTolerance = (PATH_DISTANCE_EPSILON - smoothing) / s;
17511
17679
  distanceTolerance *= distanceTolerance;
17512
17680
  begin(sX, sY, cp1x, cp1y, cp2x, cp2y, eX, eY, points, distanceTolerance);
17513
17681
  return points;
@@ -17697,7 +17865,7 @@ function recursive(x1, y1, x2, y2, x3, y3, x4, y4, points, distanceTolerance, le
17697
17865
  _proto.getY = function getY() {
17698
17866
  return this.y;
17699
17867
  };
17700
- _proto.build = function build(points) {
17868
+ _proto.build = function build(points, screenScale) {
17701
17869
  var x = this.x;
17702
17870
  var y = this.y;
17703
17871
  var rx = this.halfWidth;
@@ -17707,9 +17875,10 @@ function recursive(x1, y1, x2, y2, x3, y3, x4, y4, points, distanceTolerance, le
17707
17875
  if (!(rx >= 0 && ry >= 0 && dx >= 0 && dy >= 0)) {
17708
17876
  return points;
17709
17877
  }
17710
- // Choose a number of segments such that the maximum absolute deviation from the circle is approximately 0.029
17711
- var sampleDensity = 5;
17712
- var n = Math.ceil(sampleDensity * Math.sqrt(rx + ry));
17878
+ // n 个等分段逼近四分之一椭圆弧,最大弦高误差 ε = R·π²/(8n²)
17879
+ // 屏幕误差 = ε × ppu = ppu·R·π²/(8n²),令 n = √(ppu·(rx+ry)),则误差 ≈ π²/8 ≈ 1.2px
17880
+ var ppu = screenScale != null ? screenScale : 1;
17881
+ var n = Math.ceil(Math.sqrt(ppu * (rx + ry)));
17713
17882
  var m = n * 8 + (0) + (0);
17714
17883
  if (m === 0) {
17715
17884
  return points;
@@ -17844,7 +18013,7 @@ var PolyStar = /*#__PURE__*/ function(ShapePrimitive) {
17844
18013
  _proto.copyTo = function copyTo(destination) {
17845
18014
  destination.copyFrom(this);
17846
18015
  };
17847
- _proto.build = function build(points) {
18016
+ _proto.build = function build(points, screenScale) {
17848
18017
  switch(this.starType){
17849
18018
  case 0:
17850
18019
  {
@@ -17857,13 +18026,13 @@ var PolyStar = /*#__PURE__*/ function(ShapePrimitive) {
17857
18026
  break;
17858
18027
  }
17859
18028
  }
17860
- var smoothness = 1;
18029
+ var ppu = screenScale != null ? screenScale : 1;
17861
18030
  for(var i = 0; i < this.v.length - 2; i += 2){
17862
- buildAdaptiveBezier(points, this.v[i], this.v[i + 1], this.out[i], this.out[i + 1], this.in[i + 2], this.in[i + 3], this.v[i + 2], this.v[i + 3], smoothness);
18031
+ buildAdaptiveBezier(points, this.v[i], this.v[i + 1], this.out[i], this.out[i + 1], this.in[i + 2], this.in[i + 3], this.v[i + 2], this.v[i + 3], undefined, ppu);
17863
18032
  }
17864
18033
  // draw last curve
17865
18034
  var lastIndex = this.v.length - 1;
17866
- buildAdaptiveBezier(points, this.v[lastIndex - 1], this.v[lastIndex], this.out[lastIndex - 1], this.out[lastIndex], this.in[0], this.in[1], this.v[0], this.v[1], smoothness);
18035
+ buildAdaptiveBezier(points, this.v[lastIndex - 1], this.v[lastIndex], this.out[lastIndex - 1], this.out[lastIndex], this.in[0], this.in[1], this.v[0], this.v[1], undefined, ppu);
17867
18036
  };
17868
18037
  _proto.triangulate = function triangulate1(points, vertices, verticesOffset, indices, indicesOffset) {
17869
18038
  var triangles = triangulate([
@@ -18008,7 +18177,7 @@ var PolyStar = /*#__PURE__*/ function(ShapePrimitive) {
18008
18177
  rectangle.copyFrom(this);
18009
18178
  return rectangle;
18010
18179
  };
18011
- _proto.build = function build(points) {
18180
+ _proto.build = function build(points, screenScale) {
18012
18181
  var ry;
18013
18182
  var halfWidth = this.width / 2;
18014
18183
  var halfHeight = this.height / 2;
@@ -18020,10 +18189,10 @@ var PolyStar = /*#__PURE__*/ function(ShapePrimitive) {
18020
18189
  if (!(rx >= 0 && ry >= 0 && dx >= 0 && dy >= 0)) {
18021
18190
  return;
18022
18191
  }
18023
- // 控制边缘的平滑程度
18024
- var densityScale = 5;
18025
- // Choose a number of segments such that the maximum absolute deviation from the circle is approximately 0.029
18026
- var n = densityScale * Math.ceil(2.3 * Math.sqrt(rx + ry));
18192
+ // n 个等分段逼近四分之一圆角弧,最大弦高误差 ε = R·π²/(8n²)
18193
+ // 屏幕误差 = ε × ppu,令 n = √(ppu·(rx+ry)),则误差 ≈ π²/8 ≈ 1.2px
18194
+ var ppu = screenScale != null ? screenScale : 1;
18195
+ var n = Math.ceil(Math.sqrt(ppu * (rx + ry)));
18027
18196
  var m = n * 8 + (dx ? 4 : 0) + (dy ? 4 : 0);
18028
18197
  if (m === 0) {
18029
18198
  return;
@@ -18232,7 +18401,7 @@ var PolyStar = /*#__PURE__*/ function(ShapePrimitive) {
18232
18401
  _proto.getY = function getY() {
18233
18402
  return this.y;
18234
18403
  };
18235
- _proto.build = function build(points) {
18404
+ _proto.build = function build(points, screenScale) {
18236
18405
  points[0] = this.x;
18237
18406
  points[1] = this.y;
18238
18407
  points[2] = this.x2;
@@ -18449,7 +18618,7 @@ var PolyStar = /*#__PURE__*/ function(ShapePrimitive) {
18449
18618
  circle.copyFrom(this);
18450
18619
  return circle;
18451
18620
  };
18452
- _proto.build = function build(points) {
18621
+ _proto.build = function build(points, screenScale) {
18453
18622
  var x = this.x;
18454
18623
  var y = this.y;
18455
18624
  var dx = 0;
@@ -18459,8 +18628,10 @@ var PolyStar = /*#__PURE__*/ function(ShapePrimitive) {
18459
18628
  if (rx <= 0) {
18460
18629
  return;
18461
18630
  }
18462
- // Choose a number of segments such that the maximum absolute deviation from the circle is approximately 0.029
18463
- var n = Math.ceil(2.3 * Math.sqrt(rx + ry));
18631
+ // n 个等分段逼近四分之一圆弧,最大弦高误差 ε = R·π²/(8n²)
18632
+ // 屏幕误差 = ε × ppu = ppu·R·π²/(8n²),令 n = √(ppu·(rx+ry)),则误差 ≈ π²/8 ≈ 1.2px
18633
+ var ppu = screenScale != null ? screenScale : 1;
18634
+ var n = Math.ceil(Math.sqrt(ppu * (rx + ry)));
18464
18635
  var m = n * 8 + (0) + (0);
18465
18636
  if (m === 0) {
18466
18637
  return;
@@ -18570,7 +18741,7 @@ var ShapePath = /*#__PURE__*/ function() {
18570
18741
  switch(action){
18571
18742
  case "bezierCurveTo":
18572
18743
  {
18573
- this.bezierCurveTo(data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
18744
+ this.bezierCurveTo(data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
18574
18745
  break;
18575
18746
  }
18576
18747
  case "moveTo":
@@ -18629,10 +18800,10 @@ var ShapePath = /*#__PURE__*/ function() {
18629
18800
  * @param y - The y-coordinate of the end point.
18630
18801
  * @param smoothness - Optional parameter to adjust the smoothness of the curve.
18631
18802
  * @returns The instance of the current object for chaining.
18632
- */ _proto.bezierCurveTo = function bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y, smoothness) {
18803
+ */ _proto.bezierCurveTo = function bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y, smoothness, scale) {
18633
18804
  this.ensurePoly();
18634
18805
  var currentPoly = this.currentPoly;
18635
- buildAdaptiveBezier(currentPoly.points, currentPoly.lastX, currentPoly.lastY, cp1x, cp1y, cp2x, cp2y, x, y, smoothness);
18806
+ buildAdaptiveBezier(currentPoly.points, currentPoly.lastX, currentPoly.lastY, cp1x, cp1y, cp2x, cp2y, x, y, smoothness, scale);
18636
18807
  return this;
18637
18808
  };
18638
18809
  _proto.moveTo = function moveTo(x, y) {
@@ -18797,7 +18968,7 @@ var GraphicsPath = /*#__PURE__*/ function() {
18797
18968
  * @param y - The y-coordinate of the end point.
18798
18969
  * @param smoothness - Optional parameter to adjust the smoothness of the curve.
18799
18970
  * @returns The instance of the current object for chaining.
18800
- */ _proto.bezierCurveTo = function bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y, smoothness) {
18971
+ */ _proto.bezierCurveTo = function bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y, smoothness, scale) {
18801
18972
  this.instructions.push({
18802
18973
  action: "bezierCurveTo",
18803
18974
  data: [
@@ -18807,7 +18978,8 @@ var GraphicsPath = /*#__PURE__*/ function() {
18807
18978
  cp2y,
18808
18979
  x,
18809
18980
  y,
18810
- smoothness
18981
+ smoothness,
18982
+ scale
18811
18983
  ]
18812
18984
  });
18813
18985
  this.dirty = true;
@@ -19108,28 +19280,6 @@ exports.CompositionComponent = /*#__PURE__*/ function(Component) {
19108
19280
  return item.dispose();
19109
19281
  });
19110
19282
  };
19111
- _proto.hitTest = function hitTest(ray, x, y, regions, force, options) {
19112
- var _this_item_composition;
19113
- var isHitTestSuccess = hitTestRecursive(this.item, ray, x, y, regions, force, options);
19114
- // 子元素碰撞测试成功加入当前预合成元素,判断是否是合成根元素,根元素不加入
19115
- if (isHitTestSuccess && this.item !== ((_this_item_composition = this.item.composition) == null ? void 0 : _this_item_composition.rootItem)) {
19116
- var item = this.item;
19117
- var lastRegion = regions[regions.length - 1];
19118
- var hitPositions = lastRegion.hitPositions;
19119
- var region = {
19120
- id: item.getInstanceId(),
19121
- name: item.name,
19122
- position: hitPositions[hitPositions.length - 1],
19123
- parentId: item.parentId,
19124
- hitPositions: hitPositions,
19125
- behavior: InteractBehavior.NONE,
19126
- item: item,
19127
- composition: item.composition
19128
- };
19129
- regions.push(region);
19130
- }
19131
- return isHitTestSuccess;
19132
- };
19133
19283
  /**
19134
19284
  * 设置当前合成子元素的渲染顺序
19135
19285
  *
@@ -19239,98 +19389,6 @@ __decorate([
19239
19389
  exports.CompositionComponent = __decorate([
19240
19390
  effectsClass("CompositionComponent")
19241
19391
  ], exports.CompositionComponent);
19242
- function hitTestRecursive(item, ray, x, y, regions, force, options) {
19243
- var _loop = function() {
19244
- var hitTestItem = _step.value;
19245
- if (hitTestItem.isActive && hitTestItem.transform.getValid() && !skip(hitTestItem)) {
19246
- var hitParams = hitTestItem.getHitTestParams(force);
19247
- if (hitParams) {
19248
- var success = false;
19249
- var intersectPoint = new Vector3();
19250
- if (hitParams.type === exports.HitTestType.triangle) {
19251
- var triangles = hitParams.triangles, backfaceCulling = hitParams.backfaceCulling;
19252
- for(var j = 0; j < triangles.length; j++){
19253
- var triangle = triangles[j];
19254
- if (ray.intersectTriangle(triangle, intersectPoint, backfaceCulling)) {
19255
- success = true;
19256
- hitPositions.push(intersectPoint);
19257
- break;
19258
- }
19259
- }
19260
- } else if (hitParams.type === exports.HitTestType.box) {
19261
- var center = hitParams.center, size = hitParams.size;
19262
- var boxMin = center.clone().addScaledVector(size, 0.5);
19263
- var boxMax = center.clone().addScaledVector(size, -0.5);
19264
- if (ray.intersectBox({
19265
- min: boxMin,
19266
- max: boxMax
19267
- }, intersectPoint)) {
19268
- success = true;
19269
- hitPositions.push(intersectPoint);
19270
- }
19271
- } else if (hitParams.type === exports.HitTestType.sphere) {
19272
- var center1 = hitParams.center, radius = hitParams.radius;
19273
- if (ray.intersectSphere({
19274
- center: center1,
19275
- radius: radius
19276
- }, intersectPoint)) {
19277
- success = true;
19278
- hitPositions.push(intersectPoint);
19279
- }
19280
- } else if (hitParams.type === exports.HitTestType.custom) {
19281
- var tempPosition = hitParams.collect(ray, new Vector2(x, y));
19282
- if (tempPosition && tempPosition.length > 0) {
19283
- tempPosition.forEach(function(pos) {
19284
- hitPositions.push(pos);
19285
- });
19286
- success = true;
19287
- }
19288
- }
19289
- if (success) {
19290
- var region = {
19291
- id: hitTestItem.getInstanceId(),
19292
- name: hitTestItem.name,
19293
- position: hitPositions[hitPositions.length - 1],
19294
- parentId: hitTestItem.parentId,
19295
- hitPositions: hitPositions,
19296
- behavior: hitParams.behavior,
19297
- item: hitTestItem,
19298
- composition: hitTestItem.composition
19299
- };
19300
- regions.push(region);
19301
- hitTestSuccess = true;
19302
- if (stop(region)) {
19303
- return {
19304
- v: true
19305
- };
19306
- }
19307
- }
19308
- }
19309
- }
19310
- if (exports.VFXItem.isComposition(hitTestItem)) {
19311
- if (hitTestItem.getComponent(exports.CompositionComponent).hitTest(ray, x, y, regions, force, options)) {
19312
- hitTestSuccess = true;
19313
- }
19314
- } else {
19315
- if (hitTestRecursive(hitTestItem, ray, x, y, regions, force, options)) {
19316
- hitTestSuccess = true;
19317
- }
19318
- }
19319
- };
19320
- var hitPositions = [];
19321
- var stop = (options == null ? void 0 : options.stop) || noop;
19322
- var skip = (options == null ? void 0 : options.skip) || noop;
19323
- var maxCount = options == null ? void 0 : options.maxCount;
19324
- if (maxCount !== undefined && regions.length >= maxCount) {
19325
- return false;
19326
- }
19327
- var hitTestSuccess = false;
19328
- for(var _iterator = _create_for_of_iterator_helper_loose(item.children), _step; !(_step = _iterator()).done;){
19329
- var _ret = _loop();
19330
- if (_type_of(_ret) === "object") return _ret.v;
19331
- }
19332
- return hitTestSuccess;
19333
- }
19334
19392
 
19335
19393
  /**
19336
19394
  * Mesh 组件
@@ -19347,7 +19405,8 @@ function hitTestRecursive(item, ray, x, y, regions, force, options) {
19347
19405
  if (area) {
19348
19406
  return {
19349
19407
  type: area.type,
19350
- triangles: area.area
19408
+ triangles: area.area,
19409
+ clipMasks: _this.frameClipMasks
19351
19410
  };
19352
19411
  }
19353
19412
  };
@@ -21486,7 +21545,8 @@ var Graphics = /*#__PURE__*/ function() {
21486
21545
  behavior: ((_this_interaction = _this.interaction) == null ? void 0 : _this_interaction.behavior) || 0,
21487
21546
  type: area.type,
21488
21547
  triangles: area.area,
21489
- backfaceCulling: _this.renderer.side === SideMode.FRONT
21548
+ backfaceCulling: _this.renderer.side === SideMode.FRONT,
21549
+ clipMasks: _this.frameClipMasks
21490
21550
  };
21491
21551
  }
21492
21552
  }
@@ -21785,7 +21845,8 @@ exports.ShapeComponent = /*#__PURE__*/ function(RendererComponent) {
21785
21845
  behavior: 0,
21786
21846
  type: area.type,
21787
21847
  triangles: area.area,
21788
- backfaceCulling: _this.rendererOptions.side === SideMode.FRONT
21848
+ backfaceCulling: _this.rendererOptions.side === SideMode.FRONT,
21849
+ clipMasks: _this.frameClipMasks
21789
21850
  };
21790
21851
  }
21791
21852
  }
@@ -21888,8 +21949,9 @@ exports.ShapeComponent = /*#__PURE__*/ function(RendererComponent) {
21888
21949
  };
21889
21950
  _proto.onUpdate = function onUpdate(dt) {
21890
21951
  if (this.shapeDirty) {
21891
- this.buildPath(this.shapeAttributes);
21892
- this.buildGeometryFromPath(this.graphicsPath.shapePath);
21952
+ var screenScale = this.computeScreenScale();
21953
+ this.buildPath(this.shapeAttributes, screenScale);
21954
+ this.buildGeometryFromPath(this.graphicsPath.shapePath, screenScale);
21893
21955
  this.shapeDirty = false;
21894
21956
  }
21895
21957
  if (this.materialDirty) {
@@ -21940,7 +22002,7 @@ exports.ShapeComponent = /*#__PURE__*/ function(RendererComponent) {
21940
22002
  }
21941
22003
  return this.boundingBoxInfo;
21942
22004
  };
21943
- _proto.buildGeometryFromPath = function buildGeometryFromPath(shapePath) {
22005
+ _proto.buildGeometryFromPath = function buildGeometryFromPath(shapePath, screenScale) {
21944
22006
  var shapePrimitives = shapePath.shapePrimitives;
21945
22007
  var vertices = [];
21946
22008
  var indices = [];
@@ -21952,7 +22014,7 @@ exports.ShapeComponent = /*#__PURE__*/ function(RendererComponent) {
21952
22014
  var points = [];
21953
22015
  var indexOffset = indices.length;
21954
22016
  var vertOffset = vertices.length / 2;
21955
- shape.build(points);
22017
+ shape.build(points, screenScale);
21956
22018
  shape.triangulate(points, vertices, vertOffset, indices, indexOffset);
21957
22019
  }
21958
22020
  }
@@ -21972,7 +22034,7 @@ exports.ShapeComponent = /*#__PURE__*/ function(RendererComponent) {
21972
22034
  if (this.shapeAttributes.type === ShapePrimitiveType.Custom) {
21973
22035
  close = shape1.closePath;
21974
22036
  }
21975
- shape1.build(points1);
22037
+ shape1.build(points1, screenScale);
21976
22038
  buildLine(points1, lineStyle, false, close, vertices, 2, vertOffset1, indices);
21977
22039
  }
21978
22040
  }
@@ -22032,8 +22094,40 @@ exports.ShapeComponent = /*#__PURE__*/ function(RendererComponent) {
22032
22094
  strokeSubMesh.offset = fillIndexCount * u16Size;
22033
22095
  strokeSubMesh.indexCount = strokeIndexCount;
22034
22096
  };
22035
- _proto.buildPath = function buildPath(shapeAttribute) {
22097
+ _proto.computeScreenScale = function computeScreenScale() {
22098
+ var defaultPpu = 1;
22099
+ var composition = this.item.composition;
22100
+ if (!composition) {
22101
+ return defaultPpu;
22102
+ }
22103
+ var camera = composition.camera;
22104
+ if (!camera) {
22105
+ return defaultPpu;
22106
+ }
22107
+ var mvp = camera.getModelViewProjection(ShapeComponent.tempMVP, this.transform.getWorldMatrix());
22108
+ var e = mvp.elements;
22109
+ // 列优先:col0=[e[0],e[1]], col1=[e[4],e[5]]
22110
+ // 透视投影下 MVP 不含 w-divide,cols 0-1 的长度是 clip-space 缩放
22111
+ // 需要除以物体中心的 w 值才能得到 NDC 缩放
22112
+ // 物体局部原点 [0,0,0,1] 经 MVP 后 w = e[15](≈ 物体到相机距离)
22113
+ var w = Math.abs(e[15]) || 1;
22114
+ var sx = Math.sqrt(e[0] * e[0] + e[1] * e[1]) / w;
22115
+ var sy = Math.sqrt(e[4] * e[4] + e[5] * e[5]) / w;
22116
+ var maxNdcScale = Math.max(sx, sy);
22117
+ // NDC -> 像素: canvasSize / 2
22118
+ var canvasRect = this.engine.canvas.getBoundingClientRect();
22119
+ var ndcToPixels = Math.max(canvasRect.width, canvasRect.height) / 2;
22120
+ // pixelsPerUnit: 1个局部空间单位在屏幕上对应多少像素
22121
+ // 椭圆/圆/矩形中使用 n = ceil(√(ppu × (rx+ry))) 确保圆弧误差 ≈ 1.2px
22122
+ var pixelsPerUnit = maxNdcScale * ndcToPixels * this.engine.pixelRatio;
22123
+ var minPpu = 1;
22124
+ var maxPpu = 2000;
22125
+ return Math.max(minPpu, Math.min(maxPpu, pixelsPerUnit));
22126
+ };
22127
+ _proto.buildPath = function buildPath(shapeAttribute, screenScale) {
22128
+ if (screenScale === void 0) screenScale = 1;
22036
22129
  this.graphicsPath.clear();
22130
+ var ppu = screenScale;
22037
22131
  switch(shapeAttribute.type){
22038
22132
  case ShapePrimitiveType.Custom:
22039
22133
  {
@@ -22053,7 +22147,7 @@ exports.ShapeComponent = /*#__PURE__*/ function(RendererComponent) {
22053
22147
  var lastPoint = points[lastPointIndex.point];
22054
22148
  var control1 = easingOuts[lastPointIndex.easingOut];
22055
22149
  var control2 = easingIns[pointIndex.easingIn];
22056
- this.graphicsPath.bezierCurveTo(control1.x + lastPoint.x, control1.y + lastPoint.y, control2.x + point.x, control2.y + point.y, point.x, point.y, 1);
22150
+ this.graphicsPath.bezierCurveTo(control1.x + lastPoint.x, control1.y + lastPoint.y, control2.x + point.x, control2.y + point.y, point.x, point.y, undefined, ppu);
22057
22151
  }
22058
22152
  if (shape.close) {
22059
22153
  var pointIndex1 = indices[0];
@@ -22062,7 +22156,7 @@ exports.ShapeComponent = /*#__PURE__*/ function(RendererComponent) {
22062
22156
  var lastPoint1 = points[lastPointIndex1.point];
22063
22157
  var control11 = easingOuts[lastPointIndex1.easingOut];
22064
22158
  var control21 = easingIns[pointIndex1.easingIn];
22065
- this.graphicsPath.bezierCurveTo(control11.x + lastPoint1.x, control11.y + lastPoint1.y, control21.x + point1.x, control21.y + point1.y, point1.x, point1.y, 1);
22159
+ this.graphicsPath.bezierCurveTo(control11.x + lastPoint1.x, control11.y + lastPoint1.y, control21.x + point1.x, control21.y + point1.y, point1.x, point1.y, undefined, ppu);
22066
22160
  this.graphicsPath.closePath();
22067
22161
  }
22068
22162
  }
@@ -22357,6 +22451,7 @@ exports.ShapeComponent = /*#__PURE__*/ function(RendererComponent) {
22357
22451
  ]);
22358
22452
  return ShapeComponent;
22359
22453
  }(RendererComponent);
22454
+ exports.ShapeComponent.tempMVP = Matrix4.fromIdentity();
22360
22455
  exports.ShapeComponent = __decorate([
22361
22456
  effectsClass("ShapeComponent")
22362
22457
  ], exports.ShapeComponent);
@@ -22503,7 +22598,8 @@ exports.FrameComponent = /*#__PURE__*/ function(RendererComponent1) {
22503
22598
  if (area) {
22504
22599
  return {
22505
22600
  type: area.type,
22506
- triangles: area.area
22601
+ triangles: area.area,
22602
+ clipMasks: _this.frameClipMasks
22507
22603
  };
22508
22604
  }
22509
22605
  }
@@ -22616,7 +22712,7 @@ exports.FrameComponent = /*#__PURE__*/ function(RendererComponent1) {
22616
22712
  var child = _step.value;
22617
22713
  var childFrameComponent = child.getComponent(RendererComponent);
22618
22714
  if (childFrameComponent) {
22619
- childFrameComponent.frameClipMasks.push(this);
22715
+ addItem(childFrameComponent.frameClipMasks, this);
22620
22716
  }
22621
22717
  this.setClipRectangleRecursive(child);
22622
22718
  }
@@ -23153,7 +23249,8 @@ exports.InteractComponent = /*#__PURE__*/ function(RendererComponent) {
23153
23249
  return {
23154
23250
  type: area.type,
23155
23251
  triangles: area.area,
23156
- behavior: behavior
23252
+ behavior: behavior,
23253
+ clipMasks: _this.frameClipMasks
23157
23254
  };
23158
23255
  }
23159
23256
  };
@@ -27557,6 +27654,7 @@ exports.ParticleSystem = /*#__PURE__*/ function(Component) {
27557
27654
  if (force || interactParams) {
27558
27655
  return {
27559
27656
  type: exports.HitTestType.custom,
27657
+ clipMasks: _this.renderer.frameClipMasks,
27560
27658
  collect: function(ray) {
27561
27659
  return _this.raycast({
27562
27660
  radius: (interactParams == null ? void 0 : interactParams.radius) || 0.4,
@@ -29292,13 +29390,14 @@ var TextLayout = /*#__PURE__*/ function() {
29292
29390
  }
29293
29391
  var _proto = TextLayout.prototype;
29294
29392
  _proto.update = function update(options) {
29295
- var _options_textHeight = options.textHeight, textHeight = _options_textHeight === void 0 ? 100 : _options_textHeight, _options_textWidth = options.textWidth, textWidth = _options_textWidth === void 0 ? 100 : _options_textWidth, _options_textOverflow = options.textOverflow, textOverflow = _options_textOverflow === void 0 ? TextOverflow.clip : _options_textOverflow, _options_textVerticalAlign = options.textVerticalAlign, textVerticalAlign = _options_textVerticalAlign === void 0 ? TextVerticalAlign.top : _options_textVerticalAlign, _options_textAlign = options.textAlign, textAlign = _options_textAlign === void 0 ? TextAlignment.left : _options_textAlign, _options_letterSpace = options.letterSpace, letterSpace = _options_letterSpace === void 0 ? 0 : _options_letterSpace, fontSize = options.fontSize, _options_lineHeight = options.lineHeight, lineHeight = _options_lineHeight === void 0 ? fontSize : _options_lineHeight;
29393
+ var _options_textHeight = options.textHeight, textHeight = _options_textHeight === void 0 ? 100 : _options_textHeight, _options_textWidth = options.textWidth, textWidth = _options_textWidth === void 0 ? 100 : _options_textWidth, _options_textOverflow = options.textOverflow, textOverflow = _options_textOverflow === void 0 ? TextOverflow.clip : _options_textOverflow, _options_textVerticalAlign = options.textVerticalAlign, textVerticalAlign = _options_textVerticalAlign === void 0 ? TextVerticalAlign.top : _options_textVerticalAlign, _options_textAlign = options.textAlign, textAlign = _options_textAlign === void 0 ? TextAlignment.left : _options_textAlign, _options_letterSpace = options.letterSpace, letterSpace = _options_letterSpace === void 0 ? 0 : _options_letterSpace, fontSize = options.fontSize, _options_lineHeight = options.lineHeight, lineHeight = _options_lineHeight === void 0 ? fontSize : _options_lineHeight, _options_autoResize = options.autoResize, autoResize = _options_autoResize === void 0 ? TextSizeMode.fixed : _options_autoResize;
29296
29394
  this.letterSpace = letterSpace;
29297
29395
  this.overflow = textOverflow;
29298
29396
  this.textVerticalAlign = textVerticalAlign;
29299
29397
  this.textAlign = textAlign;
29300
29398
  this.width = textWidth;
29301
29399
  this.height = textHeight;
29400
+ this.autoResize = autoResize;
29302
29401
  this.lineHeight = lineHeight;
29303
29402
  };
29304
29403
  /**
@@ -29310,7 +29409,6 @@ var TextLayout = /*#__PURE__*/ function() {
29310
29409
  * @param totalLineHeight - 可选的实际总行高,用于替代默认计算
29311
29410
  * @returns - 行高偏移值
29312
29411
  */ _proto.getOffsetY = function getOffsetY(style, lineCount, lineHeight, fontSize, totalLineHeight) {
29313
- var fontScale = style.fontScale;
29314
29412
  // /3 计算Y轴偏移量,以匹配编辑器行为
29315
29413
  var offsetY = (lineHeight - fontSize) / 3;
29316
29414
  // 计算基础偏移量
@@ -29322,10 +29420,10 @@ var TextLayout = /*#__PURE__*/ function() {
29322
29420
  offsetResult = baseOffset + offsetY;
29323
29421
  break;
29324
29422
  case TextVerticalAlign.middle:
29325
- offsetResult = (this.height * fontScale - commonCalculation + baseOffset) / 2;
29423
+ offsetResult = (this.height - commonCalculation + baseOffset) / 2;
29326
29424
  break;
29327
29425
  case TextVerticalAlign.bottom:
29328
- offsetResult = this.height * fontScale - commonCalculation - offsetY;
29426
+ offsetResult = this.height - commonCalculation - offsetY;
29329
29427
  break;
29330
29428
  }
29331
29429
  return offsetResult;
@@ -29342,10 +29440,10 @@ var TextLayout = /*#__PURE__*/ function() {
29342
29440
  offsetX = 0;
29343
29441
  break;
29344
29442
  case TextAlignment.middle:
29345
- offsetX = (this.width * style.fontScale - maxWidth) / 2;
29443
+ offsetX = (this.width - maxWidth) / 2;
29346
29444
  break;
29347
29445
  case TextAlignment.right:
29348
- offsetX = this.width * style.fontScale - maxWidth;
29446
+ offsetX = this.width - maxWidth;
29349
29447
  break;
29350
29448
  }
29351
29449
  return offsetX;
@@ -29598,8 +29696,8 @@ var TextStyle = /*#__PURE__*/ function() {
29598
29696
  };
29599
29697
  // 通用工具方法
29600
29698
  _proto.getFontDesc = function getFontDesc(size) {
29601
- var _this_textStyle = this.textStyle, fontSize = _this_textStyle.fontSize, fontScale = _this_textStyle.fontScale, fontFamily = _this_textStyle.fontFamily, textWeight = _this_textStyle.textWeight, fontStyle = _this_textStyle.fontStyle;
29602
- var fontDesc = "" + (size || fontSize * fontScale).toString() + "px ";
29699
+ var _this_textStyle = this.textStyle, fontSize = _this_textStyle.fontSize, fontFamily = _this_textStyle.fontFamily, textWeight = _this_textStyle.textWeight, fontStyle = _this_textStyle.fontStyle;
29700
+ var fontDesc = "" + (size || fontSize).toString() + "px ";
29603
29701
  if (![
29604
29702
  "serif",
29605
29703
  "sans-serif",
@@ -29629,13 +29727,13 @@ var TextStyle = /*#__PURE__*/ function() {
29629
29727
  };
29630
29728
  _proto.setupShadow = function setupShadow() {
29631
29729
  var context = this.context;
29632
- var _this_textStyle = this.textStyle, shadowColor = _this_textStyle.shadowColor, shadowBlur = _this_textStyle.shadowBlur, shadowOffsetX = _this_textStyle.shadowOffsetX, shadowOffsetY = _this_textStyle.shadowOffsetY;
29730
+ var _this_textStyle = this.textStyle, shadowColor = _this_textStyle.shadowColor, shadowBlur = _this_textStyle.shadowBlur, shadowOffsetX = _this_textStyle.shadowOffsetX, shadowOffsetY = _this_textStyle.shadowOffsetY, fontScale = _this_textStyle.fontScale;
29633
29731
  var r = shadowColor[0], g = shadowColor[1], b = shadowColor[2], a = shadowColor[3];
29634
29732
  if (context) {
29635
29733
  context.shadowColor = "rgba(" + r * 255 + ", " + g * 255 + ", " + b * 255 + ", " + a + ")";
29636
- context.shadowBlur = shadowBlur;
29637
- context.shadowOffsetX = shadowOffsetX;
29638
- context.shadowOffsetY = -shadowOffsetY;
29734
+ context.shadowBlur = shadowBlur * fontScale;
29735
+ context.shadowOffsetX = shadowOffsetX * fontScale;
29736
+ context.shadowOffsetY = -shadowOffsetY * fontScale;
29639
29737
  }
29640
29738
  };
29641
29739
  // 通用纹理生命周期管理
@@ -29880,30 +29978,40 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
29880
29978
  layout.width = this.getTextWidth();
29881
29979
  this.lineCount = this.getLineCount(this.text);
29882
29980
  layout.height = layout.lineHeight * this.lineCount;
29981
+ } else if (layout.autoResize === TextSizeMode.autoHeight) {
29982
+ this.lineCount = this.getLineCount(this.text);
29983
+ layout.height = layout.lineHeight * this.lineCount;
29883
29984
  } else {
29884
29985
  this.lineCount = this.getLineCount(this.text);
29885
29986
  }
29886
- var baseWidth = (layout.width + style.fontOffset) * fontScale;
29887
- var baseHeight = layout.height * fontScale;
29888
- var fontSize = style.fontSize * fontScale;
29889
- var lineHeight = layout.lineHeight * fontScale;
29987
+ var baseWidth = layout.width + style.fontOffset;
29988
+ var baseHeight = layout.height;
29989
+ var fontSize = style.fontSize;
29990
+ var lineHeight = layout.lineHeight;
29890
29991
  style.fontDesc = this.getFontDesc(fontSize);
29891
29992
  // 使用 Array.from 正确分割 Unicode 字符(包括 emoji)
29892
29993
  var char = Array.from(this.text || "");
29893
29994
  var _this_getEffectPadding = this.getEffectPadding(), padL = _this_getEffectPadding.padL, padR = _this_getEffectPadding.padR, padT = _this_getEffectPadding.padT, padB = _this_getEffectPadding.padB;
29894
29995
  var hasEffect = (padL | padR | padT | padB) !== 0;
29895
- var texWidth = hasEffect ? Math.ceil(baseWidth + padL + padR) : baseWidth;
29896
- var texHeight = hasEffect ? Math.ceil(baseHeight + padT + padB) : baseHeight;
29996
+ // 限制 fontScale,确保纹理尺寸不超过 maxTextureSize / 2
29997
+ var maxTexSize = this.engine.gpuCapability.detail.maxTextureSize / 2;
29998
+ var logicalWidth = hasEffect ? baseWidth + padL + padR : baseWidth;
29999
+ var logicalHeight = hasEffect ? baseHeight + padT + padB : baseHeight;
30000
+ var maxLogical = Math.max(logicalWidth, logicalHeight, 1);
30001
+ fontScale = Math.min(fontScale, maxTexSize / maxLogical);
30002
+ var texWidth = Math.ceil(logicalWidth * fontScale);
30003
+ var texHeight = Math.ceil(logicalHeight * fontScale);
29897
30004
  var shiftX = hasEffect ? padL : 0;
29898
30005
  var shiftY = hasEffect ? flipY ? padT : padB : 0;
29899
30006
  // 给渲染层用:扩容比例
29900
- this.effectScaleX = baseWidth > 0 ? texWidth / baseWidth : 1;
29901
- this.effectScaleY = baseHeight > 0 ? texHeight / baseHeight : 1;
30007
+ this.effectScaleX = baseWidth > 0 ? texWidth / (baseWidth * fontScale) : 1;
30008
+ this.effectScaleY = baseHeight > 0 ? texHeight / (baseHeight * fontScale) : 1;
29902
30009
  // 默认 camera 下的 world per pixel
29903
30010
  var scaleFactor = 0.11092565;
29904
30011
  var scaleFactor2 = scaleFactor * scaleFactor;
29905
- this.transform.setSize(baseWidth * scaleFactor2 / fontScale, baseHeight * scaleFactor2 / fontScale);
30012
+ this.transform.setSize(baseWidth * scaleFactor2, baseHeight * scaleFactor2);
29906
30013
  this.renderToTexture(texWidth, texHeight, flipY, function(context) {
30014
+ context.scale(fontScale, fontScale);
29907
30015
  // canvas size 变化后重新刷新 context
29908
30016
  if (_this.maxLineWidth > baseWidth && layout.overflow === TextOverflow.display) {
29909
30017
  context.font = _this.getFontDesc(fontSize * baseWidth / _this.maxLineWidth);
@@ -29924,7 +30032,7 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
29924
30032
  // 和浏览器行为保持一致
29925
30033
  // 字符间距只应用在字符之间,每行第一个字符不加间距
29926
30034
  if (charsArray.length > 0) {
29927
- x += layout.letterSpace * fontScale;
30035
+ x += layout.letterSpace;
29928
30036
  }
29929
30037
  if (x + textMetrics.width > baseWidth && i > 0 || str === "\n") {
29930
30038
  charsInfo.push({
@@ -30009,9 +30117,9 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
30009
30117
  */ _proto.getEffectPadding = function getEffectPadding() {
30010
30118
  var style = this.textStyle;
30011
30119
  var hasDrawOutline = style.isOutlined && style.outlineWidth > 0;
30012
- var outlinePad = hasDrawOutline ? Math.ceil(style.outlineWidth * 2 * style.fontScale) : 0;
30120
+ var outlinePad = hasDrawOutline ? Math.ceil(style.outlineWidth * 2) : 0;
30013
30121
  var hasShadow = style.hasShadow && (style.shadowBlur > 0 || style.shadowOffsetX !== 0 || style.shadowOffsetY !== 0);
30014
- var shadowPad = hasShadow ? Math.ceil((Math.abs(style.shadowOffsetX) + Math.abs(style.shadowOffsetY) + style.shadowBlur) * style.fontScale) : 0;
30122
+ var shadowPad = hasShadow ? Math.ceil(Math.abs(style.shadowOffsetX) + Math.abs(style.shadowOffsetY) + style.shadowBlur) : 0;
30015
30123
  var pad = outlinePad + shadowPad;
30016
30124
  return {
30017
30125
  padL: pad,
@@ -30036,11 +30144,13 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
30036
30144
  var width = Math.max(0, Number(value) || 0);
30037
30145
  var layout = this.textLayout;
30038
30146
  // 宽度没变且已是非 autoWidth 模式,直接返回
30039
- if (layout.width === width && layout.autoResize === TextSizeMode.autoWidth) {
30147
+ if (layout.width === width) {
30040
30148
  return;
30041
30149
  }
30042
30150
  // 手动设置宽度时关闭 autoWidth
30043
- layout.autoResize = TextSizeMode.autoHeight;
30151
+ if (layout.autoResize === TextSizeMode.autoWidth) {
30152
+ layout.autoResize = TextSizeMode.autoHeight;
30153
+ }
30044
30154
  layout.width = width;
30045
30155
  // 按当前 overflow 模式重新计算 maxLineWidth
30046
30156
  this.isDirty = true;
@@ -30153,7 +30263,7 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
30153
30263
  *
30154
30264
  * 说明:
30155
30265
  * - 使用 Canvas 2D 的 measureText,并按当前实现的逐字符排版规则累加宽度(与 updateTexture 保持一致)。
30156
- * - 结果为"逻辑宽度"(已除去 fontScale,并扣除 fontOffset),可直接写回 options.textWidth。
30266
+ * - 结果为"逻辑宽度"(扣除 fontOffset),可直接写回 options.textWidth。,可直接写回 options.textWidth
30157
30267
  * - 通过 padding 追加少量冗余像素,用于降低边缘裁切风险。
30158
30268
  *
30159
30269
  * @returns 文本宽度(>= 0)
@@ -30168,10 +30278,8 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
30168
30278
  var text = ((_this_text = this.text) != null ? _this_text : "").toString();
30169
30279
  var layout = this.textLayout;
30170
30280
  var style = this.textStyle;
30171
- var fontScale = style.fontScale || 1;
30172
- var renderFontSize = style.fontSize * fontScale;
30173
- // 与 updateTexture 一致:用 render 字号测量
30174
- ctx.font = this.getFontDesc(renderFontSize);
30281
+ // updateTexture 一致:用逻辑字号测量
30282
+ ctx.font = this.getFontDesc(style.fontSize);
30175
30283
  var maxLineWidthRender = 0;
30176
30284
  var x = 0;
30177
30285
  for(var i = 0; i < text.length; i++){
@@ -30181,17 +30289,14 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
30181
30289
  x = 0;
30182
30290
  continue;
30183
30291
  }
30184
- // 与 updateTexture 一致:每个字符前加一次 letterSpace * fontScale
30185
- x += (layout.letterSpace || 0) * fontScale;
30292
+ // 与 updateTexture 一致:每个字符前加一次 letterSpace
30293
+ x += layout.letterSpace || 0;
30186
30294
  x += ctx.measureText(ch).width;
30187
30295
  }
30188
30296
  maxLineWidthRender = Math.max(maxLineWidthRender, x);
30189
- // render -> 逻辑宽度
30190
- var logicalMax = maxLineWidthRender / fontScale;
30191
- // 反推 layout.width:renderWidth = (layout.width + fontOffset) * fontScale
30192
30297
  var padding = 2;
30193
30298
  var EPS = 1e-4;
30194
- var w = Math.ceil(logicalMax - (style.fontOffset || 0) - EPS) + padding;
30299
+ var w = Math.ceil(maxLineWidthRender - (style.fontOffset || 0) - EPS) + padding;
30195
30300
  return Math.max(0, w);
30196
30301
  };
30197
30302
  _proto.getDefaultProps = function getDefaultProps() {
@@ -30303,9 +30408,9 @@ var SerializationHelper = /*#__PURE__*/ function() {
30303
30408
  }
30304
30409
  }
30305
30410
  // TODO 待移除 tagggedProperties 为没有装饰器的临时方案
30306
- for(var _iterator1 = _create_for_of_iterator_helper_loose(Object.keys(effectsObject.defination)), _step1; !(_step1 = _iterator1()).done;){
30411
+ for(var _iterator1 = _create_for_of_iterator_helper_loose(Object.keys(effectsObject.definition)), _step1; !(_step1 = _iterator1()).done;){
30307
30412
  var key1 = _step1.value;
30308
- var value1 = effectsObject.defination[key1];
30413
+ var value1 = effectsObject.definition[key1];
30309
30414
  if (typeof value1 === "number" || typeof value1 === "string" || typeof value1 === "boolean" || SerializationHelper.checkTypedArray(value1)) {
30310
30415
  // TODO json 数据避免传 typedArray
30311
30416
  serializedData[key1] = value1;
@@ -30329,7 +30434,7 @@ var SerializationHelper = /*#__PURE__*/ function() {
30329
30434
  return serializedData;
30330
30435
  };
30331
30436
  SerializationHelper.deserialize = function deserialize(serializedData, effectsObject) {
30332
- effectsObject.defination = serializedData;
30437
+ effectsObject.definition = serializedData;
30333
30438
  var serializedProperties = getMergedStore(effectsObject);
30334
30439
  var engine = effectsObject.engine;
30335
30440
  if (serializedProperties) {
@@ -30344,7 +30449,7 @@ var SerializationHelper = /*#__PURE__*/ function() {
30344
30449
  effectsObject[key] = SerializationHelper.deserializeProperty(value, engine, 0, propertyType);
30345
30450
  }
30346
30451
  }
30347
- effectsObject.fromData(effectsObject.defination);
30452
+ effectsObject.fromData(effectsObject.definition);
30348
30453
  };
30349
30454
  SerializationHelper.checkTypedArray = function checkTypedArray(obj) {
30350
30455
  return _instanceof1(obj, Int8Array) || _instanceof1(obj, Uint8Array) || _instanceof1(obj, Uint8ClampedArray) || _instanceof1(obj, Int16Array) || _instanceof1(obj, Uint16Array) || _instanceof1(obj, Int32Array) || _instanceof1(obj, Uint32Array) || _instanceof1(obj, Float32Array) || _instanceof1(obj, Float64Array) || _instanceof1(obj, ArrayBuffer);
@@ -30475,7 +30580,7 @@ var SerializationHelper = /*#__PURE__*/ function() {
30475
30580
  var effectsObjectData = this.findData(guid);
30476
30581
  var effectsObject;
30477
30582
  if (!effectsObjectData) {
30478
- console.error("Object data with uuid: " + guid + " not found.");
30583
+ console.warn("Object data with uuid: " + guid + " not found.");
30479
30584
  return undefined;
30480
30585
  }
30481
30586
  switch(effectsObjectData.dataType){
@@ -30497,7 +30602,7 @@ var SerializationHelper = /*#__PURE__*/ function() {
30497
30602
  }
30498
30603
  }
30499
30604
  if (!effectsObject) {
30500
- console.error("Constructor for DataType: " + effectsObjectData.dataType + " not found.");
30605
+ console.warn("Constructor for DataType: " + effectsObjectData.dataType + " not found.");
30501
30606
  return undefined;
30502
30607
  }
30503
30608
  effectsObject.setInstanceId(effectsObjectData.id);
@@ -32339,7 +32444,7 @@ function getStandardSpriteContent(sprite, transform) {
32339
32444
  return ret;
32340
32445
  }
32341
32446
 
32342
- var version$1 = "2.9.0-alpha.1";
32447
+ var version$1 = "2.9.0-alpha.2";
32343
32448
  var v0 = /^(\d+)\.(\d+)\.(\d+)(-(\w+)\.\d+)?$/;
32344
32449
  var standardVersion = /^(\d+)\.(\d+)$/;
32345
32450
  var reverseParticle = false;
@@ -34658,7 +34763,9 @@ var PreRenderTickData = /*#__PURE__*/ function(TickData) {
34658
34763
  }
34659
34764
  var regions = [];
34660
34765
  var ray = this.getHitTestRay(x, y);
34661
- this.rootComposition.hitTest(ray, x, y, regions, force, options);
34766
+ // 所有命中的元素共享同一个 hitPositions 数组,保持与原有行为一致
34767
+ var hitPositions = [];
34768
+ this.rootItem.hitTest(ray, x, y, regions, hitPositions, force, options);
34662
34769
  return regions;
34663
34770
  };
34664
34771
  /**
@@ -37226,10 +37333,6 @@ var PassTextureCache = /*#__PURE__*/ function() {
37226
37333
  height: renderer.getHeight(),
37227
37334
  event: engine.eventSystem
37228
37335
  }), scene);
37229
- // 中低端设备降帧到 30fps·
37230
- if (engine.ticker && options.renderLevel === RenderLevel.B) {
37231
- engine.ticker.setFPS(Math.min(engine.ticker.getFPS(), 30));
37232
- }
37233
37336
  // TODO 目前编辑器会每帧调用 loadScene, 在这编译会导致闪帧,待编辑器渲染逻辑优化后移除。
37234
37337
  if (engine.env !== PLAYER_OPTIONS_ENV_EDITOR) {
37235
37338
  engine.assetService.createShaderVariant();
@@ -37294,7 +37397,7 @@ registerPlugin("text", TextLoader);
37294
37397
  registerPlugin("sprite", SpriteLoader);
37295
37398
  registerPlugin("particle", ParticleLoader);
37296
37399
  registerPlugin("interact", InteractLoader);
37297
- var version = "2.9.0-alpha.1";
37400
+ var version = "2.9.0-alpha.2";
37298
37401
  logger.info("Core version: " + version + ".");
37299
37402
 
37300
37403
  exports.ActivationMixerPlayable = ActivationMixerPlayable;