locusing 0.1.2 → 0.1.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
@@ -1129,6 +1129,20 @@ var init_diagram = __esm({
1129
1129
  constructor(shape) {
1130
1130
  this.shape = shape;
1131
1131
  }
1132
+ /**
1133
+ * 设置目标状态(Manim 风格)
1134
+ * 用于 MoveToTarget 动画
1135
+ */
1136
+ setTarget(targetDiagram) {
1137
+ this.target = targetDiagram;
1138
+ return this;
1139
+ }
1140
+ /**
1141
+ * 获取目标状态
1142
+ */
1143
+ getTarget() {
1144
+ return this.target;
1145
+ }
1132
1146
  // ========== 样式方法 ==========
1133
1147
  /** 设置填充颜色 */
1134
1148
  fill(color) {
@@ -3074,44 +3088,97 @@ function braceBetweenPoints(start, end, options) {
3074
3088
  const {
3075
3089
  direction = 1,
3076
3090
  // 1 = 垂直于连线的正方向,-1 = 反方向
3077
- sharpness = 0.3,
3078
- tipExtent = 0.2
3091
+ sharpness = 2,
3092
+ // Manim 默认值
3093
+ tipExtent: _tipExtent = 0.2
3094
+ // 保留向后兼容但不使用
3079
3095
  } = options || {};
3080
3096
  const dx = end[0] - start[0];
3081
3097
  const dy = end[1] - start[1];
3082
3098
  const length2 = Math.sqrt(dx * dx + dy * dy);
3083
- if (length2 < 1) {
3099
+ if (length2 < 1e-3) {
3084
3100
  return path([]);
3085
3101
  }
3086
3102
  const ux = dx / length2;
3087
3103
  const uy = dy / length2;
3088
3104
  const perpX = -uy * direction;
3089
3105
  const perpY = ux * direction;
3090
- const height = length2 * tipExtent;
3091
- const curveDepth = length2 * sharpness * 0.15;
3106
+ const braceHeight = length2 * 0.09;
3107
+ const curlHeight = braceHeight * 0.35;
3108
+ const curlWidth = length2 * 0.02;
3109
+ const defaultMinWidth = 0.90552;
3110
+ const linearRatio = Math.max(0, (sharpness - defaultMinWidth) / 2);
3111
+ const linearLength = linearRatio * length2;
3112
+ const curveWidth = length2 / 2 - linearLength - curlWidth;
3092
3113
  const midX = (start[0] + end[0]) / 2;
3093
3114
  const midY = (start[1] + end[1]) / 2;
3094
- const tipX = midX + perpX * height;
3095
- const tipY = midY + perpY * height;
3096
- const q1X = start[0] + dx * 0.25;
3097
- const q1Y = start[1] + dy * 0.25;
3098
- const q3X = start[0] + dx * 0.75;
3099
- const q3Y = start[1] + dy * 0.75;
3100
- const ctrl1X = start[0] + perpX * curveDepth;
3101
- const ctrl1Y = start[1] + perpY * curveDepth;
3102
- const ctrl2X = q1X + perpX * height * 0.6;
3103
- const ctrl2Y = q1Y + perpY * height * 0.6;
3104
- const ctrl5X = q3X + perpX * height * 0.6;
3105
- const ctrl5Y = q3Y + perpY * height * 0.6;
3106
- const ctrl6X = end[0] + perpX * curveDepth;
3107
- const ctrl6Y = end[1] + perpY * curveDepth;
3115
+ const tipX = midX + perpX * braceHeight;
3116
+ const tipY = midY + perpY * braceHeight;
3117
+ const leftCurlEndX = start[0] + ux * curlWidth - perpX * curlHeight;
3118
+ const leftCurlEndY = start[1] + uy * curlWidth - perpY * curlHeight;
3119
+ const leftLineEndX = leftCurlEndX + ux * linearLength;
3120
+ const leftLineEndY = leftCurlEndY + uy * linearLength;
3121
+ const rightLineStartX = end[0] - ux * (curlWidth + linearLength) - perpX * curlHeight;
3122
+ const rightLineStartY = end[1] - uy * (curlWidth + linearLength) - perpY * curlHeight;
3123
+ const rightCurlStartX = rightLineStartX + ux * linearLength;
3124
+ const rightCurlStartY = rightLineStartY + uy * linearLength;
3108
3125
  const commands = [
3109
3126
  { type: "M", x: start[0], y: start[1] },
3110
- { type: "C", x1: ctrl1X, y1: ctrl1Y, x2: ctrl2X, y2: ctrl2Y, x: tipX - ux * length2 * 0.05, y: tipY - uy * length2 * 0.05 },
3111
- { type: "Q", x1: tipX, y1: tipY, x: tipX + ux * length2 * 0.05, y: tipY + uy * length2 * 0.05 },
3112
- { type: "C", x1: ctrl5X, y1: ctrl5Y, x2: ctrl6X, y2: ctrl6Y, x: end[0], y: end[1] }
3127
+ // 左端卷曲:明显的向外翘小勾
3128
+ // 控制点1向外凸出,控制点2稍微回来
3129
+ {
3130
+ type: "C",
3131
+ x1: start[0] - perpX * curlHeight * 1.2,
3132
+ y1: start[1] - perpY * curlHeight * 1.2,
3133
+ x2: leftCurlEndX - perpX * curlHeight * 0.3,
3134
+ y2: leftCurlEndY - perpY * curlHeight * 0.3,
3135
+ x: leftCurlEndX,
3136
+ y: leftCurlEndY
3137
+ },
3138
+ // 左直线段
3139
+ ...linearLength > 1e-3 ? [{
3140
+ type: "L",
3141
+ x: leftLineEndX,
3142
+ y: leftLineEndY
3143
+ }] : [],
3144
+ // 左曲线到尖端:平滑的弧线
3145
+ {
3146
+ type: "C",
3147
+ x1: leftLineEndX + ux * curveWidth * 0.55,
3148
+ y1: leftLineEndY + uy * curveWidth * 0.55,
3149
+ x2: tipX - ux * curveWidth * 0.25,
3150
+ y2: tipY - uy * curveWidth * 0.25,
3151
+ x: tipX,
3152
+ y: tipY
3153
+ },
3154
+ // 右曲线从尖端:与左侧对称
3155
+ {
3156
+ type: "C",
3157
+ x1: tipX + ux * curveWidth * 0.25,
3158
+ y1: tipY + uy * curveWidth * 0.25,
3159
+ x2: rightLineStartX - ux * curveWidth * 0.55,
3160
+ y2: rightLineStartY - uy * curveWidth * 0.55,
3161
+ x: rightLineStartX,
3162
+ y: rightLineStartY
3163
+ },
3164
+ // 右直线段
3165
+ ...linearLength > 1e-3 ? [{
3166
+ type: "L",
3167
+ x: rightCurlStartX,
3168
+ y: rightCurlStartY
3169
+ }] : [],
3170
+ // 右端卷曲:明显的向外翘小勾
3171
+ {
3172
+ type: "C",
3173
+ x1: rightCurlStartX - perpX * curlHeight * 0.3,
3174
+ y1: rightCurlStartY - perpY * curlHeight * 0.3,
3175
+ x2: end[0] - perpX * curlHeight * 1.2,
3176
+ y2: end[1] - perpY * curlHeight * 1.2,
3177
+ x: end[0],
3178
+ y: end[1]
3179
+ }
3113
3180
  ];
3114
- return path(commands).fill("none").stroke("#374151").strokeWidth(2);
3181
+ return path(commands).fill("none").stroke("#FFFFFF").strokeWidth(2);
3115
3182
  }
3116
3183
  function brace(target, options) {
3117
3184
  var _a;
@@ -3152,22 +3219,27 @@ function brace(target, options) {
3152
3219
  end = [bounds.x - buff, bounds.y + bounds.height];
3153
3220
  }
3154
3221
  }
3155
- const braceDir = 1;
3222
+ let braceDir;
3223
+ if (Math.abs(normDir[1]) > 0.5) {
3224
+ braceDir = normDir[1] > 0 ? 1 : -1;
3225
+ } else {
3226
+ braceDir = normDir[0] > 0 ? -1 : 1;
3227
+ }
3156
3228
  return braceBetweenPoints(start, end, { direction: braceDir, sharpness });
3157
3229
  }
3158
- function getBraceTipPosition(start, end, direction, tipExtent) {
3230
+ function getBraceTipPosition(start, end, direction, _tipExtent) {
3159
3231
  const dx = end[0] - start[0];
3160
3232
  const dy = end[1] - start[1];
3161
3233
  const length2 = Math.sqrt(dx * dx + dy * dy);
3162
- if (length2 < 1) return [(start[0] + end[0]) / 2, (start[1] + end[1]) / 2];
3234
+ if (length2 < 1e-3) return [(start[0] + end[0]) / 2, (start[1] + end[1]) / 2];
3163
3235
  const ux = dx / length2;
3164
3236
  const uy = dy / length2;
3165
3237
  const perpX = -uy * direction;
3166
3238
  const perpY = ux * direction;
3167
3239
  const midX = (start[0] + end[0]) / 2;
3168
3240
  const midY = (start[1] + end[1]) / 2;
3169
- const height = length2 * tipExtent;
3170
- return [midX + perpX * height, midY + perpY * height];
3241
+ const braceHeight = length2 * 0.09;
3242
+ return [midX + perpX * braceHeight, midY + perpY * braceHeight];
3171
3243
  }
3172
3244
  function braceLabel(target, label, options) {
3173
3245
  var _a;
@@ -3179,7 +3251,8 @@ function braceLabel(target, label, options) {
3179
3251
  sharpness = 0.3,
3180
3252
  buff = 0.1,
3181
3253
  // 使用适合数学坐标系的默认值
3182
- labelBuff = 0.15
3254
+ labelBuff = 0.35
3255
+ // 增大默认值,让标签在花括号外侧
3183
3256
  } = options || {};
3184
3257
  const br = brace(target, { direction, sharpness, buff });
3185
3258
  let dir;
@@ -3213,7 +3286,13 @@ function braceLabel(target, label, options) {
3213
3286
  end = [bounds.x - buff, bounds.y + bounds.height];
3214
3287
  }
3215
3288
  }
3216
- const tipPos = getBraceTipPosition(start, end, 1, 0.2);
3289
+ let braceDir;
3290
+ if (Math.abs(normDir[1]) > 0.5) {
3291
+ braceDir = normDir[1] > 0 ? 1 : -1;
3292
+ } else {
3293
+ braceDir = normDir[0] > 0 ? -1 : 1;
3294
+ }
3295
+ const tipPos = getBraceTipPosition(start, end, braceDir, 0.2);
3217
3296
  const labelX = tipPos[0] + normDir[0] * labelBuff;
3218
3297
  const labelY = tipPos[1] + normDir[1] * labelBuff;
3219
3298
  const labelText = text(label, { fontSize }).fill(labelColor).translate(labelX, labelY);
@@ -3338,7 +3417,7 @@ function pathFromString(d) {
3338
3417
  }
3339
3418
  function text(content, options) {
3340
3419
  const {
3341
- fontSize = 16,
3420
+ fontSize = 1,
3342
3421
  fontFamily = "system-ui, sans-serif",
3343
3422
  fontWeight = "normal",
3344
3423
  fontStyle = "normal",
@@ -3366,7 +3445,7 @@ function text(content, options) {
3366
3445
  return new Diagram(shape);
3367
3446
  }
3368
3447
  function tex(latex, options) {
3369
- const { fontSize = 20, color = "#374151" } = options || {};
3448
+ const { fontSize = 1, color = "#374151" } = options || {};
3370
3449
  const html = import_katex.default.renderToString(latex, {
3371
3450
  throwOnError: false,
3372
3451
  displayMode: false,
@@ -3427,27 +3506,95 @@ function bulletedList(items, options) {
3427
3506
  }
3428
3507
  function code(source, options) {
3429
3508
  const {
3430
- fontSize = 14,
3509
+ fontSize = 0.25,
3510
+ // 使用适合数学坐标系的默认值
3431
3511
  theme = "dark",
3432
- showLineNumbers = false,
3433
- lineNumberWidth = 30,
3434
- lineHeight = 1.3
3512
+ showLineNumbers = true,
3513
+ // 默认显示行号
3514
+ lineNumberWidth = 0.5,
3515
+ lineHeight = 1.4,
3516
+ showBackground = true,
3517
+ // 默认显示背景
3518
+ showWindowButtons = true,
3519
+ // 默认显示窗口按钮
3520
+ language = "javascript",
3521
+ padding = 0.3
3435
3522
  } = options || {};
3436
3523
  const fontFamily = 'Consolas, Monaco, "Courier New", monospace';
3437
3524
  const lines = source.split("\n");
3438
3525
  const lineSpacing = fontSize * lineHeight;
3439
- const textColor = theme === "dark" ? "#E5E7EB" : "#374151";
3440
- const lineNumColor = theme === "dark" ? "#6B7280" : "#9CA3AF";
3526
+ const bgColor = theme === "dark" ? "#1E1E2E" : "#F8F8F8";
3527
+ const textColor = theme === "dark" ? "#CDD6F4" : "#374151";
3528
+ const lineNumColor = theme === "dark" ? "#6C7086" : "#9CA3AF";
3529
+ const keywordColor = theme === "dark" ? "#CBA6F7" : "#7C3AED";
3530
+ const stringColor = theme === "dark" ? "#A6E3A1" : "#059669";
3531
+ const numberColor = theme === "dark" ? "#FAB387" : "#D97706";
3532
+ const commentColor = theme === "dark" ? "#6C7086" : "#9CA3AF";
3533
+ const keywords = ["const", "let", "var", "function", "return", "if", "else", "for", "while", "class", "import", "export", "from", "async", "await", "new", "this", "true", "false", "null", "undefined"];
3534
+ const highlightLine = (lineContent) => {
3535
+ const tokens = [];
3536
+ let x = 0;
3537
+ const regex = /(\s+)|("[^"]*"|'[^']*')|(\d+\.?\d*)|(\b\w+\b)|(\/\/.*$)|([^\s\w"']+)/g;
3538
+ let match;
3539
+ while ((match = regex.exec(lineContent)) !== null) {
3540
+ const token = match[0];
3541
+ let color = textColor;
3542
+ if (match[1]) {
3543
+ x += token.length * fontSize * 0.6;
3544
+ continue;
3545
+ } else if (match[2]) {
3546
+ color = stringColor;
3547
+ } else if (match[3]) {
3548
+ color = numberColor;
3549
+ } else if (match[4] && keywords.includes(token)) {
3550
+ color = keywordColor;
3551
+ } else if (match[5]) {
3552
+ color = commentColor;
3553
+ }
3554
+ const tokenText = text(token, { fontSize, fontFamily, anchor: "start" }).fill(color).translate(x, 0);
3555
+ tokens.push(tokenText);
3556
+ x += token.length * fontSize * 0.6;
3557
+ }
3558
+ return tokens;
3559
+ };
3441
3560
  const elements = [];
3561
+ const maxLineLength = Math.max(...lines.map((l) => l.length), 1);
3562
+ const contentWidth = (showLineNumbers ? lineNumberWidth : 0) + maxLineLength * fontSize * 0.6 + padding;
3563
+ const contentHeight = lines.length * lineSpacing + padding * 2;
3564
+ const headerHeight = showWindowButtons ? 0.4 : 0;
3565
+ const totalHeight = contentHeight + headerHeight;
3566
+ if (showBackground) {
3567
+ const cornerRadius = 0.15;
3568
+ const bg = rect(contentWidth + padding * 2, totalHeight, { rx: cornerRadius, ry: cornerRadius }).fill(bgColor).translate(contentWidth / 2, -totalHeight / 2 + headerHeight + padding);
3569
+ elements.push(bg);
3570
+ }
3571
+ if (showWindowButtons && showBackground) {
3572
+ const buttonY = headerHeight / 2 + padding * 0.5;
3573
+ const buttonRadius = 0.08;
3574
+ const buttonSpacing = 0.25;
3575
+ const buttonStartX = padding + 0.2;
3576
+ const redBtn = circle(buttonRadius).fill("#FF5F56").translate(buttonStartX, buttonY);
3577
+ const yellowBtn = circle(buttonRadius).fill("#FFBD2E").translate(buttonStartX + buttonSpacing, buttonY);
3578
+ const greenBtn = circle(buttonRadius).fill("#27C93F").translate(buttonStartX + buttonSpacing * 2, buttonY);
3579
+ elements.push(redBtn, yellowBtn, greenBtn);
3580
+ }
3581
+ const codeStartY = showWindowButtons ? -headerHeight : 0;
3442
3582
  lines.forEach((lineContent, i) => {
3443
- const y = -i * lineSpacing;
3583
+ const y = codeStartY - i * lineSpacing - padding;
3444
3584
  if (showLineNumbers) {
3445
- const lineNum = text(String(i + 1), { fontSize, fontFamily, anchor: "end" }).fill(lineNumColor).translate(lineNumberWidth - 5, y);
3585
+ const lineNum = text(String(i + 1), { fontSize, fontFamily, anchor: "end" }).fill(lineNumColor).translate(lineNumberWidth + padding - 0.05, y);
3446
3586
  elements.push(lineNum);
3447
3587
  }
3448
- const xOffset = showLineNumbers ? lineNumberWidth + 10 : 0;
3449
- const codeLine = text(lineContent || " ", { fontSize, fontFamily, anchor: "start" }).fill(textColor).translate(xOffset, y);
3450
- elements.push(codeLine);
3588
+ const xOffset = (showLineNumbers ? lineNumberWidth + 0.15 : 0) + padding;
3589
+ if (language && lineContent.trim()) {
3590
+ const highlightedTokens = highlightLine(lineContent);
3591
+ highlightedTokens.forEach((token) => {
3592
+ elements.push(token.translate(xOffset, y));
3593
+ });
3594
+ } else {
3595
+ const codeLine = text(lineContent || " ", { fontSize, fontFamily, anchor: "start" }).fill(textColor).translate(xOffset, y);
3596
+ elements.push(codeLine);
3597
+ }
3451
3598
  });
3452
3599
  if (elements.length === 0) {
3453
3600
  return group();
@@ -3456,11 +3603,104 @@ function code(source, options) {
3456
3603
  }
3457
3604
  function markupText(content, options) {
3458
3605
  const {
3459
- fontSize = 16,
3460
- fontFamily = "system-ui, sans-serif"
3606
+ fontSize = 0.4,
3607
+ // 使用适合数学坐标系的默认值
3608
+ fontFamily = "system-ui, sans-serif",
3609
+ color = "#FFFFFF"
3461
3610
  } = options || {};
3462
- const plainText = content.replace(/<b>|<\/b>/g, "").replace(/<i>|<\/i>/g, "").replace(/<color=[^>]*>|<\/color>/g, "").replace(/<sub>|<\/sub>/g, "").replace(/<sup>|<\/sup>/g, "");
3463
- return text(plainText, { fontSize, fontFamily });
3611
+ const parseMarkup = (input) => {
3612
+ const segments2 = [];
3613
+ let currentText = "";
3614
+ let bold = false;
3615
+ let italic = false;
3616
+ let currentColor;
3617
+ let i = 0;
3618
+ while (i < input.length) {
3619
+ if (input.slice(i).startsWith("<b>")) {
3620
+ if (currentText) {
3621
+ segments2.push({ text: currentText, bold, italic, color: currentColor });
3622
+ currentText = "";
3623
+ }
3624
+ bold = true;
3625
+ i += 3;
3626
+ continue;
3627
+ }
3628
+ if (input.slice(i).startsWith("</b>")) {
3629
+ if (currentText) {
3630
+ segments2.push({ text: currentText, bold, italic, color: currentColor });
3631
+ currentText = "";
3632
+ }
3633
+ bold = false;
3634
+ i += 4;
3635
+ continue;
3636
+ }
3637
+ if (input.slice(i).startsWith("<i>")) {
3638
+ if (currentText) {
3639
+ segments2.push({ text: currentText, bold, italic, color: currentColor });
3640
+ currentText = "";
3641
+ }
3642
+ italic = true;
3643
+ i += 3;
3644
+ continue;
3645
+ }
3646
+ if (input.slice(i).startsWith("</i>")) {
3647
+ if (currentText) {
3648
+ segments2.push({ text: currentText, bold, italic, color: currentColor });
3649
+ currentText = "";
3650
+ }
3651
+ italic = false;
3652
+ i += 4;
3653
+ continue;
3654
+ }
3655
+ const colorMatch = input.slice(i).match(/^<color=([^>]+)>/);
3656
+ if (colorMatch) {
3657
+ if (currentText) {
3658
+ segments2.push({ text: currentText, bold, italic, color: currentColor });
3659
+ currentText = "";
3660
+ }
3661
+ currentColor = colorMatch[1];
3662
+ i += colorMatch[0].length;
3663
+ continue;
3664
+ }
3665
+ if (input.slice(i).startsWith("</color>")) {
3666
+ if (currentText) {
3667
+ segments2.push({ text: currentText, bold, italic, color: currentColor });
3668
+ currentText = "";
3669
+ }
3670
+ currentColor = void 0;
3671
+ i += 8;
3672
+ continue;
3673
+ }
3674
+ currentText += input[i];
3675
+ i++;
3676
+ }
3677
+ if (currentText) {
3678
+ segments2.push({ text: currentText, bold, italic, color: currentColor });
3679
+ }
3680
+ return segments2;
3681
+ };
3682
+ const segments = parseMarkup(content);
3683
+ const elements = [];
3684
+ let x = 0;
3685
+ segments.forEach((segment) => {
3686
+ if (!segment.text) return;
3687
+ const fontWeight = segment.bold ? "bold" : "normal";
3688
+ const fontStyle = segment.italic ? "italic" : "normal";
3689
+ const textColor = segment.color || color;
3690
+ const segmentText = text(segment.text, {
3691
+ fontSize,
3692
+ fontFamily,
3693
+ fontWeight,
3694
+ fontStyle,
3695
+ anchor: "start"
3696
+ }).fill(textColor).translate(x, 0);
3697
+ elements.push(segmentText);
3698
+ x += segment.text.length * fontSize * 0.6;
3699
+ });
3700
+ if (elements.length === 0) {
3701
+ return text("", { fontSize, fontFamily });
3702
+ }
3703
+ return elements[0].combine(...elements.slice(1));
3464
3704
  }
3465
3705
  function crossMark(size, options) {
3466
3706
  const { strokeWidth = 2, style = "x" } = options || {};
@@ -4588,507 +4828,114 @@ var init_core = __esm({
4588
4828
  }
4589
4829
  });
4590
4830
 
4591
- // src/animate/animations/utils.ts
4592
- function querySelectorAllIncludingSelf(element, selector) {
4593
- const results = Array.from(element.querySelectorAll(selector));
4594
- if (element.matches(selector)) {
4595
- results.unshift(element);
4596
- }
4597
- return results;
4598
- }
4599
- var init_utils = __esm({
4600
- "src/animate/animations/utils.ts"() {
4601
- "use strict";
4602
- }
4603
- });
4604
-
4605
- // src/animate/animations/transform.ts
4606
- var transform_exports = {};
4607
- __export(transform_exports, {
4831
+ // src/index.ts
4832
+ var index_exports = {};
4833
+ __export(index_exports, {
4834
+ AddTextLetterByLetter: () => AddTextLetterByLetter,
4835
+ AddTextWordByWord: () => AddTextWordByWord,
4836
+ AnimationGroup: () => AnimationGroup,
4837
+ ApplyComplexFunction: () => ApplyComplexFunction,
4838
+ ApplyFunction: () => ApplyFunction,
4839
+ ApplyMethod: () => ApplyMethod,
4840
+ ApplyWave: () => ApplyWave,
4841
+ Axes: () => Axes,
4842
+ Blink: () => Blink,
4843
+ Broadcast: () => Broadcast,
4844
+ Camera: () => Camera,
4845
+ CameraAutoZoom: () => CameraAutoZoom,
4846
+ CameraMove: () => CameraMove,
4847
+ CameraReset: () => CameraReset,
4848
+ CameraSetFrame: () => CameraSetFrame,
4849
+ CameraZoom: () => CameraZoom,
4850
+ ChangingDecimal: () => ChangingDecimal,
4851
+ Circumscribe: () => Circumscribe,
4608
4852
  ClockwiseTransform: () => ClockwiseTransform,
4853
+ ColorScales: () => ColorScales,
4854
+ Colors: () => Colors,
4855
+ ComplexValueTracker: () => ComplexValueTracker,
4609
4856
  CounterclockwiseTransform: () => CounterclockwiseTransform,
4857
+ Create: () => Create,
4858
+ CyclicReplace: () => CyclicReplace,
4859
+ DEGREES: () => DEGREES,
4860
+ DL: () => DL,
4861
+ DOWN: () => DOWN,
4862
+ DR: () => DR,
4863
+ DiGraph: () => DiGraph,
4864
+ Diagram: () => Diagram,
4865
+ Dir: () => Dir,
4866
+ DrawBorderThenFill: () => DrawBorderThenFill,
4867
+ FadeIn: () => FadeIn,
4868
+ FadeInFrom: () => FadeInFrom,
4869
+ FadeInFromDown: () => FadeInFromDown,
4870
+ FadeInFromLeft: () => FadeInFromLeft,
4871
+ FadeInFromRight: () => FadeInFromRight,
4872
+ FadeInFromUp: () => FadeInFromUp,
4873
+ FadeOut: () => FadeOut,
4874
+ FadeOutTo: () => FadeOutTo,
4875
+ FadeToColor: () => FadeToColor,
4876
+ FadeTransform: () => FadeTransform,
4877
+ Flash: () => Flash,
4878
+ FocusOn: () => FocusOn,
4879
+ Graph: () => Graph,
4880
+ Group: () => Group,
4881
+ GrowArrow: () => GrowArrow,
4882
+ GrowFromCenter: () => GrowFromCenter,
4883
+ GrowFromEdge: () => GrowFromEdge,
4884
+ GrowFromPoint: () => GrowFromPoint,
4885
+ Homotopy: () => Homotopy,
4886
+ IDENTITY: () => IDENTITY,
4887
+ Indicate: () => Indicate,
4888
+ Interactive: () => Interactive,
4889
+ LEFT: () => LEFT,
4890
+ LaggedStart: () => LaggedStart,
4891
+ LaggedStartMap: () => LaggedStartMap,
4892
+ LinearTransformationScene: () => LinearTransformationScene,
4893
+ ManimColor: () => ManimColor,
4894
+ MathTex: () => MathTex,
4895
+ MatrixDisplay: () => MatrixDisplay,
4610
4896
  Morphing: () => Morphing,
4897
+ MoveAlongPath: () => MoveAlongPath,
4898
+ MoveTo: () => MoveTo,
4611
4899
  MoveToTarget: () => MoveToTarget,
4900
+ MovingCamera: () => MovingCamera,
4901
+ MovingCameraScene: () => MovingCameraScene,
4902
+ NumberLine: () => NumberLine,
4903
+ NumberPlane: () => NumberPlane,
4904
+ ORIGIN: () => ORIGIN,
4905
+ PI: () => PI,
4906
+ PhaseFlow: () => PhaseFlow,
4907
+ Physics2DWorld: () => Physics2DWorld,
4908
+ PolarAxes: () => PolarAxes,
4909
+ RIGHT: () => RIGHT,
4910
+ RemoveTextLetterByLetter: () => RemoveTextLetterByLetter,
4612
4911
  ReplacementTransform: () => ReplacementTransform,
4613
- Transform: () => Transform,
4614
- TransformFromCopy: () => TransformFromCopy,
4615
- TransformMatchingShapes: () => TransformMatchingShapes,
4616
- TransformMatchingTex: () => TransformMatchingTex
4617
- });
4618
- function Transform(source, target, options = {}) {
4619
- const { duration = 1, easing: easing2 = "easeInOut", delay = 0 } = options;
4620
- return {
4621
- duration,
4622
- target: source,
4623
- execute(scene, timeline, startTime) {
4624
- var _a, _b;
4625
- const sourceElement = scene.getElement(source);
4626
- const targetElement = scene.getOrCreateElement(target);
4627
- if (!sourceElement || !targetElement) return;
4628
- import_gsap5.gsap.set(targetElement, { opacity: 0 });
4629
- const sourceBBox = ((_a = sourceElement.getBBox) == null ? void 0 : _a.call(sourceElement)) || { x: 0, y: 0, width: 0, height: 0 };
4630
- const targetBBox = ((_b = targetElement.getBBox) == null ? void 0 : _b.call(targetElement)) || { x: 0, y: 0, width: 0, height: 0 };
4631
- const scaleX = targetBBox.width / (sourceBBox.width || 1);
4632
- const scaleY = targetBBox.height / (sourceBBox.height || 1);
4633
- const translateX = targetBBox.x + targetBBox.width / 2 - (sourceBBox.x + sourceBBox.width / 2);
4634
- const translateY = targetBBox.y + targetBBox.height / 2 - (sourceBBox.y + sourceBBox.height / 2);
4635
- const originX = sourceBBox.x + sourceBBox.width / 2;
4636
- const originY = sourceBBox.y + sourceBBox.height / 2;
4637
- import_gsap5.gsap.set(sourceElement, {
4638
- transformOrigin: `${originX}px ${originY}px`
4639
- });
4640
- timeline.add(sourceElement, {
4641
- scaleX,
4642
- scaleY,
4643
- x: translateX,
4644
- y: translateY,
4645
- duration,
4646
- ease: getGSAPEasing(easing2),
4647
- delay,
4648
- onComplete: () => {
4649
- sourceElement.remove();
4650
- import_gsap5.gsap.set(targetElement, { opacity: 1 });
4651
- }
4652
- }, startTime);
4653
- }
4654
- };
4655
- }
4656
- function ReplacementTransform(source, target, options = {}) {
4657
- const { duration = 1, easing: easing2 = "easeInOut", delay = 0, replace = true } = options;
4658
- return {
4659
- duration,
4660
- target: source,
4661
- execute(scene, timeline, startTime) {
4662
- var _a, _b;
4663
- const sourceElement = scene.getElement(source);
4664
- const targetElement = scene.getOrCreateElement(target);
4665
- if (!sourceElement || !targetElement) return;
4666
- import_gsap5.gsap.set(targetElement, { opacity: 0, visibility: "hidden" });
4667
- const sourceBBox = ((_a = sourceElement.getBBox) == null ? void 0 : _a.call(sourceElement)) || { x: 0, y: 0, width: 0, height: 0 };
4668
- const targetBBox = ((_b = targetElement.getBBox) == null ? void 0 : _b.call(targetElement)) || { x: 0, y: 0, width: 0, height: 0 };
4669
- const scaleX = targetBBox.width / (sourceBBox.width || 1);
4670
- const scaleY = targetBBox.height / (sourceBBox.height || 1);
4671
- const sourceCenterX = sourceBBox.x + sourceBBox.width / 2;
4672
- const sourceCenterY = sourceBBox.y + sourceBBox.height / 2;
4673
- const targetCenterX = targetBBox.x + targetBBox.width / 2;
4674
- const targetCenterY = targetBBox.y + targetBBox.height / 2;
4675
- timeline.add(sourceElement, {
4676
- transformOrigin: `${sourceCenterX}px ${sourceCenterY}px`,
4677
- scaleX,
4678
- scaleY,
4679
- x: targetCenterX - sourceCenterX,
4680
- y: targetCenterY - sourceCenterY,
4681
- opacity: 0,
4682
- duration,
4683
- ease: getGSAPEasing(easing2),
4684
- delay,
4685
- onComplete: () => {
4686
- if (replace) {
4687
- sourceElement.remove();
4688
- }
4689
- }
4690
- }, startTime);
4691
- timeline.add(targetElement, {
4692
- visibility: "visible",
4693
- opacity: 1,
4694
- duration: duration * 0.5,
4695
- ease: "power2.out",
4696
- delay: delay + duration * 0.5
4697
- }, startTime);
4698
- }
4699
- };
4700
- }
4701
- function MoveToTarget(target, options = {}) {
4702
- const { duration = 1, easing: easing2 = "easeInOut", delay = 0 } = options;
4703
- return {
4704
- duration,
4705
- target,
4706
- execute(scene, timeline, startTime) {
4707
- const element = scene.getElement(target);
4708
- if (!element) return;
4709
- const targetState = target._targetState;
4710
- if (targetState) {
4711
- timeline.add(element, __spreadProps(__spreadValues({}, targetState), {
4712
- duration,
4713
- ease: getGSAPEasing(easing2),
4714
- delay
4715
- }), startTime);
4716
- }
4717
- }
4718
- };
4719
- }
4720
- function Morphing(source, target, options = {}) {
4721
- const { duration = 1, easing: easing2 = "easeInOut", delay = 0 } = options;
4722
- return {
4723
- duration,
4724
- target: source,
4725
- execute(scene, timeline, startTime) {
4726
- var _a;
4727
- const sourceElement = scene.getElement(source);
4728
- const targetElement = scene.getOrCreateElement(target);
4729
- if (!sourceElement || !targetElement) return;
4730
- const sourcePath = sourceElement.querySelector("path") || sourceElement;
4731
- const targetPath = targetElement.querySelector("path") || targetElement;
4732
- import_gsap5.gsap.set(targetElement, { opacity: 0 });
4733
- if ((_a = import_gsap5.gsap.plugins) == null ? void 0 : _a.morphSVG) {
4734
- const targetD = targetPath.getAttribute("d");
4735
- if (targetD) {
4736
- timeline.add(sourcePath, {
4737
- morphSVG: targetD,
4738
- duration,
4739
- ease: getGSAPEasing(easing2),
4740
- delay,
4741
- onComplete: () => {
4742
- sourceElement.remove();
4743
- import_gsap5.gsap.set(targetElement, { opacity: 1 });
4744
- }
4745
- }, startTime);
4746
- }
4747
- } else {
4748
- Transform(source, target, options).execute(scene, timeline, startTime);
4749
- }
4750
- }
4751
- };
4752
- }
4753
- function TransformMatchingShapes(source, target, options = {}) {
4754
- const { duration = 1, easing: easing2 = "easeInOut", delay = 0 } = options;
4755
- return {
4756
- duration,
4757
- target: source,
4758
- execute(scene, timeline, startTime) {
4759
- var _a, _b;
4760
- const sourceElement = scene.getElement(source);
4761
- const targetElement = scene.getOrCreateElement(target);
4762
- if (!sourceElement || !targetElement) return;
4763
- const sourceChildren = Array.from(sourceElement.children);
4764
- const targetChildren = Array.from(targetElement.children);
4765
- import_gsap5.gsap.set(targetElement, { opacity: 0 });
4766
- const pairs = Math.min(sourceChildren.length, targetChildren.length);
4767
- for (let i = 0; i < pairs; i++) {
4768
- const sourceChild = sourceChildren[i];
4769
- const targetChild = targetChildren[i];
4770
- const sourceBBox = ((_a = sourceChild.getBBox) == null ? void 0 : _a.call(sourceChild)) || { x: 0, y: 0, width: 0, height: 0 };
4771
- const targetBBox = ((_b = targetChild.getBBox) == null ? void 0 : _b.call(targetChild)) || { x: 0, y: 0, width: 0, height: 0 };
4772
- const scaleX = targetBBox.width / (sourceBBox.width || 1);
4773
- const scaleY = targetBBox.height / (sourceBBox.height || 1);
4774
- const translateX = targetBBox.x - sourceBBox.x;
4775
- const translateY = targetBBox.y - sourceBBox.y;
4776
- timeline.add(sourceChild, {
4777
- scaleX,
4778
- scaleY,
4779
- x: translateX,
4780
- y: translateY,
4781
- duration,
4782
- ease: getGSAPEasing(easing2),
4783
- delay
4784
- }, startTime);
4785
- }
4786
- for (let i = pairs; i < sourceChildren.length; i++) {
4787
- const child = sourceChildren[i];
4788
- if (child) {
4789
- timeline.add(child, {
4790
- opacity: 0,
4791
- duration: duration * 0.5,
4792
- ease: "power2.in"
4793
- }, startTime);
4794
- }
4795
- }
4796
- timeline.call(() => {
4797
- sourceElement.remove();
4798
- import_gsap5.gsap.set(targetElement, { opacity: 1 });
4799
- }, startTime + duration);
4800
- }
4801
- };
4802
- }
4803
- function TransformMatchingTex(source, target, options = {}) {
4804
- const { duration = 1, easing: easing2 = "easeInOut", delay = 0 } = options;
4805
- return {
4806
- duration,
4807
- target: source,
4808
- execute(scene, timeline, startTime) {
4809
- var _a, _b;
4810
- const sourceElement = scene.getElement(source);
4811
- const targetElement = scene.getOrCreateElement(target);
4812
- if (!sourceElement || !targetElement) return;
4813
- import_gsap5.gsap.set(targetElement, { opacity: 0 });
4814
- const sourceTexParts = querySelectorAllIncludingSelf(sourceElement, "path, use, text");
4815
- const targetTexParts = querySelectorAllIncludingSelf(targetElement, "path, use, text");
4816
- const pairs = Math.min(sourceTexParts.length, targetTexParts.length);
4817
- for (let i = 0; i < pairs; i++) {
4818
- const sourcePart = sourceTexParts[i];
4819
- const targetPart = targetTexParts[i];
4820
- const sourceBBox = ((_a = sourcePart.getBBox) == null ? void 0 : _a.call(sourcePart)) || { x: 0, y: 0, width: 0, height: 0 };
4821
- const targetBBox = ((_b = targetPart.getBBox) == null ? void 0 : _b.call(targetPart)) || { x: 0, y: 0, width: 0, height: 0 };
4822
- const scaleX = targetBBox.width / (sourceBBox.width || 1);
4823
- const scaleY = targetBBox.height / (sourceBBox.height || 1);
4824
- const translateX = targetBBox.x + targetBBox.width / 2 - (sourceBBox.x + sourceBBox.width / 2);
4825
- const translateY = targetBBox.y + targetBBox.height / 2 - (sourceBBox.y + sourceBBox.height / 2);
4826
- timeline.add(sourcePart, {
4827
- scaleX: isFinite(scaleX) ? scaleX : 1,
4828
- scaleY: isFinite(scaleY) ? scaleY : 1,
4829
- x: translateX,
4830
- y: translateY,
4831
- duration,
4832
- ease: getGSAPEasing(easing2),
4833
- delay
4834
- }, startTime);
4835
- }
4836
- for (let i = pairs; i < sourceTexParts.length; i++) {
4837
- const part = sourceTexParts[i];
4838
- if (part) {
4839
- timeline.add(part, {
4840
- opacity: 0,
4841
- duration: duration * 0.5,
4842
- ease: "power2.in"
4843
- }, startTime);
4844
- }
4845
- }
4846
- timeline.call(() => {
4847
- sourceElement.remove();
4848
- import_gsap5.gsap.set(targetElement, { opacity: 1 });
4849
- }, startTime + duration);
4850
- }
4851
- };
4852
- }
4853
- function ClockwiseTransform(source, target, options = {}) {
4854
- const { duration = 1, easing: easing2 = "easeInOut", delay = 0 } = options;
4855
- return {
4856
- duration,
4857
- target: source,
4858
- execute(scene, timeline, startTime) {
4859
- var _a, _b;
4860
- const sourceElement = scene.getElement(source);
4861
- const targetElement = scene.getOrCreateElement(target);
4862
- if (!sourceElement || !targetElement) return;
4863
- import_gsap5.gsap.set(targetElement, { opacity: 0 });
4864
- const sourceBBox = ((_a = sourceElement.getBBox) == null ? void 0 : _a.call(sourceElement)) || { x: 0, y: 0, width: 0, height: 0 };
4865
- const targetBBox = ((_b = targetElement.getBBox) == null ? void 0 : _b.call(targetElement)) || { x: 0, y: 0, width: 0, height: 0 };
4866
- const sourceCenterX = sourceBBox.x + sourceBBox.width / 2;
4867
- const sourceCenterY = sourceBBox.y + sourceBBox.height / 2;
4868
- const targetCenterX = targetBBox.x + targetBBox.width / 2;
4869
- const targetCenterY = targetBBox.y + targetBBox.height / 2;
4870
- const scaleX = targetBBox.width / (sourceBBox.width || 1);
4871
- const scaleY = targetBBox.height / (sourceBBox.height || 1);
4872
- import_gsap5.gsap.set(sourceElement, {
4873
- transformOrigin: `${sourceCenterX}px ${sourceCenterY}px`
4874
- });
4875
- timeline.add(sourceElement, {
4876
- rotation: 180,
4877
- scaleX: isFinite(scaleX) ? scaleX : 1,
4878
- scaleY: isFinite(scaleY) ? scaleY : 1,
4879
- x: targetCenterX - sourceCenterX,
4880
- y: targetCenterY - sourceCenterY,
4881
- opacity: 0,
4882
- duration,
4883
- ease: getGSAPEasing(easing2),
4884
- delay,
4885
- onComplete: () => {
4886
- sourceElement.remove();
4887
- import_gsap5.gsap.set(targetElement, { opacity: 1 });
4888
- }
4889
- }, startTime);
4890
- }
4891
- };
4892
- }
4893
- function CounterclockwiseTransform(source, target, options = {}) {
4894
- const { duration = 1, easing: easing2 = "easeInOut", delay = 0 } = options;
4895
- return {
4896
- duration,
4897
- target: source,
4898
- execute(scene, timeline, startTime) {
4899
- var _a, _b;
4900
- const sourceElement = scene.getElement(source);
4901
- const targetElement = scene.getOrCreateElement(target);
4902
- if (!sourceElement || !targetElement) return;
4903
- import_gsap5.gsap.set(targetElement, { opacity: 0 });
4904
- const sourceBBox = ((_a = sourceElement.getBBox) == null ? void 0 : _a.call(sourceElement)) || { x: 0, y: 0, width: 0, height: 0 };
4905
- const targetBBox = ((_b = targetElement.getBBox) == null ? void 0 : _b.call(targetElement)) || { x: 0, y: 0, width: 0, height: 0 };
4906
- const sourceCenterX = sourceBBox.x + sourceBBox.width / 2;
4907
- const sourceCenterY = sourceBBox.y + sourceBBox.height / 2;
4908
- const targetCenterX = targetBBox.x + targetBBox.width / 2;
4909
- const targetCenterY = targetBBox.y + targetBBox.height / 2;
4910
- const scaleX = targetBBox.width / (sourceBBox.width || 1);
4911
- const scaleY = targetBBox.height / (sourceBBox.height || 1);
4912
- import_gsap5.gsap.set(sourceElement, {
4913
- transformOrigin: `${sourceCenterX}px ${sourceCenterY}px`
4914
- });
4915
- timeline.add(sourceElement, {
4916
- rotation: -180,
4917
- scaleX: isFinite(scaleX) ? scaleX : 1,
4918
- scaleY: isFinite(scaleY) ? scaleY : 1,
4919
- x: targetCenterX - sourceCenterX,
4920
- y: targetCenterY - sourceCenterY,
4921
- opacity: 0,
4922
- duration,
4923
- ease: getGSAPEasing(easing2),
4924
- delay,
4925
- onComplete: () => {
4926
- sourceElement.remove();
4927
- import_gsap5.gsap.set(targetElement, { opacity: 1 });
4928
- }
4929
- }, startTime);
4930
- }
4931
- };
4932
- }
4933
- function TransformFromCopy(source, target, options = {}) {
4934
- const { duration = 1, easing: easing2 = "easeInOut", delay = 0 } = options;
4935
- return {
4936
- duration,
4937
- target: source,
4938
- execute(scene, timeline, startTime) {
4939
- var _a, _b, _c;
4940
- const sourceElement = scene.getElement(source);
4941
- const targetElement = scene.getOrCreateElement(target);
4942
- if (!sourceElement || !targetElement) return;
4943
- import_gsap5.gsap.set(targetElement, { opacity: 0 });
4944
- const copyElement = sourceElement.cloneNode(true);
4945
- copyElement.setAttribute("id", `${sourceElement.id}-copy-${Date.now()}`);
4946
- (_a = sourceElement.parentNode) == null ? void 0 : _a.appendChild(copyElement);
4947
- const sourceBBox = ((_b = sourceElement.getBBox) == null ? void 0 : _b.call(sourceElement)) || { x: 0, y: 0, width: 0, height: 0 };
4948
- const targetBBox = ((_c = targetElement.getBBox) == null ? void 0 : _c.call(targetElement)) || { x: 0, y: 0, width: 0, height: 0 };
4949
- const sourceCenterX = sourceBBox.x + sourceBBox.width / 2;
4950
- const sourceCenterY = sourceBBox.y + sourceBBox.height / 2;
4951
- const targetCenterX = targetBBox.x + targetBBox.width / 2;
4952
- const targetCenterY = targetBBox.y + targetBBox.height / 2;
4953
- const scaleX = targetBBox.width / (sourceBBox.width || 1);
4954
- const scaleY = targetBBox.height / (sourceBBox.height || 1);
4955
- import_gsap5.gsap.set(copyElement, {
4956
- transformOrigin: `${sourceCenterX}px ${sourceCenterY}px`
4957
- });
4958
- timeline.add(copyElement, {
4959
- scaleX: isFinite(scaleX) ? scaleX : 1,
4960
- scaleY: isFinite(scaleY) ? scaleY : 1,
4961
- x: targetCenterX - sourceCenterX,
4962
- y: targetCenterY - sourceCenterY,
4963
- opacity: 0,
4964
- duration,
4965
- ease: getGSAPEasing(easing2),
4966
- delay,
4967
- onComplete: () => {
4968
- copyElement.remove();
4969
- import_gsap5.gsap.set(targetElement, { opacity: 1 });
4970
- }
4971
- }, startTime);
4972
- }
4973
- };
4974
- }
4975
- var import_gsap5;
4976
- var init_transform = __esm({
4977
- "src/animate/animations/transform.ts"() {
4978
- "use strict";
4979
- import_gsap5 = require("gsap");
4980
- init_timeline();
4981
- init_utils();
4982
- }
4983
- });
4984
-
4985
- // src/index.ts
4986
- var index_exports = {};
4987
- __export(index_exports, {
4988
- AddTextLetterByLetter: () => AddTextLetterByLetter,
4989
- AddTextWordByWord: () => AddTextWordByWord,
4990
- AnimationGroup: () => AnimationGroup,
4991
- ApplyComplexFunction: () => ApplyComplexFunction,
4992
- ApplyFunction: () => ApplyFunction,
4993
- ApplyMethod: () => ApplyMethod,
4994
- ApplyWave: () => ApplyWave,
4995
- Axes: () => Axes,
4996
- Blink: () => Blink,
4997
- Broadcast: () => Broadcast,
4998
- Camera: () => Camera,
4999
- CameraAutoZoom: () => CameraAutoZoom,
5000
- CameraMove: () => CameraMove,
5001
- CameraReset: () => CameraReset,
5002
- CameraSetFrame: () => CameraSetFrame,
5003
- CameraZoom: () => CameraZoom,
5004
- ChangingDecimal: () => ChangingDecimal,
5005
- Circumscribe: () => Circumscribe,
5006
- ClockwiseTransform: () => ClockwiseTransform,
5007
- ColorScales: () => ColorScales,
5008
- Colors: () => Colors,
5009
- ComplexValueTracker: () => ComplexValueTracker,
5010
- CounterclockwiseTransform: () => CounterclockwiseTransform,
5011
- Create: () => Create,
5012
- CyclicReplace: () => CyclicReplace,
5013
- DEGREES: () => DEGREES,
5014
- DL: () => DL,
5015
- DOWN: () => DOWN,
5016
- DR: () => DR,
5017
- DiGraph: () => DiGraph,
5018
- Diagram: () => Diagram,
5019
- Dir: () => Dir,
5020
- DrawBorderThenFill: () => DrawBorderThenFill,
5021
- FadeIn: () => FadeIn,
5022
- FadeInFrom: () => FadeInFrom,
5023
- FadeInFromDown: () => FadeInFromDown,
5024
- FadeInFromLeft: () => FadeInFromLeft,
5025
- FadeInFromRight: () => FadeInFromRight,
5026
- FadeInFromUp: () => FadeInFromUp,
5027
- FadeOut: () => FadeOut,
5028
- FadeOutTo: () => FadeOutTo,
5029
- FadeToColor: () => FadeToColor,
5030
- FadeTransform: () => FadeTransform,
5031
- Flash: () => Flash,
5032
- FocusOn: () => FocusOn,
5033
- Graph: () => Graph,
5034
- Group: () => Group,
5035
- GrowArrow: () => GrowArrow,
5036
- GrowFromCenter: () => GrowFromCenter,
5037
- GrowFromEdge: () => GrowFromEdge,
5038
- GrowFromPoint: () => GrowFromPoint,
5039
- Homotopy: () => Homotopy,
5040
- IDENTITY: () => IDENTITY,
5041
- Indicate: () => Indicate,
5042
- Interactive: () => Interactive,
5043
- LEFT: () => LEFT,
5044
- LaggedStart: () => LaggedStart,
5045
- LaggedStartMap: () => LaggedStartMap,
5046
- LinearTransformationScene: () => LinearTransformationScene,
5047
- ManimColor: () => ManimColor,
5048
- MathTex: () => MathTex,
5049
- MatrixDisplay: () => MatrixDisplay,
5050
- Morphing: () => Morphing,
5051
- MoveAlongPath: () => MoveAlongPath,
5052
- MoveTo: () => MoveTo,
5053
- MoveToTarget: () => MoveToTarget,
5054
- MovingCamera: () => MovingCamera,
5055
- MovingCameraScene: () => MovingCameraScene,
5056
- NumberLine: () => NumberLine,
5057
- NumberPlane: () => NumberPlane,
5058
- ORIGIN: () => ORIGIN,
5059
- PI: () => PI,
5060
- PhaseFlow: () => PhaseFlow,
5061
- Physics2DWorld: () => Physics2DWorld,
5062
- PolarAxes: () => PolarAxes,
5063
- RIGHT: () => RIGHT,
5064
- RemoveTextLetterByLetter: () => RemoveTextLetterByLetter,
5065
- ReplacementTransform: () => ReplacementTransform,
5066
- Restore: () => Restore,
5067
- Rotate: () => Rotate,
5068
- Rotating: () => Rotating,
5069
- Scale: () => Scale,
5070
- ScaleInPlace: () => ScaleInPlace,
5071
- Scene: () => Scene,
5072
- Shift: () => Shift,
5073
- ShowIncreasingSubsets: () => ShowIncreasingSubsets,
5074
- ShowPassingFlash: () => ShowPassingFlash,
5075
- ShrinkToCenter: () => ShrinkToCenter,
5076
- SpinInFromNothing: () => SpinInFromNothing,
5077
- SpiralIn: () => SpiralIn,
5078
- Succession: () => Succession,
5079
- Swap: () => Swap,
5080
- TAU: () => TAU,
5081
- Table: () => Table,
5082
- Tex: () => Tex,
5083
- ThreeB1BColors: () => ThreeB1BColors,
5084
- ThreeCamera: () => ThreeCamera,
5085
- ThreeDAxes: () => ThreeDAxes,
5086
- ThreeDCamera: () => ThreeDCamera,
5087
- ThreeDiagram: () => ThreeDiagram,
5088
- ThreeScene: () => ThreeScene,
5089
- Timeline: () => Timeline,
5090
- TracedPath: () => TracedPath,
5091
- TracedPathAnimation: () => TracedPathAnimation,
4912
+ Restore: () => Restore,
4913
+ Rotate: () => Rotate,
4914
+ Rotating: () => Rotating,
4915
+ Scale: () => Scale,
4916
+ ScaleInPlace: () => ScaleInPlace,
4917
+ Scene: () => Scene,
4918
+ Shift: () => Shift,
4919
+ ShowIncreasingSubsets: () => ShowIncreasingSubsets,
4920
+ ShowPassingFlash: () => ShowPassingFlash,
4921
+ Showcase: () => Showcase,
4922
+ ShrinkToCenter: () => ShrinkToCenter,
4923
+ SpinInFromNothing: () => SpinInFromNothing,
4924
+ SpiralIn: () => SpiralIn,
4925
+ Succession: () => Succession,
4926
+ Swap: () => Swap,
4927
+ TAU: () => TAU,
4928
+ Table: () => Table,
4929
+ Tex: () => Tex,
4930
+ ThreeB1BColors: () => ThreeB1BColors,
4931
+ ThreeCamera: () => ThreeCamera,
4932
+ ThreeDAxes: () => ThreeDAxes,
4933
+ ThreeDCamera: () => ThreeDCamera,
4934
+ ThreeDiagram: () => ThreeDiagram,
4935
+ ThreeScene: () => ThreeScene,
4936
+ Timeline: () => Timeline,
4937
+ TracedPath: () => TracedPath,
4938
+ TracedPathAnimation: () => TracedPathAnimation,
5092
4939
  Transform: () => Transform,
5093
4940
  TransformFromCopy: () => TransformFromCopy,
5094
4941
  TransformMatchingShapes: () => TransformMatchingShapes,
@@ -5173,6 +5020,7 @@ __export(index_exports, {
5173
5020
  createPhysicsWorld: () => createPhysicsWorld,
5174
5021
  createPlane: () => createPlane,
5175
5022
  createScene: () => createScene,
5023
+ createShowcase: () => createShowcase,
5176
5024
  createSphere: () => createSphere,
5177
5025
  createSpringMass: () => createSpringMass,
5178
5026
  createTheme: () => createTheme,
@@ -5218,6 +5066,7 @@ __export(index_exports, {
5218
5066
  defaultTheme: () => defaultTheme,
5219
5067
  defaultTokens: () => defaultTokens,
5220
5068
  degToRad: () => degToRad,
5069
+ detectRenderMode: () => detectRenderMode,
5221
5070
  determinant: () => determinant,
5222
5071
  diagram_combine: () => diagram_combine,
5223
5072
  diff: () => diff,
@@ -5228,6 +5077,7 @@ __export(index_exports, {
5228
5077
  dot: () => dot2,
5229
5078
  dot3D: () => dot3D,
5230
5079
  doubleArrow: () => doubleArrow,
5080
+ downloadFile: () => downloadFile,
5231
5081
  draw_to_svg: () => draw_to_svg,
5232
5082
  draw_to_svg_string: () => draw_to_svg_string,
5233
5083
  easing: () => easing,
@@ -5236,6 +5086,7 @@ __export(index_exports, {
5236
5086
  ellipse: () => ellipse,
5237
5087
  empty: () => empty,
5238
5088
  equilateralTriangle: () => equilateralTriangle,
5089
+ executeCode: () => executeCode,
5239
5090
  footOfPerpendicular: () => footOfPerpendicular,
5240
5091
  functionConstraint: () => functionConstraint,
5241
5092
  getBuffer: () => getBuffer,
@@ -5305,6 +5156,7 @@ __export(index_exports, {
5305
5156
  polygon: () => polygon,
5306
5157
  polyline: () => polyline,
5307
5158
  powScale: () => powScale,
5159
+ preprocessCode: () => preprocessCode,
5308
5160
  quadraticBezier: () => quadraticBezier,
5309
5161
  radToDeg: () => radToDeg,
5310
5162
  randomLayout: () => randomLayout,
@@ -5331,6 +5183,9 @@ __export(index_exports, {
5331
5183
  sector: () => sector,
5332
5184
  semanticStyle: () => semanticStyle,
5333
5185
  setCurrentTheme: () => setCurrentTheme,
5186
+ showcaseExportJPG: () => exportJPG,
5187
+ showcaseExportMP4: () => exportMP4,
5188
+ showcaseExportSVG: () => exportSVG,
5334
5189
  shuffle: () => shuffle2,
5335
5190
  sortGroups: () => sortGroups,
5336
5191
  sphere: () => sphere,
@@ -5353,6 +5208,8 @@ __export(index_exports, {
5353
5208
  translationMatrix: () => translationMatrix,
5354
5209
  treeLayout: () => treeLayout,
5355
5210
  triangle: () => triangle,
5211
+ useExport: () => useExport,
5212
+ useShowcase: () => useShowcase,
5356
5213
  vector: () => vector,
5357
5214
  vector3D: () => vector3D,
5358
5215
  vectorDot: () => dot
@@ -6319,212 +6176,549 @@ var Scene = class {
6319
6176
  if (this.svg && this.container && !(this.container instanceof SVGSVGElement)) {
6320
6177
  this.svg.remove();
6321
6178
  }
6322
- this.objects.clear();
6323
- this._isSetup = false;
6324
- }
6325
- };
6326
- function createScene(container, buildFn, config) {
6327
- const scene = new SimpleScene(container, buildFn, config);
6328
- return scene;
6179
+ this.objects.clear();
6180
+ this._isSetup = false;
6181
+ }
6182
+ };
6183
+ function createScene(container, buildFn, config) {
6184
+ const scene = new SimpleScene(container, buildFn, config);
6185
+ return scene;
6186
+ }
6187
+ var SimpleScene = class extends Scene {
6188
+ constructor(container, buildFn, config) {
6189
+ super(container, config);
6190
+ this.buildFn = buildFn;
6191
+ }
6192
+ construct() {
6193
+ this.buildFn(this);
6194
+ }
6195
+ };
6196
+
6197
+ // src/animate/moving-camera-scene.ts
6198
+ var MovingCameraScene = class extends Scene {
6199
+ /**
6200
+ * 创建 MovingCameraScene 实例
6201
+ * @param container - 可选的容器元素
6202
+ * @param config - 场景配置
6203
+ */
6204
+ constructor(container, config = {}) {
6205
+ super(container, config);
6206
+ }
6207
+ /**
6208
+ * 初始化场景(重写以使用 MovingCamera)
6209
+ */
6210
+ setup(svgOrContainer, config = {}) {
6211
+ var _a, _b, _c, _d;
6212
+ super.setup(svgOrContainer, config);
6213
+ const cameraConfig = (_a = config.camera) != null ? _a : {};
6214
+ const movingCameraConfig = {
6215
+ frameCenter: (_b = cameraConfig.frameCenter) != null ? _b : [0, 0],
6216
+ frameWidth: (_c = cameraConfig.frameWidth) != null ? _c : this.frameWidth,
6217
+ frameHeight: (_d = cameraConfig.frameHeight) != null ? _d : this.frameHeight
6218
+ };
6219
+ if (cameraConfig.defaultDuration !== void 0) {
6220
+ movingCameraConfig.defaultDuration = cameraConfig.defaultDuration;
6221
+ }
6222
+ if (cameraConfig.defaultEasing !== void 0) {
6223
+ movingCameraConfig.defaultEasing = cameraConfig.defaultEasing;
6224
+ }
6225
+ this.camera = new MovingCamera(movingCameraConfig);
6226
+ this.updateCameraViewBox();
6227
+ }
6228
+ };
6229
+ function createMovingCameraScene(container, buildFn, config) {
6230
+ const scene = new SimpleMovingCameraScene(container, buildFn, config);
6231
+ return scene;
6232
+ }
6233
+ var SimpleMovingCameraScene = class extends MovingCameraScene {
6234
+ constructor(container, buildFn, config) {
6235
+ super(container, config);
6236
+ this.buildFn = buildFn;
6237
+ }
6238
+ construct() {
6239
+ this.buildFn(this);
6240
+ }
6241
+ };
6242
+
6243
+ // src/animate/animations/create.ts
6244
+ var import_gsap3 = require("gsap");
6245
+ init_timeline();
6246
+
6247
+ // src/animate/animations/utils.ts
6248
+ function querySelectorAllIncludingSelf(element, selector) {
6249
+ const results = Array.from(element.querySelectorAll(selector));
6250
+ if (element.matches(selector)) {
6251
+ results.unshift(element);
6252
+ }
6253
+ return results;
6254
+ }
6255
+
6256
+ // src/animate/animations/create.ts
6257
+ function Create(target, options = {}) {
6258
+ const { duration = 1, easing: easing2 = "easeInOut", delay = 0 } = options;
6259
+ return {
6260
+ duration,
6261
+ target,
6262
+ execute(scene, timeline, startTime) {
6263
+ const element = scene.getOrCreateElement(target);
6264
+ if (!element) return;
6265
+ const paths = querySelectorAllIncludingSelf(element, "path, line, polyline, polygon, circle, ellipse, rect");
6266
+ paths.forEach((path2) => {
6267
+ if (path2 instanceof SVGGeometryElement) {
6268
+ const length2 = path2.getTotalLength();
6269
+ import_gsap3.gsap.set(path2, {
6270
+ strokeDasharray: length2,
6271
+ strokeDashoffset: length2,
6272
+ fillOpacity: 0
6273
+ });
6274
+ timeline.add(path2, {
6275
+ strokeDashoffset: 0,
6276
+ duration,
6277
+ ease: getGSAPEasing(easing2),
6278
+ delay
6279
+ }, startTime);
6280
+ const fill = path2.getAttribute("fill");
6281
+ if (fill && fill !== "none") {
6282
+ timeline.add(path2, {
6283
+ fillOpacity: 1,
6284
+ duration: duration * 0.3,
6285
+ ease: "power2.out"
6286
+ }, startTime + duration);
6287
+ }
6288
+ }
6289
+ });
6290
+ const texts = querySelectorAllIncludingSelf(element, "text");
6291
+ texts.forEach((text2) => {
6292
+ import_gsap3.gsap.set(text2, { opacity: 0 });
6293
+ timeline.add(text2, {
6294
+ opacity: 1,
6295
+ duration: duration * 0.5,
6296
+ ease: "power2.out"
6297
+ }, startTime + duration * 0.5);
6298
+ });
6299
+ }
6300
+ };
6301
+ }
6302
+ function Write(target, options = {}) {
6303
+ const { duration = 1, easing: easing2 = "easeOut", delay = 0 } = options;
6304
+ return {
6305
+ duration,
6306
+ target,
6307
+ execute(scene, timeline, startTime) {
6308
+ const element = scene.getOrCreateElement(target);
6309
+ if (!element) return;
6310
+ const texts = querySelectorAllIncludingSelf(element, "text");
6311
+ if (texts.length > 0) {
6312
+ texts.forEach((text2) => {
6313
+ const content = text2.textContent || "";
6314
+ const chars = content.split("");
6315
+ text2.textContent = "";
6316
+ chars.forEach((char, i) => {
6317
+ const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
6318
+ tspan.textContent = char;
6319
+ import_gsap3.gsap.set(tspan, { opacity: 0 });
6320
+ text2.appendChild(tspan);
6321
+ const charDelay = i / chars.length * duration;
6322
+ timeline.add(tspan, {
6323
+ opacity: 1,
6324
+ duration: duration / chars.length,
6325
+ ease: getGSAPEasing(easing2)
6326
+ }, startTime + delay + charDelay);
6327
+ });
6328
+ });
6329
+ } else {
6330
+ return Create(target, options).execute(scene, timeline, startTime);
6331
+ }
6332
+ }
6333
+ };
6334
+ }
6335
+ function DrawBorderThenFill(target, options = {}) {
6336
+ const { duration = 1.5, easing: easing2 = "easeInOut", delay = 0 } = options;
6337
+ return {
6338
+ duration,
6339
+ target,
6340
+ execute(scene, timeline, startTime) {
6341
+ const element = scene.getOrCreateElement(target);
6342
+ if (!element) return;
6343
+ const paths = querySelectorAllIncludingSelf(element, "path, line, polyline, polygon, circle, ellipse, rect");
6344
+ paths.forEach((path2) => {
6345
+ if (path2 instanceof SVGGeometryElement) {
6346
+ const length2 = path2.getTotalLength();
6347
+ const originalFill = path2.getAttribute("fill") || "none";
6348
+ const originalStroke = path2.getAttribute("stroke") || "#374151";
6349
+ import_gsap3.gsap.set(path2, {
6350
+ strokeDasharray: length2,
6351
+ strokeDashoffset: length2,
6352
+ fill: "none",
6353
+ stroke: originalStroke,
6354
+ strokeWidth: path2.getAttribute("stroke-width") || 2
6355
+ });
6356
+ const borderDuration = duration * 0.6;
6357
+ timeline.add(path2, {
6358
+ strokeDashoffset: 0,
6359
+ duration: borderDuration,
6360
+ ease: getGSAPEasing(easing2)
6361
+ }, startTime + delay);
6362
+ if (originalFill && originalFill !== "none") {
6363
+ const fillDuration = duration * 0.4;
6364
+ timeline.add(path2, {
6365
+ fill: originalFill,
6366
+ fillOpacity: 1,
6367
+ duration: fillDuration,
6368
+ ease: "power2.out"
6369
+ }, startTime + delay + borderDuration);
6370
+ }
6371
+ }
6372
+ });
6373
+ }
6374
+ };
6375
+ }
6376
+ function GrowFromCenter(target, options = {}) {
6377
+ const { duration = 0.5, easing: easing2 = "easeOutBack", delay = 0 } = options;
6378
+ return {
6379
+ duration,
6380
+ target,
6381
+ execute(scene, timeline, startTime) {
6382
+ var _a;
6383
+ const element = scene.getOrCreateElement(target);
6384
+ if (!element) return;
6385
+ const bbox = ((_a = element.getBBox) == null ? void 0 : _a.call(element)) || { x: 0, y: 0, width: 0, height: 0 };
6386
+ const cx = bbox.x + bbox.width / 2;
6387
+ const cy = bbox.y + bbox.height / 2;
6388
+ import_gsap3.gsap.set(element, {
6389
+ transformOrigin: `${cx}px ${cy}px`,
6390
+ scale: 0,
6391
+ opacity: 0
6392
+ });
6393
+ timeline.add(element, {
6394
+ scale: 1,
6395
+ opacity: 1,
6396
+ duration,
6397
+ ease: getGSAPEasing(easing2),
6398
+ delay
6399
+ }, startTime);
6400
+ }
6401
+ };
6329
6402
  }
6330
- var SimpleScene = class extends Scene {
6331
- constructor(container, buildFn, config) {
6332
- super(container, config);
6333
- this.buildFn = buildFn;
6334
- }
6335
- construct() {
6336
- this.buildFn(this);
6337
- }
6338
- };
6339
-
6340
- // src/animate/moving-camera-scene.ts
6341
- var MovingCameraScene = class extends Scene {
6342
- /**
6343
- * 创建 MovingCameraScene 实例
6344
- * @param container - 可选的容器元素
6345
- * @param config - 场景配置
6346
- */
6347
- constructor(container, config = {}) {
6348
- super(container, config);
6349
- }
6350
- /**
6351
- * 初始化场景(重写以使用 MovingCamera)
6352
- */
6353
- setup(svgOrContainer, config = {}) {
6354
- var _a, _b, _c, _d;
6355
- super.setup(svgOrContainer, config);
6356
- const cameraConfig = (_a = config.camera) != null ? _a : {};
6357
- const movingCameraConfig = {
6358
- frameCenter: (_b = cameraConfig.frameCenter) != null ? _b : [0, 0],
6359
- frameWidth: (_c = cameraConfig.frameWidth) != null ? _c : this.frameWidth,
6360
- frameHeight: (_d = cameraConfig.frameHeight) != null ? _d : this.frameHeight
6361
- };
6362
- if (cameraConfig.defaultDuration !== void 0) {
6363
- movingCameraConfig.defaultDuration = cameraConfig.defaultDuration;
6403
+ function GrowFromPoint(target, point, options = {}) {
6404
+ const { duration = 0.5, easing: easing2 = "easeOutBack", delay = 0 } = options;
6405
+ return {
6406
+ duration,
6407
+ target,
6408
+ execute(scene, timeline, startTime) {
6409
+ const element = scene.getOrCreateElement(target);
6410
+ if (!element) return;
6411
+ import_gsap3.gsap.set(element, {
6412
+ transformOrigin: `${point[0]}px ${point[1]}px`,
6413
+ scale: 0,
6414
+ opacity: 0
6415
+ });
6416
+ timeline.add(element, {
6417
+ scale: 1,
6418
+ opacity: 1,
6419
+ duration,
6420
+ ease: getGSAPEasing(easing2),
6421
+ delay
6422
+ }, startTime);
6364
6423
  }
6365
- if (cameraConfig.defaultEasing !== void 0) {
6366
- movingCameraConfig.defaultEasing = cameraConfig.defaultEasing;
6424
+ };
6425
+ }
6426
+ function GrowFromEdge(target, edge = "LEFT", options = {}) {
6427
+ const { duration = 0.5, easing: easing2 = "easeOut", delay = 0 } = options;
6428
+ return {
6429
+ duration,
6430
+ target,
6431
+ execute(scene, timeline, startTime) {
6432
+ var _a;
6433
+ const element = scene.getOrCreateElement(target);
6434
+ if (!element) return;
6435
+ const bbox = ((_a = element.getBBox) == null ? void 0 : _a.call(element)) || { x: 0, y: 0, width: 0, height: 0 };
6436
+ let origin;
6437
+ let scaleFrom;
6438
+ switch (edge) {
6439
+ case "LEFT":
6440
+ origin = `${bbox.x}px ${bbox.y + bbox.height / 2}px`;
6441
+ scaleFrom = { scaleX: 0 };
6442
+ break;
6443
+ case "RIGHT":
6444
+ origin = `${bbox.x + bbox.width}px ${bbox.y + bbox.height / 2}px`;
6445
+ scaleFrom = { scaleX: 0 };
6446
+ break;
6447
+ case "TOP":
6448
+ origin = `${bbox.x + bbox.width / 2}px ${bbox.y}px`;
6449
+ scaleFrom = { scaleY: 0 };
6450
+ break;
6451
+ case "BOTTOM":
6452
+ origin = `${bbox.x + bbox.width / 2}px ${bbox.y + bbox.height}px`;
6453
+ scaleFrom = { scaleY: 0 };
6454
+ break;
6455
+ }
6456
+ import_gsap3.gsap.set(element, __spreadProps(__spreadValues({
6457
+ transformOrigin: origin
6458
+ }, scaleFrom), {
6459
+ opacity: 0
6460
+ }));
6461
+ timeline.add(element, {
6462
+ scaleX: 1,
6463
+ scaleY: 1,
6464
+ opacity: 1,
6465
+ duration,
6466
+ ease: getGSAPEasing(easing2),
6467
+ delay
6468
+ }, startTime);
6367
6469
  }
6368
- this.camera = new MovingCamera(movingCameraConfig);
6369
- this.updateCameraViewBox();
6370
- }
6371
- };
6372
- function createMovingCameraScene(container, buildFn, config) {
6373
- const scene = new SimpleMovingCameraScene(container, buildFn, config);
6374
- return scene;
6470
+ };
6375
6471
  }
6376
- var SimpleMovingCameraScene = class extends MovingCameraScene {
6377
- constructor(container, buildFn, config) {
6378
- super(container, config);
6379
- this.buildFn = buildFn;
6380
- }
6381
- construct() {
6382
- this.buildFn(this);
6383
- }
6384
- };
6385
-
6386
- // src/animate/animations/create.ts
6387
- var import_gsap3 = require("gsap");
6388
- init_timeline();
6389
- init_utils();
6390
- function Create(target, options = {}) {
6391
- const { duration = 1, easing: easing2 = "easeInOut", delay = 0 } = options;
6472
+ function SpinInFromNothing(target, options = {}) {
6473
+ const { duration = 0.8, easing: easing2 = "easeOut", delay = 0 } = options;
6392
6474
  return {
6393
6475
  duration,
6394
6476
  target,
6395
6477
  execute(scene, timeline, startTime) {
6478
+ var _a;
6396
6479
  const element = scene.getOrCreateElement(target);
6397
6480
  if (!element) return;
6481
+ const bbox = ((_a = element.getBBox) == null ? void 0 : _a.call(element)) || { x: 0, y: 0, width: 0, height: 0 };
6482
+ const cx = bbox.x + bbox.width / 2;
6483
+ const cy = bbox.y + bbox.height / 2;
6484
+ import_gsap3.gsap.set(element, {
6485
+ transformOrigin: `${cx}px ${cy}px`,
6486
+ scale: 0,
6487
+ rotation: -360,
6488
+ opacity: 0
6489
+ });
6490
+ timeline.add(element, {
6491
+ scale: 1,
6492
+ rotation: 0,
6493
+ opacity: 1,
6494
+ duration,
6495
+ ease: getGSAPEasing(easing2),
6496
+ delay
6497
+ }, startTime);
6498
+ }
6499
+ };
6500
+ }
6501
+ function Uncreate(target, options = {}) {
6502
+ const { duration = 1, easing: easing2 = "easeInOut", delay = 0 } = options;
6503
+ return {
6504
+ duration,
6505
+ target,
6506
+ execute(scene, timeline, startTime) {
6507
+ const element = scene.getElement(target);
6508
+ if (!element) return;
6398
6509
  const paths = querySelectorAllIncludingSelf(element, "path, line, polyline, polygon, circle, ellipse, rect");
6399
6510
  paths.forEach((path2) => {
6400
6511
  if (path2 instanceof SVGGeometryElement) {
6401
6512
  const length2 = path2.getTotalLength();
6402
6513
  import_gsap3.gsap.set(path2, {
6403
6514
  strokeDasharray: length2,
6404
- strokeDashoffset: length2,
6405
- fillOpacity: 0
6515
+ strokeDashoffset: 0
6406
6516
  });
6407
- timeline.add(path2, {
6408
- strokeDashoffset: 0,
6409
- duration,
6410
- ease: getGSAPEasing(easing2),
6411
- delay
6412
- }, startTime);
6413
6517
  const fill = path2.getAttribute("fill");
6414
6518
  if (fill && fill !== "none") {
6415
6519
  timeline.add(path2, {
6416
- fillOpacity: 1,
6520
+ fillOpacity: 0,
6417
6521
  duration: duration * 0.3,
6418
- ease: "power2.out"
6419
- }, startTime + duration);
6522
+ ease: "power2.in"
6523
+ }, startTime + delay);
6420
6524
  }
6525
+ timeline.add(path2, {
6526
+ strokeDashoffset: length2,
6527
+ duration,
6528
+ ease: getGSAPEasing(easing2),
6529
+ delay: delay + (fill && fill !== "none" ? duration * 0.1 : 0)
6530
+ }, startTime);
6421
6531
  }
6422
6532
  });
6423
6533
  const texts = querySelectorAllIncludingSelf(element, "text");
6424
6534
  texts.forEach((text2) => {
6425
- import_gsap3.gsap.set(text2, { opacity: 0 });
6426
6535
  timeline.add(text2, {
6427
- opacity: 1,
6536
+ opacity: 0,
6428
6537
  duration: duration * 0.5,
6429
- ease: "power2.out"
6430
- }, startTime + duration * 0.5);
6538
+ ease: "power2.in"
6539
+ }, startTime + delay);
6540
+ });
6541
+ timeline.call(() => {
6542
+ element.remove();
6543
+ }, startTime + duration + delay);
6544
+ }
6545
+ };
6546
+ }
6547
+ function Unwrite(target, options = {}) {
6548
+ const { duration = 1, easing: easing2 = "easeIn", delay = 0 } = options;
6549
+ return {
6550
+ duration,
6551
+ target,
6552
+ execute(scene, timeline, startTime) {
6553
+ const element = scene.getElement(target);
6554
+ if (!element) return;
6555
+ const texts = querySelectorAllIncludingSelf(element, "text");
6556
+ if (texts.length > 0) {
6557
+ texts.forEach((text2) => {
6558
+ const content = text2.textContent || "";
6559
+ const chars = content.split("");
6560
+ text2.textContent = "";
6561
+ chars.forEach((char, i) => {
6562
+ const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
6563
+ tspan.textContent = char;
6564
+ text2.appendChild(tspan);
6565
+ const charDelay = (chars.length - 1 - i) / chars.length * duration;
6566
+ timeline.add(tspan, {
6567
+ opacity: 0,
6568
+ duration: duration / chars.length,
6569
+ ease: getGSAPEasing(easing2)
6570
+ }, startTime + delay + charDelay);
6571
+ });
6572
+ });
6573
+ timeline.call(() => {
6574
+ element.remove();
6575
+ }, startTime + duration + delay);
6576
+ } else {
6577
+ return Uncreate(target, options).execute(scene, timeline, startTime);
6578
+ }
6579
+ }
6580
+ };
6581
+ }
6582
+ function ShrinkToCenter(target, options = {}) {
6583
+ const { duration = 0.5, easing: easing2 = "easeInBack", delay = 0 } = options;
6584
+ return {
6585
+ duration,
6586
+ target,
6587
+ execute(scene, timeline, startTime) {
6588
+ var _a;
6589
+ const element = scene.getElement(target);
6590
+ if (!element) return;
6591
+ const bbox = ((_a = element.getBBox) == null ? void 0 : _a.call(element)) || { x: 0, y: 0, width: 0, height: 0 };
6592
+ const cx = bbox.x + bbox.width / 2;
6593
+ const cy = bbox.y + bbox.height / 2;
6594
+ import_gsap3.gsap.set(element, {
6595
+ transformOrigin: `${cx}px ${cy}px`
6431
6596
  });
6597
+ timeline.add(element, {
6598
+ scale: 0,
6599
+ opacity: 0,
6600
+ duration,
6601
+ ease: getGSAPEasing(easing2),
6602
+ delay,
6603
+ onComplete: () => {
6604
+ element.remove();
6605
+ }
6606
+ }, startTime);
6432
6607
  }
6433
6608
  };
6434
6609
  }
6435
- function Write(target, options = {}) {
6436
- const { duration = 1, easing: easing2 = "easeOut", delay = 0 } = options;
6610
+
6611
+ // src/animate/animations/fade.ts
6612
+ var import_gsap4 = require("gsap");
6613
+ init_math();
6614
+ init_timeline();
6615
+ function directionToVector(direction) {
6616
+ if (!direction) return void 0;
6617
+ if (Array.isArray(direction)) return direction;
6618
+ switch (direction) {
6619
+ case "UP":
6620
+ return UP;
6621
+ case "DOWN":
6622
+ return DOWN;
6623
+ case "LEFT":
6624
+ return LEFT;
6625
+ case "RIGHT":
6626
+ return RIGHT;
6627
+ }
6628
+ }
6629
+ function FadeIn(target, options = {}) {
6630
+ const { duration = 0.5, easing: easing2 = "easeOut", delay = 0, direction, shift = 50 } = options;
6631
+ const dir = directionToVector(direction);
6437
6632
  return {
6438
6633
  duration,
6439
6634
  target,
6440
6635
  execute(scene, timeline, startTime) {
6441
6636
  const element = scene.getOrCreateElement(target);
6442
6637
  if (!element) return;
6443
- const texts = querySelectorAllIncludingSelf(element, "text");
6444
- if (texts.length > 0) {
6445
- texts.forEach((text2) => {
6446
- const content = text2.textContent || "";
6447
- const chars = content.split("");
6448
- text2.textContent = "";
6449
- chars.forEach((char, i) => {
6450
- const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
6451
- tspan.textContent = char;
6452
- import_gsap3.gsap.set(tspan, { opacity: 0 });
6453
- text2.appendChild(tspan);
6454
- const charDelay = i / chars.length * duration;
6455
- timeline.add(tspan, {
6456
- opacity: 1,
6457
- duration: duration / chars.length,
6458
- ease: getGSAPEasing(easing2)
6459
- }, startTime + delay + charDelay);
6460
- });
6461
- });
6462
- } else {
6463
- return Create(target, options).execute(scene, timeline, startTime);
6638
+ const initialState = { opacity: 0 };
6639
+ if (dir) {
6640
+ initialState.x = -dir[0] * shift;
6641
+ initialState.y = -dir[1] * shift;
6642
+ }
6643
+ import_gsap4.gsap.set(element, initialState);
6644
+ const targetState = {
6645
+ opacity: 1,
6646
+ duration,
6647
+ ease: getGSAPEasing(easing2),
6648
+ delay
6649
+ };
6650
+ if (dir) {
6651
+ targetState.x = 0;
6652
+ targetState.y = 0;
6464
6653
  }
6654
+ timeline.add(element, targetState, startTime);
6465
6655
  }
6466
6656
  };
6467
6657
  }
6468
- function DrawBorderThenFill(target, options = {}) {
6469
- const { duration = 1.5, easing: easing2 = "easeInOut", delay = 0 } = options;
6658
+ function FadeOut(target, options = {}) {
6659
+ const { duration = 0.5, easing: easing2 = "easeIn", delay = 0, direction, shift = 50 } = options;
6660
+ const dir = directionToVector(direction);
6470
6661
  return {
6471
6662
  duration,
6472
6663
  target,
6473
6664
  execute(scene, timeline, startTime) {
6474
- const element = scene.getOrCreateElement(target);
6665
+ const element = scene.getElement(target);
6475
6666
  if (!element) return;
6476
- const paths = querySelectorAllIncludingSelf(element, "path, line, polyline, polygon, circle, ellipse, rect");
6477
- paths.forEach((path2) => {
6478
- if (path2 instanceof SVGGeometryElement) {
6479
- const length2 = path2.getTotalLength();
6480
- const originalFill = path2.getAttribute("fill") || "none";
6481
- const originalStroke = path2.getAttribute("stroke") || "#374151";
6482
- import_gsap3.gsap.set(path2, {
6483
- strokeDasharray: length2,
6484
- strokeDashoffset: length2,
6485
- fill: "none",
6486
- stroke: originalStroke,
6487
- strokeWidth: path2.getAttribute("stroke-width") || 2
6488
- });
6489
- const borderDuration = duration * 0.6;
6490
- timeline.add(path2, {
6491
- strokeDashoffset: 0,
6492
- duration: borderDuration,
6493
- ease: getGSAPEasing(easing2)
6494
- }, startTime + delay);
6495
- if (originalFill && originalFill !== "none") {
6496
- const fillDuration = duration * 0.4;
6497
- timeline.add(path2, {
6498
- fill: originalFill,
6499
- fillOpacity: 1,
6500
- duration: fillDuration,
6501
- ease: "power2.out"
6502
- }, startTime + delay + borderDuration);
6503
- }
6667
+ const targetState = {
6668
+ opacity: 0,
6669
+ duration,
6670
+ ease: getGSAPEasing(easing2),
6671
+ delay,
6672
+ onComplete: () => {
6673
+ element.remove();
6504
6674
  }
6505
- });
6675
+ };
6676
+ if (dir) {
6677
+ targetState.x = dir[0] * shift;
6678
+ targetState.y = dir[1] * shift;
6679
+ }
6680
+ timeline.add(element, targetState, startTime);
6506
6681
  }
6507
6682
  };
6508
6683
  }
6509
- function GrowFromCenter(target, options = {}) {
6510
- const { duration = 0.5, easing: easing2 = "easeOutBack", delay = 0 } = options;
6684
+ function FadeInFrom(target, direction, options = {}) {
6685
+ return FadeIn(target, __spreadProps(__spreadValues({}, options), { direction }));
6686
+ }
6687
+ function FadeOutTo(target, direction, options = {}) {
6688
+ return FadeOut(target, __spreadProps(__spreadValues({}, options), { direction }));
6689
+ }
6690
+ function FadeInFromDown(target, options = {}) {
6691
+ return FadeIn(target, __spreadProps(__spreadValues({}, options), { direction: "DOWN" }));
6692
+ }
6693
+ function FadeInFromUp(target, options = {}) {
6694
+ return FadeIn(target, __spreadProps(__spreadValues({}, options), { direction: "UP" }));
6695
+ }
6696
+ function FadeInFromLeft(target, options = {}) {
6697
+ return FadeIn(target, __spreadProps(__spreadValues({}, options), { direction: "LEFT" }));
6698
+ }
6699
+ function FadeInFromRight(target, options = {}) {
6700
+ return FadeIn(target, __spreadProps(__spreadValues({}, options), { direction: "RIGHT" }));
6701
+ }
6702
+ function FadeTransform(source, target, options = {}) {
6703
+ const { duration = 0.5, easing: easing2 = "easeInOut", delay = 0 } = options;
6511
6704
  return {
6512
6705
  duration,
6513
- target,
6706
+ target: source,
6514
6707
  execute(scene, timeline, startTime) {
6515
- var _a;
6516
- const element = scene.getOrCreateElement(target);
6517
- if (!element) return;
6518
- const bbox = ((_a = element.getBBox) == null ? void 0 : _a.call(element)) || { x: 0, y: 0, width: 0, height: 0 };
6519
- const cx = bbox.x + bbox.width / 2;
6520
- const cy = bbox.y + bbox.height / 2;
6521
- import_gsap3.gsap.set(element, {
6522
- transformOrigin: `${cx}px ${cy}px`,
6523
- scale: 0,
6524
- opacity: 0
6525
- });
6526
- timeline.add(element, {
6527
- scale: 1,
6708
+ const sourceElement = scene.getElement(source);
6709
+ const targetElement = scene.getOrCreateElement(target);
6710
+ if (!sourceElement || !targetElement) return;
6711
+ import_gsap4.gsap.set(targetElement, { opacity: 0 });
6712
+ timeline.add(sourceElement, {
6713
+ opacity: 0,
6714
+ duration,
6715
+ ease: getGSAPEasing(easing2),
6716
+ delay,
6717
+ onComplete: () => {
6718
+ sourceElement.remove();
6719
+ }
6720
+ }, startTime);
6721
+ timeline.add(targetElement, {
6528
6722
  opacity: 1,
6529
6723
  duration,
6530
6724
  ease: getGSAPEasing(easing2),
@@ -6533,97 +6727,126 @@ function GrowFromCenter(target, options = {}) {
6533
6727
  }
6534
6728
  };
6535
6729
  }
6536
- function GrowFromPoint(target, point, options = {}) {
6537
- const { duration = 0.5, easing: easing2 = "easeOutBack", delay = 0 } = options;
6730
+
6731
+ // src/animate/animations/transform.ts
6732
+ var import_gsap5 = require("gsap");
6733
+ init_timeline();
6734
+ function Transform(source, target, options = {}) {
6735
+ const { duration = 1, easing: easing2 = "easeInOut", delay = 0 } = options;
6538
6736
  return {
6539
6737
  duration,
6540
- target,
6738
+ target: source,
6541
6739
  execute(scene, timeline, startTime) {
6542
- const element = scene.getOrCreateElement(target);
6543
- if (!element) return;
6544
- import_gsap3.gsap.set(element, {
6545
- transformOrigin: `${point[0]}px ${point[1]}px`,
6546
- scale: 0,
6547
- opacity: 0
6740
+ var _a, _b;
6741
+ const sourceElement = scene.getElement(source);
6742
+ const targetElement = scene.getOrCreateElement(target);
6743
+ if (!sourceElement || !targetElement) return;
6744
+ import_gsap5.gsap.set(targetElement, { opacity: 0 });
6745
+ const sourceBBox = ((_a = sourceElement.getBBox) == null ? void 0 : _a.call(sourceElement)) || { x: 0, y: 0, width: 0, height: 0 };
6746
+ const targetBBox = ((_b = targetElement.getBBox) == null ? void 0 : _b.call(targetElement)) || { x: 0, y: 0, width: 0, height: 0 };
6747
+ const scaleX = targetBBox.width / (sourceBBox.width || 1);
6748
+ const scaleY = targetBBox.height / (sourceBBox.height || 1);
6749
+ const translateX = targetBBox.x + targetBBox.width / 2 - (sourceBBox.x + sourceBBox.width / 2);
6750
+ const translateY = targetBBox.y + targetBBox.height / 2 - (sourceBBox.y + sourceBBox.height / 2);
6751
+ const originX = sourceBBox.x + sourceBBox.width / 2;
6752
+ const originY = sourceBBox.y + sourceBBox.height / 2;
6753
+ import_gsap5.gsap.set(sourceElement, {
6754
+ transformOrigin: `${originX}px ${originY}px`
6548
6755
  });
6549
- timeline.add(element, {
6550
- scale: 1,
6551
- opacity: 1,
6756
+ timeline.add(sourceElement, {
6757
+ scaleX,
6758
+ scaleY,
6759
+ x: translateX,
6760
+ y: translateY,
6552
6761
  duration,
6553
6762
  ease: getGSAPEasing(easing2),
6554
- delay
6763
+ delay,
6764
+ onComplete: () => {
6765
+ sourceElement.remove();
6766
+ import_gsap5.gsap.set(targetElement, { opacity: 1 });
6767
+ }
6555
6768
  }, startTime);
6556
6769
  }
6557
6770
  };
6558
6771
  }
6559
- function GrowFromEdge(target, edge = "LEFT", options = {}) {
6560
- const { duration = 0.5, easing: easing2 = "easeOut", delay = 0 } = options;
6772
+ function ReplacementTransform(source, target, options = {}) {
6773
+ const { duration = 1, easing: easing2 = "easeInOut", delay = 0, replace = true } = options;
6561
6774
  return {
6562
6775
  duration,
6563
- target,
6776
+ target: source,
6564
6777
  execute(scene, timeline, startTime) {
6565
- var _a;
6566
- const element = scene.getOrCreateElement(target);
6567
- if (!element) return;
6568
- const bbox = ((_a = element.getBBox) == null ? void 0 : _a.call(element)) || { x: 0, y: 0, width: 0, height: 0 };
6569
- let origin;
6570
- let scaleFrom;
6571
- switch (edge) {
6572
- case "LEFT":
6573
- origin = `${bbox.x}px ${bbox.y + bbox.height / 2}px`;
6574
- scaleFrom = { scaleX: 0 };
6575
- break;
6576
- case "RIGHT":
6577
- origin = `${bbox.x + bbox.width}px ${bbox.y + bbox.height / 2}px`;
6578
- scaleFrom = { scaleX: 0 };
6579
- break;
6580
- case "TOP":
6581
- origin = `${bbox.x + bbox.width / 2}px ${bbox.y}px`;
6582
- scaleFrom = { scaleY: 0 };
6583
- break;
6584
- case "BOTTOM":
6585
- origin = `${bbox.x + bbox.width / 2}px ${bbox.y + bbox.height}px`;
6586
- scaleFrom = { scaleY: 0 };
6587
- break;
6588
- }
6589
- import_gsap3.gsap.set(element, __spreadProps(__spreadValues({
6590
- transformOrigin: origin
6591
- }, scaleFrom), {
6592
- opacity: 0
6593
- }));
6594
- timeline.add(element, {
6595
- scaleX: 1,
6596
- scaleY: 1,
6597
- opacity: 1,
6778
+ var _a, _b;
6779
+ const sourceElement = scene.getElement(source);
6780
+ const targetElement = scene.getOrCreateElement(target);
6781
+ if (!sourceElement || !targetElement) return;
6782
+ import_gsap5.gsap.set(targetElement, { opacity: 0, visibility: "hidden" });
6783
+ const sourceBBox = ((_a = sourceElement.getBBox) == null ? void 0 : _a.call(sourceElement)) || { x: 0, y: 0, width: 0, height: 0 };
6784
+ const targetBBox = ((_b = targetElement.getBBox) == null ? void 0 : _b.call(targetElement)) || { x: 0, y: 0, width: 0, height: 0 };
6785
+ const scaleX = targetBBox.width / (sourceBBox.width || 1);
6786
+ const scaleY = targetBBox.height / (sourceBBox.height || 1);
6787
+ const sourceCenterX = sourceBBox.x + sourceBBox.width / 2;
6788
+ const sourceCenterY = sourceBBox.y + sourceBBox.height / 2;
6789
+ const targetCenterX = targetBBox.x + targetBBox.width / 2;
6790
+ const targetCenterY = targetBBox.y + targetBBox.height / 2;
6791
+ timeline.add(sourceElement, {
6792
+ transformOrigin: `${sourceCenterX}px ${sourceCenterY}px`,
6793
+ scaleX,
6794
+ scaleY,
6795
+ x: targetCenterX - sourceCenterX,
6796
+ y: targetCenterY - sourceCenterY,
6797
+ opacity: 0,
6598
6798
  duration,
6599
6799
  ease: getGSAPEasing(easing2),
6600
- delay
6800
+ delay,
6801
+ onComplete: () => {
6802
+ if (replace) {
6803
+ sourceElement.remove();
6804
+ }
6805
+ }
6806
+ }, startTime);
6807
+ timeline.add(targetElement, {
6808
+ visibility: "visible",
6809
+ opacity: 1,
6810
+ duration: duration * 0.5,
6811
+ ease: "power2.out",
6812
+ delay: delay + duration * 0.5
6601
6813
  }, startTime);
6602
6814
  }
6603
6815
  };
6604
6816
  }
6605
- function SpinInFromNothing(target, options = {}) {
6606
- const { duration = 0.8, easing: easing2 = "easeOut", delay = 0 } = options;
6817
+ function MoveToTarget(source, options = {}) {
6818
+ const { duration = 1, easing: easing2 = "easeInOut", delay = 0 } = options;
6819
+ const targetDiagram = source.getTarget();
6607
6820
  return {
6608
6821
  duration,
6609
- target,
6822
+ target: source,
6610
6823
  execute(scene, timeline, startTime) {
6611
- var _a;
6612
- const element = scene.getOrCreateElement(target);
6613
- if (!element) return;
6614
- const bbox = ((_a = element.getBBox) == null ? void 0 : _a.call(element)) || { x: 0, y: 0, width: 0, height: 0 };
6615
- const cx = bbox.x + bbox.width / 2;
6616
- const cy = bbox.y + bbox.height / 2;
6617
- import_gsap3.gsap.set(element, {
6618
- transformOrigin: `${cx}px ${cy}px`,
6619
- scale: 0,
6620
- rotation: -360,
6621
- opacity: 0
6824
+ var _a, _b, _c, _d, _e, _f;
6825
+ const element = scene.getOrCreateElement(source);
6826
+ if (!element || !targetDiagram) return;
6827
+ const sourceBounds = source.bounds();
6828
+ const targetBounds = targetDiagram.bounds();
6829
+ const sourceCenter = [
6830
+ sourceBounds.x + sourceBounds.width / 2,
6831
+ sourceBounds.y + sourceBounds.height / 2
6832
+ ];
6833
+ const targetCenter = [
6834
+ targetBounds.x + targetBounds.width / 2,
6835
+ targetBounds.y + targetBounds.height / 2
6836
+ ];
6837
+ const translateX = ((_a = targetCenter[0]) != null ? _a : 0) - ((_b = sourceCenter[0]) != null ? _b : 0);
6838
+ const translateY = ((_c = targetCenter[1]) != null ? _c : 0) - ((_d = sourceCenter[1]) != null ? _d : 0);
6839
+ const scaleX = targetBounds.width / (sourceBounds.width || 1);
6840
+ const scaleY = targetBounds.height / (sourceBounds.height || 1);
6841
+ import_gsap5.gsap.set(element, {
6842
+ transformOrigin: `${(_e = sourceCenter[0]) != null ? _e : 0}px ${(_f = sourceCenter[1]) != null ? _f : 0}px`
6622
6843
  });
6623
6844
  timeline.add(element, {
6624
- scale: 1,
6625
- rotation: 0,
6626
- opacity: 1,
6845
+ x: translateX,
6846
+ y: -translateY,
6847
+ // SVG Y 轴翻转
6848
+ scaleX: isFinite(scaleX) ? scaleX : 1,
6849
+ scaleY: isFinite(scaleY) ? scaleY : 1,
6627
6850
  duration,
6628
6851
  ease: getGSAPEasing(easing2),
6629
6852
  delay
@@ -6631,244 +6854,266 @@ function SpinInFromNothing(target, options = {}) {
6631
6854
  }
6632
6855
  };
6633
6856
  }
6634
- function Uncreate(target, options = {}) {
6857
+ function Morphing(source, target, options = {}) {
6635
6858
  const { duration = 1, easing: easing2 = "easeInOut", delay = 0 } = options;
6636
6859
  return {
6637
6860
  duration,
6638
- target,
6861
+ target: source,
6639
6862
  execute(scene, timeline, startTime) {
6640
- const element = scene.getElement(target);
6641
- if (!element) return;
6642
- const paths = querySelectorAllIncludingSelf(element, "path, line, polyline, polygon, circle, ellipse, rect");
6643
- paths.forEach((path2) => {
6644
- if (path2 instanceof SVGGeometryElement) {
6645
- const length2 = path2.getTotalLength();
6646
- import_gsap3.gsap.set(path2, {
6647
- strokeDasharray: length2,
6648
- strokeDashoffset: 0
6649
- });
6650
- const fill = path2.getAttribute("fill");
6651
- if (fill && fill !== "none") {
6652
- timeline.add(path2, {
6653
- fillOpacity: 0,
6654
- duration: duration * 0.3,
6655
- ease: "power2.in"
6656
- }, startTime + delay);
6657
- }
6658
- timeline.add(path2, {
6659
- strokeDashoffset: length2,
6863
+ var _a;
6864
+ const sourceElement = scene.getElement(source);
6865
+ const targetElement = scene.getOrCreateElement(target);
6866
+ if (!sourceElement || !targetElement) return;
6867
+ const sourcePath = sourceElement.querySelector("path") || sourceElement;
6868
+ const targetPath = targetElement.querySelector("path") || targetElement;
6869
+ import_gsap5.gsap.set(targetElement, { opacity: 0 });
6870
+ if ((_a = import_gsap5.gsap.plugins) == null ? void 0 : _a.morphSVG) {
6871
+ const targetD = targetPath.getAttribute("d");
6872
+ if (targetD) {
6873
+ timeline.add(sourcePath, {
6874
+ morphSVG: targetD,
6660
6875
  duration,
6661
6876
  ease: getGSAPEasing(easing2),
6662
- delay: delay + (fill && fill !== "none" ? duration * 0.1 : 0)
6877
+ delay,
6878
+ onComplete: () => {
6879
+ sourceElement.remove();
6880
+ import_gsap5.gsap.set(targetElement, { opacity: 1 });
6881
+ }
6663
6882
  }, startTime);
6664
6883
  }
6665
- });
6666
- const texts = querySelectorAllIncludingSelf(element, "text");
6667
- texts.forEach((text2) => {
6668
- timeline.add(text2, {
6669
- opacity: 0,
6670
- duration: duration * 0.5,
6671
- ease: "power2.in"
6672
- }, startTime + delay);
6673
- });
6674
- timeline.call(() => {
6675
- element.remove();
6676
- }, startTime + duration + delay);
6677
- }
6678
- };
6679
- }
6680
- function Unwrite(target, options = {}) {
6681
- const { duration = 1, easing: easing2 = "easeIn", delay = 0 } = options;
6682
- return {
6683
- duration,
6684
- target,
6685
- execute(scene, timeline, startTime) {
6686
- const element = scene.getElement(target);
6687
- if (!element) return;
6688
- const texts = querySelectorAllIncludingSelf(element, "text");
6689
- if (texts.length > 0) {
6690
- texts.forEach((text2) => {
6691
- const content = text2.textContent || "";
6692
- const chars = content.split("");
6693
- text2.textContent = "";
6694
- chars.forEach((char, i) => {
6695
- const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
6696
- tspan.textContent = char;
6697
- text2.appendChild(tspan);
6698
- const charDelay = (chars.length - 1 - i) / chars.length * duration;
6699
- timeline.add(tspan, {
6700
- opacity: 0,
6701
- duration: duration / chars.length,
6702
- ease: getGSAPEasing(easing2)
6703
- }, startTime + delay + charDelay);
6704
- });
6705
- });
6706
- timeline.call(() => {
6707
- element.remove();
6708
- }, startTime + duration + delay);
6709
6884
  } else {
6710
- return Uncreate(target, options).execute(scene, timeline, startTime);
6885
+ Transform(source, target, options).execute(scene, timeline, startTime);
6711
6886
  }
6712
6887
  }
6713
6888
  };
6714
6889
  }
6715
- function ShrinkToCenter(target, options = {}) {
6716
- const { duration = 0.5, easing: easing2 = "easeInBack", delay = 0 } = options;
6890
+ function TransformMatchingShapes(source, target, options = {}) {
6891
+ const { duration = 1, easing: easing2 = "easeInOut", delay = 0 } = options;
6717
6892
  return {
6718
6893
  duration,
6719
- target,
6894
+ target: source,
6720
6895
  execute(scene, timeline, startTime) {
6721
- var _a;
6722
- const element = scene.getElement(target);
6723
- if (!element) return;
6724
- const bbox = ((_a = element.getBBox) == null ? void 0 : _a.call(element)) || { x: 0, y: 0, width: 0, height: 0 };
6725
- const cx = bbox.x + bbox.width / 2;
6726
- const cy = bbox.y + bbox.height / 2;
6727
- import_gsap3.gsap.set(element, {
6728
- transformOrigin: `${cx}px ${cy}px`
6729
- });
6730
- timeline.add(element, {
6731
- scale: 0,
6732
- opacity: 0,
6733
- duration,
6734
- ease: getGSAPEasing(easing2),
6735
- delay,
6736
- onComplete: () => {
6737
- element.remove();
6896
+ var _a, _b;
6897
+ const sourceElement = scene.getElement(source);
6898
+ const targetElement = scene.getOrCreateElement(target);
6899
+ if (!sourceElement || !targetElement) return;
6900
+ const sourceChildren = Array.from(sourceElement.children);
6901
+ const targetChildren = Array.from(targetElement.children);
6902
+ import_gsap5.gsap.set(targetElement, { opacity: 0 });
6903
+ const pairs = Math.min(sourceChildren.length, targetChildren.length);
6904
+ for (let i = 0; i < pairs; i++) {
6905
+ const sourceChild = sourceChildren[i];
6906
+ const targetChild = targetChildren[i];
6907
+ const sourceBBox = ((_a = sourceChild.getBBox) == null ? void 0 : _a.call(sourceChild)) || { x: 0, y: 0, width: 0, height: 0 };
6908
+ const targetBBox = ((_b = targetChild.getBBox) == null ? void 0 : _b.call(targetChild)) || { x: 0, y: 0, width: 0, height: 0 };
6909
+ const scaleX = targetBBox.width / (sourceBBox.width || 1);
6910
+ const scaleY = targetBBox.height / (sourceBBox.height || 1);
6911
+ const translateX = targetBBox.x - sourceBBox.x;
6912
+ const translateY = targetBBox.y - sourceBBox.y;
6913
+ timeline.add(sourceChild, {
6914
+ scaleX,
6915
+ scaleY,
6916
+ x: translateX,
6917
+ y: translateY,
6918
+ duration,
6919
+ ease: getGSAPEasing(easing2),
6920
+ delay
6921
+ }, startTime);
6922
+ }
6923
+ for (let i = pairs; i < sourceChildren.length; i++) {
6924
+ const child = sourceChildren[i];
6925
+ if (child) {
6926
+ timeline.add(child, {
6927
+ opacity: 0,
6928
+ duration: duration * 0.5,
6929
+ ease: "power2.in"
6930
+ }, startTime);
6738
6931
  }
6739
- }, startTime);
6932
+ }
6933
+ timeline.call(() => {
6934
+ sourceElement.remove();
6935
+ import_gsap5.gsap.set(targetElement, { opacity: 1 });
6936
+ }, startTime + duration);
6740
6937
  }
6741
6938
  };
6742
6939
  }
6743
-
6744
- // src/animate/animations/fade.ts
6745
- var import_gsap4 = require("gsap");
6746
- init_math();
6747
- init_timeline();
6748
- function directionToVector(direction) {
6749
- if (!direction) return void 0;
6750
- if (Array.isArray(direction)) return direction;
6751
- switch (direction) {
6752
- case "UP":
6753
- return UP;
6754
- case "DOWN":
6755
- return DOWN;
6756
- case "LEFT":
6757
- return LEFT;
6758
- case "RIGHT":
6759
- return RIGHT;
6760
- }
6761
- }
6762
- function FadeIn(target, options = {}) {
6763
- const { duration = 0.5, easing: easing2 = "easeOut", delay = 0, direction, shift = 50 } = options;
6764
- const dir = directionToVector(direction);
6940
+ function TransformMatchingTex(source, target, options = {}) {
6941
+ const { duration = 1, easing: easing2 = "easeInOut", delay = 0 } = options;
6765
6942
  return {
6766
6943
  duration,
6767
- target,
6944
+ target: source,
6768
6945
  execute(scene, timeline, startTime) {
6769
- const element = scene.getOrCreateElement(target);
6770
- if (!element) return;
6771
- const initialState = { opacity: 0 };
6772
- if (dir) {
6773
- initialState.x = -dir[0] * shift;
6774
- initialState.y = -dir[1] * shift;
6946
+ var _a, _b;
6947
+ const sourceElement = scene.getElement(source);
6948
+ const targetElement = scene.getOrCreateElement(target);
6949
+ if (!sourceElement || !targetElement) return;
6950
+ import_gsap5.gsap.set(targetElement, { opacity: 0 });
6951
+ const sourceTexParts = querySelectorAllIncludingSelf(sourceElement, "path, use, text");
6952
+ const targetTexParts = querySelectorAllIncludingSelf(targetElement, "path, use, text");
6953
+ const pairs = Math.min(sourceTexParts.length, targetTexParts.length);
6954
+ for (let i = 0; i < pairs; i++) {
6955
+ const sourcePart = sourceTexParts[i];
6956
+ const targetPart = targetTexParts[i];
6957
+ const sourceBBox = ((_a = sourcePart.getBBox) == null ? void 0 : _a.call(sourcePart)) || { x: 0, y: 0, width: 0, height: 0 };
6958
+ const targetBBox = ((_b = targetPart.getBBox) == null ? void 0 : _b.call(targetPart)) || { x: 0, y: 0, width: 0, height: 0 };
6959
+ const scaleX = targetBBox.width / (sourceBBox.width || 1);
6960
+ const scaleY = targetBBox.height / (sourceBBox.height || 1);
6961
+ const translateX = targetBBox.x + targetBBox.width / 2 - (sourceBBox.x + sourceBBox.width / 2);
6962
+ const translateY = targetBBox.y + targetBBox.height / 2 - (sourceBBox.y + sourceBBox.height / 2);
6963
+ timeline.add(sourcePart, {
6964
+ scaleX: isFinite(scaleX) ? scaleX : 1,
6965
+ scaleY: isFinite(scaleY) ? scaleY : 1,
6966
+ x: translateX,
6967
+ y: translateY,
6968
+ duration,
6969
+ ease: getGSAPEasing(easing2),
6970
+ delay
6971
+ }, startTime);
6775
6972
  }
6776
- import_gsap4.gsap.set(element, initialState);
6777
- const targetState = {
6778
- opacity: 1,
6779
- duration,
6780
- ease: getGSAPEasing(easing2),
6781
- delay
6782
- };
6783
- if (dir) {
6784
- targetState.x = 0;
6785
- targetState.y = 0;
6973
+ for (let i = pairs; i < sourceTexParts.length; i++) {
6974
+ const part = sourceTexParts[i];
6975
+ if (part) {
6976
+ timeline.add(part, {
6977
+ opacity: 0,
6978
+ duration: duration * 0.5,
6979
+ ease: "power2.in"
6980
+ }, startTime);
6981
+ }
6786
6982
  }
6787
- timeline.add(element, targetState, startTime);
6983
+ timeline.call(() => {
6984
+ sourceElement.remove();
6985
+ import_gsap5.gsap.set(targetElement, { opacity: 1 });
6986
+ }, startTime + duration);
6788
6987
  }
6789
6988
  };
6790
6989
  }
6791
- function FadeOut(target, options = {}) {
6792
- const { duration = 0.5, easing: easing2 = "easeIn", delay = 0, direction, shift = 50 } = options;
6793
- const dir = directionToVector(direction);
6990
+ function ClockwiseTransform(source, target, options = {}) {
6991
+ const { duration = 1, easing: easing2 = "easeInOut", delay = 0 } = options;
6794
6992
  return {
6795
6993
  duration,
6796
- target,
6994
+ target: source,
6797
6995
  execute(scene, timeline, startTime) {
6798
- const element = scene.getElement(target);
6799
- if (!element) return;
6800
- const targetState = {
6996
+ var _a, _b;
6997
+ const sourceElement = scene.getElement(source);
6998
+ const targetElement = scene.getOrCreateElement(target);
6999
+ if (!sourceElement || !targetElement) return;
7000
+ import_gsap5.gsap.set(targetElement, { opacity: 0 });
7001
+ const sourceBBox = ((_a = sourceElement.getBBox) == null ? void 0 : _a.call(sourceElement)) || { x: 0, y: 0, width: 0, height: 0 };
7002
+ const targetBBox = ((_b = targetElement.getBBox) == null ? void 0 : _b.call(targetElement)) || { x: 0, y: 0, width: 0, height: 0 };
7003
+ const sourceCenterX = sourceBBox.x + sourceBBox.width / 2;
7004
+ const sourceCenterY = sourceBBox.y + sourceBBox.height / 2;
7005
+ const targetCenterX = targetBBox.x + targetBBox.width / 2;
7006
+ const targetCenterY = targetBBox.y + targetBBox.height / 2;
7007
+ const scaleX = targetBBox.width / (sourceBBox.width || 1);
7008
+ const scaleY = targetBBox.height / (sourceBBox.height || 1);
7009
+ import_gsap5.gsap.set(sourceElement, {
7010
+ transformOrigin: `${sourceCenterX}px ${sourceCenterY}px`
7011
+ });
7012
+ timeline.add(sourceElement, {
7013
+ rotation: 180,
7014
+ scaleX: isFinite(scaleX) ? scaleX : 1,
7015
+ scaleY: isFinite(scaleY) ? scaleY : 1,
7016
+ x: targetCenterX - sourceCenterX,
7017
+ y: targetCenterY - sourceCenterY,
6801
7018
  opacity: 0,
6802
7019
  duration,
6803
7020
  ease: getGSAPEasing(easing2),
6804
7021
  delay,
6805
7022
  onComplete: () => {
6806
- element.remove();
7023
+ sourceElement.remove();
7024
+ import_gsap5.gsap.set(targetElement, { opacity: 1 });
6807
7025
  }
6808
- };
6809
- if (dir) {
6810
- targetState.x = dir[0] * shift;
6811
- targetState.y = dir[1] * shift;
6812
- }
6813
- timeline.add(element, targetState, startTime);
7026
+ }, startTime);
6814
7027
  }
6815
7028
  };
6816
7029
  }
6817
- function FadeInFrom(target, direction, options = {}) {
6818
- return FadeIn(target, __spreadProps(__spreadValues({}, options), { direction }));
6819
- }
6820
- function FadeOutTo(target, direction, options = {}) {
6821
- return FadeOut(target, __spreadProps(__spreadValues({}, options), { direction }));
6822
- }
6823
- function FadeInFromDown(target, options = {}) {
6824
- return FadeIn(target, __spreadProps(__spreadValues({}, options), { direction: "DOWN" }));
6825
- }
6826
- function FadeInFromUp(target, options = {}) {
6827
- return FadeIn(target, __spreadProps(__spreadValues({}, options), { direction: "UP" }));
6828
- }
6829
- function FadeInFromLeft(target, options = {}) {
6830
- return FadeIn(target, __spreadProps(__spreadValues({}, options), { direction: "LEFT" }));
6831
- }
6832
- function FadeInFromRight(target, options = {}) {
6833
- return FadeIn(target, __spreadProps(__spreadValues({}, options), { direction: "RIGHT" }));
6834
- }
6835
- function FadeTransform(source, target, options = {}) {
6836
- const { duration = 0.5, easing: easing2 = "easeInOut", delay = 0 } = options;
7030
+ function CounterclockwiseTransform(source, target, options = {}) {
7031
+ const { duration = 1, easing: easing2 = "easeInOut", delay = 0 } = options;
6837
7032
  return {
6838
7033
  duration,
6839
7034
  target: source,
6840
7035
  execute(scene, timeline, startTime) {
7036
+ var _a, _b;
6841
7037
  const sourceElement = scene.getElement(source);
6842
7038
  const targetElement = scene.getOrCreateElement(target);
6843
7039
  if (!sourceElement || !targetElement) return;
6844
- import_gsap4.gsap.set(targetElement, { opacity: 0 });
7040
+ import_gsap5.gsap.set(targetElement, { opacity: 0 });
7041
+ const sourceBBox = ((_a = sourceElement.getBBox) == null ? void 0 : _a.call(sourceElement)) || { x: 0, y: 0, width: 0, height: 0 };
7042
+ const targetBBox = ((_b = targetElement.getBBox) == null ? void 0 : _b.call(targetElement)) || { x: 0, y: 0, width: 0, height: 0 };
7043
+ const sourceCenterX = sourceBBox.x + sourceBBox.width / 2;
7044
+ const sourceCenterY = sourceBBox.y + sourceBBox.height / 2;
7045
+ const targetCenterX = targetBBox.x + targetBBox.width / 2;
7046
+ const targetCenterY = targetBBox.y + targetBBox.height / 2;
7047
+ const scaleX = targetBBox.width / (sourceBBox.width || 1);
7048
+ const scaleY = targetBBox.height / (sourceBBox.height || 1);
7049
+ import_gsap5.gsap.set(sourceElement, {
7050
+ transformOrigin: `${sourceCenterX}px ${sourceCenterY}px`
7051
+ });
6845
7052
  timeline.add(sourceElement, {
7053
+ rotation: -180,
7054
+ scaleX: isFinite(scaleX) ? scaleX : 1,
7055
+ scaleY: isFinite(scaleY) ? scaleY : 1,
7056
+ x: targetCenterX - sourceCenterX,
7057
+ y: targetCenterY - sourceCenterY,
6846
7058
  opacity: 0,
6847
7059
  duration,
6848
7060
  ease: getGSAPEasing(easing2),
6849
7061
  delay,
6850
7062
  onComplete: () => {
6851
7063
  sourceElement.remove();
7064
+ import_gsap5.gsap.set(targetElement, { opacity: 1 });
6852
7065
  }
6853
7066
  }, startTime);
6854
- timeline.add(targetElement, {
6855
- opacity: 1,
7067
+ }
7068
+ };
7069
+ }
7070
+ function TransformFromCopy(source, target, options = {}) {
7071
+ const { duration = 1, easing: easing2 = "easeInOut", delay = 0 } = options;
7072
+ return {
7073
+ duration,
7074
+ target: source,
7075
+ execute(scene, timeline, startTime) {
7076
+ var _a, _b, _c;
7077
+ const sourceElement = scene.getElement(source);
7078
+ const targetElement = scene.getOrCreateElement(target);
7079
+ if (!sourceElement || !targetElement) return;
7080
+ import_gsap5.gsap.set(targetElement, { opacity: 0 });
7081
+ const copyElement = sourceElement.cloneNode(true);
7082
+ copyElement.setAttribute("id", `${sourceElement.id}-copy-${Date.now()}`);
7083
+ (_a = sourceElement.parentNode) == null ? void 0 : _a.appendChild(copyElement);
7084
+ const sourceBBox = ((_b = sourceElement.getBBox) == null ? void 0 : _b.call(sourceElement)) || { x: 0, y: 0, width: 0, height: 0 };
7085
+ const targetBBox = ((_c = targetElement.getBBox) == null ? void 0 : _c.call(targetElement)) || { x: 0, y: 0, width: 0, height: 0 };
7086
+ const sourceCenterX = sourceBBox.x + sourceBBox.width / 2;
7087
+ const sourceCenterY = sourceBBox.y + sourceBBox.height / 2;
7088
+ const targetCenterX = targetBBox.x + targetBBox.width / 2;
7089
+ const targetCenterY = targetBBox.y + targetBBox.height / 2;
7090
+ const scaleX = targetBBox.width / (sourceBBox.width || 1);
7091
+ const scaleY = targetBBox.height / (sourceBBox.height || 1);
7092
+ import_gsap5.gsap.set(copyElement, {
7093
+ transformOrigin: `${sourceCenterX}px ${sourceCenterY}px`
7094
+ });
7095
+ timeline.add(copyElement, {
7096
+ scaleX: isFinite(scaleX) ? scaleX : 1,
7097
+ scaleY: isFinite(scaleY) ? scaleY : 1,
7098
+ x: targetCenterX - sourceCenterX,
7099
+ y: targetCenterY - sourceCenterY,
7100
+ opacity: 0,
6856
7101
  duration,
6857
7102
  ease: getGSAPEasing(easing2),
6858
- delay
7103
+ delay,
7104
+ onComplete: () => {
7105
+ copyElement.remove();
7106
+ import_gsap5.gsap.set(targetElement, { opacity: 1 });
7107
+ }
6859
7108
  }, startTime);
6860
7109
  }
6861
7110
  };
6862
7111
  }
6863
7112
 
6864
- // src/animate/animations/index.ts
6865
- init_transform();
6866
-
6867
7113
  // src/animate/animations/move.ts
6868
7114
  var import_gsap6 = require("gsap");
6869
7115
  var import_MotionPathPlugin = require("gsap/MotionPathPlugin");
6870
7116
  init_timeline();
6871
- init_utils();
6872
7117
  if (typeof window !== "undefined") {
6873
7118
  import_gsap6.gsap.registerPlugin(import_MotionPathPlugin.MotionPathPlugin);
6874
7119
  }
@@ -7190,7 +7435,6 @@ function FadeToColor(target, color, options = {}) {
7190
7435
  // src/animate/animations/indicate.ts
7191
7436
  var import_gsap7 = require("gsap");
7192
7437
  init_timeline();
7193
- init_utils();
7194
7438
  function Indicate(target, options = {}) {
7195
7439
  const {
7196
7440
  duration = 0.5,
@@ -7682,8 +7926,9 @@ function PhaseFlow(target, options = {}) {
7682
7926
  }
7683
7927
 
7684
7928
  // src/animate/animations/composition.ts
7929
+ var import_gsap8 = require("gsap");
7685
7930
  init_core();
7686
- init_utils();
7931
+ init_timeline();
7687
7932
  function AnimationGroup(animations, options = {}) {
7688
7933
  var _a, _b;
7689
7934
  const { lagRatio = 0 } = options;
@@ -7738,16 +7983,61 @@ function Wait(duration = 1) {
7738
7983
  }
7739
7984
  };
7740
7985
  }
7741
- function ApplyMethod(target, method, options = {}) {
7742
- const { duration = 0.5, easing: easing2 = "easeInOut", delay = 0 } = options;
7986
+ function ApplyMethod(target, methodOrName, argsOrOptions, options = {}) {
7987
+ let method;
7988
+ let config;
7989
+ if (typeof methodOrName === "string") {
7990
+ const methodName = methodOrName;
7991
+ const args = argsOrOptions || [];
7992
+ config = options;
7993
+ method = (d) => {
7994
+ const fn = d[methodName];
7995
+ if (typeof fn === "function") {
7996
+ return fn.apply(d, args);
7997
+ }
7998
+ console.warn(`Method "${methodName}" not found on Diagram`);
7999
+ return d;
8000
+ };
8001
+ } else {
8002
+ method = methodOrName;
8003
+ config = argsOrOptions || {};
8004
+ }
8005
+ const { duration = 0.5, easing: easing2 = "easeInOut", delay = 0 } = config;
7743
8006
  const targetDiagram = method(target);
7744
8007
  return {
7745
8008
  duration,
7746
8009
  target,
7747
8010
  execute(scene, timeline, startTime) {
7748
- Promise.resolve().then(() => (init_transform(), transform_exports)).then(({ Transform: Transform2 }) => {
7749
- Transform2(target, targetDiagram, { duration, easing: easing2, delay }).execute(scene, timeline, startTime);
8011
+ var _a, _b, _c, _d, _e, _f;
8012
+ const element = scene.getOrCreateElement(target);
8013
+ if (!element) return;
8014
+ const sourceBounds = target.bounds();
8015
+ const targetBounds = targetDiagram.bounds();
8016
+ const sourceCenter = [
8017
+ sourceBounds.x + sourceBounds.width / 2,
8018
+ sourceBounds.y + sourceBounds.height / 2
8019
+ ];
8020
+ const targetCenter = [
8021
+ targetBounds.x + targetBounds.width / 2,
8022
+ targetBounds.y + targetBounds.height / 2
8023
+ ];
8024
+ const translateX = ((_a = targetCenter[0]) != null ? _a : 0) - ((_b = sourceCenter[0]) != null ? _b : 0);
8025
+ const translateY = ((_c = targetCenter[1]) != null ? _c : 0) - ((_d = sourceCenter[1]) != null ? _d : 0);
8026
+ const scaleX = targetBounds.width / (sourceBounds.width || 1);
8027
+ const scaleY = targetBounds.height / (sourceBounds.height || 1);
8028
+ import_gsap8.gsap.set(element, {
8029
+ transformOrigin: `${(_e = sourceCenter[0]) != null ? _e : 0}px ${(_f = sourceCenter[1]) != null ? _f : 0}px`
7750
8030
  });
8031
+ timeline.add(element, {
8032
+ x: translateX,
8033
+ y: -translateY,
8034
+ // SVG Y 轴翻转
8035
+ scaleX: isFinite(scaleX) ? scaleX : 1,
8036
+ scaleY: isFinite(scaleY) ? scaleY : 1,
8037
+ duration,
8038
+ ease: getGSAPEasing(easing2),
8039
+ delay
8040
+ }, startTime);
7751
8041
  }
7752
8042
  };
7753
8043
  }
@@ -7812,9 +8102,8 @@ function transformPathByHomotopy(d, homotopyFn, t) {
7812
8102
  }
7813
8103
 
7814
8104
  // src/animate/animations/text.ts
7815
- var import_gsap8 = require("gsap");
8105
+ var import_gsap9 = require("gsap");
7816
8106
  init_timeline();
7817
- init_utils();
7818
8107
  function AddTextLetterByLetter(target, options = {}) {
7819
8108
  const { duration = 1, easing: easing2 = "linear", delay = 0, timePerChar } = options;
7820
8109
  return {
@@ -7833,7 +8122,7 @@ function AddTextLetterByLetter(target, options = {}) {
7833
8122
  chars.forEach((char, i) => {
7834
8123
  const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
7835
8124
  tspan.textContent = char;
7836
- import_gsap8.gsap.set(tspan, { opacity: 0 });
8125
+ import_gsap9.gsap.set(tspan, { opacity: 0 });
7837
8126
  text2.appendChild(tspan);
7838
8127
  const charDelay = i * charDuration;
7839
8128
  timeline.add(tspan, {
@@ -7910,7 +8199,7 @@ function Typewriter(target, options = {}) {
7910
8199
  cursorTspan.textContent = cursorChar;
7911
8200
  cursorTspan.setAttribute("class", "typewriter-cursor");
7912
8201
  text2.appendChild(cursorTspan);
7913
- import_gsap8.gsap.to(cursorTspan, {
8202
+ import_gsap9.gsap.to(cursorTspan, {
7914
8203
  opacity: 0,
7915
8204
  duration: cursorBlinkInterval,
7916
8205
  repeat: -1,
@@ -7932,8 +8221,8 @@ function Typewriter(target, options = {}) {
7932
8221
  });
7933
8222
  if (cursorTspan) {
7934
8223
  timeline.call(() => {
7935
- import_gsap8.gsap.killTweensOf(cursorTspan);
7936
- import_gsap8.gsap.to(cursorTspan, {
8224
+ import_gsap9.gsap.killTweensOf(cursorTspan);
8225
+ import_gsap9.gsap.to(cursorTspan, {
7937
8226
  opacity: 0,
7938
8227
  duration: 0.3,
7939
8228
  delay: 1
@@ -8145,7 +8434,7 @@ function CameraSetFrame(camera, targetFrame, options = {}) {
8145
8434
  }
8146
8435
 
8147
8436
  // src/animate/animations/traced-path.ts
8148
- var import_gsap9 = require("gsap");
8437
+ var import_gsap10 = require("gsap");
8149
8438
  init_core();
8150
8439
  function TracedPath(target, config = {}) {
8151
8440
  const {
@@ -8187,11 +8476,10 @@ function TracedPath(target, config = {}) {
8187
8476
  const stop = () => {
8188
8477
  state.active = false;
8189
8478
  };
8190
- return {
8191
- diagram: traceDiagram,
8192
- updater,
8193
- stop
8194
- };
8479
+ const result = traceDiagram;
8480
+ result.updater = updater;
8481
+ result.stop = stop;
8482
+ return result;
8195
8483
  }
8196
8484
  function TracedPathAnimation(target, config = {}) {
8197
8485
  const {
@@ -8255,7 +8543,7 @@ function GrowArrow(arrowDiagram, config = {}) {
8255
8543
  lines.forEach((line3) => {
8256
8544
  var _a;
8257
8545
  const length2 = ((_a = line3.getTotalLength) == null ? void 0 : _a.call(line3)) || 100;
8258
- import_gsap9.gsap.set(line3, {
8546
+ import_gsap10.gsap.set(line3, {
8259
8547
  strokeDasharray: length2,
8260
8548
  strokeDashoffset: length2
8261
8549
  });
@@ -8270,7 +8558,7 @@ function GrowArrow(arrowDiagram, config = {}) {
8270
8558
  }
8271
8559
 
8272
8560
  // src/animate/animations/p1-animations.ts
8273
- var import_gsap10 = require("gsap");
8561
+ var import_gsap11 = require("gsap");
8274
8562
  init_core();
8275
8563
  init_complex();
8276
8564
  function AddTextWordByWord(textDiagram, config = {}) {
@@ -8283,7 +8571,7 @@ function AddTextWordByWord(textDiagram, config = {}) {
8283
8571
  if (!element) return;
8284
8572
  const textElement = element.querySelector("text") || element;
8285
8573
  if (!(textElement instanceof SVGTextElement)) {
8286
- import_gsap10.gsap.set(element, { opacity: 0 });
8574
+ import_gsap11.gsap.set(element, { opacity: 0 });
8287
8575
  timeline.add(element, { opacity: 1, duration }, startTime);
8288
8576
  return;
8289
8577
  }
@@ -8309,18 +8597,19 @@ function AddTextWordByWord(textDiagram, config = {}) {
8309
8597
  }
8310
8598
  };
8311
8599
  }
8312
- function ShowIncreasingSubsets(group4, config = {}) {
8600
+ function ShowIncreasingSubsets(groupOrArray, config = {}) {
8313
8601
  const { duration = 1 } = config;
8602
+ const targetGroup = Array.isArray(groupOrArray) ? group(...groupOrArray) : groupOrArray;
8314
8603
  return {
8315
8604
  duration,
8316
- target: group4,
8605
+ target: targetGroup,
8317
8606
  execute(scene, timeline, startTime) {
8318
- const element = scene.getOrCreateElement(group4);
8607
+ const element = scene.getOrCreateElement(targetGroup);
8319
8608
  if (!element) return;
8320
8609
  const children = Array.from(element.children);
8321
8610
  if (children.length === 0) return;
8322
8611
  const timePerChild = duration / children.length;
8323
- children.forEach((child) => import_gsap10.gsap.set(child, { opacity: 0 }));
8612
+ children.forEach((child) => import_gsap11.gsap.set(child, { opacity: 0 }));
8324
8613
  children.forEach((child, i) => {
8325
8614
  timeline.add(child, { opacity: 1, duration: timePerChild * 0.5 }, startTime + i * timePerChild);
8326
8615
  });
@@ -8338,7 +8627,7 @@ function ChangingDecimal(textDiagram, targetValue, config = {}) {
8338
8627
  const textElement = element.querySelector("text") || element;
8339
8628
  const obj = { value: startValue };
8340
8629
  timeline.call(() => {
8341
- import_gsap10.gsap.to(obj, {
8630
+ import_gsap11.gsap.to(obj, {
8342
8631
  value: targetValue,
8343
8632
  duration,
8344
8633
  ease: "none",
@@ -8369,7 +8658,7 @@ function Broadcast(source, config = {}) {
8369
8658
  const waveDiagram = circle(0.01).stroke(color).strokeWidth(0.05).fill("none").translate(cx, cy);
8370
8659
  const waveElement = scene.getOrCreateElement(waveDiagram);
8371
8660
  if (!waveElement) continue;
8372
- import_gsap10.gsap.set(waveElement, { opacity: 1 });
8661
+ import_gsap11.gsap.set(waveElement, { opacity: 1 });
8373
8662
  const waveStartTime = startTime + i * waveDelay;
8374
8663
  timeline.add(waveElement, {
8375
8664
  attr: { r: maxRadius },
@@ -8402,7 +8691,7 @@ function ApplyFunction(diagram, fn, config = {}) {
8402
8691
  }
8403
8692
  const obj = { progress: 0 };
8404
8693
  timeline.call(() => {
8405
- import_gsap10.gsap.to(obj, {
8694
+ import_gsap11.gsap.to(obj, {
8406
8695
  progress: 1,
8407
8696
  duration,
8408
8697
  ease: "power2.inOut",
@@ -8441,7 +8730,7 @@ function Restore(diagram, config = {}) {
8441
8730
  const currentElement = scene.getElement(diagram);
8442
8731
  const targetElement = scene.getOrCreateElement(savedState);
8443
8732
  if (!currentElement || !targetElement) return;
8444
- import_gsap10.gsap.set(targetElement, { opacity: 0 });
8733
+ import_gsap11.gsap.set(targetElement, { opacity: 0 });
8445
8734
  timeline.add(currentElement, { opacity: 0, duration: duration / 2 }, startTime);
8446
8735
  timeline.add(targetElement, { opacity: 1, duration: duration / 2 }, startTime + duration / 2);
8447
8736
  }
@@ -8515,7 +8804,7 @@ var Axes = class {
8515
8804
  );
8516
8805
  }
8517
8806
  for (let y = yMin; y <= yMax; y += yStep) {
8518
- const py = oy - y * yScale;
8807
+ const py = oy + y * yScale;
8519
8808
  diagrams.push(
8520
8809
  line([ox + xMin * xScale, py], [ox + xMax * xScale, py]).stroke(gridColor).strokeWidth(gridStrokeWidth)
8521
8810
  );
@@ -8524,8 +8813,8 @@ var Axes = class {
8524
8813
  const xAxisStart = [ox + xMin * xScale, oy];
8525
8814
  const xAxisEnd = [ox + xMax * xScale, oy];
8526
8815
  diagrams.push(arrow(xAxisStart, xAxisEnd, { headSize }).stroke(axisColor).strokeWidth(strokeWidth));
8527
- const yAxisStart = [ox, oy - yMin * yScale];
8528
- const yAxisEnd = [ox, oy - yMax * yScale];
8816
+ const yAxisStart = [ox, oy + yMin * yScale];
8817
+ const yAxisEnd = [ox, oy + yMax * yScale];
8529
8818
  diagrams.push(arrow(yAxisStart, yAxisEnd, { headSize }).stroke(axisColor).strokeWidth(strokeWidth));
8530
8819
  if (showTicks || showLabels) {
8531
8820
  for (let x = xMin; x <= xMax; x += xStep) {
@@ -8544,7 +8833,7 @@ var Axes = class {
8544
8833
  }
8545
8834
  for (let y = yMin; y <= yMax; y += yStep) {
8546
8835
  if (y === 0) continue;
8547
- const py = oy - y * yScale;
8836
+ const py = oy + y * yScale;
8548
8837
  if (showTicks) {
8549
8838
  diagrams.push(
8550
8839
  line([ox - tickSize, py], [ox + tickSize, py]).stroke(axisColor).strokeWidth(strokeWidth)
@@ -8571,7 +8860,7 @@ var Axes = class {
8571
8860
  const yScale = yLength / (yRange[1] - yRange[0]);
8572
8861
  return [
8573
8862
  origin[0] + x * xScale,
8574
- origin[1] - yVal * yScale
8863
+ origin[1] + yVal * yScale
8575
8864
  // Y 轴向上为正
8576
8865
  ];
8577
8866
  }
@@ -8582,7 +8871,8 @@ var Axes = class {
8582
8871
  const yScale = yLength / (yRange[1] - yRange[0]);
8583
8872
  return [
8584
8873
  (px - origin[0]) / xScale,
8585
- -(pyVal - origin[1]) / yScale
8874
+ (pyVal - origin[1]) / yScale
8875
+ // Y 轴向上为正
8586
8876
  ];
8587
8877
  }
8588
8878
  /** 绑制函数图像 */
@@ -8869,9 +9159,9 @@ var LinearTransformationScene = class extends Scene {
8869
9159
  ];
8870
9160
  void _transformFn;
8871
9161
  return new Promise((resolve) => {
8872
- import("gsap").then(({ gsap: gsap11 }) => {
9162
+ import("gsap").then(({ gsap: gsap12 }) => {
8873
9163
  const obj = { t: 0 };
8874
- gsap11.to(obj, {
9164
+ gsap12.to(obj, {
8875
9165
  t: 1,
8876
9166
  duration,
8877
9167
  ease: "power2.inOut",
@@ -9313,8 +9603,10 @@ var Interactive = class {
9313
9603
  const rect2 = this.svg.getBoundingClientRect();
9314
9604
  const clientX = "touches" in e ? (_b = (_a = e.touches[0]) == null ? void 0 : _a.clientX) != null ? _b : 0 : e.clientX;
9315
9605
  const clientY = "touches" in e ? (_d = (_c = e.touches[0]) == null ? void 0 : _c.clientY) != null ? _d : 0 : e.clientY;
9316
- let newX = (clientX - rect2.left) * (this.options.width / rect2.width);
9317
- let newY = (clientY - rect2.top) * (this.options.height / rect2.height);
9606
+ const svgWidth = this.svg.viewBox.baseVal.width || this.options.width;
9607
+ const svgHeight = this.svg.viewBox.baseVal.height || this.options.height;
9608
+ let newX = (clientX - rect2.left) * (svgWidth / rect2.width);
9609
+ let newY = (clientY - rect2.top) * (svgHeight / rect2.height);
9318
9610
  if (constraint) {
9319
9611
  [newX, newY] = constraint([newX, newY]);
9320
9612
  }
@@ -10336,19 +10628,19 @@ var Table = class {
10336
10628
  } else {
10337
10629
  this._colWidths = Array(numCols).fill(80);
10338
10630
  }
10339
- if (config.hLines === true) {
10340
- this._hLines = Array.from({ length: numRows + 1 }, (_, i) => i);
10631
+ if (config.hLines === false) {
10632
+ this._hLines = [];
10341
10633
  } else if (Array.isArray(config.hLines)) {
10342
10634
  this._hLines = config.hLines;
10343
10635
  } else {
10344
- this._hLines = [];
10636
+ this._hLines = Array.from({ length: numRows + 1 }, (_, i) => i);
10345
10637
  }
10346
- if (config.vLines === true) {
10347
- this._vLines = Array.from({ length: numCols + 1 }, (_, i) => i);
10638
+ if (config.vLines === false) {
10639
+ this._vLines = [];
10348
10640
  } else if (Array.isArray(config.vLines)) {
10349
10641
  this._vLines = config.vLines;
10350
10642
  } else {
10351
- this._vLines = [];
10643
+ this._vLines = Array.from({ length: numCols + 1 }, (_, i) => i);
10352
10644
  }
10353
10645
  this._headerRow = (_a = config.headerRow) != null ? _a : false;
10354
10646
  this._headerCol = (_b = config.headerCol) != null ? _b : false;
@@ -10369,11 +10661,12 @@ var Table = class {
10369
10661
  buildCells() {
10370
10662
  var _a, _b;
10371
10663
  const cells = [];
10372
- let y = 0;
10664
+ let y = this._totalHeight;
10373
10665
  for (let row = 0; row < this._data.length; row++) {
10374
10666
  const rowCells = [];
10375
10667
  let x = 0;
10376
10668
  const rowHeight = (_a = this._rowHeights[row]) != null ? _a : 30;
10669
+ y -= rowHeight / 2;
10377
10670
  for (let col = 0; col < this._data[row].length; col++) {
10378
10671
  const colWidth = (_b = this._colWidths[col]) != null ? _b : 80;
10379
10672
  const cellData = this._data[row][col];
@@ -10393,14 +10686,14 @@ var Table = class {
10393
10686
  row,
10394
10687
  col,
10395
10688
  x: x + colWidth / 2,
10396
- y: y + rowHeight / 2,
10689
+ y,
10397
10690
  width: colWidth,
10398
10691
  height: rowHeight
10399
10692
  });
10400
10693
  x += colWidth;
10401
10694
  }
10402
10695
  cells.push(rowCells);
10403
- y += rowHeight;
10696
+ y -= rowHeight / 2;
10404
10697
  }
10405
10698
  return cells;
10406
10699
  }
@@ -10491,22 +10784,22 @@ var Table = class {
10491
10784
  var _a, _b, _c, _d, _e;
10492
10785
  const elements = [];
10493
10786
  if (this._alternateRowColor) {
10494
- let y2 = 0;
10787
+ let y2 = this._totalHeight;
10495
10788
  for (let row = 0; row < this._data.length; row++) {
10496
10789
  const rowHeight = (_a = this._rowHeights[row]) != null ? _a : 30;
10790
+ y2 -= rowHeight;
10497
10791
  if (row % 2 === 1) {
10498
10792
  elements.push(
10499
10793
  rect(this._totalWidth, rowHeight).fill(this._alternateRowColor).translate(this._totalWidth / 2, y2 + rowHeight / 2)
10500
10794
  );
10501
10795
  }
10502
- y2 += rowHeight;
10503
10796
  }
10504
10797
  }
10505
10798
  if (this._headerBackground) {
10506
10799
  if (this._headerRow) {
10507
10800
  const headerHeight = (_b = this._rowHeights[0]) != null ? _b : 30;
10508
10801
  elements.push(
10509
- rect(this._totalWidth, headerHeight).fill(this._headerBackground).translate(this._totalWidth / 2, headerHeight / 2)
10802
+ rect(this._totalWidth, headerHeight).fill(this._headerBackground).translate(this._totalWidth / 2, this._totalHeight - headerHeight / 2)
10510
10803
  );
10511
10804
  }
10512
10805
  if (this._headerCol) {
@@ -10516,7 +10809,7 @@ var Table = class {
10516
10809
  );
10517
10810
  }
10518
10811
  }
10519
- let y = 0;
10812
+ let y = this._totalHeight;
10520
10813
  for (let i = 0; i <= this._data.length; i++) {
10521
10814
  if (this._hLines.includes(i)) {
10522
10815
  elements.push(
@@ -10524,7 +10817,7 @@ var Table = class {
10524
10817
  );
10525
10818
  }
10526
10819
  if (i < this._data.length) {
10527
- y += (_d = this._rowHeights[i]) != null ? _d : 30;
10820
+ y -= (_d = this._rowHeights[i]) != null ? _d : 30;
10528
10821
  }
10529
10822
  }
10530
10823
  let x = 0;
@@ -15296,119 +15589,1180 @@ function axes3D(config = {}) {
15296
15589
  );
15297
15590
  group4.add(zArrow);
15298
15591
  }
15299
- if (showTicks) {
15300
- for (let x = Math.ceil(xRange[0]); x <= Math.floor(xRange[1]); x += tickSpacing) {
15301
- if (x === 0) continue;
15302
- const tickGeom = new THREE14.BufferGeometry().setFromPoints([
15303
- new THREE14.Vector3(x, -tickLength, 0),
15304
- new THREE14.Vector3(x, tickLength, 0)
15305
- ]);
15306
- group4.add(new THREE14.Line(tickGeom, xMaterial));
15592
+ if (showTicks) {
15593
+ for (let x = Math.ceil(xRange[0]); x <= Math.floor(xRange[1]); x += tickSpacing) {
15594
+ if (x === 0) continue;
15595
+ const tickGeom = new THREE14.BufferGeometry().setFromPoints([
15596
+ new THREE14.Vector3(x, -tickLength, 0),
15597
+ new THREE14.Vector3(x, tickLength, 0)
15598
+ ]);
15599
+ group4.add(new THREE14.Line(tickGeom, xMaterial));
15600
+ }
15601
+ for (let y = Math.ceil(yRange[0]); y <= Math.floor(yRange[1]); y += tickSpacing) {
15602
+ if (y === 0) continue;
15603
+ const tickGeom = new THREE14.BufferGeometry().setFromPoints([
15604
+ new THREE14.Vector3(-tickLength, y, 0),
15605
+ new THREE14.Vector3(tickLength, y, 0)
15606
+ ]);
15607
+ group4.add(new THREE14.Line(tickGeom, yMaterial));
15608
+ }
15609
+ for (let z = Math.ceil(zRange[0]); z <= Math.floor(zRange[1]); z += tickSpacing) {
15610
+ if (z === 0) continue;
15611
+ const tickGeom = new THREE14.BufferGeometry().setFromPoints([
15612
+ new THREE14.Vector3(0, -tickLength, z),
15613
+ new THREE14.Vector3(0, tickLength, z)
15614
+ ]);
15615
+ group4.add(new THREE14.Line(tickGeom, zMaterial));
15616
+ }
15617
+ }
15618
+ return new ThreeDiagram(group4);
15619
+ }
15620
+ function createArrowHead(position, direction, size, color) {
15621
+ const geometry = new THREE14.ConeGeometry(size * 0.5, size, 8);
15622
+ const material = new THREE14.MeshBasicMaterial({ color });
15623
+ const cone2 = new THREE14.Mesh(geometry, material);
15624
+ cone2.position.copy(position);
15625
+ const axis = new THREE14.Vector3(0, 1, 0);
15626
+ const quaternion = new THREE14.Quaternion().setFromUnitVectors(axis, direction.normalize());
15627
+ cone2.setRotationFromQuaternion(quaternion);
15628
+ return cone2;
15629
+ }
15630
+ var createAxes3D = axes3D;
15631
+
15632
+ // src/webgl/math/vector3d.ts
15633
+ var THREE15 = __toESM(require("three"));
15634
+ function vector3D(from = [0, 0, 0], to = [1, 0, 0], config = {}) {
15635
+ const {
15636
+ color = "#3498db",
15637
+ lineWidth = 2,
15638
+ arrowSize = 0.15,
15639
+ showArrow = true
15640
+ } = config;
15641
+ const group4 = new THREE15.Group();
15642
+ const material = new THREE15.LineBasicMaterial({ color, linewidth: lineWidth });
15643
+ const geometry = new THREE15.BufferGeometry().setFromPoints([
15644
+ new THREE15.Vector3(from[0], from[1], from[2]),
15645
+ new THREE15.Vector3(to[0], to[1], to[2])
15646
+ ]);
15647
+ const line3 = new THREE15.Line(geometry, material);
15648
+ group4.add(line3);
15649
+ if (showArrow) {
15650
+ const direction = new THREE15.Vector3(
15651
+ to[0] - from[0],
15652
+ to[1] - from[1],
15653
+ to[2] - from[2]
15654
+ ).normalize();
15655
+ const arrowGeometry = new THREE15.ConeGeometry(arrowSize * 0.5, arrowSize, 8);
15656
+ const arrowMaterial = new THREE15.MeshBasicMaterial({ color });
15657
+ const arrow2 = new THREE15.Mesh(arrowGeometry, arrowMaterial);
15658
+ arrow2.position.set(to[0], to[1], to[2]);
15659
+ const axis = new THREE15.Vector3(0, 1, 0);
15660
+ const quaternion = new THREE15.Quaternion().setFromUnitVectors(axis, direction);
15661
+ arrow2.setRotationFromQuaternion(quaternion);
15662
+ group4.add(arrow2);
15663
+ }
15664
+ return new ThreeDiagram(group4);
15665
+ }
15666
+ var createVector3D = vector3D;
15667
+
15668
+ // src/webgl/math/grid3d.ts
15669
+ var THREE16 = __toESM(require("three"));
15670
+ function grid3D(config = {}) {
15671
+ const {
15672
+ size = 10,
15673
+ divisions = 10,
15674
+ color1 = "#444444",
15675
+ color2 = "#888888",
15676
+ plane: plane2 = "xz",
15677
+ center = [0, 0, 0]
15678
+ } = config;
15679
+ const gridHelper = new THREE16.GridHelper(size, divisions, color1, color2);
15680
+ switch (plane2) {
15681
+ case "xy":
15682
+ gridHelper.rotation.x = Math.PI / 2;
15683
+ break;
15684
+ case "yz":
15685
+ gridHelper.rotation.z = Math.PI / 2;
15686
+ break;
15687
+ case "xz":
15688
+ default:
15689
+ break;
15690
+ }
15691
+ gridHelper.position.set(center[0], center[1], center[2]);
15692
+ return new ThreeDiagram(gridHelper);
15693
+ }
15694
+ var createGrid3D = grid3D;
15695
+
15696
+ // src/webgl/materials/index.ts
15697
+ var THREE17 = __toESM(require("three"));
15698
+
15699
+ // src/webgl/lights/index.ts
15700
+ var THREE18 = __toESM(require("three"));
15701
+
15702
+ // src/webgl/overlay/index.ts
15703
+ var THREE19 = __toESM(require("three"));
15704
+ var import_CSS2DRenderer = require("three/examples/jsm/renderers/CSS2DRenderer.js");
15705
+
15706
+ // src/showcase/Showcase.tsx
15707
+ var import_react3 = __toESM(require("react"));
15708
+
15709
+ // src/showcase/hooks/useShowcase.ts
15710
+ var import_react = require("react");
15711
+
15712
+ // src/showcase/ShowcaseCore.ts
15713
+ init_core();
15714
+
15715
+ // src/showcase/utils/scope-api.ts
15716
+ var scope_api_exports = {};
15717
+ __export(scope_api_exports, {
15718
+ AddTextLetterByLetter: () => AddTextLetterByLetter,
15719
+ AddTextWordByWord: () => AddTextWordByWord,
15720
+ AnimationGroup: () => AnimationGroup,
15721
+ ApplyComplexFunction: () => ApplyComplexFunction,
15722
+ ApplyFunction: () => ApplyFunction,
15723
+ ApplyMethod: () => ApplyMethod,
15724
+ ApplyWave: () => ApplyWave,
15725
+ Axes: () => Axes,
15726
+ Blink: () => Blink,
15727
+ Broadcast: () => Broadcast,
15728
+ Camera: () => Camera,
15729
+ CameraAutoZoom: () => CameraAutoZoom,
15730
+ CameraMove: () => CameraMove,
15731
+ CameraReset: () => CameraReset,
15732
+ CameraSetFrame: () => CameraSetFrame,
15733
+ CameraZoom: () => CameraZoom,
15734
+ ChangingDecimal: () => ChangingDecimal,
15735
+ Circumscribe: () => Circumscribe,
15736
+ ClockwiseTransform: () => ClockwiseTransform,
15737
+ ColorScales: () => ColorScales,
15738
+ Colors: () => Colors,
15739
+ CounterclockwiseTransform: () => CounterclockwiseTransform,
15740
+ Create: () => Create,
15741
+ CyclicReplace: () => CyclicReplace,
15742
+ DEGREES: () => DEGREES,
15743
+ DL: () => DL,
15744
+ DOWN: () => DOWN,
15745
+ DR: () => DR,
15746
+ DiGraph: () => DiGraph,
15747
+ Diagram: () => Diagram,
15748
+ Dir: () => Dir,
15749
+ DrawBorderThenFill: () => DrawBorderThenFill,
15750
+ FadeIn: () => FadeIn,
15751
+ FadeInFrom: () => FadeInFrom,
15752
+ FadeInFromDown: () => FadeInFromDown,
15753
+ FadeInFromLeft: () => FadeInFromLeft,
15754
+ FadeInFromRight: () => FadeInFromRight,
15755
+ FadeInFromUp: () => FadeInFromUp,
15756
+ FadeOut: () => FadeOut,
15757
+ FadeOutTo: () => FadeOutTo,
15758
+ FadeToColor: () => FadeToColor,
15759
+ FadeTransform: () => FadeTransform,
15760
+ Flash: () => Flash,
15761
+ FocusOn: () => FocusOn,
15762
+ Graph: () => Graph,
15763
+ GrowArrow: () => GrowArrow,
15764
+ GrowFromCenter: () => GrowFromCenter,
15765
+ GrowFromEdge: () => GrowFromEdge,
15766
+ GrowFromPoint: () => GrowFromPoint,
15767
+ Homotopy: () => Homotopy,
15768
+ IDENTITY: () => IDENTITY,
15769
+ Indicate: () => Indicate,
15770
+ Interactive: () => Interactive,
15771
+ LEFT: () => LEFT,
15772
+ LaggedStart: () => LaggedStart,
15773
+ LaggedStartMap: () => LaggedStartMap,
15774
+ ManimColor: () => ManimColor,
15775
+ MatrixDisplay: () => MatrixDisplay,
15776
+ Morphing: () => Morphing,
15777
+ MoveAlongPath: () => MoveAlongPath,
15778
+ MoveTo: () => MoveTo,
15779
+ MoveToTarget: () => MoveToTarget,
15780
+ MovingCamera: () => MovingCamera,
15781
+ NumberLine: () => NumberLine,
15782
+ NumberPlane: () => NumberPlane,
15783
+ ORIGIN: () => ORIGIN,
15784
+ PI: () => PI,
15785
+ PhaseFlow: () => PhaseFlow,
15786
+ PolarAxes: () => PolarAxes,
15787
+ RIGHT: () => RIGHT,
15788
+ RemoveTextLetterByLetter: () => RemoveTextLetterByLetter,
15789
+ ReplacementTransform: () => ReplacementTransform,
15790
+ Restore: () => Restore,
15791
+ Rotate: () => Rotate,
15792
+ Rotating: () => Rotating,
15793
+ Scale: () => Scale,
15794
+ ScaleInPlace: () => ScaleInPlace,
15795
+ Scene: () => Scene,
15796
+ Shift: () => Shift,
15797
+ ShowIncreasingSubsets: () => ShowIncreasingSubsets,
15798
+ ShowPassingFlash: () => ShowPassingFlash,
15799
+ ShrinkToCenter: () => ShrinkToCenter,
15800
+ SpinInFromNothing: () => SpinInFromNothing,
15801
+ SpiralIn: () => SpiralIn,
15802
+ Succession: () => Succession,
15803
+ Swap: () => Swap,
15804
+ TAU: () => TAU,
15805
+ Table: () => Table,
15806
+ ThreeB1BColors: () => ThreeB1BColors,
15807
+ TracedPath: () => TracedPath,
15808
+ TracedPathAnimation: () => TracedPathAnimation,
15809
+ Transform: () => Transform,
15810
+ TransformFromCopy: () => TransformFromCopy,
15811
+ TransformMatchingShapes: () => TransformMatchingShapes,
15812
+ TransformMatchingTex: () => TransformMatchingTex,
15813
+ Typewriter: () => Typewriter,
15814
+ UL: () => UL,
15815
+ UP: () => UP,
15816
+ UR: () => UR,
15817
+ Uncreate: () => Uncreate,
15818
+ Unwrite: () => Unwrite,
15819
+ UpdateFromAlphaFunc: () => UpdateFromAlphaFunc,
15820
+ UpdateFromFunc: () => UpdateFromFunc,
15821
+ V2: () => V2,
15822
+ V3: () => V3,
15823
+ Wait: () => Wait,
15824
+ Wiggle: () => Wiggle,
15825
+ Write: () => Write,
15826
+ add: () => add,
15827
+ altitude: () => altitude,
15828
+ angle: () => angle,
15829
+ angleBetween: () => angleBetween,
15830
+ angleBisector: () => angleBisector,
15831
+ angleMarker: () => angleMarker,
15832
+ annularSector: () => annularSector,
15833
+ annulus: () => annulus,
15834
+ applyMatrix: () => applyMatrix,
15835
+ arc: () => arc,
15836
+ arcBetweenPoints: () => arcBetweenPoints,
15837
+ arrow: () => arrow,
15838
+ brace: () => brace,
15839
+ braceBetweenPoints: () => braceBetweenPoints,
15840
+ braceLabel: () => braceLabel,
15841
+ bulletedList: () => bulletedList,
15842
+ centroid: () => centroid,
15843
+ circle: () => circle,
15844
+ circleConstraint: () => circleConstraint,
15845
+ circleIntersections: () => circleIntersections,
15846
+ circumscribedCircle: () => circumscribedCircle,
15847
+ clamp: () => clamp,
15848
+ code: () => code,
15849
+ colorGradient: () => colorGradient,
15850
+ combine: () => combine,
15851
+ createCamera: () => createCamera,
15852
+ createInteractive: () => createInteractive,
15853
+ createMovingCamera: () => createMovingCamera,
15854
+ createTimeline: () => createTimeline,
15855
+ cross: () => cross,
15856
+ crossMark: () => crossMark,
15857
+ cubicBezier: () => cubicBezier,
15858
+ curvedArrow: () => curvedArrow,
15859
+ curvedDoubleArrow: () => curvedDoubleArrow,
15860
+ cutout: () => cutout,
15861
+ decimalMatrix: () => decimalMatrix,
15862
+ decimalTable: () => decimalTable,
15863
+ degToRad: () => degToRad,
15864
+ determinant: () => determinant,
15865
+ digraph: () => digraph,
15866
+ distance: () => distance,
15867
+ div: () => div,
15868
+ dot: () => dot2,
15869
+ doubleArrow: () => doubleArrow,
15870
+ easing: () => easing,
15871
+ elbow: () => elbow,
15872
+ ellipse: () => ellipse,
15873
+ equilateralTriangle: () => equilateralTriangle,
15874
+ footOfPerpendicular: () => footOfPerpendicular,
15875
+ functionConstraint: () => functionConstraint,
15876
+ getColor: () => getColor,
15877
+ graph: () => graph,
15878
+ gridConstraint: () => gridConstraint,
15879
+ group: () => group,
15880
+ inscribedCircle: () => inscribedCircle,
15881
+ integerMatrix: () => integerMatrix,
15882
+ integerTable: () => integerTable,
15883
+ interpolateColor: () => interpolateColor,
15884
+ labeledDot: () => labeledDot,
15885
+ length: () => length,
15886
+ lerp: () => lerp,
15887
+ lerpNumber: () => lerpNumber,
15888
+ line: () => line,
15889
+ lineConstraint: () => lineConstraint,
15890
+ lineIntersection: () => lineIntersection,
15891
+ mapRange: () => mapRange,
15892
+ markupText: () => markupText,
15893
+ mathTable: () => mathTable,
15894
+ matrix: () => matrix,
15895
+ matrixMultiply: () => matrixMultiply,
15896
+ median: () => median,
15897
+ midpoint: () => midpoint,
15898
+ mul: () => mul,
15899
+ normalize: () => normalize,
15900
+ orthocenter: () => orthocenter,
15901
+ paragraph: () => paragraph,
15902
+ parallelLine: () => parallelLine,
15903
+ path: () => path,
15904
+ pathFromString: () => pathFromString,
15905
+ perpendicular: () => perpendicular,
15906
+ perpendicularBisector: () => perpendicularBisector,
15907
+ perpendicularLine: () => perpendicularLine,
15908
+ polarConstraint: () => polarConstraint,
15909
+ polygon: () => polygon,
15910
+ polyline: () => polyline,
15911
+ quadraticBezier: () => quadraticBezier,
15912
+ radToDeg: () => radToDeg,
15913
+ rect: () => rect,
15914
+ rectConstraint: () => rectConstraint,
15915
+ reflect: () => reflect,
15916
+ reflectOverPoint: () => reflectOverPoint,
15917
+ reflectPoint: () => reflectPoint,
15918
+ reflectPointOverLine: () => reflectPointOverLine,
15919
+ regularPolygon: () => regularPolygon,
15920
+ regularPolygram: () => regularPolygram,
15921
+ renderToRough: () => renderToRough,
15922
+ renderToSVG: () => renderToSVG,
15923
+ rightAngleMarker: () => rightAngleMarker,
15924
+ rotate: () => rotate,
15925
+ rotationMatrix: () => rotationMatrix,
15926
+ roughPresets: () => roughPresets,
15927
+ sampleParametric: () => sampleParametric,
15928
+ scaleMatrix: () => scaleMatrix,
15929
+ sector: () => sector,
15930
+ square: () => square,
15931
+ star: () => star,
15932
+ sub: () => sub,
15933
+ table: () => table,
15934
+ tangentLine: () => tangentLine,
15935
+ tex: () => tex,
15936
+ text: () => text,
15937
+ toSVGString: () => toSVGString,
15938
+ translationMatrix: () => translationMatrix,
15939
+ triangle: () => triangle,
15940
+ vector: () => vector
15941
+ });
15942
+ init_math();
15943
+ init_core();
15944
+
15945
+ // src/showcase/utils/code-executor.ts
15946
+ function preprocessCode(code2) {
15947
+ return code2.split("\n").filter((line3) => {
15948
+ const trimmed = line3.trim();
15949
+ return !trimmed.startsWith("import ") && !trimmed.startsWith("export ");
15950
+ }).join("\n");
15951
+ }
15952
+ function detectRenderMode(code2) {
15953
+ const processedCode = preprocessCode(code2);
15954
+ if (processedCode.includes("scene.play") || processedCode.includes("scene.add") || /play\s*\(/.test(processedCode)) {
15955
+ return "animation";
15956
+ }
15957
+ if (/\bint\./.test(processedCode) || /\bint\[/.test(processedCode)) {
15958
+ return "interactive";
15959
+ }
15960
+ return "static";
15961
+ }
15962
+ async function executeCode(code2, svg, options) {
15963
+ const processedCode = preprocessCode(code2);
15964
+ const mode = detectRenderMode(processedCode);
15965
+ const diagrams = [];
15966
+ let sceneInstance = null;
15967
+ let interactiveInstance = null;
15968
+ let RegisteredSceneClass = null;
15969
+ const scope = __spreadProps(__spreadValues({}, scope_api_exports), {
15970
+ // draw 函数:收集静态图形
15971
+ draw: (diagram) => {
15972
+ diagrams.push(diagram);
15973
+ },
15974
+ // play 函数:注册 Scene 类
15975
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15976
+ play: (sceneClass) => {
15977
+ RegisteredSceneClass = sceneClass;
15978
+ },
15979
+ // int 代理:交互模式
15980
+ int: new Proxy({}, {
15981
+ get(_target, prop) {
15982
+ if (!interactiveInstance) {
15983
+ const Interactive2 = Interactive;
15984
+ if (Interactive2) {
15985
+ interactiveInstance = new Interactive2(
15986
+ svg.parentElement,
15987
+ { width: options.width, height: options.height }
15988
+ );
15989
+ }
15990
+ }
15991
+ return interactiveInstance == null ? void 0 : interactiveInstance[prop];
15992
+ }
15993
+ }),
15994
+ // SVG 元素
15995
+ svg,
15996
+ // 控制台
15997
+ console,
15998
+ // scene 对象(动画模式直接使用)
15999
+ scene: null
16000
+ });
16001
+ if (mode === "animation" && (processedCode.includes("scene.play") || processedCode.includes("scene.add"))) {
16002
+ class ShowcaseScene extends Scene {
16003
+ async construct() {
16004
+ }
15307
16005
  }
15308
- for (let y = Math.ceil(yRange[0]); y <= Math.floor(yRange[1]); y += tickSpacing) {
15309
- if (y === 0) continue;
15310
- const tickGeom = new THREE14.BufferGeometry().setFromPoints([
15311
- new THREE14.Vector3(-tickLength, y, 0),
15312
- new THREE14.Vector3(tickLength, y, 0)
15313
- ]);
15314
- group4.add(new THREE14.Line(tickGeom, yMaterial));
16006
+ sceneInstance = new ShowcaseScene();
16007
+ sceneInstance.setup(svg, {
16008
+ width: options.width,
16009
+ height: options.height,
16010
+ background: options.background || "#000"
16011
+ });
16012
+ scope.scene = sceneInstance;
16013
+ }
16014
+ try {
16015
+ const AsyncFunction = Object.getPrototypeOf(async function() {
16016
+ }).constructor;
16017
+ const fn = new AsyncFunction(
16018
+ "scope",
16019
+ `with (scope) {
16020
+ ${processedCode}
16021
+ }`
16022
+ );
16023
+ await fn(scope);
16024
+ if (RegisteredSceneClass && !sceneInstance) {
16025
+ const SceneClass = RegisteredSceneClass;
16026
+ const newScene = new SceneClass();
16027
+ newScene.setup(svg, {
16028
+ width: options.width,
16029
+ height: options.height,
16030
+ background: options.background || "#000"
16031
+ });
16032
+ await newScene.construct();
16033
+ sceneInstance = newScene;
15315
16034
  }
15316
- for (let z = Math.ceil(zRange[0]); z <= Math.floor(zRange[1]); z += tickSpacing) {
15317
- if (z === 0) continue;
15318
- const tickGeom = new THREE14.BufferGeometry().setFromPoints([
15319
- new THREE14.Vector3(0, -tickLength, z),
15320
- new THREE14.Vector3(0, tickLength, z)
15321
- ]);
15322
- group4.add(new THREE14.Line(tickGeom, zMaterial));
16035
+ if (sceneInstance) {
16036
+ sceneInstance.start();
15323
16037
  }
16038
+ return {
16039
+ mode,
16040
+ diagrams,
16041
+ scene: sceneInstance,
16042
+ interactive: interactiveInstance
16043
+ };
16044
+ } catch (error) {
16045
+ throw new Error(`\u4EE3\u7801\u6267\u884C\u9519\u8BEF: ${error.message}`);
15324
16046
  }
15325
- return new ThreeDiagram(group4);
15326
- }
15327
- function createArrowHead(position, direction, size, color) {
15328
- const geometry = new THREE14.ConeGeometry(size * 0.5, size, 8);
15329
- const material = new THREE14.MeshBasicMaterial({ color });
15330
- const cone2 = new THREE14.Mesh(geometry, material);
15331
- cone2.position.copy(position);
15332
- const axis = new THREE14.Vector3(0, 1, 0);
15333
- const quaternion = new THREE14.Quaternion().setFromUnitVectors(axis, direction.normalize());
15334
- cone2.setRotationFromQuaternion(quaternion);
15335
- return cone2;
15336
16047
  }
15337
- var createAxes3D = axes3D;
15338
16048
 
15339
- // src/webgl/math/vector3d.ts
15340
- var THREE15 = __toESM(require("three"));
15341
- function vector3D(from = [0, 0, 0], to = [1, 0, 0], config = {}) {
15342
- const {
15343
- color = "#3498db",
15344
- lineWidth = 2,
15345
- arrowSize = 0.15,
15346
- showArrow = true
15347
- } = config;
15348
- const group4 = new THREE15.Group();
15349
- const material = new THREE15.LineBasicMaterial({ color, linewidth: lineWidth });
15350
- const geometry = new THREE15.BufferGeometry().setFromPoints([
15351
- new THREE15.Vector3(from[0], from[1], from[2]),
15352
- new THREE15.Vector3(to[0], to[1], to[2])
15353
- ]);
15354
- const line3 = new THREE15.Line(geometry, material);
15355
- group4.add(line3);
15356
- if (showArrow) {
15357
- const direction = new THREE15.Vector3(
15358
- to[0] - from[0],
15359
- to[1] - from[1],
15360
- to[2] - from[2]
15361
- ).normalize();
15362
- const arrowGeometry = new THREE15.ConeGeometry(arrowSize * 0.5, arrowSize, 8);
15363
- const arrowMaterial = new THREE15.MeshBasicMaterial({ color });
15364
- const arrow2 = new THREE15.Mesh(arrowGeometry, arrowMaterial);
15365
- arrow2.position.set(to[0], to[1], to[2]);
15366
- const axis = new THREE15.Vector3(0, 1, 0);
15367
- const quaternion = new THREE15.Quaternion().setFromUnitVectors(axis, direction);
15368
- arrow2.setRotationFromQuaternion(quaternion);
15369
- group4.add(arrow2);
16049
+ // src/showcase/utils/export.ts
16050
+ function exportSVG(svg) {
16051
+ const serializer = new XMLSerializer();
16052
+ const svgString = serializer.serializeToString(svg);
16053
+ return `<?xml version="1.0" encoding="UTF-8"?>
16054
+ ${svgString}`;
16055
+ }
16056
+ async function exportJPG(svg, options = {}) {
16057
+ const { quality = 0.9 } = options;
16058
+ const bbox = svg.getBBox();
16059
+ const width = options.width || svg.clientWidth || bbox.width || 800;
16060
+ const height = options.height || svg.clientHeight || bbox.height || 450;
16061
+ const canvas = document.createElement("canvas");
16062
+ canvas.width = width;
16063
+ canvas.height = height;
16064
+ const ctx = canvas.getContext("2d");
16065
+ if (!ctx) {
16066
+ throw new Error("\u65E0\u6CD5\u521B\u5EFA Canvas \u4E0A\u4E0B\u6587");
16067
+ }
16068
+ const svgString = exportSVG(svg);
16069
+ const blob = new Blob([svgString], { type: "image/svg+xml;charset=utf-8" });
16070
+ const url = URL.createObjectURL(blob);
16071
+ return new Promise((resolve, reject) => {
16072
+ const img = new Image();
16073
+ img.onload = () => {
16074
+ ctx.fillStyle = "#ffffff";
16075
+ ctx.fillRect(0, 0, width, height);
16076
+ ctx.drawImage(img, 0, 0, width, height);
16077
+ URL.revokeObjectURL(url);
16078
+ canvas.toBlob(
16079
+ (blob2) => {
16080
+ if (blob2) {
16081
+ resolve(blob2);
16082
+ } else {
16083
+ reject(new Error("JPG \u5BFC\u51FA\u5931\u8D25"));
16084
+ }
16085
+ },
16086
+ "image/jpeg",
16087
+ quality
16088
+ );
16089
+ };
16090
+ img.onerror = () => {
16091
+ URL.revokeObjectURL(url);
16092
+ reject(new Error("SVG \u56FE\u50CF\u52A0\u8F7D\u5931\u8D25"));
16093
+ };
16094
+ img.src = url;
16095
+ });
16096
+ }
16097
+ async function exportMP4(svg, captureFrame, options = {}) {
16098
+ const { fps = 60, duration = 3 } = options;
16099
+ if (typeof VideoEncoder === "undefined") {
16100
+ throw new Error("\u6D4F\u89C8\u5668\u4E0D\u652F\u6301 VideoEncoder API");
16101
+ }
16102
+ const { Muxer, ArrayBufferTarget } = await import("mp4-muxer");
16103
+ const width = svg.clientWidth || 800;
16104
+ const height = svg.clientHeight || 450;
16105
+ const encoderWidth = Math.ceil(width / 2) * 2;
16106
+ const encoderHeight = Math.ceil(height / 2) * 2;
16107
+ const target = new ArrayBufferTarget();
16108
+ const muxer = new Muxer({
16109
+ target,
16110
+ video: {
16111
+ codec: "avc",
16112
+ width: encoderWidth,
16113
+ height: encoderHeight
16114
+ },
16115
+ fastStart: "in-memory"
16116
+ });
16117
+ const encoder = new VideoEncoder({
16118
+ output: (chunk, meta) => {
16119
+ muxer.addVideoChunk(chunk, meta);
16120
+ },
16121
+ error: (e) => {
16122
+ console.error("VideoEncoder error:", e);
16123
+ }
16124
+ });
16125
+ encoder.configure({
16126
+ codec: "avc1.42001f",
16127
+ width: encoderWidth,
16128
+ height: encoderHeight,
16129
+ bitrate: 5e6,
16130
+ framerate: fps
16131
+ });
16132
+ const canvas = document.createElement("canvas");
16133
+ canvas.width = encoderWidth;
16134
+ canvas.height = encoderHeight;
16135
+ const ctx = canvas.getContext("2d");
16136
+ if (!ctx) {
16137
+ throw new Error("\u65E0\u6CD5\u521B\u5EFA Canvas \u4E0A\u4E0B\u6587");
16138
+ }
16139
+ const totalFrames = Math.ceil(duration * fps);
16140
+ const frameDuration = 1e6 / fps;
16141
+ for (let i = 0; i < totalFrames; i++) {
16142
+ await captureFrame();
16143
+ const svgString = new XMLSerializer().serializeToString(svg);
16144
+ const blob = new Blob([svgString], { type: "image/svg+xml;charset=utf-8" });
16145
+ const url = URL.createObjectURL(blob);
16146
+ await new Promise((resolve, reject) => {
16147
+ const img = new Image();
16148
+ img.onload = () => {
16149
+ ctx.fillStyle = "#000000";
16150
+ ctx.fillRect(0, 0, encoderWidth, encoderHeight);
16151
+ ctx.drawImage(img, 0, 0, encoderWidth, encoderHeight);
16152
+ URL.revokeObjectURL(url);
16153
+ resolve();
16154
+ };
16155
+ img.onerror = () => {
16156
+ URL.revokeObjectURL(url);
16157
+ reject(new Error("\u5E27\u6355\u83B7\u5931\u8D25"));
16158
+ };
16159
+ img.src = url;
16160
+ });
16161
+ const frame = new VideoFrame(canvas, {
16162
+ timestamp: i * frameDuration,
16163
+ duration: frameDuration
16164
+ });
16165
+ encoder.encode(frame);
16166
+ frame.close();
16167
+ }
16168
+ await encoder.flush();
16169
+ encoder.close();
16170
+ muxer.finalize();
16171
+ const buffer = target.buffer;
16172
+ return new Blob([buffer], { type: "video/mp4" });
16173
+ }
16174
+ function downloadFile(blob, filename) {
16175
+ const url = typeof blob === "string" ? `data:image/svg+xml;charset=utf-8,${encodeURIComponent(blob)}` : URL.createObjectURL(blob);
16176
+ const a = document.createElement("a");
16177
+ a.href = url;
16178
+ a.download = filename;
16179
+ document.body.appendChild(a);
16180
+ a.click();
16181
+ document.body.removeChild(a);
16182
+ if (typeof blob !== "string") {
16183
+ URL.revokeObjectURL(url);
15370
16184
  }
15371
- return new ThreeDiagram(group4);
15372
16185
  }
15373
- var createVector3D = vector3D;
15374
16186
 
15375
- // src/webgl/math/grid3d.ts
15376
- var THREE16 = __toESM(require("three"));
15377
- function grid3D(config = {}) {
16187
+ // src/showcase/ShowcaseCore.ts
16188
+ function createShowcase(options) {
16189
+ let status = "idle";
16190
+ let mode = null;
16191
+ let animationState = "idle";
16192
+ let error = null;
16193
+ let container = null;
16194
+ let svg = null;
16195
+ let sceneInstance = null;
16196
+ let interactiveInstance = null;
16197
+ let diagrams = [];
15378
16198
  const {
15379
- size = 10,
15380
- divisions = 10,
15381
- color1 = "#444444",
15382
- color2 = "#888888",
15383
- plane: plane2 = "xz",
15384
- center = [0, 0, 0]
15385
- } = config;
15386
- const gridHelper = new THREE16.GridHelper(size, divisions, color1, color2);
15387
- switch (plane2) {
15388
- case "xy":
15389
- gridHelper.rotation.x = Math.PI / 2;
15390
- break;
15391
- case "yz":
15392
- gridHelper.rotation.z = Math.PI / 2;
15393
- break;
15394
- case "xz":
15395
- default:
15396
- break;
16199
+ code: code2,
16200
+ diagram,
16201
+ sceneClass,
16202
+ width: configWidth = "auto",
16203
+ height: configHeight = "auto",
16204
+ aspectRatio = 16 / 9,
16205
+ background = "#000",
16206
+ onReady,
16207
+ onError,
16208
+ onStatusChange
16209
+ } = options;
16210
+ function setStatus(newStatus) {
16211
+ status = newStatus;
16212
+ onStatusChange == null ? void 0 : onStatusChange(newStatus);
16213
+ }
16214
+ function getDimensions() {
16215
+ if (!container) return { width: 800, height: 450 };
16216
+ const containerWidth = container.clientWidth || 800;
16217
+ const width = configWidth === "auto" ? containerWidth : configWidth;
16218
+ const height = configHeight === "auto" ? Math.round(width / aspectRatio) : configHeight;
16219
+ return { width, height };
16220
+ }
16221
+ function createSVG() {
16222
+ const { width, height } = getDimensions();
16223
+ const svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
16224
+ svgElement.setAttribute("width", String(width));
16225
+ svgElement.setAttribute("height", String(height));
16226
+ svgElement.style.width = "100%";
16227
+ svgElement.style.aspectRatio = String(aspectRatio);
16228
+ svgElement.style.borderRadius = "8px";
16229
+ svgElement.style.overflow = "hidden";
16230
+ svgElement.style.background = background;
16231
+ return svgElement;
16232
+ }
16233
+ function cleanup() {
16234
+ if (sceneInstance) {
16235
+ if ("destroy" in sceneInstance && typeof sceneInstance.destroy === "function") {
16236
+ sceneInstance.destroy();
16237
+ }
16238
+ sceneInstance = null;
16239
+ }
16240
+ if (interactiveInstance) {
16241
+ if (typeof interactiveInstance.destroy === "function") {
16242
+ interactiveInstance.destroy();
16243
+ }
16244
+ interactiveInstance = null;
16245
+ }
16246
+ if (svg && svg.parentElement) {
16247
+ svg.remove();
16248
+ }
16249
+ svg = null;
16250
+ diagrams = [];
16251
+ mode = null;
16252
+ animationState = "idle";
16253
+ }
16254
+ function renderStatic() {
16255
+ if (!svg || diagrams.length === 0) return;
16256
+ const { width, height } = getDimensions();
16257
+ const combined = diagrams.length === 1 ? diagrams[0] : combine(...diagrams);
16258
+ renderToSVG(combined, svg, {
16259
+ width,
16260
+ height,
16261
+ background
16262
+ });
16263
+ const bounds = combined.bounds();
16264
+ if (bounds.width > 0 && bounds.height > 0) {
16265
+ const padding = 0.5;
16266
+ const contentW = bounds.width + padding * 2;
16267
+ const contentH = bounds.height + padding * 2;
16268
+ const vX = bounds.x - padding;
16269
+ const vY = bounds.y - padding;
16270
+ svg.setAttribute("viewBox", `${vX} ${vY} ${contentW} ${contentH}`);
16271
+ }
16272
+ svg.removeAttribute("width");
16273
+ svg.removeAttribute("height");
16274
+ svg.style.overflow = "visible";
15397
16275
  }
15398
- gridHelper.position.set(center[0], center[1], center[2]);
15399
- return new ThreeDiagram(gridHelper);
16276
+ const controller = {
16277
+ get status() {
16278
+ return status;
16279
+ },
16280
+ get mode() {
16281
+ return mode;
16282
+ },
16283
+ get animationState() {
16284
+ return animationState;
16285
+ },
16286
+ get error() {
16287
+ return error;
16288
+ },
16289
+ /**
16290
+ * 初始化
16291
+ */
16292
+ async init(containerElement) {
16293
+ container = containerElement;
16294
+ setStatus("loading");
16295
+ error = null;
16296
+ try {
16297
+ cleanup();
16298
+ svg = createSVG();
16299
+ container.appendChild(svg);
16300
+ const { width, height } = getDimensions();
16301
+ if (diagram) {
16302
+ mode = "static";
16303
+ diagrams = [diagram];
16304
+ renderStatic();
16305
+ } else if (sceneClass) {
16306
+ mode = "animation";
16307
+ const newScene = new sceneClass();
16308
+ newScene.setup(svg, { width, height, background });
16309
+ await newScene.construct();
16310
+ sceneInstance = newScene;
16311
+ } else if (code2) {
16312
+ mode = detectRenderMode(code2);
16313
+ const result = await executeCode(code2, svg, { width, height, background });
16314
+ diagrams = result.diagrams;
16315
+ sceneInstance = result.scene;
16316
+ interactiveInstance = result.interactive;
16317
+ if (result.mode === "static" && diagrams.length > 0) {
16318
+ renderStatic();
16319
+ }
16320
+ } else {
16321
+ throw new Error("\u5FC5\u987B\u63D0\u4F9B code\u3001diagram \u6216 sceneClass \u4E4B\u4E00");
16322
+ }
16323
+ setStatus("ready");
16324
+ onReady == null ? void 0 : onReady();
16325
+ } catch (e) {
16326
+ error = e;
16327
+ setStatus("error");
16328
+ onError == null ? void 0 : onError(error);
16329
+ console.error("Showcase \u521D\u59CB\u5316\u9519\u8BEF:", error);
16330
+ }
16331
+ },
16332
+ /**
16333
+ * 销毁
16334
+ */
16335
+ destroy() {
16336
+ cleanup();
16337
+ container = null;
16338
+ setStatus("idle");
16339
+ },
16340
+ /**
16341
+ * 重置
16342
+ */
16343
+ async reset() {
16344
+ if (container) {
16345
+ await controller.init(container);
16346
+ }
16347
+ },
16348
+ /**
16349
+ * 播放动画
16350
+ */
16351
+ play() {
16352
+ if (mode !== "animation" || !sceneInstance) return;
16353
+ if (animationState === "idle") {
16354
+ sceneInstance.start();
16355
+ animationState = "playing";
16356
+ } else if (animationState === "paused") {
16357
+ sceneInstance.resume();
16358
+ animationState = "playing";
16359
+ }
16360
+ },
16361
+ /**
16362
+ * 暂停动画
16363
+ */
16364
+ pause() {
16365
+ if (mode !== "animation" || !sceneInstance) return;
16366
+ if (animationState === "playing") {
16367
+ sceneInstance.pause();
16368
+ animationState = "paused";
16369
+ }
16370
+ },
16371
+ /**
16372
+ * 恢复动画
16373
+ */
16374
+ resume() {
16375
+ if (mode !== "animation" || !sceneInstance) return;
16376
+ if (animationState === "paused") {
16377
+ sceneInstance.resume();
16378
+ animationState = "playing";
16379
+ }
16380
+ },
16381
+ /**
16382
+ * 导出 SVG
16383
+ */
16384
+ async exportSVG() {
16385
+ if (!svg) throw new Error("SVG \u672A\u521D\u59CB\u5316");
16386
+ return exportSVG(svg);
16387
+ },
16388
+ /**
16389
+ * 导出 JPG
16390
+ */
16391
+ async exportJPG(quality = 0.9) {
16392
+ if (!svg) throw new Error("SVG \u672A\u521D\u59CB\u5316");
16393
+ const { width, height } = getDimensions();
16394
+ return exportJPG(svg, { quality, width, height });
16395
+ },
16396
+ /**
16397
+ * 导出 MP4
16398
+ */
16399
+ async exportMP4(exportOptions = {}) {
16400
+ if (!svg) throw new Error("SVG \u672A\u521D\u59CB\u5316");
16401
+ if (mode !== "animation" || !sceneInstance) {
16402
+ throw new Error("\u53EA\u6709\u52A8\u753B\u6A21\u5F0F\u652F\u6301 MP4 \u5BFC\u51FA");
16403
+ }
16404
+ await controller.reset();
16405
+ const captureFrame = async () => {
16406
+ await new Promise((resolve) => setTimeout(resolve, 16));
16407
+ };
16408
+ return exportMP4(svg, captureFrame, exportOptions);
16409
+ }
16410
+ };
16411
+ return controller;
15400
16412
  }
15401
- var createGrid3D = grid3D;
15402
16413
 
15403
- // src/webgl/materials/index.ts
15404
- var THREE17 = __toESM(require("three"));
16414
+ // src/showcase/hooks/useShowcase.ts
16415
+ function useShowcase(options) {
16416
+ const containerRef = (0, import_react.useRef)(null);
16417
+ const controllerRef = (0, import_react.useRef)(null);
16418
+ const [status, setStatus] = (0, import_react.useState)("idle");
16419
+ const [mode, setMode] = (0, import_react.useState)(null);
16420
+ const [animationState, setAnimationState] = (0, import_react.useState)("idle");
16421
+ const [error, setError] = (0, import_react.useState)(null);
16422
+ (0, import_react.useEffect)(() => {
16423
+ if (!containerRef.current) return;
16424
+ const controller = createShowcase(__spreadProps(__spreadValues({}, options), {
16425
+ onStatusChange: (newStatus) => {
16426
+ var _a;
16427
+ setStatus(newStatus);
16428
+ (_a = options.onStatusChange) == null ? void 0 : _a.call(options, newStatus);
16429
+ },
16430
+ onReady: () => {
16431
+ var _a;
16432
+ setMode(controller.mode);
16433
+ setAnimationState(controller.animationState);
16434
+ (_a = options.onReady) == null ? void 0 : _a.call(options);
16435
+ },
16436
+ onError: (err) => {
16437
+ var _a;
16438
+ setError(err);
16439
+ (_a = options.onError) == null ? void 0 : _a.call(options, err);
16440
+ }
16441
+ }));
16442
+ controllerRef.current = controller;
16443
+ controller.init(containerRef.current);
16444
+ return () => {
16445
+ controller.destroy();
16446
+ controllerRef.current = null;
16447
+ };
16448
+ }, [options.code, options.diagram, options.sceneClass]);
16449
+ const play = (0, import_react.useCallback)(() => {
16450
+ if (controllerRef.current) {
16451
+ controllerRef.current.play();
16452
+ setAnimationState("playing");
16453
+ }
16454
+ }, []);
16455
+ const pause = (0, import_react.useCallback)(() => {
16456
+ if (controllerRef.current) {
16457
+ controllerRef.current.pause();
16458
+ setAnimationState("paused");
16459
+ }
16460
+ }, []);
16461
+ const resume = (0, import_react.useCallback)(() => {
16462
+ if (controllerRef.current) {
16463
+ controllerRef.current.resume();
16464
+ setAnimationState("playing");
16465
+ }
16466
+ }, []);
16467
+ const reset = (0, import_react.useCallback)(async () => {
16468
+ if (controllerRef.current) {
16469
+ await controllerRef.current.reset();
16470
+ setAnimationState("idle");
16471
+ }
16472
+ }, []);
16473
+ const exportSVG2 = (0, import_react.useCallback)(async () => {
16474
+ if (!controllerRef.current) {
16475
+ throw new Error("Showcase \u672A\u521D\u59CB\u5316");
16476
+ }
16477
+ return controllerRef.current.exportSVG();
16478
+ }, []);
16479
+ const exportJPG2 = (0, import_react.useCallback)(async (quality) => {
16480
+ if (!controllerRef.current) {
16481
+ throw new Error("Showcase \u672A\u521D\u59CB\u5316");
16482
+ }
16483
+ return controllerRef.current.exportJPG(quality);
16484
+ }, []);
16485
+ const exportMP42 = (0, import_react.useCallback)(async (exportOptions) => {
16486
+ if (!controllerRef.current) {
16487
+ throw new Error("Showcase \u672A\u521D\u59CB\u5316");
16488
+ }
16489
+ return controllerRef.current.exportMP4(exportOptions);
16490
+ }, []);
16491
+ return {
16492
+ containerRef,
16493
+ status,
16494
+ mode,
16495
+ animationState,
16496
+ error,
16497
+ play,
16498
+ pause,
16499
+ resume,
16500
+ reset,
16501
+ exportSVG: exportSVG2,
16502
+ exportJPG: exportJPG2,
16503
+ exportMP4: exportMP42
16504
+ };
16505
+ }
15405
16506
 
15406
- // src/webgl/lights/index.ts
15407
- var THREE18 = __toESM(require("three"));
16507
+ // src/showcase/hooks/useExport.ts
16508
+ var import_react2 = require("react");
16509
+ function useExport() {
16510
+ const [status, setStatus] = (0, import_react2.useState)("idle");
16511
+ const [error, setError] = (0, import_react2.useState)(null);
16512
+ const downloadSVG = (0, import_react2.useCallback)(async (getSVG, filename = "diagram.svg") => {
16513
+ setStatus("exporting");
16514
+ setError(null);
16515
+ try {
16516
+ const svgString = await getSVG();
16517
+ downloadFile(svgString, filename);
16518
+ setStatus("success");
16519
+ } catch (err) {
16520
+ setError(err);
16521
+ setStatus("error");
16522
+ throw err;
16523
+ }
16524
+ }, []);
16525
+ const downloadJPG = (0, import_react2.useCallback)(async (getJPG, filename = "diagram.jpg") => {
16526
+ setStatus("exporting");
16527
+ setError(null);
16528
+ try {
16529
+ const blob = await getJPG();
16530
+ downloadFile(blob, filename);
16531
+ setStatus("success");
16532
+ } catch (err) {
16533
+ setError(err);
16534
+ setStatus("error");
16535
+ throw err;
16536
+ }
16537
+ }, []);
16538
+ const downloadMP4 = (0, import_react2.useCallback)(async (getMP4, filename = "animation.mp4") => {
16539
+ setStatus("exporting");
16540
+ setError(null);
16541
+ try {
16542
+ const blob = await getMP4();
16543
+ downloadFile(blob, filename);
16544
+ setStatus("success");
16545
+ } catch (err) {
16546
+ setError(err);
16547
+ setStatus("error");
16548
+ throw err;
16549
+ }
16550
+ }, []);
16551
+ return {
16552
+ status,
16553
+ error,
16554
+ downloadSVG,
16555
+ downloadJPG,
16556
+ downloadMP4
16557
+ };
16558
+ }
15408
16559
 
15409
- // src/webgl/overlay/index.ts
15410
- var THREE19 = __toESM(require("three"));
15411
- var import_CSS2DRenderer = require("three/examples/jsm/renderers/CSS2DRenderer.js");
16560
+ // src/showcase/Showcase.tsx
16561
+ function Showcase({
16562
+ code: code2,
16563
+ diagram,
16564
+ sceneClass,
16565
+ width = "auto",
16566
+ height = "auto",
16567
+ aspectRatio = 16 / 9,
16568
+ background = "#000",
16569
+ className,
16570
+ showControls = true,
16571
+ showExport = true,
16572
+ showCode = false,
16573
+ onReady,
16574
+ onError,
16575
+ onStatusChange
16576
+ }) {
16577
+ const showcaseOptions = {
16578
+ width,
16579
+ height,
16580
+ aspectRatio,
16581
+ background
16582
+ };
16583
+ if (code2 !== void 0) showcaseOptions.code = code2;
16584
+ if (diagram !== void 0) showcaseOptions.diagram = diagram;
16585
+ if (sceneClass !== void 0) showcaseOptions.sceneClass = sceneClass;
16586
+ if (onReady !== void 0) showcaseOptions.onReady = onReady;
16587
+ if (onError !== void 0) showcaseOptions.onError = onError;
16588
+ if (onStatusChange !== void 0) showcaseOptions.onStatusChange = onStatusChange;
16589
+ const {
16590
+ containerRef,
16591
+ status,
16592
+ mode,
16593
+ animationState,
16594
+ error,
16595
+ play,
16596
+ pause,
16597
+ reset,
16598
+ exportSVG: exportSVG2,
16599
+ exportJPG: exportJPG2,
16600
+ exportMP4: exportMP42
16601
+ } = useShowcase(showcaseOptions);
16602
+ const {
16603
+ status: exportStatus,
16604
+ downloadSVG,
16605
+ downloadJPG,
16606
+ downloadMP4
16607
+ } = useExport();
16608
+ const shouldShowControls = showControls && mode === "animation";
16609
+ const shouldShowExport = showExport && status === "ready";
16610
+ const handlePlayPause = (0, import_react3.useCallback)(() => {
16611
+ if (animationState === "playing") {
16612
+ pause();
16613
+ } else {
16614
+ play();
16615
+ }
16616
+ }, [animationState, play, pause]);
16617
+ const handleExportSVG = (0, import_react3.useCallback)(() => {
16618
+ downloadSVG(exportSVG2, "locusing-diagram.svg");
16619
+ }, [downloadSVG, exportSVG2]);
16620
+ const handleExportJPG = (0, import_react3.useCallback)(() => {
16621
+ downloadJPG(() => exportJPG2(0.9), "locusing-diagram.jpg");
16622
+ }, [downloadJPG, exportJPG2]);
16623
+ const handleExportMP4 = (0, import_react3.useCallback)(() => {
16624
+ downloadMP4(exportMP42, "locusing-animation.mp4");
16625
+ }, [downloadMP4, exportMP42]);
16626
+ const containerStyle = (0, import_react3.useMemo)(() => ({
16627
+ position: "relative",
16628
+ width: width === "auto" ? "100%" : width,
16629
+ aspectRatio: height === "auto" ? String(aspectRatio) : void 0,
16630
+ height: height === "auto" ? void 0 : height,
16631
+ borderRadius: "8px",
16632
+ overflow: "hidden",
16633
+ background
16634
+ }), [width, height, aspectRatio, background]);
16635
+ const controlsStyle = (0, import_react3.useMemo)(() => ({
16636
+ position: "absolute",
16637
+ bottom: "12px",
16638
+ left: "50%",
16639
+ transform: "translateX(-50%)",
16640
+ display: "flex",
16641
+ gap: "8px",
16642
+ padding: "8px 12px",
16643
+ background: "rgba(0, 0, 0, 0.6)",
16644
+ borderRadius: "8px",
16645
+ backdropFilter: "blur(4px)"
16646
+ }), []);
16647
+ const buttonStyle = (0, import_react3.useMemo)(() => ({
16648
+ padding: "6px 12px",
16649
+ border: "none",
16650
+ borderRadius: "4px",
16651
+ background: "rgba(255, 255, 255, 0.2)",
16652
+ color: "#fff",
16653
+ cursor: "pointer",
16654
+ fontSize: "14px",
16655
+ transition: "background 0.2s"
16656
+ }), []);
16657
+ if (status === "loading") {
16658
+ return /* @__PURE__ */ import_react3.default.createElement("div", { className, style: containerStyle }, /* @__PURE__ */ import_react3.default.createElement("div", { style: {
16659
+ display: "flex",
16660
+ alignItems: "center",
16661
+ justifyContent: "center",
16662
+ width: "100%",
16663
+ height: "100%",
16664
+ color: "rgba(255, 255, 255, 0.6)"
16665
+ } }, "\u52A0\u8F7D\u4E2D..."));
16666
+ }
16667
+ if (status === "error" && error) {
16668
+ return /* @__PURE__ */ import_react3.default.createElement("div", { className, style: containerStyle }, /* @__PURE__ */ import_react3.default.createElement("div", { style: {
16669
+ display: "flex",
16670
+ flexDirection: "column",
16671
+ alignItems: "center",
16672
+ justifyContent: "center",
16673
+ width: "100%",
16674
+ height: "100%",
16675
+ color: "#ff6b6b",
16676
+ padding: "20px",
16677
+ textAlign: "center"
16678
+ } }, /* @__PURE__ */ import_react3.default.createElement("div", { style: { marginBottom: "8px" } }, "\u6E32\u67D3\u9519\u8BEF"), /* @__PURE__ */ import_react3.default.createElement("div", { style: { fontSize: "12px", opacity: 0.8 } }, error.message)));
16679
+ }
16680
+ return /* @__PURE__ */ import_react3.default.createElement("div", { className, style: containerStyle }, /* @__PURE__ */ import_react3.default.createElement(
16681
+ "div",
16682
+ {
16683
+ ref: containerRef,
16684
+ style: {
16685
+ width: "100%",
16686
+ height: "100%"
16687
+ }
16688
+ }
16689
+ ), shouldShowControls && /* @__PURE__ */ import_react3.default.createElement("div", { style: controlsStyle }, /* @__PURE__ */ import_react3.default.createElement(
16690
+ "button",
16691
+ {
16692
+ style: buttonStyle,
16693
+ onClick: handlePlayPause,
16694
+ onMouseOver: (e) => e.currentTarget.style.background = "rgba(255, 255, 255, 0.3)",
16695
+ onMouseOut: (e) => e.currentTarget.style.background = "rgba(255, 255, 255, 0.2)"
16696
+ },
16697
+ animationState === "playing" ? "\u6682\u505C" : "\u64AD\u653E"
16698
+ ), /* @__PURE__ */ import_react3.default.createElement(
16699
+ "button",
16700
+ {
16701
+ style: buttonStyle,
16702
+ onClick: reset,
16703
+ onMouseOver: (e) => e.currentTarget.style.background = "rgba(255, 255, 255, 0.3)",
16704
+ onMouseOut: (e) => e.currentTarget.style.background = "rgba(255, 255, 255, 0.2)"
16705
+ },
16706
+ "\u91CD\u7F6E"
16707
+ )), shouldShowExport && /* @__PURE__ */ import_react3.default.createElement("div", { style: {
16708
+ position: "absolute",
16709
+ top: "12px",
16710
+ right: "12px",
16711
+ display: "flex",
16712
+ gap: "4px"
16713
+ } }, /* @__PURE__ */ import_react3.default.createElement(
16714
+ "button",
16715
+ {
16716
+ style: __spreadProps(__spreadValues({}, buttonStyle), {
16717
+ padding: "4px 8px",
16718
+ fontSize: "12px"
16719
+ }),
16720
+ onClick: handleExportSVG,
16721
+ disabled: exportStatus === "exporting",
16722
+ onMouseOver: (e) => e.currentTarget.style.background = "rgba(255, 255, 255, 0.3)",
16723
+ onMouseOut: (e) => e.currentTarget.style.background = "rgba(255, 255, 255, 0.2)"
16724
+ },
16725
+ "SVG"
16726
+ ), /* @__PURE__ */ import_react3.default.createElement(
16727
+ "button",
16728
+ {
16729
+ style: __spreadProps(__spreadValues({}, buttonStyle), {
16730
+ padding: "4px 8px",
16731
+ fontSize: "12px"
16732
+ }),
16733
+ onClick: handleExportJPG,
16734
+ disabled: exportStatus === "exporting",
16735
+ onMouseOver: (e) => e.currentTarget.style.background = "rgba(255, 255, 255, 0.3)",
16736
+ onMouseOut: (e) => e.currentTarget.style.background = "rgba(255, 255, 255, 0.2)"
16737
+ },
16738
+ "JPG"
16739
+ ), mode === "animation" && /* @__PURE__ */ import_react3.default.createElement(
16740
+ "button",
16741
+ {
16742
+ style: __spreadProps(__spreadValues({}, buttonStyle), {
16743
+ padding: "4px 8px",
16744
+ fontSize: "12px"
16745
+ }),
16746
+ onClick: handleExportMP4,
16747
+ disabled: exportStatus === "exporting",
16748
+ onMouseOver: (e) => e.currentTarget.style.background = "rgba(255, 255, 255, 0.3)",
16749
+ onMouseOut: (e) => e.currentTarget.style.background = "rgba(255, 255, 255, 0.2)"
16750
+ },
16751
+ "MP4"
16752
+ )), showCode && code2 && /* @__PURE__ */ import_react3.default.createElement("details", { style: {
16753
+ position: "absolute",
16754
+ bottom: shouldShowControls ? "60px" : "12px",
16755
+ left: "12px",
16756
+ right: "12px",
16757
+ background: "rgba(0, 0, 0, 0.8)",
16758
+ borderRadius: "8px",
16759
+ padding: "8px 12px",
16760
+ color: "#fff",
16761
+ fontSize: "12px",
16762
+ maxHeight: "200px",
16763
+ overflow: "auto"
16764
+ } }, /* @__PURE__ */ import_react3.default.createElement("summary", { style: { cursor: "pointer", marginBottom: "8px" } }, "\u67E5\u770B\u4EE3\u7801"), /* @__PURE__ */ import_react3.default.createElement("pre", { style: { margin: 0, whiteSpace: "pre-wrap" } }, code2)));
16765
+ }
15412
16766
  // Annotate the CommonJS export names for ESM import in node:
15413
16767
  0 && (module.exports = {
15414
16768
  AddTextLetterByLetter,
@@ -15498,6 +16852,7 @@ var import_CSS2DRenderer = require("three/examples/jsm/renderers/CSS2DRenderer.j
15498
16852
  Shift,
15499
16853
  ShowIncreasingSubsets,
15500
16854
  ShowPassingFlash,
16855
+ Showcase,
15501
16856
  ShrinkToCenter,
15502
16857
  SpinInFromNothing,
15503
16858
  SpiralIn,
@@ -15599,6 +16954,7 @@ var import_CSS2DRenderer = require("three/examples/jsm/renderers/CSS2DRenderer.j
15599
16954
  createPhysicsWorld,
15600
16955
  createPlane,
15601
16956
  createScene,
16957
+ createShowcase,
15602
16958
  createSphere,
15603
16959
  createSpringMass,
15604
16960
  createTheme,
@@ -15644,6 +17000,7 @@ var import_CSS2DRenderer = require("three/examples/jsm/renderers/CSS2DRenderer.j
15644
17000
  defaultTheme,
15645
17001
  defaultTokens,
15646
17002
  degToRad,
17003
+ detectRenderMode,
15647
17004
  determinant,
15648
17005
  diagram_combine,
15649
17006
  diff,
@@ -15654,6 +17011,7 @@ var import_CSS2DRenderer = require("three/examples/jsm/renderers/CSS2DRenderer.j
15654
17011
  dot,
15655
17012
  dot3D,
15656
17013
  doubleArrow,
17014
+ downloadFile,
15657
17015
  draw_to_svg,
15658
17016
  draw_to_svg_string,
15659
17017
  easing,
@@ -15662,6 +17020,7 @@ var import_CSS2DRenderer = require("three/examples/jsm/renderers/CSS2DRenderer.j
15662
17020
  ellipse,
15663
17021
  empty,
15664
17022
  equilateralTriangle,
17023
+ executeCode,
15665
17024
  footOfPerpendicular,
15666
17025
  functionConstraint,
15667
17026
  getBuffer,
@@ -15731,6 +17090,7 @@ var import_CSS2DRenderer = require("three/examples/jsm/renderers/CSS2DRenderer.j
15731
17090
  polygon,
15732
17091
  polyline,
15733
17092
  powScale,
17093
+ preprocessCode,
15734
17094
  quadraticBezier,
15735
17095
  radToDeg,
15736
17096
  randomLayout,
@@ -15757,6 +17117,9 @@ var import_CSS2DRenderer = require("three/examples/jsm/renderers/CSS2DRenderer.j
15757
17117
  sector,
15758
17118
  semanticStyle,
15759
17119
  setCurrentTheme,
17120
+ showcaseExportJPG,
17121
+ showcaseExportMP4,
17122
+ showcaseExportSVG,
15760
17123
  shuffle,
15761
17124
  sortGroups,
15762
17125
  sphere,
@@ -15779,6 +17142,8 @@ var import_CSS2DRenderer = require("three/examples/jsm/renderers/CSS2DRenderer.j
15779
17142
  translationMatrix,
15780
17143
  treeLayout,
15781
17144
  triangle,
17145
+ useExport,
17146
+ useShowcase,
15782
17147
  vector,
15783
17148
  vector3D,
15784
17149
  vectorDot