@galacean/effects-threejs 2.9.1 → 2.9.3

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 threejs plugin for the web
4
4
  * Author: Ant Group CO., Ltd.
5
5
  * Contributors: 燃然,飂兮,十弦,云垣,茂安,意绮
6
- * Version: v2.9.1
6
+ * Version: v2.9.3
7
7
  */
8
8
 
9
9
  'use strict';
@@ -30217,6 +30217,54 @@ var ParticleLoader = /*#__PURE__*/ function(Plugin) {
30217
30217
  return ParticleLoader;
30218
30218
  }(_wrap_native_super(Plugin));
30219
30219
 
30220
+ /**
30221
+ * 文本换行机会判定:UAX #14 风格的"换行机会"模型。
30222
+ *
30223
+ * - CJK 表意字 / 假名 / 韩文音节:任意两个字之间都是合法断点(字符级)
30224
+ * - 空格 / 制表符 / NBSP:可断,且断行时被吞掉(不留在行尾 / 行首)
30225
+ * - 西文字母 / 数字:词内不可断;整体超宽时由调用方退化到字符级断(overflow-wrap)
30226
+ *
30227
+ * 不含 kinsoku 禁则(句号 / 逗号不进行首等留作后续)。
30228
+ */ /** 换行机会类型(断点字符之后):决定断点字符归属及断行时是否吞掉 */ /**
30229
+ * 是否为可换行断点字符(空格 / 制表符 / NBSP)。
30230
+ * 断在此字符之前,且断行时该字符被吞掉(不进旧行也不进新行)。
30231
+ * @param ch - 当前字符
30232
+ */ function isBreakChar(ch) {
30233
+ return ch === " " || ch === " " || ch === "\xa0";
30234
+ }
30235
+ /**
30236
+ * 是否为 CJK 类字符(中文表意字 / 假名 / 韩文音节)。可在其与相邻字符之间换行。
30237
+ * 用码点判定以支持 CJK 扩展 B 等代理对字符(不能用 /u 正则,browserslist 为 iOS 9)。
30238
+ * @param ch - 当前字符(须为完整码点,调用方应使用 Array.from 遍历)
30239
+ */ function isCJKLike(ch) {
30240
+ var _ch_codePointAt;
30241
+ var cp = (_ch_codePointAt = ch.codePointAt(0)) != null ? _ch_codePointAt : 0;
30242
+ return cp >= 0x3400 && cp <= 0x4DBF || // CJK 统一表意扩展 A
30243
+ cp >= 0x4E00 && cp <= 0x9FFF || // CJK 统一表意
30244
+ cp >= 0xF900 && cp <= 0xFAFF || // CJK 兼容表意
30245
+ cp >= 0x20000 && cp <= 0x2FA1F || // CJK 扩展 B~F + 兼容增补(代理对)
30246
+ cp >= 0x3040 && cp <= 0x309F || // 平假名
30247
+ cp >= 0x30A0 && cp <= 0x30FF || // 片假名
30248
+ cp >= 0x31F0 && cp <= 0x31FF || // 片假名语音扩展
30249
+ cp >= 0xAC00 && cp <= 0xD7AF // 韩文音节
30250
+ ;
30251
+ }
30252
+ /**
30253
+ * 计算 prev(已推入的字符)之后是否为换行机会。只看 prev,不看后续字符。
30254
+ * @param prev - 前一字符(已推入旧行)
30255
+ * @returns 'swallow'=prev 是空格类,断行时吞掉 prev;'keep'=prev 是 CJK,prev 留本行末、下行从其后起;false=不可断
30256
+ */ function breakOpportunityAfter(prev) {
30257
+ // prev 是空格类 → 断在 prev 处,断行时吞掉 prev(不进旧行也不进新行)
30258
+ if (isBreakChar(prev)) {
30259
+ return "swallow";
30260
+ }
30261
+ // prev 是 CJK → prev 留本行末,下行从 prev 之后起(字符级断点,不吞)
30262
+ if (isCJKLike(prev)) {
30263
+ return "keep";
30264
+ }
30265
+ return false;
30266
+ }
30267
+
30220
30268
  var CanvasPool = /*#__PURE__*/ function() {
30221
30269
  function CanvasPool() {
30222
30270
  this.elements = [];
@@ -30698,9 +30746,6 @@ var DEFAULT_FONTS = [
30698
30746
  "courier"
30699
30747
  ];
30700
30748
  /** 检测字符串是否包含需要 RTL 和连写排版的字符(阿拉伯语等) */ var HAS_RTL_OR_JOINING = /[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/;
30701
- /** 可换行断点:空格、制表符等 */ var IS_BREAK_CHAR = function(ch) {
30702
- return ch === " " || ch === " " || ch === "\xa0";
30703
- };
30704
30749
  var seed$2 = 0;
30705
30750
  exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
30706
30751
  _inherits(TextComponent, MaskableGraphic);
@@ -30801,13 +30846,15 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
30801
30846
  var lineCount = 1;
30802
30847
  var x = 0;
30803
30848
  var charCountInLine = 0;
30849
+ // 使用码点遍历,正确处理 emoji 与 CJK 扩展 B 等代理对字符
30850
+ var chars = Array.from(text);
30804
30851
  if (context) {
30805
30852
  context.font = this.getFontDesc(this.textStyle.fontSize);
30806
30853
  }
30807
30854
  if (overflow === TextOverflow.display) {
30808
- for(var i = 0; i < text.length; i++){
30855
+ for(var _iterator = _create_for_of_iterator_helper_loose(chars), _step; !(_step = _iterator()).done;){
30856
+ var str = _step.value;
30809
30857
  var _context_measureText;
30810
- var str = text[i];
30811
30858
  var _context_measureText_width;
30812
30859
  var textMetrics = (_context_measureText_width = context == null ? void 0 : (_context_measureText = context.measureText(str)) == null ? void 0 : _context_measureText.width) != null ? _context_measureText_width : 0;
30813
30860
  if (str === "\n") {
@@ -30826,12 +30873,12 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
30826
30873
  return lineCount;
30827
30874
  }
30828
30875
  if (this.textLayout.keepWordIntact) {
30829
- // 单词完整换行:优先在空格处断行,避免从单词中间断开
30876
+ // 单词完整换行:优先在换行机会处断行(空格吞断 / CJK 字间可断),避免从西文词中间断开
30830
30877
  var lastBreakX = 0;
30831
30878
  var countAtBreak = 0;
30832
- for(var i1 = 0; i1 < text.length; i1++){
30879
+ for(var _iterator1 = _create_for_of_iterator_helper_loose(chars), _step1; !(_step1 = _iterator1()).done;){
30880
+ var str1 = _step1.value;
30833
30881
  var _context_measureText1;
30834
- var str1 = text[i1];
30835
30882
  var _context_measureText_width1;
30836
30883
  var textMetrics1 = (_context_measureText_width1 = context == null ? void 0 : (_context_measureText1 = context.measureText(str1)) == null ? void 0 : _context_measureText1.width) != null ? _context_measureText_width1 : 0;
30837
30884
  if (str1 === "\n") {
@@ -30864,22 +30911,23 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
30864
30911
  }
30865
30912
  x += textMetrics1;
30866
30913
  charCountInLine++;
30867
- if (IS_BREAK_CHAR(str1)) {
30914
+ // 记换行机会:str 之后可断(空格 swallow / CJK keep)。lastBreakX 含 str 宽度(str 留本行末)
30915
+ if (breakOpportunityAfter(str1) !== false) {
30868
30916
  lastBreakX = x;
30869
30917
  countAtBreak = charCountInLine;
30870
30918
  }
30871
30919
  }
30872
30920
  } else {
30873
30921
  // 逐字符换行:允许在任意字符处断开
30874
- for(var i2 = 0; i2 < text.length; i2++){
30922
+ for(var i = 0; i < chars.length; i++){
30875
30923
  var _context_measureText2;
30876
- var str2 = text[i2];
30924
+ var str2 = chars[i];
30877
30925
  var _context_measureText_width2;
30878
30926
  var textMetrics2 = (_context_measureText_width2 = context == null ? void 0 : (_context_measureText2 = context.measureText(str2)) == null ? void 0 : _context_measureText2.width) != null ? _context_measureText_width2 : 0;
30879
30927
  if (charCountInLine > 0) {
30880
30928
  x += letterSpace;
30881
30929
  }
30882
- if (x + textMetrics2 > width && i2 > 0 || str2 === "\n") {
30930
+ if (x + textMetrics2 > width && i > 0 || str2 === "\n") {
30883
30931
  lineCount++;
30884
30932
  this.maxLineWidth = Math.max(this.maxLineWidth, x);
30885
30933
  x = 0;
@@ -30972,8 +31020,11 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
30972
31020
  var charsArray = [];
30973
31021
  var charOffsetX = [];
30974
31022
  if (layout.keepWordIntact) {
30975
- // 单词完整换行:优先在空格处断行,避免从单词中间断开
31023
+ // 单词完整换行:优先在换行机会处断行(空格吞断 / CJK 字间可断),避免从西文词中间断开。
31024
+ // lastBreakIdx 指向断点字符在 charsArray 中的索引;breakSwallow=true 时该字符被吞(空格),
31025
+ // false 时该字符留本行末(CJK),下行均从 lastBreakIdx+1 起。
30976
31026
  var lastBreakIdx = -1;
31027
+ var breakSwallow = false;
30977
31028
  for(var i = 0; i < char.length; i++){
30978
31029
  var str = char[i];
30979
31030
  var textMetrics = context.measureText(str);
@@ -30989,15 +31040,18 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
30989
31040
  charsArray = [];
30990
31041
  charOffsetX = [];
30991
31042
  lastBreakIdx = -1;
31043
+ breakSwallow = false;
30992
31044
  continue;
30993
31045
  }
30994
31046
  var spacing = charsArray.length > 0 ? layout.letterSpace : 0;
30995
31047
  var willWidth = x + spacing + textMetrics.width;
30996
31048
  if (willWidth > baseWidth && charsArray.length > 0) {
30997
31049
  if (lastBreakIdx > 0) {
30998
- // 在空格处换行
30999
- var lineChars = charsArray.slice(0, lastBreakIdx);
31000
- var lineOffsets = charOffsetX.slice(0, lastBreakIdx);
31050
+ // 在换行机会处断行:swallow 取 [0,lastBreakIdx)(吞掉断点字符),
31051
+ // keep [0,lastBreakIdx](断点字符留本行末),下行均从 lastBreakIdx+1 起。
31052
+ var endIdx = breakSwallow ? lastBreakIdx : lastBreakIdx + 1;
31053
+ var lineChars = charsArray.slice(0, endIdx);
31054
+ var lineOffsets = charOffsetX.slice(0, endIdx);
31001
31055
  var lineWidth = lineChars.length > 0 ? lineOffsets[lineOffsets.length - 1] + context.measureText(lineChars[lineChars.length - 1]).width : 0;
31002
31056
  charsInfo.push({
31003
31057
  y: y,
@@ -31018,6 +31072,7 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
31018
31072
  x += context.measureText(charsArray[j]).width;
31019
31073
  }
31020
31074
  lastBreakIdx = -1;
31075
+ breakSwallow = false;
31021
31076
  } else {
31022
31077
  charsInfo.push({
31023
31078
  y: y,
@@ -31030,6 +31085,7 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
31030
31085
  charsArray = [];
31031
31086
  charOffsetX = [];
31032
31087
  lastBreakIdx = -1;
31088
+ breakSwallow = false;
31033
31089
  }
31034
31090
  }
31035
31091
  if (charsArray.length > 0) {
@@ -31038,8 +31094,12 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
31038
31094
  charOffsetX.push(x);
31039
31095
  charsArray.push(str);
31040
31096
  x += textMetrics.width;
31041
- if (IS_BREAK_CHAR(str)) {
31097
+ // 记换行机会:str 之后可断。lastBreakIdx 指向 str(charsArray 末尾),
31098
+ // swallow=吞 str(空格),keep=str 留本行末(CJK)。
31099
+ var opp = breakOpportunityAfter(str);
31100
+ if (opp !== false) {
31042
31101
  lastBreakIdx = charsArray.length - 1;
31102
+ breakSwallow = opp === "swallow";
31043
31103
  }
31044
31104
  }
31045
31105
  } else {
@@ -33677,7 +33737,7 @@ function getStandardSpriteContent(sprite, transform) {
33677
33737
  return ret;
33678
33738
  }
33679
33739
 
33680
- var version$2 = "2.9.1";
33740
+ var version$2 = "2.9.3";
33681
33741
  var v0 = /^(\d+)\.(\d+)\.(\d+)(-(\w+)\.\d+)?$/;
33682
33742
  var standardVersion = /^(\d+)\.(\d+)$/;
33683
33743
  var reverseParticle = false;
@@ -38731,7 +38791,7 @@ registerPlugin("text", TextLoader);
38731
38791
  registerPlugin("sprite", SpriteLoader);
38732
38792
  registerPlugin("particle", ParticleLoader);
38733
38793
  registerPlugin("interact", InteractLoader);
38734
- var version$1 = "2.9.1";
38794
+ var version$1 = "2.9.3";
38735
38795
  logger.info("Core version: " + version$1 + ".");
38736
38796
 
38737
38797
  var _obj;
@@ -40305,7 +40365,7 @@ applyMixins(exports.ThreeTextComponent, [
40305
40365
  */ Mesh.create = function(engine, props) {
40306
40366
  return new ThreeMesh(engine, props);
40307
40367
  };
40308
- var version = "2.9.1";
40368
+ var version = "2.9.3";
40309
40369
  logger.info("THREEJS plugin version: " + version + ".");
40310
40370
 
40311
40371
  exports.ActivationMixerPlayable = ActivationMixerPlayable;
@@ -40502,6 +40562,7 @@ exports.applyMixins = applyMixins;
40502
40562
  exports.assertExist = assertExist;
40503
40563
  exports.asserts = asserts;
40504
40564
  exports.base64ToFile = base64ToFile;
40565
+ exports.breakOpportunityAfter = breakOpportunityAfter;
40505
40566
  exports.buildBezierData = buildBezierData;
40506
40567
  exports.buildEasingCurve = buildEasingCurve;
40507
40568
  exports.buildLine = buildLine;
@@ -40567,6 +40628,8 @@ exports.interpolateColor = interpolateColor;
40567
40628
  exports.isAlipayMiniApp = isAlipayMiniApp;
40568
40629
  exports.isAndroid = isAndroid;
40569
40630
  exports.isArray = isArray;
40631
+ exports.isBreakChar = isBreakChar;
40632
+ exports.isCJKLike = isCJKLike;
40570
40633
  exports.isCanvas = isCanvas;
40571
40634
  exports.isFunction = isFunction;
40572
40635
  exports.isIOS = isIOS;