@galacean/effects-core 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 core 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';
@@ -30190,6 +30190,54 @@ var ParticleLoader = /*#__PURE__*/ function(Plugin) {
30190
30190
  return ParticleLoader;
30191
30191
  }(_wrap_native_super(Plugin));
30192
30192
 
30193
+ /**
30194
+ * 文本换行机会判定:UAX #14 风格的"换行机会"模型。
30195
+ *
30196
+ * - CJK 表意字 / 假名 / 韩文音节:任意两个字之间都是合法断点(字符级)
30197
+ * - 空格 / 制表符 / NBSP:可断,且断行时被吞掉(不留在行尾 / 行首)
30198
+ * - 西文字母 / 数字:词内不可断;整体超宽时由调用方退化到字符级断(overflow-wrap)
30199
+ *
30200
+ * 不含 kinsoku 禁则(句号 / 逗号不进行首等留作后续)。
30201
+ */ /** 换行机会类型(断点字符之后):决定断点字符归属及断行时是否吞掉 */ /**
30202
+ * 是否为可换行断点字符(空格 / 制表符 / NBSP)。
30203
+ * 断在此字符之前,且断行时该字符被吞掉(不进旧行也不进新行)。
30204
+ * @param ch - 当前字符
30205
+ */ function isBreakChar(ch) {
30206
+ return ch === " " || ch === " " || ch === "\xa0";
30207
+ }
30208
+ /**
30209
+ * 是否为 CJK 类字符(中文表意字 / 假名 / 韩文音节)。可在其与相邻字符之间换行。
30210
+ * 用码点判定以支持 CJK 扩展 B 等代理对字符(不能用 /u 正则,browserslist 为 iOS 9)。
30211
+ * @param ch - 当前字符(须为完整码点,调用方应使用 Array.from 遍历)
30212
+ */ function isCJKLike(ch) {
30213
+ var _ch_codePointAt;
30214
+ var cp = (_ch_codePointAt = ch.codePointAt(0)) != null ? _ch_codePointAt : 0;
30215
+ return cp >= 0x3400 && cp <= 0x4DBF || // CJK 统一表意扩展 A
30216
+ cp >= 0x4E00 && cp <= 0x9FFF || // CJK 统一表意
30217
+ cp >= 0xF900 && cp <= 0xFAFF || // CJK 兼容表意
30218
+ cp >= 0x20000 && cp <= 0x2FA1F || // CJK 扩展 B~F + 兼容增补(代理对)
30219
+ cp >= 0x3040 && cp <= 0x309F || // 平假名
30220
+ cp >= 0x30A0 && cp <= 0x30FF || // 片假名
30221
+ cp >= 0x31F0 && cp <= 0x31FF || // 片假名语音扩展
30222
+ cp >= 0xAC00 && cp <= 0xD7AF // 韩文音节
30223
+ ;
30224
+ }
30225
+ /**
30226
+ * 计算 prev(已推入的字符)之后是否为换行机会。只看 prev,不看后续字符。
30227
+ * @param prev - 前一字符(已推入旧行)
30228
+ * @returns 'swallow'=prev 是空格类,断行时吞掉 prev;'keep'=prev 是 CJK,prev 留本行末、下行从其后起;false=不可断
30229
+ */ function breakOpportunityAfter(prev) {
30230
+ // prev 是空格类 → 断在 prev 处,断行时吞掉 prev(不进旧行也不进新行)
30231
+ if (isBreakChar(prev)) {
30232
+ return "swallow";
30233
+ }
30234
+ // prev 是 CJK → prev 留本行末,下行从 prev 之后起(字符级断点,不吞)
30235
+ if (isCJKLike(prev)) {
30236
+ return "keep";
30237
+ }
30238
+ return false;
30239
+ }
30240
+
30193
30241
  var CanvasPool = /*#__PURE__*/ function() {
30194
30242
  function CanvasPool() {
30195
30243
  this.elements = [];
@@ -30671,9 +30719,6 @@ var DEFAULT_FONTS = [
30671
30719
  "courier"
30672
30720
  ];
30673
30721
  /** 检测字符串是否包含需要 RTL 和连写排版的字符(阿拉伯语等) */ var HAS_RTL_OR_JOINING = /[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/;
30674
- /** 可换行断点:空格、制表符等 */ var IS_BREAK_CHAR = function(ch) {
30675
- return ch === " " || ch === " " || ch === "\xa0";
30676
- };
30677
30722
  var seed$1 = 0;
30678
30723
  exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
30679
30724
  _inherits(TextComponent, MaskableGraphic);
@@ -30774,13 +30819,15 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
30774
30819
  var lineCount = 1;
30775
30820
  var x = 0;
30776
30821
  var charCountInLine = 0;
30822
+ // 使用码点遍历,正确处理 emoji 与 CJK 扩展 B 等代理对字符
30823
+ var chars = Array.from(text);
30777
30824
  if (context) {
30778
30825
  context.font = this.getFontDesc(this.textStyle.fontSize);
30779
30826
  }
30780
30827
  if (overflow === TextOverflow.display) {
30781
- for(var i = 0; i < text.length; i++){
30828
+ for(var _iterator = _create_for_of_iterator_helper_loose(chars), _step; !(_step = _iterator()).done;){
30829
+ var str = _step.value;
30782
30830
  var _context_measureText;
30783
- var str = text[i];
30784
30831
  var _context_measureText_width;
30785
30832
  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;
30786
30833
  if (str === "\n") {
@@ -30799,12 +30846,12 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
30799
30846
  return lineCount;
30800
30847
  }
30801
30848
  if (this.textLayout.keepWordIntact) {
30802
- // 单词完整换行:优先在空格处断行,避免从单词中间断开
30849
+ // 单词完整换行:优先在换行机会处断行(空格吞断 / CJK 字间可断),避免从西文词中间断开
30803
30850
  var lastBreakX = 0;
30804
30851
  var countAtBreak = 0;
30805
- for(var i1 = 0; i1 < text.length; i1++){
30852
+ for(var _iterator1 = _create_for_of_iterator_helper_loose(chars), _step1; !(_step1 = _iterator1()).done;){
30853
+ var str1 = _step1.value;
30806
30854
  var _context_measureText1;
30807
- var str1 = text[i1];
30808
30855
  var _context_measureText_width1;
30809
30856
  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;
30810
30857
  if (str1 === "\n") {
@@ -30837,22 +30884,23 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
30837
30884
  }
30838
30885
  x += textMetrics1;
30839
30886
  charCountInLine++;
30840
- if (IS_BREAK_CHAR(str1)) {
30887
+ // 记换行机会:str 之后可断(空格 swallow / CJK keep)。lastBreakX 含 str 宽度(str 留本行末)
30888
+ if (breakOpportunityAfter(str1) !== false) {
30841
30889
  lastBreakX = x;
30842
30890
  countAtBreak = charCountInLine;
30843
30891
  }
30844
30892
  }
30845
30893
  } else {
30846
30894
  // 逐字符换行:允许在任意字符处断开
30847
- for(var i2 = 0; i2 < text.length; i2++){
30895
+ for(var i = 0; i < chars.length; i++){
30848
30896
  var _context_measureText2;
30849
- var str2 = text[i2];
30897
+ var str2 = chars[i];
30850
30898
  var _context_measureText_width2;
30851
30899
  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;
30852
30900
  if (charCountInLine > 0) {
30853
30901
  x += letterSpace;
30854
30902
  }
30855
- if (x + textMetrics2 > width && i2 > 0 || str2 === "\n") {
30903
+ if (x + textMetrics2 > width && i > 0 || str2 === "\n") {
30856
30904
  lineCount++;
30857
30905
  this.maxLineWidth = Math.max(this.maxLineWidth, x);
30858
30906
  x = 0;
@@ -30945,8 +30993,11 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
30945
30993
  var charsArray = [];
30946
30994
  var charOffsetX = [];
30947
30995
  if (layout.keepWordIntact) {
30948
- // 单词完整换行:优先在空格处断行,避免从单词中间断开
30996
+ // 单词完整换行:优先在换行机会处断行(空格吞断 / CJK 字间可断),避免从西文词中间断开。
30997
+ // lastBreakIdx 指向断点字符在 charsArray 中的索引;breakSwallow=true 时该字符被吞(空格),
30998
+ // false 时该字符留本行末(CJK),下行均从 lastBreakIdx+1 起。
30949
30999
  var lastBreakIdx = -1;
31000
+ var breakSwallow = false;
30950
31001
  for(var i = 0; i < char.length; i++){
30951
31002
  var str = char[i];
30952
31003
  var textMetrics = context.measureText(str);
@@ -30962,15 +31013,18 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
30962
31013
  charsArray = [];
30963
31014
  charOffsetX = [];
30964
31015
  lastBreakIdx = -1;
31016
+ breakSwallow = false;
30965
31017
  continue;
30966
31018
  }
30967
31019
  var spacing = charsArray.length > 0 ? layout.letterSpace : 0;
30968
31020
  var willWidth = x + spacing + textMetrics.width;
30969
31021
  if (willWidth > baseWidth && charsArray.length > 0) {
30970
31022
  if (lastBreakIdx > 0) {
30971
- // 在空格处换行
30972
- var lineChars = charsArray.slice(0, lastBreakIdx);
30973
- var lineOffsets = charOffsetX.slice(0, lastBreakIdx);
31023
+ // 在换行机会处断行:swallow 取 [0,lastBreakIdx)(吞掉断点字符),
31024
+ // keep [0,lastBreakIdx](断点字符留本行末),下行均从 lastBreakIdx+1 起。
31025
+ var endIdx = breakSwallow ? lastBreakIdx : lastBreakIdx + 1;
31026
+ var lineChars = charsArray.slice(0, endIdx);
31027
+ var lineOffsets = charOffsetX.slice(0, endIdx);
30974
31028
  var lineWidth = lineChars.length > 0 ? lineOffsets[lineOffsets.length - 1] + context.measureText(lineChars[lineChars.length - 1]).width : 0;
30975
31029
  charsInfo.push({
30976
31030
  y: y,
@@ -30991,6 +31045,7 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
30991
31045
  x += context.measureText(charsArray[j]).width;
30992
31046
  }
30993
31047
  lastBreakIdx = -1;
31048
+ breakSwallow = false;
30994
31049
  } else {
30995
31050
  charsInfo.push({
30996
31051
  y: y,
@@ -31003,6 +31058,7 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
31003
31058
  charsArray = [];
31004
31059
  charOffsetX = [];
31005
31060
  lastBreakIdx = -1;
31061
+ breakSwallow = false;
31006
31062
  }
31007
31063
  }
31008
31064
  if (charsArray.length > 0) {
@@ -31011,8 +31067,12 @@ exports.TextComponent = /*#__PURE__*/ function(MaskableGraphic) {
31011
31067
  charOffsetX.push(x);
31012
31068
  charsArray.push(str);
31013
31069
  x += textMetrics.width;
31014
- if (IS_BREAK_CHAR(str)) {
31070
+ // 记换行机会:str 之后可断。lastBreakIdx 指向 str(charsArray 末尾),
31071
+ // swallow=吞 str(空格),keep=str 留本行末(CJK)。
31072
+ var opp = breakOpportunityAfter(str);
31073
+ if (opp !== false) {
31015
31074
  lastBreakIdx = charsArray.length - 1;
31075
+ breakSwallow = opp === "swallow";
31016
31076
  }
31017
31077
  }
31018
31078
  } else {
@@ -33650,7 +33710,7 @@ function getStandardSpriteContent(sprite, transform) {
33650
33710
  return ret;
33651
33711
  }
33652
33712
 
33653
- var version$1 = "2.9.1";
33713
+ var version$1 = "2.9.3";
33654
33714
  var v0 = /^(\d+)\.(\d+)\.(\d+)(-(\w+)\.\d+)?$/;
33655
33715
  var standardVersion = /^(\d+)\.(\d+)$/;
33656
33716
  var reverseParticle = false;
@@ -38704,7 +38764,7 @@ registerPlugin("text", TextLoader);
38704
38764
  registerPlugin("sprite", SpriteLoader);
38705
38765
  registerPlugin("particle", ParticleLoader);
38706
38766
  registerPlugin("interact", InteractLoader);
38707
- var version = "2.9.1";
38767
+ var version = "2.9.3";
38708
38768
  logger.info("Core version: " + version + ".");
38709
38769
 
38710
38770
  exports.ActivationMixerPlayable = ActivationMixerPlayable;
@@ -38891,6 +38951,7 @@ exports.applyMixins = applyMixins;
38891
38951
  exports.assertExist = assertExist;
38892
38952
  exports.asserts = asserts;
38893
38953
  exports.base64ToFile = base64ToFile;
38954
+ exports.breakOpportunityAfter = breakOpportunityAfter;
38894
38955
  exports.buildBezierData = buildBezierData;
38895
38956
  exports.buildEasingCurve = buildEasingCurve;
38896
38957
  exports.buildLine = buildLine;
@@ -38956,6 +39017,8 @@ exports.interpolateColor = interpolateColor;
38956
39017
  exports.isAlipayMiniApp = isAlipayMiniApp;
38957
39018
  exports.isAndroid = isAndroid;
38958
39019
  exports.isArray = isArray;
39020
+ exports.isBreakChar = isBreakChar;
39021
+ exports.isCJKLike = isCJKLike;
38959
39022
  exports.isCanvas = isCanvas;
38960
39023
  exports.isFunction = isFunction;
38961
39024
  exports.isIOS = isIOS;