@microfox/remotion 1.2.1 → 1.2.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.mjs CHANGED
@@ -4,21 +4,21 @@ var ComponentRegistryManager = class {
4
4
  this.registry = {};
5
5
  this.packageRegistry = {};
6
6
  }
7
- registerComponent(name, component, type, config15 = { displayName: "" }, packageName) {
8
- this.registry[name] = { component, config: config15 };
7
+ registerComponent(name, component, type, config18 = { displayName: "" }, packageName) {
8
+ this.registry[name] = { component, config: config18 };
9
9
  if (packageName) {
10
10
  if (!this.packageRegistry[packageName]) {
11
11
  this.packageRegistry[packageName] = {};
12
12
  }
13
- this.packageRegistry[packageName][name] = { component, config: config15 };
13
+ this.packageRegistry[packageName][name] = { component, config: config18 };
14
14
  }
15
15
  }
16
- registerEffect(name, component, config15 = { displayName: "" }, packageName) {
16
+ registerEffect(name, component, config18 = { displayName: "" }, packageName) {
17
17
  this.registerComponent(
18
18
  name?.includes("effect-") ? name : `effect-${name}`,
19
19
  component,
20
20
  "layout",
21
- config15,
21
+ config18,
22
22
  packageName
23
23
  );
24
24
  }
@@ -33,8 +33,8 @@ var ComponentRegistryManager = class {
33
33
  }
34
34
  registerPackage(packageName, components) {
35
35
  this.packageRegistry[packageName] = components;
36
- Object.entries(components).forEach(([name, { component, config: config15 }]) => {
37
- this.registry[`${packageName}:${name}`] = { component, config: config15 };
36
+ Object.entries(components).forEach(([name, { component, config: config18 }]) => {
37
+ this.registry[`${packageName}:${name}`] = { component, config: config18 };
38
38
  });
39
39
  }
40
40
  getPackageComponents(packageName) {
@@ -49,17 +49,17 @@ var ComponentRegistryManager = class {
49
49
  }
50
50
  };
51
51
  var componentRegistry = new ComponentRegistryManager();
52
- var registerComponent = (name, component, type, config15 = { displayName: "" }, packageName) => {
52
+ var registerComponent = (name, component, type, config18 = { displayName: "" }, packageName) => {
53
53
  componentRegistry.registerComponent(
54
54
  name,
55
55
  component,
56
56
  type,
57
- config15,
57
+ config18,
58
58
  packageName
59
59
  );
60
60
  };
61
- var registerEffect = (name, component, config15 = { displayName: "" }, packageName) => {
62
- componentRegistry.registerEffect(name, component, config15, packageName);
61
+ var registerEffect = (name, component, config18 = { displayName: "" }, packageName) => {
62
+ componentRegistry.registerEffect(name, component, config18, packageName);
63
63
  };
64
64
  var registerPackage = (packageName, components) => {
65
65
  componentRegistry.registerPackage(packageName, components);
@@ -142,9 +142,9 @@ var calculateComponentDuration = async (component) => {
142
142
  } else {
143
143
  }
144
144
  };
145
- var calculateDuration = async (childrenData, config15) => {
145
+ var calculateDuration = async (childrenData, config18) => {
146
146
  let calculatedDuration = void 0;
147
- const targetIds = Array.isArray(config15.fitDurationTo) ? config15.fitDurationTo : [config15.fitDurationTo];
147
+ const targetIds = Array.isArray(config18.fitDurationTo) ? config18.fitDurationTo : [config18.fitDurationTo];
148
148
  const matchingComponents = findMatchingComponents(
149
149
  childrenData || [],
150
150
  targetIds
@@ -498,8 +498,8 @@ var ComponentRenderer = ({
498
498
  context
499
499
  };
500
500
  if (type === "layout") {
501
- const config15 = getComponentConfig(componentId);
502
- const isInnerSequence = config15?.isInnerSequence;
501
+ const config18 = getComponentConfig(componentId);
502
+ const isInnerSequence = config18?.isInnerSequence;
503
503
  if (isInnerSequence) {
504
504
  return /* @__PURE__ */ React3.createElement(RenderContext.Provider, { value: newContext }, /* @__PURE__ */ React3.createElement(ComponentClass, { ...props }, effects && effects.length > 0 ? /* @__PURE__ */ React3.createElement(EffectWrapper, { effects, context: newContext }, childrenData?.map((child) => /* @__PURE__ */ React3.createElement(ComponentRenderer, { key: child.id, ...child }))) : childrenData?.map((child) => /* @__PURE__ */ React3.createElement(ComponentRenderer, { key: child.id, ...child }))));
505
505
  }
@@ -542,7 +542,7 @@ var SceneFrame = ({ children }) => {
542
542
  };
543
543
 
544
544
  // src/components/layouts/BaseLayout.tsx
545
- import React13, { Children, useMemo as useMemo7 } from "react";
545
+ import React19, { Children, useMemo as useMemo9 } from "react";
546
546
  import { AbsoluteFill as AbsoluteFill3 } from "remotion";
547
547
 
548
548
  // src/components/effects/BlurEffect.tsx
@@ -557,10 +557,45 @@ var parseFunctionsString = (functions) => {
557
557
  if (!functions) {
558
558
  return result;
559
559
  }
560
- const regex = /(\w+)\(([^)]*)\)/g;
561
- let match;
562
- while ((match = regex.exec(functions)) !== null) {
563
- result.set(match[1], match[0]);
560
+ let i = 0;
561
+ while (i < functions.length) {
562
+ while (i < functions.length && /\s/.test(functions[i])) {
563
+ i++;
564
+ }
565
+ if (i >= functions.length) break;
566
+ const nameStart = i;
567
+ while (i < functions.length && /[\w-]/.test(functions[i])) {
568
+ i++;
569
+ }
570
+ if (i === nameStart) break;
571
+ const functionName = functions.substring(nameStart, i);
572
+ while (i < functions.length && /\s/.test(functions[i])) {
573
+ i++;
574
+ }
575
+ if (i >= functions.length || functions[i] !== "(") {
576
+ break;
577
+ }
578
+ i++;
579
+ let depth = 1;
580
+ const contentStart = i;
581
+ while (i < functions.length && depth > 0) {
582
+ if (functions[i] === "(") {
583
+ depth++;
584
+ } else if (functions[i] === ")") {
585
+ depth--;
586
+ }
587
+ if (depth > 0) {
588
+ i++;
589
+ }
590
+ }
591
+ if (depth === 0) {
592
+ const content = functions.substring(contentStart, i);
593
+ const fullFunction = `${functionName}(${content})`;
594
+ result.set(functionName, fullFunction);
595
+ i++;
596
+ } else {
597
+ break;
598
+ }
564
599
  }
565
600
  return result;
566
601
  };
@@ -724,11 +759,20 @@ var parseHexColor = (hex) => {
724
759
  var parseRgbaColor = (rgba) => {
725
760
  const match = rgba.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)/);
726
761
  if (match) {
762
+ let alpha = 1;
763
+ if (match[4]) {
764
+ const alphaValue = parseFloat(match[4]);
765
+ if (alphaValue > 1) {
766
+ alpha = Math.max(0, Math.min(1, alphaValue / 100));
767
+ } else {
768
+ alpha = Math.max(0, Math.min(1, alphaValue));
769
+ }
770
+ }
727
771
  return {
728
772
  r: Math.max(0, Math.min(255, parseInt(match[1], 10))),
729
773
  g: Math.max(0, Math.min(255, parseInt(match[2], 10))),
730
774
  b: Math.max(0, Math.min(255, parseInt(match[3], 10))),
731
- a: match[4] ? Math.max(0, Math.min(1, parseFloat(match[4]))) : 1
775
+ a: alpha
732
776
  };
733
777
  }
734
778
  return { r: 0, g: 0, b: 0, a: 1 };
@@ -742,14 +786,21 @@ var parseColor = (color) => {
742
786
  }
743
787
  return { r: 0, g: 0, b: 0, a: 1 };
744
788
  };
745
- var rgbaToString = (color) => {
746
- if (color.a === 1) {
747
- return `rgb(${Math.round(color.r)}, ${Math.round(color.g)}, ${Math.round(color.b)})`;
748
- } else {
749
- return `rgba(${Math.round(color.r)}, ${Math.round(color.g)}, ${Math.round(color.b)}, ${color.a})`;
789
+ var rgbaToString = (color, preserveFormat) => {
790
+ const r = Math.round(color.r);
791
+ const g = Math.round(color.g);
792
+ const b = Math.round(color.b);
793
+ const a = color.a;
794
+ if (preserveFormat) {
795
+ if (preserveFormat.hasSpaces) {
796
+ return `rgba(${r}, ${g}, ${b}, ${a})`;
797
+ } else {
798
+ return `rgba(${r},${g},${b},${a})`;
799
+ }
750
800
  }
801
+ return `rgba(${r}, ${g}, ${b}, ${a})`;
751
802
  };
752
- var interpolateColors = (color1, color2, progress) => {
803
+ var interpolateColors = (color1, color2, progress, preserveFormat) => {
753
804
  const parsedColor1 = parseColor(color1);
754
805
  const parsedColor2 = parseColor(color2);
755
806
  const interpolatedColor = {
@@ -758,7 +809,75 @@ var interpolateColors = (color1, color2, progress) => {
758
809
  b: interpolate(progress, [0, 1], [parsedColor1.b, parsedColor2.b]),
759
810
  a: interpolate(progress, [0, 1], [parsedColor1.a, parsedColor2.a])
760
811
  };
761
- return rgbaToString(interpolatedColor);
812
+ return rgbaToString(interpolatedColor, preserveFormat);
813
+ };
814
+ var findColorsInString = (str) => {
815
+ const matches = [];
816
+ const rgbaPattern = /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)/g;
817
+ let match;
818
+ rgbaPattern.lastIndex = 0;
819
+ while ((match = rgbaPattern.exec(str)) !== null) {
820
+ matches.push({
821
+ fullMatch: match[0],
822
+ color: match[0],
823
+ startIndex: match.index,
824
+ endIndex: match.index + match[0].length
825
+ });
826
+ }
827
+ const hexPattern = /#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b/g;
828
+ hexPattern.lastIndex = 0;
829
+ while ((match = hexPattern.exec(str)) !== null) {
830
+ matches.push({
831
+ fullMatch: match[0],
832
+ color: match[0],
833
+ startIndex: match.index,
834
+ endIndex: match.index + match[0].length
835
+ });
836
+ }
837
+ return matches.sort((a, b) => a.startIndex - b.startIndex);
838
+ };
839
+ var interpolateColorsInString = (str1, str2, progress) => {
840
+ const colors1 = findColorsInString(str1);
841
+ const colors2 = findColorsInString(str2);
842
+ if (colors1.length === 0 && colors2.length === 0) {
843
+ return str1;
844
+ }
845
+ if (colors1.length === 0 || colors2.length === 0) {
846
+ return str1;
847
+ }
848
+ const minLength = Math.min(colors1.length, colors2.length);
849
+ const replacements = [];
850
+ for (let i = 0; i < minLength; i++) {
851
+ const color1 = colors1[i];
852
+ const color2 = colors2[i];
853
+ const originalColor = color1.color;
854
+ const hasSpaces = originalColor.includes(", ");
855
+ const interpolatedColor = interpolateColors(color1.color, color2.color, progress, { hasSpaces });
856
+ replacements.push({
857
+ startIndex: color1.startIndex,
858
+ endIndex: color1.endIndex,
859
+ replacement: interpolatedColor
860
+ });
861
+ }
862
+ replacements.sort((a, b) => b.startIndex - a.startIndex);
863
+ let result = str1;
864
+ for (const replacement of replacements) {
865
+ const originalSubstring = result.substring(replacement.startIndex, replacement.endIndex);
866
+ const expectedColor = colors1.find((c) => c.startIndex === replacement.startIndex);
867
+ if (expectedColor && (originalSubstring === expectedColor.color || originalSubstring.trim().match(/^rgba?\(/i))) {
868
+ result = result.substring(0, replacement.startIndex) + replacement.replacement + result.substring(replacement.endIndex);
869
+ } else {
870
+ const currentColors = findColorsInString(result);
871
+ const matchingColor = currentColors.find(
872
+ (c) => Math.abs(c.startIndex - replacement.startIndex) < 30
873
+ // Allow some offset
874
+ );
875
+ if (matchingColor) {
876
+ result = result.substring(0, matchingColor.startIndex) + replacement.replacement + result.substring(matchingColor.endIndex);
877
+ }
878
+ }
879
+ }
880
+ return result;
762
881
  };
763
882
  var calculateAnimatedValue = (ranges, progress, key) => {
764
883
  const sortedRanges = [...ranges].sort((a, b) => a.prog - b.prog);
@@ -794,6 +913,11 @@ var calculateAnimatedValue = (ranges, progress, key) => {
794
913
  if (isColor(currentValue) && isColor(nextValue)) {
795
914
  return interpolateColors(currentValue, nextValue, localProgress);
796
915
  }
916
+ const colors1 = findColorsInString(currentValue);
917
+ const colors2 = findColorsInString(nextValue);
918
+ if (colors1.length > 0 || colors2.length > 0) {
919
+ return interpolateColorsInString(currentValue, nextValue, localProgress);
920
+ }
797
921
  const getUnitAndValue = (str) => {
798
922
  const units = ["vmax", "vmin", "rem", "deg", "bpm", "vh", "vw", "px", "em", "ms", "hz", "db", "fr", "s", "%"];
799
923
  for (const unit of units) {
@@ -842,7 +966,7 @@ var rangesToCSSProperties = (ranges, progress) => {
842
966
  const value = calculateAnimatedValue(keyRanges, progress, key);
843
967
  switch (key) {
844
968
  case "scale":
845
- styles.transform = `scale(${value})`;
969
+ styles.transform = `${styles.transform || ""} scale(${value})`.trim();
846
970
  break;
847
971
  case "rotate":
848
972
  const rotateValue = typeof value === "string" && value.includes("deg") ? value : `${value}deg`;
@@ -1748,229 +1872,1750 @@ var config7 = {
1748
1872
  }
1749
1873
  };
1750
1874
 
1751
- // src/components/effects/GenericPresets.ts
1752
- var fadeInPreset = [
1753
- { key: "opacity", val: 0, prog: 0 },
1754
- { key: "opacity", val: 1, prog: 1 }
1755
- ];
1756
- var fadeOutPreset = [
1757
- { key: "opacity", val: 1, prog: 0 },
1758
- { key: "opacity", val: 0, prog: 1 }
1759
- ];
1760
- var scaleInPreset = [
1761
- { key: "scale", val: 0, prog: 0 },
1762
- { key: "scale", val: 1, prog: 1 }
1763
- ];
1764
- var scaleOutPreset = [
1765
- { key: "scale", val: 1, prog: 0 },
1766
- { key: "scale", val: 0, prog: 1 }
1767
- ];
1768
- var slideInLeftPreset = [
1769
- { key: "translateX", val: -100, prog: 0 },
1770
- { key: "translateX", val: 0, prog: 1 }
1771
- ];
1772
- var slideInRightPreset = [
1773
- { key: "translateX", val: 100, prog: 0 },
1774
- { key: "translateX", val: 0, prog: 1 }
1775
- ];
1776
- var slideInTopPreset = [
1777
- { key: "translateY", val: -100, prog: 0 },
1778
- { key: "translateY", val: 0, prog: 1 }
1779
- ];
1780
- var slideInBottomPreset = [
1781
- { key: "translateY", val: 100, prog: 0 },
1782
- { key: "translateY", val: 0, prog: 1 }
1783
- ];
1784
- var bouncePreset = [
1785
- { key: "scale", val: 0, prog: 0 },
1786
- { key: "scale", val: 1.2, prog: 0.6 },
1787
- { key: "scale", val: 1, prog: 1 }
1788
- ];
1789
- var pulsePreset = [
1790
- { key: "scale", val: 1, prog: 0 },
1791
- { key: "scale", val: 1.1, prog: 0.5 },
1792
- { key: "scale", val: 1, prog: 1 }
1793
- ];
1794
- var rotateInPreset = [
1795
- { key: "rotate", val: -180, prog: 0 },
1796
- { key: "rotate", val: 0, prog: 1 }
1797
- ];
1798
- var blurInPreset = [
1799
- { key: "blur", val: 10, prog: 0 },
1800
- { key: "blur", val: 0, prog: 1 }
1801
- ];
1802
- var fadeInScalePreset = [
1803
- { key: "opacity", val: 0, prog: 0 },
1804
- { key: "opacity", val: 1, prog: 1 },
1805
- { key: "scale", val: 0.8, prog: 0 },
1806
- { key: "scale", val: 1, prog: 1 }
1807
- ];
1808
- var slideInFadePreset = [
1809
- { key: "translateX", val: -50, prog: 0 },
1810
- { key: "translateX", val: 0, prog: 1 },
1811
- { key: "opacity", val: 0, prog: 0 },
1812
- { key: "opacity", val: 1, prog: 1 }
1813
- ];
1814
- var slideInLeftStringPreset = [
1815
- { key: "translateX", val: "-100px", prog: 0 },
1816
- { key: "translateX", val: "0px", prog: 1 }
1817
- ];
1818
- var slideInRightStringPreset = [
1819
- { key: "translateX", val: "100px", prog: 0 },
1820
- { key: "translateX", val: "0px", prog: 1 }
1821
- ];
1822
- var slideInTopStringPreset = [
1823
- { key: "translateY", val: "-100px", prog: 0 },
1824
- { key: "translateY", val: "0px", prog: 1 }
1825
- ];
1826
- var slideInBottomStringPreset = [
1827
- { key: "translateY", val: "100px", prog: 0 },
1828
- { key: "translateY", val: "0px", prog: 1 }
1829
- ];
1830
- var rotateInStringPreset = [
1831
- { key: "rotate", val: "-180deg", prog: 0 },
1832
- { key: "rotate", val: "0deg", prog: 1 }
1833
- ];
1834
- var blurInStringPreset = [
1835
- { key: "blur", val: "10px", prog: 0 },
1836
- { key: "blur", val: "0px", prog: 1 }
1837
- ];
1838
- var scaleInStringPreset = [
1839
- { key: "scale", val: 0, prog: 0 },
1840
- { key: "scale", val: 1, prog: 1 }
1841
- ];
1842
- var slideInLeftResponsivePreset = [
1843
- { key: "translateX", val: "-50vw", prog: 0 },
1844
- { key: "translateX", val: "0vw", prog: 1 }
1845
- ];
1846
- var slideInTopResponsivePreset = [
1847
- { key: "translateY", val: "-50vh", prog: 0 },
1848
- { key: "translateY", val: "0vh", prog: 1 }
1849
- ];
1850
- var backgroundColorPreset = [
1851
- { key: "backgroundColor", val: "#ff0000", prog: 0 },
1852
- { key: "backgroundColor", val: "#0000ff", prog: 1 }
1853
- ];
1854
- var borderRadiusPreset = [
1855
- { key: "borderRadius", val: "0px", prog: 0 },
1856
- { key: "borderRadius", val: "50px", prog: 1 }
1857
- ];
1858
- var boxShadowPreset = [
1859
- { key: "boxShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
1860
- { key: "boxShadow", val: "10px 10px 20px rgba(0,0,0,0.5)", prog: 1 }
1861
- ];
1862
- var fontSizePreset = [
1863
- { key: "fontSize", val: "12px", prog: 0 },
1864
- { key: "fontSize", val: "24px", prog: 1 }
1865
- ];
1866
- var letterSpacingPreset = [
1867
- { key: "letterSpacing", val: "0px", prog: 0 },
1868
- { key: "letterSpacing", val: "5px", prog: 1 }
1869
- ];
1870
- var lineHeightPreset = [
1871
- { key: "lineHeight", val: "1", prog: 0 },
1872
- { key: "lineHeight", val: "2", prog: 1 }
1873
- ];
1874
- var textShadowPreset = [
1875
- { key: "textShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
1876
- { key: "textShadow", val: "2px 2px 4px rgba(0,0,0,0.5)", prog: 1 }
1877
- ];
1878
- var widthPreset = [
1879
- { key: "width", val: "0px", prog: 0 },
1880
- { key: "width", val: "100%", prog: 1 }
1881
- ];
1882
- var heightPreset = [
1883
- { key: "height", val: "0px", prog: 0 },
1884
- { key: "height", val: "100%", prog: 1 }
1885
- ];
1886
- var marginPreset = [
1887
- { key: "margin", val: "0px", prog: 0 },
1888
- { key: "margin", val: "20px", prog: 1 }
1889
- ];
1890
- var paddingPreset = [
1891
- { key: "padding", val: "0px", prog: 0 },
1892
- { key: "padding", val: "20px", prog: 1 }
1893
- ];
1894
- var morphingCardPreset = [
1895
- { key: "borderRadius", val: "0px", prog: 0 },
1896
- { key: "borderRadius", val: "20px", prog: 0.5 },
1897
- { key: "borderRadius", val: "50px", prog: 1 },
1898
- { key: "boxShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
1899
- { key: "boxShadow", val: "0px 10px 30px rgba(0,0,0,0.3)", prog: 1 },
1900
- { key: "backgroundColor", val: "#ffffff", prog: 0 },
1901
- { key: "backgroundColor", val: "#f0f0f0", prog: 1 }
1902
- ];
1903
- var textRevealPreset = [
1904
- { key: "opacity", val: 0, prog: 0 },
1905
- { key: "opacity", val: 1, prog: 1 },
1906
- { key: "letterSpacing", val: "10px", prog: 0 },
1907
- { key: "letterSpacing", val: "0px", prog: 1 },
1908
- { key: "textShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
1909
- { key: "textShadow", val: "2px 2px 4px rgba(0,0,0,0.5)", prog: 1 }
1910
- ];
1911
- var GenericEffectPresets = {
1912
- fadeInPreset,
1913
- fadeOutPreset,
1914
- scaleInPreset,
1915
- scaleOutPreset,
1916
- slideInLeftPreset,
1917
- slideInRightPreset,
1918
- slideInTopPreset,
1919
- slideInBottomPreset,
1920
- bouncePreset,
1921
- pulsePreset,
1922
- rotateInPreset,
1923
- blurInPreset,
1924
- fadeInScalePreset,
1925
- slideInFadePreset,
1926
- // String-based presets
1927
- slideInLeftStringPreset,
1928
- slideInRightStringPreset,
1929
- slideInTopStringPreset,
1930
- slideInBottomStringPreset,
1931
- rotateInStringPreset,
1932
- blurInStringPreset,
1933
- scaleInStringPreset,
1934
- slideInLeftResponsivePreset,
1935
- slideInTopResponsivePreset,
1936
- // Custom CSS property presets
1937
- backgroundColorPreset,
1938
- borderRadiusPreset,
1939
- boxShadowPreset,
1940
- fontSizePreset,
1941
- letterSpacingPreset,
1942
- lineHeightPreset,
1943
- textShadowPreset,
1944
- widthPreset,
1945
- heightPreset,
1946
- marginPreset,
1947
- paddingPreset,
1948
- morphingCardPreset,
1949
- textRevealPreset
1950
- };
1951
-
1952
- // src/components/effects/index.ts
1953
- registerEffect(config2.displayName, BlurEffect, config2);
1954
- registerEffect(config3.displayName, LoopEffect, config3);
1955
- registerEffect(config4.displayName, PanEffect, config4);
1956
- registerEffect(config5.displayName, ZoomEffect, config5);
1957
- registerEffect("generic", UniversalEffect, config);
1958
- registerEffect(config6.displayName, ShakeEffect, config6);
1959
- registerEffect(
1960
- config7.displayName,
1961
- StretchEffect,
1962
- config7
1963
- );
1875
+ // src/components/effects/WaveformEffect.tsx
1876
+ import React13, { useMemo as useMemo8 } from "react";
1964
1877
 
1965
- // src/components/layouts/BaseLayout.tsx
1966
- var Layout = ({ id, children, data, context }) => {
1967
- const { containerProps = {}, childrenProps = [], repeatChildrenProps = {} } = data;
1968
- const overrideStyles = useAnimatedStyles(id);
1969
- const childrenArray = Children.toArray(children);
1970
- const enhancedStyle = useMemo7(
1971
- () => ({
1972
- ...!context?.boundaries?.reset ? context?.boundaries : {},
1973
- ...containerProps.style,
1878
+ // src/templates/waveform/hooks/useWaveformData.ts
1879
+ import { useMemo as useMemo7 } from "react";
1880
+ import {
1881
+ useAudioData,
1882
+ visualizeAudioWaveform,
1883
+ visualizeAudio
1884
+ } from "@remotion/media-utils";
1885
+ import { staticFile } from "remotion";
1886
+ var isValidPowerOfTwo = (num) => {
1887
+ return num > 0 && (num & num - 1) === 0;
1888
+ };
1889
+ var getClosestPowerOfTwo = (num) => {
1890
+ if (num <= 0) return 32;
1891
+ let power = 1;
1892
+ while (power < num) {
1893
+ power *= 2;
1894
+ }
1895
+ const lower = power / 2;
1896
+ const upper = power;
1897
+ return Math.abs(num - lower) < Math.abs(num - upper) ? lower : upper;
1898
+ };
1899
+ var useWaveformData = (config18) => {
1900
+ const {
1901
+ audioSrc,
1902
+ numberOfSamples,
1903
+ windowInSeconds,
1904
+ dataOffsetInSeconds = 0,
1905
+ normalize = false,
1906
+ frame,
1907
+ fps,
1908
+ posterize,
1909
+ includeFrequencyData = false,
1910
+ minDb = -100,
1911
+ maxDb = -30,
1912
+ smoothNormalisation = 1
1913
+ } = config18;
1914
+ const { root } = useComposition();
1915
+ const validatedNumberOfSamples = useMemo7(() => {
1916
+ if (!isValidPowerOfTwo(numberOfSamples)) {
1917
+ console.warn(
1918
+ `numberOfSamples must be a power of 2. Adjusting ${numberOfSamples} to ${getClosestPowerOfTwo(numberOfSamples)}`
1919
+ );
1920
+ return getClosestPowerOfTwo(numberOfSamples);
1921
+ }
1922
+ return numberOfSamples;
1923
+ }, [numberOfSamples]);
1924
+ const { source, audioStartsFrom } = useMemo7(() => {
1925
+ if (audioSrc.startsWith("http")) {
1926
+ return { source: audioSrc, audioStartsFrom: void 0 };
1927
+ }
1928
+ if (audioSrc.startsWith("ref:")) {
1929
+ const matchingComponent = findMatchingComponents(root, [
1930
+ audioSrc.replace("ref:", "")
1931
+ ]);
1932
+ if (matchingComponent.length > 0) {
1933
+ const firstMatchingComponent = matchingComponent[0];
1934
+ if (firstMatchingComponent.componentId === "AudioAtom") {
1935
+ return {
1936
+ source: firstMatchingComponent.data.src,
1937
+ audioStartsFrom: firstMatchingComponent.data?.startFrom ?? void 0
1938
+ };
1939
+ }
1940
+ if (firstMatchingComponent.type === "layout" || firstMatchingComponent.type === "scene") {
1941
+ const audioComponents = findMatchingComponentsByQuery(
1942
+ firstMatchingComponent.childrenData,
1943
+ { componentId: "AudioAtom" }
1944
+ );
1945
+ if (audioComponents.length > 0) {
1946
+ return {
1947
+ source: audioComponents[0].data.src,
1948
+ audioStartsFrom: audioComponents[0].data?.startFrom ?? void 0
1949
+ };
1950
+ }
1951
+ }
1952
+ }
1953
+ }
1954
+ return { source: staticFile(audioSrc), audioStartsFrom: void 0 };
1955
+ }, [audioSrc]);
1956
+ const audioData = useAudioData(source);
1957
+ const adjustedFrame = useMemo7(() => {
1958
+ if (posterize && posterize > 1) {
1959
+ return Math.round(frame / posterize) * posterize;
1960
+ }
1961
+ let offset = 0;
1962
+ if (audioStartsFrom && audioStartsFrom != 0) {
1963
+ offset += Math.round(audioStartsFrom * fps);
1964
+ }
1965
+ if (dataOffsetInSeconds != 0) {
1966
+ offset += Math.round(dataOffsetInSeconds * fps);
1967
+ }
1968
+ return frame + offset;
1969
+ }, [frame, posterize, dataOffsetInSeconds, audioStartsFrom]);
1970
+ const waveformData = useMemo7(() => {
1971
+ if (!audioData) return null;
1972
+ try {
1973
+ const baseSmoothingFrames = 3;
1974
+ const smoothingFrames = smoothNormalisation > 0 ? Math.floor(smoothNormalisation * baseSmoothingFrames) : 0;
1975
+ const samples = [];
1976
+ if (smoothingFrames === 0) {
1977
+ const waveform = visualizeAudioWaveform({
1978
+ fps,
1979
+ frame: adjustedFrame,
1980
+ audioData,
1981
+ numberOfSamples: validatedNumberOfSamples,
1982
+ windowInSeconds,
1983
+ dataOffsetInSeconds: 0,
1984
+ normalize
1985
+ });
1986
+ return waveform;
1987
+ }
1988
+ for (let offset = -smoothingFrames; offset <= smoothingFrames; offset++) {
1989
+ const sampleFrame = adjustedFrame + offset;
1990
+ if (sampleFrame >= 0) {
1991
+ try {
1992
+ const waveform = visualizeAudioWaveform({
1993
+ fps,
1994
+ frame: sampleFrame,
1995
+ audioData,
1996
+ numberOfSamples: validatedNumberOfSamples,
1997
+ windowInSeconds,
1998
+ dataOffsetInSeconds: 0,
1999
+ normalize
2000
+ });
2001
+ if (waveform && waveform.length > 0) {
2002
+ samples.push(waveform);
2003
+ }
2004
+ } catch (e) {
2005
+ }
2006
+ }
2007
+ }
2008
+ if (samples.length === 0) {
2009
+ const waveform = visualizeAudioWaveform({
2010
+ fps,
2011
+ frame: adjustedFrame,
2012
+ audioData,
2013
+ numberOfSamples: validatedNumberOfSamples,
2014
+ windowInSeconds,
2015
+ dataOffsetInSeconds: 0,
2016
+ normalize
2017
+ });
2018
+ return waveform;
2019
+ }
2020
+ const averaged = new Array(validatedNumberOfSamples).fill(0);
2021
+ for (let i = 0; i < validatedNumberOfSamples; i++) {
2022
+ let sum = 0;
2023
+ let count = 0;
2024
+ for (const sample of samples) {
2025
+ if (sample[i] !== void 0) {
2026
+ sum += sample[i];
2027
+ count++;
2028
+ }
2029
+ }
2030
+ averaged[i] = count > 0 ? sum / count : 0;
2031
+ }
2032
+ return averaged;
2033
+ } catch (error2) {
2034
+ console.error("Error generating waveform:", error2);
2035
+ return null;
2036
+ }
2037
+ }, [
2038
+ audioData,
2039
+ adjustedFrame,
2040
+ fps,
2041
+ validatedNumberOfSamples,
2042
+ windowInSeconds,
2043
+ dataOffsetInSeconds,
2044
+ normalize,
2045
+ smoothNormalisation
2046
+ ]);
2047
+ const {
2048
+ frequencyData,
2049
+ amplitudes,
2050
+ bass,
2051
+ mid,
2052
+ treble,
2053
+ bassValues,
2054
+ midValues,
2055
+ trebleValues
2056
+ } = useMemo7(() => {
2057
+ if (!audioData || !includeFrequencyData) {
2058
+ return {
2059
+ frequencyData: null,
2060
+ amplitudes: null,
2061
+ bass: null,
2062
+ mid: null,
2063
+ treble: null,
2064
+ bassValues: null,
2065
+ midValues: null,
2066
+ trebleValues: null
2067
+ };
2068
+ }
2069
+ try {
2070
+ const baseSmoothingFrames = 3;
2071
+ const smoothingFrames = smoothNormalisation > 0 ? Math.floor(smoothNormalisation * baseSmoothingFrames) : 0;
2072
+ const frequencySamples = [];
2073
+ let frequencyData2;
2074
+ if (smoothingFrames === 0) {
2075
+ frequencyData2 = visualizeAudio({
2076
+ fps,
2077
+ frame: adjustedFrame,
2078
+ audioData,
2079
+ numberOfSamples: validatedNumberOfSamples
2080
+ });
2081
+ } else {
2082
+ for (let offset = -smoothingFrames; offset <= smoothingFrames; offset++) {
2083
+ const sampleFrame = adjustedFrame + offset;
2084
+ if (sampleFrame >= 0) {
2085
+ try {
2086
+ const freqData = visualizeAudio({
2087
+ fps,
2088
+ frame: sampleFrame,
2089
+ audioData,
2090
+ numberOfSamples: validatedNumberOfSamples
2091
+ });
2092
+ if (freqData && freqData.length > 0) {
2093
+ frequencySamples.push(freqData);
2094
+ }
2095
+ } catch (e) {
2096
+ }
2097
+ }
2098
+ }
2099
+ if (frequencySamples.length === 0) {
2100
+ frequencyData2 = visualizeAudio({
2101
+ fps,
2102
+ frame: adjustedFrame,
2103
+ audioData,
2104
+ numberOfSamples: validatedNumberOfSamples
2105
+ });
2106
+ } else {
2107
+ frequencyData2 = new Array(validatedNumberOfSamples).fill(0);
2108
+ for (let i = 0; i < validatedNumberOfSamples; i++) {
2109
+ let sum = 0;
2110
+ let count = 0;
2111
+ for (const sample of frequencySamples) {
2112
+ if (sample[i] !== void 0) {
2113
+ sum += sample[i];
2114
+ count++;
2115
+ }
2116
+ }
2117
+ frequencyData2[i] = count > 0 ? sum / count : 0;
2118
+ }
2119
+ }
2120
+ }
2121
+ const { sampleRate } = audioData;
2122
+ const bassValues2 = [];
2123
+ const midValues2 = [];
2124
+ const trebleValues2 = [];
2125
+ for (let i = 0; i < frequencyData2.length; i++) {
2126
+ const freq = i * sampleRate / (2 * frequencyData2.length);
2127
+ const value = frequencyData2[i];
2128
+ if (freq >= 0 && freq < 250) {
2129
+ bassValues2.push(value * 2.5);
2130
+ } else if (freq >= 250 && freq < 4e3) {
2131
+ midValues2.push(value * 3);
2132
+ midValues2.push(value * 4.5);
2133
+ midValues2.push(value * 5);
2134
+ } else if (freq >= 4e3 && freq < sampleRate / 2) {
2135
+ trebleValues2.push(value * 30);
2136
+ }
2137
+ }
2138
+ const getAverage = (arr) => arr.length > 0 ? arr.reduce((a, b) => a + b, 0) / arr.length : 0;
2139
+ const bass2 = getAverage(bassValues2);
2140
+ const mid2 = getAverage(midValues2);
2141
+ const treble2 = getAverage(trebleValues2);
2142
+ const amplitudes2 = frequencyData2.map((value) => {
2143
+ const db = 20 * Math.log10(value);
2144
+ const scaled = (db - minDb) / (maxDb - minDb);
2145
+ return Math.max(0, Math.min(1, scaled));
2146
+ });
2147
+ return {
2148
+ frequencyData: frequencyData2,
2149
+ amplitudes: amplitudes2,
2150
+ bass: bass2,
2151
+ mid: mid2,
2152
+ treble: treble2,
2153
+ bassValues: bassValues2,
2154
+ midValues: midValues2,
2155
+ trebleValues: trebleValues2.reverse()
2156
+ };
2157
+ } catch (error2) {
2158
+ console.error("Error generating frequency data:", error2);
2159
+ return {
2160
+ frequencyData: null,
2161
+ amplitudes: null,
2162
+ bass: null,
2163
+ mid: null,
2164
+ treble: null
2165
+ };
2166
+ }
2167
+ }, [
2168
+ audioData,
2169
+ includeFrequencyData,
2170
+ adjustedFrame,
2171
+ fps,
2172
+ validatedNumberOfSamples,
2173
+ windowInSeconds,
2174
+ dataOffsetInSeconds,
2175
+ minDb,
2176
+ maxDb,
2177
+ smoothNormalisation
2178
+ ]);
2179
+ const isLoading = !audioData;
2180
+ const error = audioData === null && !isLoading ? "Failed to load audio data" : null;
2181
+ return {
2182
+ waveformData,
2183
+ frequencyData,
2184
+ amplitudes,
2185
+ audioData,
2186
+ isLoading,
2187
+ error,
2188
+ bass,
2189
+ bassValues,
2190
+ mid,
2191
+ midValues,
2192
+ treble,
2193
+ trebleValues
2194
+ };
2195
+ };
2196
+
2197
+ // src/components/effects/WaveformEffect.tsx
2198
+ var WaveformEffect = ({
2199
+ id,
2200
+ componentId,
2201
+ type,
2202
+ data,
2203
+ children,
2204
+ context
2205
+ }) => {
2206
+ const { progress, frame, mode, targetIds, effectData, fps } = useUniversalAnimation(data, context);
2207
+ const {
2208
+ audioSrc,
2209
+ numberOfSamples = 128,
2210
+ windowInSeconds,
2211
+ dataOffsetInSeconds = 0,
2212
+ normalize = false,
2213
+ useFrequencyData = true,
2214
+ audioProperty = "bass",
2215
+ sensitivity = 1,
2216
+ threshold = 0,
2217
+ smoothing = 0.5,
2218
+ smoothNormalisation = 1,
2219
+ effectType = "zoom",
2220
+ intensity = 1,
2221
+ minValue,
2222
+ maxValue,
2223
+ shakeAxis = "both",
2224
+ baseScale = 1,
2225
+ baseBrightness = 1,
2226
+ rotationRange = 15
2227
+ } = effectData;
2228
+ const parentContext = useUniversalEffectOptional();
2229
+ const analysisWindow = smoothNormalisation === 0 ? windowInSeconds || 1 / fps : windowInSeconds || Math.max(1 / fps, 0.05);
2230
+ const { bass, mid, treble, waveformData } = useWaveformData({
2231
+ audioSrc,
2232
+ numberOfSamples,
2233
+ windowInSeconds: analysisWindow,
2234
+ dataOffsetInSeconds,
2235
+ normalize,
2236
+ frame,
2237
+ fps,
2238
+ includeFrequencyData: useFrequencyData,
2239
+ smoothNormalisation
2240
+ });
2241
+ const audioIntensity = useMemo8(() => {
2242
+ let rawValue = 0;
2243
+ switch (audioProperty) {
2244
+ case "bass":
2245
+ rawValue = bass || 0;
2246
+ break;
2247
+ case "mid":
2248
+ rawValue = mid || 0;
2249
+ break;
2250
+ case "treble":
2251
+ rawValue = treble || 0;
2252
+ break;
2253
+ case "waveform":
2254
+ if (waveformData && waveformData.length > 0) {
2255
+ rawValue = waveformData.reduce((sum, val) => sum + Math.abs(val), 0) / waveformData.length;
2256
+ }
2257
+ break;
2258
+ case "frequency":
2259
+ rawValue = bass || 0;
2260
+ break;
2261
+ default:
2262
+ rawValue = bass || 0;
2263
+ }
2264
+ const thresholdedValue = Math.max(0, rawValue - threshold);
2265
+ const sensitizedValue = thresholdedValue * sensitivity;
2266
+ return Math.min(1, Math.max(0, sensitizedValue));
2267
+ }, [audioProperty, bass, mid, treble, waveformData, threshold, sensitivity]);
2268
+ const smoothedIntensity = useMemo8(() => {
2269
+ if (smoothNormalisation === 0) {
2270
+ return audioIntensity;
2271
+ }
2272
+ const smoothingPower = 1 + smoothing * 2;
2273
+ const smoothed = Math.pow(audioIntensity, smoothingPower);
2274
+ const baseline = 0.1;
2275
+ const filtered = smoothed * (1 - baseline * smoothing) + baseline * smoothing;
2276
+ return Math.min(1, Math.max(0, filtered));
2277
+ }, [audioIntensity, smoothing, smoothNormalisation]);
2278
+ const animatedStyles = useMemo8(() => {
2279
+ const intensityValue = smoothedIntensity || audioIntensity;
2280
+ let effectValue = intensityValue * intensity;
2281
+ if (minValue !== void 0 || maxValue !== void 0) {
2282
+ const defaultMin = effectType === "zoom" || effectType === "scale" ? baseScale : 0;
2283
+ const defaultMax = effectType === "zoom" || effectType === "scale" ? baseScale + intensity : intensity;
2284
+ const min = minValue !== void 0 ? minValue : defaultMin;
2285
+ const max = maxValue !== void 0 ? maxValue : defaultMax;
2286
+ effectValue = min + intensityValue * (max - min);
2287
+ } else {
2288
+ switch (effectType) {
2289
+ case "zoom":
2290
+ case "scale":
2291
+ effectValue = baseScale + intensityValue * intensity;
2292
+ break;
2293
+ case "exposure":
2294
+ effectValue = baseBrightness + intensityValue * intensity;
2295
+ break;
2296
+ case "blur":
2297
+ effectValue = intensityValue * intensity * 10;
2298
+ break;
2299
+ case "rotate":
2300
+ effectValue = (intensityValue - 0.5) * 2 * rotationRange;
2301
+ break;
2302
+ case "translateX":
2303
+ case "translateY":
2304
+ effectValue = (intensityValue - 0.5) * 2 * intensity * 50;
2305
+ break;
2306
+ default:
2307
+ effectValue = intensityValue * intensity;
2308
+ }
2309
+ }
2310
+ const styles = {};
2311
+ switch (effectType) {
2312
+ case "zoom":
2313
+ case "scale":
2314
+ styles.transform = `scale(${effectValue})`;
2315
+ break;
2316
+ case "shake":
2317
+ const shakeFrequency = 0.1;
2318
+ const shakeTime = frame * shakeFrequency;
2319
+ const shakeAmplitude = intensityValue * intensity * 20;
2320
+ const shakeX = shakeAxis === "x" || shakeAxis === "both" ? Math.sin(shakeTime * 2.3) * shakeAmplitude : 0;
2321
+ const shakeY = shakeAxis === "y" || shakeAxis === "both" ? Math.cos(shakeTime * 1.7) * shakeAmplitude : 0;
2322
+ styles.transform = `translateX(${shakeX}px) translateY(${shakeY}px)`;
2323
+ break;
2324
+ case "exposure":
2325
+ styles.filter = `brightness(${effectValue})`;
2326
+ break;
2327
+ case "blur":
2328
+ styles.filter = `blur(${effectValue}px)`;
2329
+ break;
2330
+ case "rotate":
2331
+ styles.transform = `rotate(${effectValue}deg)`;
2332
+ break;
2333
+ case "translateX":
2334
+ styles.transform = `translateX(${effectValue}px)`;
2335
+ break;
2336
+ case "translateY":
2337
+ styles.transform = `translateY(${effectValue}px)`;
2338
+ break;
2339
+ default:
2340
+ styles.transform = `scale(${effectValue})`;
2341
+ }
2342
+ if (parentContext && mode === "provider") {
2343
+ const combinedStyles = mergeCSSStyles_default(parentContext.animatedStyles, styles);
2344
+ return combinedStyles;
2345
+ }
2346
+ return styles;
2347
+ }, [
2348
+ smoothedIntensity,
2349
+ audioIntensity,
2350
+ effectType,
2351
+ intensity,
2352
+ minValue,
2353
+ maxValue,
2354
+ baseScale,
2355
+ baseBrightness,
2356
+ rotationRange,
2357
+ shakeAxis,
2358
+ mode,
2359
+ parentContext?.animatedStyles,
2360
+ frame
2361
+ // Add frame dependency for shake effect
2362
+ ]);
2363
+ const contextValue = useMemo8(
2364
+ () => ({
2365
+ animatedStyles,
2366
+ targetIds,
2367
+ effectType: "waveform"
2368
+ }),
2369
+ [animatedStyles, targetIds]
2370
+ );
2371
+ if (mode === "provider") {
2372
+ return /* @__PURE__ */ React13.createElement(UniversalEffectContext.Provider, { value: contextValue }, children);
2373
+ }
2374
+ return /* @__PURE__ */ React13.createElement("div", { ...effectData.props, style: animatedStyles }, children);
2375
+ };
2376
+ var config8 = {
2377
+ displayName: "waveform",
2378
+ description: "Waveform-driven effect that reacts to audio data (bass, mid, treble, waveform)",
2379
+ isInnerSequence: false,
2380
+ props: {
2381
+ audioSrc: {
2382
+ type: "string",
2383
+ required: true,
2384
+ description: "Audio source URL or ref:componentId"
2385
+ },
2386
+ audioProperty: {
2387
+ type: "enum",
2388
+ values: ["bass", "mid", "treble", "waveform", "frequency"],
2389
+ default: "bass",
2390
+ description: "Which audio property to react to"
2391
+ },
2392
+ effectType: {
2393
+ type: "enum",
2394
+ values: ["zoom", "shake", "exposure", "blur", "scale", "rotate", "translateX", "translateY"],
2395
+ default: "zoom",
2396
+ description: "Type of effect to apply"
2397
+ },
2398
+ intensity: {
2399
+ type: "number",
2400
+ default: 1,
2401
+ description: "Effect intensity multiplier"
2402
+ },
2403
+ sensitivity: {
2404
+ type: "number",
2405
+ default: 1,
2406
+ description: "Sensitivity multiplier for audio detection"
2407
+ },
2408
+ threshold: {
2409
+ type: "number",
2410
+ default: 0,
2411
+ description: "Minimum audio value to trigger effect"
2412
+ },
2413
+ smoothing: {
2414
+ type: "number",
2415
+ default: 0.5,
2416
+ description: "Smoothing factor (0-1) for audio data"
2417
+ },
2418
+ smoothNormalisation: {
2419
+ type: "number",
2420
+ default: 1,
2421
+ description: "Frame-based smoothing control (0 = no smoothing, 1 = default, >1 = more smoothing)"
2422
+ }
2423
+ }
2424
+ };
2425
+
2426
+ // src/components/effects/CanvasWipeReveal.tsx
2427
+ import React15, { useEffect, useRef, useState } from "react";
2428
+ import { useCurrentFrame as useCurrentFrame4, useVideoConfig as useVideoConfig5 } from "remotion";
2429
+ import { z as z2 } from "zod";
2430
+
2431
+ // src/components/atoms/CanvasAtom.tsx
2432
+ import React14 from "react";
2433
+ import { z } from "zod";
2434
+ var CanvasAtomDataProps = z.object({
2435
+ className: z.string().optional(),
2436
+ style: z.record(z.string(), z.any()).optional()
2437
+ });
2438
+ var Atom = React14.forwardRef(({ data, id }, ref) => {
2439
+ const { className, style } = data;
2440
+ return /* @__PURE__ */ React14.createElement("canvas", { ref, className, style, id });
2441
+ });
2442
+ var config9 = {
2443
+ displayName: "CanvasAtom",
2444
+ type: "atom",
2445
+ isInnerSequence: false,
2446
+ props: CanvasAtomDataProps
2447
+ // The config points to the Zod schema for data
2448
+ };
2449
+
2450
+ // src/components/effects/CanvasWipeReveal.tsx
2451
+ var mulberry32 = (seed) => {
2452
+ return () => {
2453
+ let t = seed += 1831565813;
2454
+ t = Math.imul(t ^ t >>> 15, t | 1);
2455
+ t ^= t + Math.imul(t ^ t >>> 7, t | 61);
2456
+ return ((t ^ t >>> 14) >>> 0) / 4294967296;
2457
+ };
2458
+ };
2459
+ var CanvasWipeRevealProps = z2.object({
2460
+ imageUrl: z2.string().url(),
2461
+ revealDurationInFrames: z2.number().min(1),
2462
+ revealType: z2.enum(["wipe", "radial"]).default("wipe"),
2463
+ angle: z2.number().default(0),
2464
+ fit: z2.enum(["cover", "contain"]).default("cover"),
2465
+ edgeStyle: z2.enum(["straight", "organic", "burn"]).default("straight"),
2466
+ edgeWaviness: z2.number().default(30),
2467
+ edgeFrequency: z2.number().default(4),
2468
+ backgroundColor: z2.string().default("rgba(0,0,0,0)"),
2469
+ burnGlow: z2.boolean().default(true),
2470
+ burnGlowColor: z2.string().default("#ff6600"),
2471
+ burnGlowIntensity: z2.number().default(1),
2472
+ organicRandomAmplitude: z2.boolean().default(true),
2473
+ organicRandomWavelength: z2.boolean().default(false)
2474
+ });
2475
+ var CanvasWipeReveal = ({ data, id }) => {
2476
+ const {
2477
+ imageUrl,
2478
+ revealDurationInFrames,
2479
+ revealType,
2480
+ angle,
2481
+ fit,
2482
+ edgeStyle,
2483
+ edgeWaviness,
2484
+ edgeFrequency,
2485
+ backgroundColor,
2486
+ burnGlow,
2487
+ burnGlowColor,
2488
+ burnGlowIntensity,
2489
+ organicRandomAmplitude,
2490
+ organicRandomWavelength
2491
+ } = data;
2492
+ const frame = useCurrentFrame4();
2493
+ const { width, height } = useVideoConfig5();
2494
+ const canvasRef = useRef(null);
2495
+ const [image, setImage] = useState(null);
2496
+ useEffect(() => {
2497
+ const img = new window.Image();
2498
+ img.crossOrigin = "Anonymous";
2499
+ img.src = imageUrl;
2500
+ img.onload = () => setImage(img);
2501
+ }, [imageUrl]);
2502
+ useEffect(() => {
2503
+ if (!canvasRef.current || !image) return;
2504
+ const context = canvasRef.current.getContext("2d");
2505
+ if (!context) return;
2506
+ context.canvas.width = width;
2507
+ context.canvas.height = height;
2508
+ context.fillStyle = backgroundColor;
2509
+ context.fillRect(0, 0, width, height);
2510
+ const progress = Math.min(frame / revealDurationInFrames, 1);
2511
+ if (progress === 0 && backgroundColor === "rgba(0,0,0,0)") return;
2512
+ const seed = id.split("").reduce((acc, char) => acc + char.charCodeAt(0), 0);
2513
+ context.save();
2514
+ context.beginPath();
2515
+ if (revealType === "radial") {
2516
+ const baseRadius = Math.sqrt(width * width + height * height) / 2 * progress;
2517
+ if (edgeStyle === "organic") {
2518
+ const points = 120;
2519
+ const random = mulberry32(seed);
2520
+ const amplitudes = Array.from(
2521
+ { length: points + 1 },
2522
+ () => organicRandomAmplitude ? 0.5 + random() : 1
2523
+ );
2524
+ const wavelengths = Array.from(
2525
+ { length: points + 1 },
2526
+ () => organicRandomWavelength ? 0.5 + random() * 1.5 : 1
2527
+ );
2528
+ for (let i = 0; i <= points; i++) {
2529
+ const p = i / points;
2530
+ const angle2 = p * Math.PI * 2;
2531
+ const wave = Math.sin(
2532
+ p * Math.PI * edgeFrequency * wavelengths[i] + frame * 0.1
2533
+ ) * edgeWaviness * progress * amplitudes[i];
2534
+ const radius = baseRadius + wave;
2535
+ const x = width / 2 + Math.cos(angle2) * radius;
2536
+ const y = height / 2 + Math.sin(angle2) * radius;
2537
+ if (i === 0) context.moveTo(x, y);
2538
+ else context.lineTo(x, y);
2539
+ }
2540
+ context.closePath();
2541
+ } else if (edgeStyle === "burn") {
2542
+ const points = 120;
2543
+ const random = mulberry32(seed);
2544
+ const randomValues = Array.from({ length: points + 1 }, () => random());
2545
+ const phaseOffsets = Array.from(
2546
+ { length: points + 1 },
2547
+ () => random() * Math.PI * 2
2548
+ );
2549
+ const sparklePoints = [];
2550
+ for (let i = 0; i <= points; i++) {
2551
+ const p = i / points;
2552
+ const angle2 = p * Math.PI * 2;
2553
+ const flicker = Math.sin(frame * 0.3 + phaseOffsets[i]);
2554
+ const burnOffset = (randomValues[i] * 2 - 1) * flicker * edgeWaviness * progress;
2555
+ const radius = baseRadius + burnOffset;
2556
+ const x = width / 2 + Math.cos(angle2) * radius;
2557
+ const y = height / 2 + Math.sin(angle2) * radius;
2558
+ if (burnGlow && i % 5 === 0 && flicker > 0.3) {
2559
+ sparklePoints.push({ x, y, intensity: flicker });
2560
+ }
2561
+ if (i === 0) context.moveTo(x, y);
2562
+ else context.lineTo(x, y);
2563
+ }
2564
+ context.closePath();
2565
+ if (burnGlow && sparklePoints.length > 0) {
2566
+ sparklePoints.forEach((point) => {
2567
+ const glowSize = 3 + point.intensity * 5 * burnGlowIntensity;
2568
+ if (isFinite(point.x) && isFinite(point.y) && isFinite(glowSize) && glowSize > 0) {
2569
+ const gradient = context.createRadialGradient(
2570
+ point.x,
2571
+ point.y,
2572
+ 0,
2573
+ point.x,
2574
+ point.y,
2575
+ glowSize
2576
+ );
2577
+ gradient.addColorStop(0, burnGlowColor);
2578
+ gradient.addColorStop(0.5, burnGlowColor + "80");
2579
+ gradient.addColorStop(1, burnGlowColor + "00");
2580
+ context.fillStyle = gradient;
2581
+ context.fillRect(
2582
+ point.x - glowSize,
2583
+ point.y - glowSize,
2584
+ glowSize * 2,
2585
+ glowSize * 2
2586
+ );
2587
+ }
2588
+ });
2589
+ }
2590
+ } else {
2591
+ context.arc(width / 2, height / 2, baseRadius, 0, Math.PI * 2);
2592
+ }
2593
+ } else {
2594
+ const angleInRadians = angle * Math.PI / 180;
2595
+ const diagonal = Math.sqrt(width * width + height * height);
2596
+ context.translate(width / 2, height / 2);
2597
+ context.rotate(angleInRadians);
2598
+ const wipeEdgePosition = progress * diagonal - diagonal / 2;
2599
+ if (edgeStyle === "burn") {
2600
+ const points = 100;
2601
+ const random = mulberry32(seed);
2602
+ const randomValues = Array.from({ length: points + 1 }, () => random());
2603
+ const phaseOffsets = Array.from(
2604
+ { length: points + 1 },
2605
+ () => random() * Math.PI * 2
2606
+ );
2607
+ const edgePoints = [];
2608
+ context.moveTo(wipeEdgePosition, -diagonal / 2);
2609
+ for (let i = 0; i <= points; i++) {
2610
+ const p = i / points;
2611
+ const y = (p - 0.5) * diagonal;
2612
+ const flicker = Math.sin(frame * 0.3 + phaseOffsets[i]);
2613
+ const x = wipeEdgePosition + (randomValues[i] * 2 - 1) * flicker * edgeWaviness;
2614
+ context.lineTo(x, y);
2615
+ edgePoints.push({ x, y });
2616
+ }
2617
+ context.lineTo(wipeEdgePosition, diagonal / 2);
2618
+ context.lineTo(-diagonal / 2, diagonal / 2);
2619
+ context.lineTo(-diagonal / 2, -diagonal / 2);
2620
+ context.closePath();
2621
+ if (burnGlow && progress > 0.01) {
2622
+ const random2 = mulberry32(seed + frame);
2623
+ for (let i = 0; i < edgePoints.length; i += 3) {
2624
+ const point = edgePoints[i];
2625
+ const flicker = Math.sin(frame * 0.3 + phaseOffsets[i]);
2626
+ if (flicker > 0.2) {
2627
+ const glowSize = 4 + random2() * 6 * flicker * burnGlowIntensity;
2628
+ if (isFinite(point.x) && isFinite(point.y) && isFinite(glowSize) && glowSize > 0) {
2629
+ const gradient = context.createRadialGradient(
2630
+ point.x,
2631
+ point.y,
2632
+ 0,
2633
+ point.x,
2634
+ point.y,
2635
+ glowSize
2636
+ );
2637
+ gradient.addColorStop(0, burnGlowColor);
2638
+ gradient.addColorStop(0.4, burnGlowColor + "CC");
2639
+ gradient.addColorStop(1, burnGlowColor + "00");
2640
+ context.fillStyle = gradient;
2641
+ context.fillRect(
2642
+ point.x - glowSize,
2643
+ point.y - glowSize,
2644
+ glowSize * 2,
2645
+ glowSize * 2
2646
+ );
2647
+ if (random2() > 0.85) {
2648
+ const sparkleSize = 2 + random2() * 3;
2649
+ context.fillStyle = "#ffffff";
2650
+ context.fillRect(
2651
+ point.x - sparkleSize / 2,
2652
+ point.y - sparkleSize / 2,
2653
+ sparkleSize,
2654
+ sparkleSize
2655
+ );
2656
+ }
2657
+ }
2658
+ }
2659
+ }
2660
+ }
2661
+ } else if (edgeStyle === "organic") {
2662
+ const points = 100;
2663
+ const random = mulberry32(seed);
2664
+ const amplitudes = Array.from(
2665
+ { length: points + 1 },
2666
+ () => organicRandomAmplitude ? 0.5 + random() : 1
2667
+ );
2668
+ const wavelengths = Array.from(
2669
+ { length: points + 1 },
2670
+ () => organicRandomWavelength ? 0.5 + random() * 1.5 : 1
2671
+ );
2672
+ context.moveTo(wipeEdgePosition, -diagonal / 2);
2673
+ for (let i = 0; i <= points; i++) {
2674
+ const p = i / points;
2675
+ const y = (p - 0.5) * diagonal;
2676
+ const wave = Math.sin(
2677
+ p * edgeFrequency * wavelengths[i] * Math.PI + frame * 0.1
2678
+ ) * edgeWaviness * amplitudes[i];
2679
+ context.lineTo(wipeEdgePosition + wave, y);
2680
+ }
2681
+ context.lineTo(wipeEdgePosition, diagonal / 2);
2682
+ context.lineTo(-diagonal / 2, diagonal / 2);
2683
+ context.lineTo(-diagonal / 2, -diagonal / 2);
2684
+ context.closePath();
2685
+ } else {
2686
+ context.rect(
2687
+ -diagonal / 2,
2688
+ -diagonal / 2,
2689
+ wipeEdgePosition + diagonal / 2,
2690
+ diagonal
2691
+ );
2692
+ }
2693
+ context.rotate(-angleInRadians);
2694
+ context.translate(-width / 2, -height / 2);
2695
+ }
2696
+ context.clip();
2697
+ let sx = 0, sy = 0, sWidth = image.width, sHeight = image.height;
2698
+ if (fit === "cover") {
2699
+ const imgAspect = image.width / image.height;
2700
+ const canvasAspect = width / height;
2701
+ if (imgAspect > canvasAspect) {
2702
+ sWidth = image.height * canvasAspect;
2703
+ sx = (image.width - sWidth) / 2;
2704
+ } else {
2705
+ sHeight = image.width / canvasAspect;
2706
+ sy = (image.height - sHeight) / 2;
2707
+ }
2708
+ }
2709
+ context.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, width, height);
2710
+ context.restore();
2711
+ }, [
2712
+ frame,
2713
+ image,
2714
+ width,
2715
+ height,
2716
+ revealDurationInFrames,
2717
+ fit,
2718
+ revealType,
2719
+ angle,
2720
+ edgeStyle,
2721
+ edgeWaviness,
2722
+ edgeFrequency,
2723
+ id,
2724
+ backgroundColor,
2725
+ burnGlow,
2726
+ burnGlowColor,
2727
+ burnGlowIntensity,
2728
+ organicRandomAmplitude,
2729
+ organicRandomWavelength
2730
+ ]);
2731
+ return /* @__PURE__ */ React15.createElement(Atom, { ref: canvasRef, data: { className: "w-full h-full" }, id });
2732
+ };
2733
+
2734
+ // src/components/effects/CanvasContentAwareReveal.tsx
2735
+ import React16, { useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
2736
+ import { useCurrentFrame as useCurrentFrame5, useVideoConfig as useVideoConfig6 } from "remotion";
2737
+ import { z as z3 } from "zod";
2738
+ var CanvasContentAwareRevealProps = z3.object({
2739
+ imageUrl: z3.string().url(),
2740
+ revealDurationInFrames: z3.number().min(1),
2741
+ fit: z3.enum(["cover", "contain"]).default("cover"),
2742
+ backgroundColor: z3.string().default("rgba(0,0,0,0)"),
2743
+ burnColorOrder: z3.enum(["vibgyor", "luminance", "random"]).default("vibgyor"),
2744
+ revealMode: z3.enum(["color", "direction", "combined"]).default("combined").describe("Reveal mode: color-only, direction-only, or combined"),
2745
+ direction: z3.enum(["horizontal", "vertical", "diagonal-down", "diagonal-up", "top-to-bottom"]).default("top-to-bottom"),
2746
+ directionLayers: z3.number().default(10).describe("Number of layers for horizontal/vertical patterns")
2747
+ });
2748
+ var CanvasContentAwareReveal = ({ data, id }) => {
2749
+ const {
2750
+ imageUrl,
2751
+ revealDurationInFrames,
2752
+ fit,
2753
+ backgroundColor,
2754
+ burnColorOrder,
2755
+ revealMode,
2756
+ direction,
2757
+ directionLayers
2758
+ } = data;
2759
+ const frame = useCurrentFrame5();
2760
+ const { width, height } = useVideoConfig6();
2761
+ const canvasRef = useRef2(null);
2762
+ const [image, setImage] = useState2(null);
2763
+ const [pixelBurnMap, setPixelBurnMap] = useState2(null);
2764
+ const [isProcessing, setIsProcessing] = useState2(false);
2765
+ const burnMapGeneratedRef = useRef2(false);
2766
+ const rgbToHsv = (r, g, b) => {
2767
+ r /= 255;
2768
+ g /= 255;
2769
+ b /= 255;
2770
+ const max = Math.max(r, g, b), min = Math.min(r, g, b), delta = max - min;
2771
+ let h = 0;
2772
+ if (delta !== 0) {
2773
+ if (max === r) h = (g - b) / delta % 6;
2774
+ else if (max === g) h = (b - r) / delta + 2;
2775
+ else h = (r - g) / delta + 4;
2776
+ h *= 60;
2777
+ if (h < 0) h += 360;
2778
+ }
2779
+ return [h, max === 0 ? 0 : delta / max, max];
2780
+ };
2781
+ const getLuminance = (r, g, b) => 0.299 * r + 0.587 * g + 0.114 * b;
2782
+ const hueToVibgyorOrder = (hue) => {
2783
+ if (hue >= 260 && hue <= 290) return 0;
2784
+ if (hue >= 240 && hue < 260) return 0.15;
2785
+ if (hue >= 200 && hue < 240) return 0.3;
2786
+ if (hue >= 120 && hue < 200) return 0.5;
2787
+ if (hue >= 50 && hue < 120) return 0.65;
2788
+ if (hue >= 20 && hue < 50) return 0.8;
2789
+ if (hue >= 290 || hue < 20) return 1;
2790
+ return hue / 360;
2791
+ };
2792
+ useEffect2(() => {
2793
+ const img = new window.Image();
2794
+ img.crossOrigin = "Anonymous";
2795
+ img.src = imageUrl;
2796
+ img.onload = () => {
2797
+ setImage(img);
2798
+ burnMapGeneratedRef.current = false;
2799
+ };
2800
+ }, [imageUrl]);
2801
+ useEffect2(() => {
2802
+ if (!image || isProcessing || burnMapGeneratedRef.current) return;
2803
+ setIsProcessing(true);
2804
+ setTimeout(() => {
2805
+ try {
2806
+ const canvas = document.createElement("canvas");
2807
+ const ctx = canvas.getContext("2d");
2808
+ if (!ctx) return;
2809
+ canvas.width = image.width;
2810
+ canvas.height = image.height;
2811
+ ctx.drawImage(image, 0, 0);
2812
+ const imageData = ctx.getImageData(0, 0, image.width, image.height);
2813
+ const pixels = imageData.data;
2814
+ const burnMap = new Float32Array(image.width * image.height);
2815
+ const rawValues = [];
2816
+ for (let i = 0; i < pixels.length; i += 4) {
2817
+ const pixelIndex = i / 4;
2818
+ const [r, g, b] = [pixels[i], pixels[i + 1], pixels[i + 2]];
2819
+ let burnValue = 0;
2820
+ if (burnColorOrder === "vibgyor") {
2821
+ const [h, s] = rgbToHsv(r, g, b);
2822
+ burnValue = hueToVibgyorOrder(h) * s + 0.5 * (1 - s);
2823
+ } else if (burnColorOrder === "luminance") {
2824
+ burnValue = getLuminance(r, g, b) / 255;
2825
+ } else {
2826
+ burnValue = pixelIndex * 2654435761 % 2147483648 / 2147483648;
2827
+ }
2828
+ rawValues.push(burnValue);
2829
+ }
2830
+ const numBuckets = 200;
2831
+ const buckets = new Array(numBuckets).fill(0);
2832
+ rawValues.forEach((val) => {
2833
+ buckets[Math.min(Math.floor(val * numBuckets), numBuckets - 1)]++;
2834
+ });
2835
+ const cumulative = new Array(numBuckets);
2836
+ cumulative[0] = buckets[0];
2837
+ for (let i = 1; i < numBuckets; i++) {
2838
+ cumulative[i] = cumulative[i - 1] + buckets[i];
2839
+ }
2840
+ rawValues.forEach((val, idx) => {
2841
+ const bucket = Math.min(Math.floor(val * numBuckets), numBuckets - 1);
2842
+ burnMap[idx] = cumulative[bucket] / (image.width * image.height);
2843
+ });
2844
+ if (revealMode === "direction" || revealMode === "combined") {
2845
+ for (let idx = 0; idx < image.width * image.height; idx++) {
2846
+ const x = idx % image.width;
2847
+ const y = Math.floor(idx / image.width);
2848
+ let directionValue = 0;
2849
+ if (direction === "horizontal") {
2850
+ const layer = Math.floor(y / (image.height / directionLayers));
2851
+ const isReverse = layer % 2 === 1;
2852
+ const xNorm = isReverse ? (image.width - x) / image.width : x / image.width;
2853
+ directionValue = layer / directionLayers + xNorm / directionLayers;
2854
+ } else if (direction === "vertical") {
2855
+ const layer = Math.floor(x / (image.width / directionLayers));
2856
+ const isReverse = layer % 2 === 1;
2857
+ const yNorm = isReverse ? (image.height - y) / image.height : y / image.height;
2858
+ directionValue = layer / directionLayers + yNorm / directionLayers;
2859
+ } else if (direction === "top-to-bottom") {
2860
+ directionValue = y / image.height;
2861
+ } else if (direction === "diagonal-down") {
2862
+ directionValue = (x + y) / (image.width + image.height);
2863
+ } else {
2864
+ directionValue = (x + (image.height - y)) / (image.width + image.height);
2865
+ }
2866
+ burnMap[idx] = revealMode === "combined" ? burnMap[idx] * 0.6 + directionValue * 0.4 : directionValue;
2867
+ }
2868
+ let minVal = burnMap[0];
2869
+ let maxVal = burnMap[0];
2870
+ for (let i = 1; i < burnMap.length; i++) {
2871
+ if (burnMap[i] < minVal) minVal = burnMap[i];
2872
+ if (burnMap[i] > maxVal) maxVal = burnMap[i];
2873
+ }
2874
+ const range = maxVal - minVal;
2875
+ if (range > 0) {
2876
+ for (let i = 0; i < burnMap.length; i++) {
2877
+ burnMap[i] = (burnMap[i] - minVal) / range;
2878
+ }
2879
+ }
2880
+ }
2881
+ setPixelBurnMap(burnMap);
2882
+ burnMapGeneratedRef.current = true;
2883
+ } finally {
2884
+ setIsProcessing(false);
2885
+ }
2886
+ }, 0);
2887
+ }, [
2888
+ image,
2889
+ burnColorOrder,
2890
+ revealMode,
2891
+ direction,
2892
+ directionLayers
2893
+ ]);
2894
+ useEffect2(() => {
2895
+ if (!canvasRef.current || !image || !pixelBurnMap) return;
2896
+ const context = canvasRef.current.getContext("2d");
2897
+ if (!context) return;
2898
+ context.canvas.width = width;
2899
+ context.canvas.height = height;
2900
+ context.fillStyle = backgroundColor;
2901
+ context.fillRect(0, 0, width, height);
2902
+ const progress = Math.min(frame / revealDurationInFrames, 1);
2903
+ if (progress >= 1) {
2904
+ let sx2 = 0, sy2 = 0, sWidth2 = image.width, sHeight2 = image.height;
2905
+ if (fit === "cover") {
2906
+ const imgAspect = image.width / image.height;
2907
+ const canvasAspect = width / height;
2908
+ if (imgAspect > canvasAspect) {
2909
+ sWidth2 = image.height * canvasAspect;
2910
+ sx2 = (image.width - sWidth2) / 2;
2911
+ } else {
2912
+ sHeight2 = image.width / canvasAspect;
2913
+ sy2 = (image.height - sHeight2) / 2;
2914
+ }
2915
+ }
2916
+ context.drawImage(image, sx2, sy2, sWidth2, sHeight2, 0, 0, width, height);
2917
+ return;
2918
+ }
2919
+ const tempCanvas = document.createElement("canvas");
2920
+ tempCanvas.width = image.width;
2921
+ tempCanvas.height = image.height;
2922
+ const tempCtx = tempCanvas.getContext("2d");
2923
+ if (!tempCtx) return;
2924
+ tempCtx.drawImage(image, 0, 0);
2925
+ const imageData = tempCtx.getImageData(0, 0, image.width, image.height);
2926
+ const pixels = imageData.data;
2927
+ const transitionWidth = Math.max(
2928
+ 0.02,
2929
+ Math.min(0.15, 3 / (revealDurationInFrames / 100))
2930
+ );
2931
+ for (let i = 0; i < pixels.length; i += 4) {
2932
+ const pixelIndex = i / 4;
2933
+ const burnProgress = (progress - pixelBurnMap[pixelIndex]) / transitionWidth;
2934
+ pixels[i + 3] = Math.floor(
2935
+ pixels[i + 3] * Math.max(0, Math.min(1, burnProgress))
2936
+ );
2937
+ }
2938
+ tempCtx.putImageData(imageData, 0, 0);
2939
+ let sx = 0, sy = 0, sWidth = image.width, sHeight = image.height;
2940
+ if (fit === "cover") {
2941
+ const imgAspect = image.width / image.height;
2942
+ const canvasAspect = width / height;
2943
+ if (imgAspect > canvasAspect) {
2944
+ sWidth = image.height * canvasAspect;
2945
+ sx = (image.width - sWidth) / 2;
2946
+ } else {
2947
+ sHeight = image.width / canvasAspect;
2948
+ sy = (image.height - sHeight) / 2;
2949
+ }
2950
+ }
2951
+ context.drawImage(tempCanvas, sx, sy, sWidth, sHeight, 0, 0, width, height);
2952
+ }, [
2953
+ frame,
2954
+ image,
2955
+ width,
2956
+ height,
2957
+ pixelBurnMap,
2958
+ revealDurationInFrames,
2959
+ fit,
2960
+ backgroundColor
2961
+ ]);
2962
+ return /* @__PURE__ */ React16.createElement(Atom, { ref: canvasRef, data: { className: "w-full h-full" }, id });
2963
+ };
2964
+
2965
+ // src/components/effects/CanvasGlitchEffect.tsx
2966
+ import React17, { useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
2967
+ import { useCurrentFrame as useCurrentFrame6, useVideoConfig as useVideoConfig7 } from "remotion";
2968
+ import { z as z4 } from "zod";
2969
+ var CanvasGlitchEffectProps = z4.object({
2970
+ imageUrl: z4.string().url(),
2971
+ durationInFrames: z4.number().min(1),
2972
+ fit: z4.enum(["cover", "contain"]).default("cover"),
2973
+ backgroundColor: z4.string().default("rgba(0,0,0,0)"),
2974
+ glitchType: z4.enum(["rgb-shift", "slice", "corrupt", "static", "scan"]).default("rgb-shift"),
2975
+ intensity: z4.number().default(10).describe("Intensity of glitch effect"),
2976
+ frequency: z4.number().default(0.3).describe("How often glitches occur (0-1)"),
2977
+ continuous: z4.boolean().default(false).describe("Continuous glitch vs periodic"),
2978
+ glitchStartFrame: z4.number().default(0).describe("Frame to start glitching"),
2979
+ glitchEndFrame: z4.number().default(-1).describe("Frame to end glitching (-1 = duration)")
2980
+ });
2981
+ var CanvasGlitchEffect = ({ data, id }) => {
2982
+ const {
2983
+ imageUrl,
2984
+ durationInFrames,
2985
+ fit,
2986
+ backgroundColor,
2987
+ glitchType,
2988
+ intensity,
2989
+ frequency,
2990
+ continuous,
2991
+ glitchStartFrame,
2992
+ glitchEndFrame
2993
+ } = data;
2994
+ const frame = useCurrentFrame6();
2995
+ const { width, height } = useVideoConfig7();
2996
+ const canvasRef = useRef3(null);
2997
+ const [image, setImage] = useState3(null);
2998
+ useEffect3(() => {
2999
+ const img = new window.Image();
3000
+ img.crossOrigin = "Anonymous";
3001
+ img.src = imageUrl;
3002
+ img.onload = () => setImage(img);
3003
+ }, [imageUrl]);
3004
+ useEffect3(() => {
3005
+ if (!canvasRef.current || !image) return;
3006
+ const context = canvasRef.current.getContext("2d");
3007
+ if (!context) return;
3008
+ context.canvas.width = width;
3009
+ context.canvas.height = height;
3010
+ context.fillStyle = backgroundColor;
3011
+ context.fillRect(0, 0, width, height);
3012
+ const endFrame = glitchEndFrame === -1 ? durationInFrames : glitchEndFrame;
3013
+ const isInGlitchRange = frame >= glitchStartFrame && frame <= endFrame;
3014
+ const seed = Math.floor(frame / 3);
3015
+ const random = (seed * 9301 + 49297) % 233280 / 233280;
3016
+ const isGlitching = isInGlitchRange && (continuous || random < frequency);
3017
+ let sx = 0, sy = 0, sWidth = image.width, sHeight = image.height;
3018
+ if (fit === "cover") {
3019
+ const imgAspect = image.width / image.height;
3020
+ const canvasAspect = width / height;
3021
+ if (imgAspect > canvasAspect) {
3022
+ sWidth = image.height * canvasAspect;
3023
+ sx = (image.width - sWidth) / 2;
3024
+ } else {
3025
+ sHeight = image.width / canvasAspect;
3026
+ sy = (image.height - sHeight) / 2;
3027
+ }
3028
+ }
3029
+ if (!isGlitching) {
3030
+ context.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, width, height);
3031
+ return;
3032
+ }
3033
+ if (glitchType === "rgb-shift") {
3034
+ const tempCanvas = document.createElement("canvas");
3035
+ tempCanvas.width = image.width;
3036
+ tempCanvas.height = image.height;
3037
+ const tempCtx = tempCanvas.getContext("2d");
3038
+ if (!tempCtx) return;
3039
+ tempCtx.drawImage(image, 0, 0);
3040
+ const imageData = tempCtx.getImageData(0, 0, image.width, image.height);
3041
+ const pixels = imageData.data;
3042
+ const shift = intensity * (random * 2 - 1);
3043
+ const redData = tempCtx.createImageData(image.width, image.height);
3044
+ const greenData = tempCtx.createImageData(image.width, image.height);
3045
+ const blueData = tempCtx.createImageData(image.width, image.height);
3046
+ for (let i = 0; i < pixels.length; i += 4) {
3047
+ redData.data[i] = pixels[i];
3048
+ redData.data[i + 3] = pixels[i + 3];
3049
+ greenData.data[i + 1] = pixels[i + 1];
3050
+ greenData.data[i + 3] = pixels[i + 3];
3051
+ blueData.data[i + 2] = pixels[i + 2];
3052
+ blueData.data[i + 3] = pixels[i + 3];
3053
+ }
3054
+ context.save();
3055
+ context.globalCompositeOperation = "screen";
3056
+ tempCtx.putImageData(redData, 0, 0);
3057
+ context.drawImage(
3058
+ tempCanvas,
3059
+ sx + shift,
3060
+ sy,
3061
+ sWidth,
3062
+ sHeight,
3063
+ shift,
3064
+ 0,
3065
+ width,
3066
+ height
3067
+ );
3068
+ tempCtx.putImageData(greenData, 0, 0);
3069
+ context.drawImage(
3070
+ tempCanvas,
3071
+ sx,
3072
+ sy,
3073
+ sWidth,
3074
+ sHeight,
3075
+ 0,
3076
+ 0,
3077
+ width,
3078
+ height
3079
+ );
3080
+ tempCtx.putImageData(blueData, 0, 0);
3081
+ context.drawImage(
3082
+ tempCanvas,
3083
+ sx - shift,
3084
+ sy,
3085
+ sWidth,
3086
+ sHeight,
3087
+ -shift,
3088
+ 0,
3089
+ width,
3090
+ height
3091
+ );
3092
+ context.restore();
3093
+ } else if (glitchType === "slice") {
3094
+ const sliceCount = 20;
3095
+ const sliceHeight = height / sliceCount;
3096
+ for (let i = 0; i < sliceCount; i++) {
3097
+ const offset = (random * 2 - 1) * intensity * (i % 2 === 0 ? 1 : -1);
3098
+ const sy_slice = sy + sHeight / sliceCount * i;
3099
+ const dy = sliceHeight * i;
3100
+ context.drawImage(
3101
+ image,
3102
+ sx,
3103
+ sy_slice,
3104
+ sWidth,
3105
+ sHeight / sliceCount,
3106
+ offset,
3107
+ dy,
3108
+ width,
3109
+ sliceHeight
3110
+ );
3111
+ }
3112
+ } else if (glitchType === "corrupt") {
3113
+ context.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, width, height);
3114
+ const blockCount = Math.floor(intensity / 2);
3115
+ for (let i = 0; i < blockCount; i++) {
3116
+ const blockW = Math.random() * width * 0.3;
3117
+ const blockH = Math.random() * height * 0.2;
3118
+ const blockX = Math.random() * (width - blockW);
3119
+ const blockY = Math.random() * (height - blockH);
3120
+ const sourceX = Math.random() * (width - blockW);
3121
+ const sourceY = Math.random() * (height - blockH);
3122
+ try {
3123
+ const imgData = context.getImageData(
3124
+ sourceX,
3125
+ sourceY,
3126
+ blockW,
3127
+ blockH
3128
+ );
3129
+ context.putImageData(imgData, blockX, blockY);
3130
+ } catch (e) {
3131
+ }
3132
+ }
3133
+ } else if (glitchType === "static") {
3134
+ context.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, width, height);
3135
+ const imageData = context.getImageData(0, 0, width, height);
3136
+ const pixels = imageData.data;
3137
+ for (let i = 0; i < pixels.length; i += 4) {
3138
+ if (Math.random() < intensity / 100) {
3139
+ const noise = Math.random() * 255;
3140
+ pixels[i] = noise;
3141
+ pixels[i + 1] = noise;
3142
+ pixels[i + 2] = noise;
3143
+ }
3144
+ }
3145
+ context.putImageData(imageData, 0, 0);
3146
+ } else if (glitchType === "scan") {
3147
+ context.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, width, height);
3148
+ const scanY = frame * 5 % height;
3149
+ context.fillStyle = `rgba(255, 255, 255, ${intensity / 100})`;
3150
+ context.fillRect(0, scanY, width, 3);
3151
+ const distortY = Math.max(0, scanY - 10);
3152
+ const distortHeight = Math.min(20, height - distortY);
3153
+ if (distortHeight > 0) {
3154
+ try {
3155
+ const imgData = context.getImageData(
3156
+ 0,
3157
+ distortY,
3158
+ width,
3159
+ distortHeight
3160
+ );
3161
+ const shiftAmount = intensity * (random * 2 - 1);
3162
+ context.putImageData(imgData, shiftAmount, distortY);
3163
+ } catch (e) {
3164
+ }
3165
+ }
3166
+ }
3167
+ }, [
3168
+ frame,
3169
+ image,
3170
+ width,
3171
+ height,
3172
+ durationInFrames,
3173
+ fit,
3174
+ backgroundColor,
3175
+ glitchType,
3176
+ intensity,
3177
+ frequency,
3178
+ continuous,
3179
+ glitchStartFrame,
3180
+ glitchEndFrame
3181
+ ]);
3182
+ return /* @__PURE__ */ React17.createElement(Atom, { ref: canvasRef, data: { className: "w-full h-full" }, id });
3183
+ };
3184
+
3185
+ // src/components/effects/CanvasParticleEffect.tsx
3186
+ import React18, { useEffect as useEffect4, useRef as useRef4, useState as useState4 } from "react";
3187
+ import { useCurrentFrame as useCurrentFrame7, useVideoConfig as useVideoConfig8 } from "remotion";
3188
+ import { z as z5 } from "zod";
3189
+ var CanvasParticleEffectProps = z5.object({
3190
+ imageUrl: z5.string().url(),
3191
+ revealDurationInFrames: z5.number().min(1),
3192
+ fit: z5.enum(["cover", "contain"]).default("cover"),
3193
+ backgroundColor: z5.string().default("rgba(0,0,0,0)"),
3194
+ particleCount: z5.number().default(2e3).describe("Number of particles"),
3195
+ particleSize: z5.number().default(3).describe("Size of each particle"),
3196
+ particleEffect: z5.enum(["assemble", "disassemble", "explode", "pixelate"]).default("assemble"),
3197
+ assembleFrom: z5.enum(["center", "edges", "random", "bottom"]).default("random"),
3198
+ speed: z5.number().default(1).describe("Animation speed multiplier"),
3199
+ rotation: z5.boolean().default(false).describe("Add rotation to particles")
3200
+ });
3201
+ var CanvasParticleEffect = ({ data, id }) => {
3202
+ const {
3203
+ imageUrl,
3204
+ revealDurationInFrames,
3205
+ fit,
3206
+ backgroundColor,
3207
+ particleCount,
3208
+ particleSize,
3209
+ particleEffect,
3210
+ assembleFrom,
3211
+ speed,
3212
+ rotation
3213
+ } = data;
3214
+ const frame = useCurrentFrame7();
3215
+ const { width, height } = useVideoConfig8();
3216
+ const canvasRef = useRef4(null);
3217
+ const [image, setImage] = useState4(null);
3218
+ const [particles, setParticles] = useState4(null);
3219
+ useEffect4(() => {
3220
+ const img = new window.Image();
3221
+ img.crossOrigin = "Anonymous";
3222
+ img.src = imageUrl;
3223
+ img.onload = () => setImage(img);
3224
+ }, [imageUrl]);
3225
+ useEffect4(() => {
3226
+ if (!image) return;
3227
+ const canvas = document.createElement("canvas");
3228
+ const ctx = canvas.getContext("2d");
3229
+ if (!ctx) return;
3230
+ canvas.width = image.width;
3231
+ canvas.height = image.height;
3232
+ ctx.drawImage(image, 0, 0);
3233
+ const imageData = ctx.getImageData(0, 0, image.width, image.height);
3234
+ const pixels = imageData.data;
3235
+ const particleArray = [];
3236
+ const step = Math.floor(
3237
+ Math.sqrt(image.width * image.height / particleCount)
3238
+ );
3239
+ for (let y = 0; y < image.height; y += step) {
3240
+ for (let x = 0; x < image.width; x += step) {
3241
+ const i = (y * image.width + x) * 4;
3242
+ const [r, g, b, a] = [
3243
+ pixels[i],
3244
+ pixels[i + 1],
3245
+ pixels[i + 2],
3246
+ pixels[i + 3]
3247
+ ];
3248
+ if (a > 128) {
3249
+ const targetX = x;
3250
+ const targetY = y;
3251
+ let startX = targetX, startY = targetY;
3252
+ if (particleEffect === "assemble") {
3253
+ if (assembleFrom === "center") {
3254
+ startX = image.width / 2;
3255
+ startY = image.height / 2;
3256
+ } else if (assembleFrom === "edges") {
3257
+ const edge = Math.floor(Math.random() * 4);
3258
+ if (edge === 0) {
3259
+ startX = 0;
3260
+ startY = Math.random() * image.height;
3261
+ } else if (edge === 1) {
3262
+ startX = image.width;
3263
+ startY = Math.random() * image.height;
3264
+ } else if (edge === 2) {
3265
+ startX = Math.random() * image.width;
3266
+ startY = 0;
3267
+ } else {
3268
+ startX = Math.random() * image.width;
3269
+ startY = image.height;
3270
+ }
3271
+ } else if (assembleFrom === "bottom") {
3272
+ startX = targetX;
3273
+ startY = image.height + Math.random() * 200;
3274
+ } else {
3275
+ startX = Math.random() * image.width;
3276
+ startY = Math.random() * image.height;
3277
+ }
3278
+ }
3279
+ particleArray.push({
3280
+ x: startX,
3281
+ y: startY,
3282
+ targetX,
3283
+ targetY,
3284
+ color: `rgba(${r},${g},${b},${a / 255})`,
3285
+ startX,
3286
+ startY,
3287
+ angle: Math.random() * Math.PI * 2
3288
+ });
3289
+ }
3290
+ }
3291
+ }
3292
+ setParticles(particleArray);
3293
+ }, [image, particleCount, particleEffect, assembleFrom]);
3294
+ useEffect4(() => {
3295
+ if (!canvasRef.current || !image || !particles) return;
3296
+ const context = canvasRef.current.getContext("2d");
3297
+ if (!context) return;
3298
+ context.canvas.width = width;
3299
+ context.canvas.height = height;
3300
+ context.fillStyle = backgroundColor;
3301
+ context.fillRect(0, 0, width, height);
3302
+ const progress = Math.min(frame / revealDurationInFrames * speed, 1);
3303
+ if (progress >= 1 && particleEffect === "assemble") {
3304
+ const scaleX2 = width / image.width;
3305
+ const scaleY2 = height / image.height;
3306
+ let scale2 = scaleX2;
3307
+ let offsetX2 = 0, offsetY2 = 0;
3308
+ if (fit === "cover") {
3309
+ scale2 = Math.max(scaleX2, scaleY2);
3310
+ offsetX2 = (width - image.width * scale2) / 2;
3311
+ offsetY2 = (height - image.height * scale2) / 2;
3312
+ } else {
3313
+ scale2 = Math.min(scaleX2, scaleY2);
3314
+ offsetX2 = (width - image.width * scale2) / 2;
3315
+ offsetY2 = (height - image.height * scale2) / 2;
3316
+ }
3317
+ context.save();
3318
+ context.translate(offsetX2, offsetY2);
3319
+ context.scale(scale2, scale2);
3320
+ context.drawImage(image, 0, 0);
3321
+ context.restore();
3322
+ return;
3323
+ }
3324
+ const easeProgress = particleEffect === "explode" ? progress * progress * (3 - 2 * progress) : 1 - Math.pow(1 - progress, 3);
3325
+ const scaleX = width / image.width;
3326
+ const scaleY = height / image.height;
3327
+ let scale = scaleX;
3328
+ let offsetX = 0, offsetY = 0;
3329
+ if (fit === "cover") {
3330
+ scale = Math.max(scaleX, scaleY);
3331
+ offsetX = (width - image.width * scale) / 2;
3332
+ offsetY = (height - image.height * scale) / 2;
3333
+ } else {
3334
+ scale = Math.min(scaleX, scaleY);
3335
+ offsetX = (width - image.width * scale) / 2;
3336
+ offsetY = (height - image.height * scale) / 2;
3337
+ }
3338
+ particles.forEach((particle) => {
3339
+ let x, y;
3340
+ if (particleEffect === "assemble") {
3341
+ x = particle.startX + (particle.targetX - particle.startX) * easeProgress;
3342
+ y = particle.startY + (particle.targetY - particle.startY) * easeProgress;
3343
+ } else if (particleEffect === "disassemble") {
3344
+ const reverseProgress = 1 - easeProgress;
3345
+ x = particle.targetX + (particle.startX - particle.targetX) * (1 - reverseProgress);
3346
+ y = particle.targetY + (particle.startY - particle.targetY) * (1 - reverseProgress);
3347
+ } else if (particleEffect === "explode") {
3348
+ const dx = particle.targetX - image.width / 2;
3349
+ const dy = particle.targetY - image.height / 2;
3350
+ const dist = Math.sqrt(dx * dx + dy * dy);
3351
+ const explosionDist = dist * easeProgress * 3;
3352
+ x = particle.targetX + dx / dist * explosionDist;
3353
+ y = particle.targetY + dy / dist * explosionDist;
3354
+ } else {
3355
+ x = particle.targetX;
3356
+ y = particle.targetY;
3357
+ }
3358
+ const finalX = x * scale + offsetX;
3359
+ const finalY = y * scale + offsetY;
3360
+ context.save();
3361
+ context.translate(finalX, finalY);
3362
+ if (rotation && particleEffect !== "pixelate") {
3363
+ context.rotate(particle.angle * easeProgress);
3364
+ }
3365
+ const size = particleEffect === "pixelate" ? particleSize * (1 + (1 - easeProgress) * 3) : particleSize;
3366
+ context.fillStyle = particle.color;
3367
+ context.fillRect(-size / 2, -size / 2, size, size);
3368
+ context.restore();
3369
+ });
3370
+ }, [
3371
+ frame,
3372
+ image,
3373
+ width,
3374
+ height,
3375
+ particles,
3376
+ revealDurationInFrames,
3377
+ fit,
3378
+ backgroundColor,
3379
+ particleSize,
3380
+ particleEffect,
3381
+ speed,
3382
+ rotation
3383
+ ]);
3384
+ return /* @__PURE__ */ React18.createElement(Atom, { ref: canvasRef, data: { className: "w-full h-full" }, id });
3385
+ };
3386
+
3387
+ // src/components/effects/GenericPresets.ts
3388
+ var fadeInPreset = [
3389
+ { key: "opacity", val: 0, prog: 0 },
3390
+ { key: "opacity", val: 1, prog: 1 }
3391
+ ];
3392
+ var fadeOutPreset = [
3393
+ { key: "opacity", val: 1, prog: 0 },
3394
+ { key: "opacity", val: 0, prog: 1 }
3395
+ ];
3396
+ var scaleInPreset = [
3397
+ { key: "scale", val: 0, prog: 0 },
3398
+ { key: "scale", val: 1, prog: 1 }
3399
+ ];
3400
+ var scaleOutPreset = [
3401
+ { key: "scale", val: 1, prog: 0 },
3402
+ { key: "scale", val: 0, prog: 1 }
3403
+ ];
3404
+ var slideInLeftPreset = [
3405
+ { key: "translateX", val: -100, prog: 0 },
3406
+ { key: "translateX", val: 0, prog: 1 }
3407
+ ];
3408
+ var slideInRightPreset = [
3409
+ { key: "translateX", val: 100, prog: 0 },
3410
+ { key: "translateX", val: 0, prog: 1 }
3411
+ ];
3412
+ var slideInTopPreset = [
3413
+ { key: "translateY", val: -100, prog: 0 },
3414
+ { key: "translateY", val: 0, prog: 1 }
3415
+ ];
3416
+ var slideInBottomPreset = [
3417
+ { key: "translateY", val: 100, prog: 0 },
3418
+ { key: "translateY", val: 0, prog: 1 }
3419
+ ];
3420
+ var bouncePreset = [
3421
+ { key: "scale", val: 0, prog: 0 },
3422
+ { key: "scale", val: 1.2, prog: 0.6 },
3423
+ { key: "scale", val: 1, prog: 1 }
3424
+ ];
3425
+ var pulsePreset = [
3426
+ { key: "scale", val: 1, prog: 0 },
3427
+ { key: "scale", val: 1.1, prog: 0.5 },
3428
+ { key: "scale", val: 1, prog: 1 }
3429
+ ];
3430
+ var rotateInPreset = [
3431
+ { key: "rotate", val: -180, prog: 0 },
3432
+ { key: "rotate", val: 0, prog: 1 }
3433
+ ];
3434
+ var blurInPreset = [
3435
+ { key: "blur", val: 10, prog: 0 },
3436
+ { key: "blur", val: 0, prog: 1 }
3437
+ ];
3438
+ var fadeInScalePreset = [
3439
+ { key: "opacity", val: 0, prog: 0 },
3440
+ { key: "opacity", val: 1, prog: 1 },
3441
+ { key: "scale", val: 0.8, prog: 0 },
3442
+ { key: "scale", val: 1, prog: 1 }
3443
+ ];
3444
+ var slideInFadePreset = [
3445
+ { key: "translateX", val: -50, prog: 0 },
3446
+ { key: "translateX", val: 0, prog: 1 },
3447
+ { key: "opacity", val: 0, prog: 0 },
3448
+ { key: "opacity", val: 1, prog: 1 }
3449
+ ];
3450
+ var slideInLeftStringPreset = [
3451
+ { key: "translateX", val: "-100px", prog: 0 },
3452
+ { key: "translateX", val: "0px", prog: 1 }
3453
+ ];
3454
+ var slideInRightStringPreset = [
3455
+ { key: "translateX", val: "100px", prog: 0 },
3456
+ { key: "translateX", val: "0px", prog: 1 }
3457
+ ];
3458
+ var slideInTopStringPreset = [
3459
+ { key: "translateY", val: "-100px", prog: 0 },
3460
+ { key: "translateY", val: "0px", prog: 1 }
3461
+ ];
3462
+ var slideInBottomStringPreset = [
3463
+ { key: "translateY", val: "100px", prog: 0 },
3464
+ { key: "translateY", val: "0px", prog: 1 }
3465
+ ];
3466
+ var rotateInStringPreset = [
3467
+ { key: "rotate", val: "-180deg", prog: 0 },
3468
+ { key: "rotate", val: "0deg", prog: 1 }
3469
+ ];
3470
+ var blurInStringPreset = [
3471
+ { key: "blur", val: "10px", prog: 0 },
3472
+ { key: "blur", val: "0px", prog: 1 }
3473
+ ];
3474
+ var scaleInStringPreset = [
3475
+ { key: "scale", val: 0, prog: 0 },
3476
+ { key: "scale", val: 1, prog: 1 }
3477
+ ];
3478
+ var slideInLeftResponsivePreset = [
3479
+ { key: "translateX", val: "-50vw", prog: 0 },
3480
+ { key: "translateX", val: "0vw", prog: 1 }
3481
+ ];
3482
+ var slideInTopResponsivePreset = [
3483
+ { key: "translateY", val: "-50vh", prog: 0 },
3484
+ { key: "translateY", val: "0vh", prog: 1 }
3485
+ ];
3486
+ var backgroundColorPreset = [
3487
+ { key: "backgroundColor", val: "#ff0000", prog: 0 },
3488
+ { key: "backgroundColor", val: "#0000ff", prog: 1 }
3489
+ ];
3490
+ var borderRadiusPreset = [
3491
+ { key: "borderRadius", val: "0px", prog: 0 },
3492
+ { key: "borderRadius", val: "50px", prog: 1 }
3493
+ ];
3494
+ var boxShadowPreset = [
3495
+ { key: "boxShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
3496
+ { key: "boxShadow", val: "10px 10px 20px rgba(0,0,0,0.5)", prog: 1 }
3497
+ ];
3498
+ var fontSizePreset = [
3499
+ { key: "fontSize", val: "12px", prog: 0 },
3500
+ { key: "fontSize", val: "24px", prog: 1 }
3501
+ ];
3502
+ var letterSpacingPreset = [
3503
+ { key: "letterSpacing", val: "0px", prog: 0 },
3504
+ { key: "letterSpacing", val: "5px", prog: 1 }
3505
+ ];
3506
+ var lineHeightPreset = [
3507
+ { key: "lineHeight", val: "1", prog: 0 },
3508
+ { key: "lineHeight", val: "2", prog: 1 }
3509
+ ];
3510
+ var textShadowPreset = [
3511
+ { key: "textShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
3512
+ { key: "textShadow", val: "2px 2px 4px rgba(0,0,0,0.5)", prog: 1 }
3513
+ ];
3514
+ var widthPreset = [
3515
+ { key: "width", val: "0px", prog: 0 },
3516
+ { key: "width", val: "100%", prog: 1 }
3517
+ ];
3518
+ var heightPreset = [
3519
+ { key: "height", val: "0px", prog: 0 },
3520
+ { key: "height", val: "100%", prog: 1 }
3521
+ ];
3522
+ var marginPreset = [
3523
+ { key: "margin", val: "0px", prog: 0 },
3524
+ { key: "margin", val: "20px", prog: 1 }
3525
+ ];
3526
+ var paddingPreset = [
3527
+ { key: "padding", val: "0px", prog: 0 },
3528
+ { key: "padding", val: "20px", prog: 1 }
3529
+ ];
3530
+ var morphingCardPreset = [
3531
+ { key: "borderRadius", val: "0px", prog: 0 },
3532
+ { key: "borderRadius", val: "20px", prog: 0.5 },
3533
+ { key: "borderRadius", val: "50px", prog: 1 },
3534
+ { key: "boxShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
3535
+ { key: "boxShadow", val: "0px 10px 30px rgba(0,0,0,0.3)", prog: 1 },
3536
+ { key: "backgroundColor", val: "#ffffff", prog: 0 },
3537
+ { key: "backgroundColor", val: "#f0f0f0", prog: 1 }
3538
+ ];
3539
+ var textRevealPreset = [
3540
+ { key: "opacity", val: 0, prog: 0 },
3541
+ { key: "opacity", val: 1, prog: 1 },
3542
+ { key: "letterSpacing", val: "10px", prog: 0 },
3543
+ { key: "letterSpacing", val: "0px", prog: 1 },
3544
+ { key: "textShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
3545
+ { key: "textShadow", val: "2px 2px 4px rgba(0,0,0,0.5)", prog: 1 }
3546
+ ];
3547
+ var GenericEffectPresets = {
3548
+ fadeInPreset,
3549
+ fadeOutPreset,
3550
+ scaleInPreset,
3551
+ scaleOutPreset,
3552
+ slideInLeftPreset,
3553
+ slideInRightPreset,
3554
+ slideInTopPreset,
3555
+ slideInBottomPreset,
3556
+ bouncePreset,
3557
+ pulsePreset,
3558
+ rotateInPreset,
3559
+ blurInPreset,
3560
+ fadeInScalePreset,
3561
+ slideInFadePreset,
3562
+ // String-based presets
3563
+ slideInLeftStringPreset,
3564
+ slideInRightStringPreset,
3565
+ slideInTopStringPreset,
3566
+ slideInBottomStringPreset,
3567
+ rotateInStringPreset,
3568
+ blurInStringPreset,
3569
+ scaleInStringPreset,
3570
+ slideInLeftResponsivePreset,
3571
+ slideInTopResponsivePreset,
3572
+ // Custom CSS property presets
3573
+ backgroundColorPreset,
3574
+ borderRadiusPreset,
3575
+ boxShadowPreset,
3576
+ fontSizePreset,
3577
+ letterSpacingPreset,
3578
+ lineHeightPreset,
3579
+ textShadowPreset,
3580
+ widthPreset,
3581
+ heightPreset,
3582
+ marginPreset,
3583
+ paddingPreset,
3584
+ morphingCardPreset,
3585
+ textRevealPreset
3586
+ };
3587
+
3588
+ // src/components/effects/index.ts
3589
+ registerEffect(config2.displayName, BlurEffect, config2);
3590
+ registerEffect(config3.displayName, LoopEffect, config3);
3591
+ registerEffect(config4.displayName, PanEffect, config4);
3592
+ registerEffect(config5.displayName, ZoomEffect, config5);
3593
+ registerEffect("generic", UniversalEffect, config);
3594
+ registerEffect(config6.displayName, ShakeEffect, config6);
3595
+ registerEffect(
3596
+ config7.displayName,
3597
+ StretchEffect,
3598
+ config7
3599
+ );
3600
+ registerEffect(
3601
+ config8.displayName,
3602
+ WaveformEffect,
3603
+ config8
3604
+ );
3605
+ registerEffect("CanvasWipeReveal", CanvasWipeReveal);
3606
+ registerEffect("CanvasContentAwareReveal", CanvasContentAwareReveal);
3607
+ registerEffect("CanvasParticleEffect", CanvasParticleEffect);
3608
+ registerEffect("CanvasGlitchEffect", CanvasGlitchEffect);
3609
+
3610
+ // src/components/layouts/BaseLayout.tsx
3611
+ var Layout = ({ id, children, data, context }) => {
3612
+ const { containerProps = {}, childrenProps = [], repeatChildrenProps = {} } = data;
3613
+ const overrideStyles = useAnimatedStyles(id);
3614
+ const childrenArray = Children.toArray(children);
3615
+ const enhancedStyle = useMemo9(
3616
+ () => ({
3617
+ ...!context?.boundaries?.reset ? context?.boundaries : {},
3618
+ ...containerProps.style,
1974
3619
  ...overrideStyles
1975
3620
  }),
1976
3621
  [
@@ -1981,7 +3626,7 @@ var Layout = ({ id, children, data, context }) => {
1981
3626
  );
1982
3627
  if (Object.keys(repeatChildrenProps).length <= 0 && childrenProps.length <= 0) {
1983
3628
  if (data.isAbsoluteFill) {
1984
- return /* @__PURE__ */ React13.createElement(
3629
+ return /* @__PURE__ */ React19.createElement(
1985
3630
  AbsoluteFill3,
1986
3631
  {
1987
3632
  ...containerProps,
@@ -1990,25 +3635,25 @@ var Layout = ({ id, children, data, context }) => {
1990
3635
  childrenArray
1991
3636
  );
1992
3637
  }
1993
- return /* @__PURE__ */ React13.createElement(
3638
+ return /* @__PURE__ */ React19.createElement(
1994
3639
  "div",
1995
3640
  {
1996
3641
  id,
1997
3642
  ...containerProps,
1998
3643
  style: enhancedStyle
1999
3644
  },
2000
- childrenArray.map((child, index) => /* @__PURE__ */ React13.createElement(React13.Fragment, { key: index }, child))
3645
+ childrenArray.map((child, index) => /* @__PURE__ */ React19.createElement(React19.Fragment, { key: index }, child))
2001
3646
  );
2002
3647
  }
2003
3648
  if (data.isAbsoluteFill) {
2004
- return /* @__PURE__ */ React13.createElement(
3649
+ return /* @__PURE__ */ React19.createElement(
2005
3650
  AbsoluteFill3,
2006
3651
  {
2007
3652
  id,
2008
3653
  ...containerProps,
2009
3654
  style: enhancedStyle
2010
3655
  },
2011
- childrenArray.map((child, index) => /* @__PURE__ */ React13.createElement(
3656
+ childrenArray.map((child, index) => /* @__PURE__ */ React19.createElement(
2012
3657
  "div",
2013
3658
  {
2014
3659
  key: index,
@@ -2018,14 +3663,14 @@ var Layout = ({ id, children, data, context }) => {
2018
3663
  ))
2019
3664
  );
2020
3665
  }
2021
- return /* @__PURE__ */ React13.createElement(
3666
+ return /* @__PURE__ */ React19.createElement(
2022
3667
  "div",
2023
3668
  {
2024
3669
  id,
2025
3670
  ...containerProps,
2026
3671
  style: enhancedStyle
2027
3672
  },
2028
- childrenArray.map((child, index) => /* @__PURE__ */ React13.createElement(
3673
+ childrenArray.map((child, index) => /* @__PURE__ */ React19.createElement(
2029
3674
  "div",
2030
3675
  {
2031
3676
  key: index,
@@ -2035,7 +3680,7 @@ var Layout = ({ id, children, data, context }) => {
2035
3680
  ))
2036
3681
  );
2037
3682
  };
2038
- var config8 = {
3683
+ var config10 = {
2039
3684
  displayName: "BaseLayout",
2040
3685
  type: "layout",
2041
3686
  isInnerSequence: false
@@ -2043,17 +3688,17 @@ var config8 = {
2043
3688
 
2044
3689
  // src/components/layouts/index.ts
2045
3690
  registerComponent(
2046
- config8.displayName,
3691
+ config10.displayName,
2047
3692
  Layout,
2048
3693
  "layout",
2049
- config8
3694
+ config10
2050
3695
  );
2051
3696
 
2052
3697
  // src/components/atoms/ShapeAtom.tsx
2053
- import React14 from "react";
2054
- import { Easing as Easing4, interpolate as interpolate4, useCurrentFrame as useCurrentFrame4 } from "remotion";
2055
- var Atom = ({ data }) => {
2056
- const frame = useCurrentFrame4();
3698
+ import React20 from "react";
3699
+ import { Easing as Easing4, interpolate as interpolate4, useCurrentFrame as useCurrentFrame8 } from "remotion";
3700
+ var Atom2 = ({ data }) => {
3701
+ const frame = useCurrentFrame8();
2057
3702
  const { shape, color, rotation, style } = data;
2058
3703
  const rotationStyle = rotation ? {
2059
3704
  transform: `rotate(${interpolate4(
@@ -2075,22 +3720,22 @@ var Atom = ({ data }) => {
2075
3720
  };
2076
3721
  switch (shape) {
2077
3722
  case "circle":
2078
- return /* @__PURE__ */ React14.createElement("div", { style: { ...baseStyle, backgroundColor: color, borderRadius: "50%" } });
3723
+ return /* @__PURE__ */ React20.createElement("div", { style: { ...baseStyle, backgroundColor: color, borderRadius: "50%" } });
2079
3724
  case "rectangle":
2080
- return /* @__PURE__ */ React14.createElement("div", { style: { ...baseStyle, backgroundColor: color } });
3725
+ return /* @__PURE__ */ React20.createElement("div", { style: { ...baseStyle, backgroundColor: color } });
2081
3726
  default:
2082
3727
  return null;
2083
3728
  }
2084
3729
  };
2085
- var config9 = {
3730
+ var config11 = {
2086
3731
  displayName: "ShapeAtom",
2087
3732
  type: "atom",
2088
3733
  isInnerSequence: false
2089
3734
  };
2090
3735
 
2091
3736
  // src/components/atoms/ImageAtom.tsx
2092
- import React15, { useMemo as useMemo8, useState, useEffect } from "react";
2093
- import { continueRender, delayRender, Img, staticFile } from "remotion";
3737
+ import React21, { useMemo as useMemo10, useState as useState5, useEffect as useEffect5 } from "react";
3738
+ import { continueRender, delayRender, Img, staticFile as staticFile2 } from "remotion";
2094
3739
  var CORS_PROXIES = [
2095
3740
  "https://thingproxy.freeboard.io/fetch/",
2096
3741
  "https://api.allorigins.win/raw?url=",
@@ -2100,11 +3745,11 @@ var getCorsProxyUrl = (url) => {
2100
3745
  return `${CORS_PROXIES[0]}${encodeURIComponent(url)}`;
2101
3746
  };
2102
3747
  var useImageSource = (src, proxySrc) => {
2103
- const [imageSource, setImageSource] = useState(src);
2104
- const [isLoading, setIsLoading] = useState(false);
2105
- const [hasError, setHasError] = useState(false);
2106
- const [handle] = useState(() => delayRender("Loading image"));
2107
- useEffect(() => {
3748
+ const [imageSource, setImageSource] = useState5(src);
3749
+ const [isLoading, setIsLoading] = useState5(false);
3750
+ const [hasError, setHasError] = useState5(false);
3751
+ const [handle] = useState5(() => delayRender("Loading image"));
3752
+ useEffect5(() => {
2108
3753
  if (!src.startsWith("http")) {
2109
3754
  setImageSource(src);
2110
3755
  continueRender(handle);
@@ -2140,20 +3785,20 @@ var useImageSource = (src, proxySrc) => {
2140
3785
  }, [src, proxySrc, handle]);
2141
3786
  return { imageSource, isLoading, hasError };
2142
3787
  };
2143
- var Atom2 = ({ data, id }) => {
3788
+ var Atom3 = ({ data, id }) => {
2144
3789
  const overrideStyles = useAnimatedStyles(id);
2145
3790
  const { imageSource, isLoading, hasError } = useImageSource(data.src, data.proxySrc);
2146
- const source = useMemo8(() => {
3791
+ const source = useMemo10(() => {
2147
3792
  if (data.src.startsWith("http")) {
2148
3793
  return imageSource;
2149
3794
  }
2150
- return staticFile(data.src);
3795
+ return staticFile2(data.src);
2151
3796
  }, [data.src, imageSource]);
2152
- const enhancedStyle = useMemo8(() => ({
3797
+ const enhancedStyle = useMemo10(() => ({
2153
3798
  ...data.style,
2154
3799
  ...overrideStyles
2155
3800
  }), [data.style, overrideStyles, isLoading, hasError]);
2156
- return /* @__PURE__ */ React15.createElement(
3801
+ return /* @__PURE__ */ React21.createElement(
2157
3802
  Img,
2158
3803
  {
2159
3804
  className: data.className,
@@ -2167,18 +3812,18 @@ var Atom2 = ({ data, id }) => {
2167
3812
  }
2168
3813
  );
2169
3814
  };
2170
- var config10 = {
3815
+ var config12 = {
2171
3816
  displayName: "ImageAtom",
2172
3817
  type: "atom",
2173
3818
  isInnerSequence: false
2174
3819
  };
2175
3820
 
2176
3821
  // src/components/atoms/TextAtom.tsx
2177
- import React16, { useEffect as useEffect3, useMemo as useMemo9, useState as useState3 } from "react";
3822
+ import React22, { useEffect as useEffect7, useMemo as useMemo11, useState as useState7 } from "react";
2178
3823
  import { delayRender as delayRender3, continueRender as continueRender3 } from "remotion";
2179
3824
 
2180
3825
  // src/hooks/useFontLoader.ts
2181
- import { useState as useState2, useEffect as useEffect2, useCallback } from "react";
3826
+ import { useState as useState6, useEffect as useEffect6, useCallback } from "react";
2182
3827
  import { delayRender as delayRender2, continueRender as continueRender2 } from "remotion";
2183
3828
 
2184
3829
  // src/utils/fontUtils.ts
@@ -2320,7 +3965,7 @@ var getNormalizedFontName = (fontFamily) => {
2320
3965
 
2321
3966
  // src/hooks/useFontLoader.ts
2322
3967
  var useFontLoader = (options = {}) => {
2323
- const [state, setState] = useState2({
3968
+ const [state, setState] = useState6({
2324
3969
  loadedFonts: /* @__PURE__ */ new Map(),
2325
3970
  loadingFonts: /* @__PURE__ */ new Set(),
2326
3971
  errorFonts: /* @__PURE__ */ new Map()
@@ -2479,14 +4124,14 @@ var useFontLoader = (options = {}) => {
2479
4124
  };
2480
4125
  var useFont = (fontFamily, options = {}) => {
2481
4126
  const { loadFont, isFontReady, getFontFamily, getFontError, ...rest } = useFontLoader(options);
2482
- const [isLoaded, setIsLoaded] = useState2(false);
2483
- const [error, setError] = useState2(null);
2484
- const [renderHandle] = useState2(
4127
+ const [isLoaded, setIsLoaded] = useState6(false);
4128
+ const [error, setError] = useState6(null);
4129
+ const [renderHandle] = useState6(
2485
4130
  () => delayRender2(`Loading font: ${fontFamily}`)
2486
4131
  );
2487
4132
  const initialFontFamily = getFontFamily(fontFamily, options) || `"${fontFamily}", sans-serif`;
2488
- const [fontFamilyValue, setFontFamilyValue] = useState2(initialFontFamily);
2489
- useEffect2(() => {
4133
+ const [fontFamilyValue, setFontFamilyValue] = useState6(initialFontFamily);
4134
+ useEffect6(() => {
2490
4135
  const loadFontAsync = async () => {
2491
4136
  try {
2492
4137
  const cssValue = await loadFont(fontFamily, options);
@@ -2521,10 +4166,10 @@ var useFont = (fontFamily, options = {}) => {
2521
4166
  };
2522
4167
 
2523
4168
  // src/components/atoms/TextAtom.tsx
2524
- var Atom3 = ({ id, data }) => {
4169
+ var Atom4 = ({ id, data }) => {
2525
4170
  const overrideStyles = useAnimatedStyles(id);
2526
- const [isFontLoading, setIsFontLoading] = useState3(false);
2527
- const [renderHandle] = useState3(
4171
+ const [isFontLoading, setIsFontLoading] = useState7(false);
4172
+ const [renderHandle] = useState7(
2528
4173
  () => delayRender3(`Loading font: ${data.font?.family}`)
2529
4174
  );
2530
4175
  const { isLoaded, error, isReady, fontFamily } = useFont(
@@ -2544,7 +4189,7 @@ var Atom3 = ({ id, data }) => {
2544
4189
  }
2545
4190
  }
2546
4191
  );
2547
- useEffect3(() => {
4192
+ useEffect7(() => {
2548
4193
  if (data.font?.family) {
2549
4194
  if (isReady || isLoaded) {
2550
4195
  setIsFontLoading(false);
@@ -2553,18 +4198,33 @@ var Atom3 = ({ id, data }) => {
2553
4198
  }
2554
4199
  }
2555
4200
  }, [data.font, isReady, isLoaded, error]);
2556
- const enhancedStyle = useMemo9(() => ({
2557
- fontFamily,
2558
- ...data.style,
2559
- ...overrideStyles
2560
- }), [fontFamily, data.style, overrideStyles]);
4201
+ const enhancedStyle = useMemo11(() => {
4202
+ const baseStyle = {
4203
+ fontFamily,
4204
+ ...data.style
4205
+ };
4206
+ if (data.gradient) {
4207
+ return {
4208
+ ...baseStyle,
4209
+ backgroundImage: data.gradient,
4210
+ backgroundClip: "text",
4211
+ WebkitBackgroundClip: "text",
4212
+ color: "transparent",
4213
+ ...overrideStyles
4214
+ };
4215
+ }
4216
+ return {
4217
+ ...baseStyle,
4218
+ ...overrideStyles
4219
+ };
4220
+ }, [fontFamily, data.style, data.gradient, overrideStyles]);
2561
4221
  if (isFontLoading && data.loadingState?.showLoadingIndicator) {
2562
- return /* @__PURE__ */ React16.createElement("div", { style: enhancedStyle, className: data.className }, /* @__PURE__ */ React16.createElement("span", { style: data.loadingState.loadingStyle }, data.loadingState.loadingText || "Loading..."));
4222
+ return /* @__PURE__ */ React22.createElement("div", { style: enhancedStyle, className: data.className }, /* @__PURE__ */ React22.createElement("span", { style: data.loadingState.loadingStyle }, data.loadingState.loadingText || "Loading..."));
2563
4223
  }
2564
4224
  if (error && data.errorState?.showErrorIndicator) {
2565
- return /* @__PURE__ */ React16.createElement("div", { style: enhancedStyle, className: data.className }, /* @__PURE__ */ React16.createElement("span", { style: data.errorState.errorStyle }, data.errorState.errorText || data.text));
4225
+ return /* @__PURE__ */ React22.createElement("div", { style: enhancedStyle, className: data.className }, /* @__PURE__ */ React22.createElement("span", { style: data.errorState.errorStyle }, data.errorState.errorText || data.text));
2566
4226
  }
2567
- return /* @__PURE__ */ React16.createElement(
4227
+ return /* @__PURE__ */ React22.createElement(
2568
4228
  "div",
2569
4229
  {
2570
4230
  style: enhancedStyle,
@@ -2577,59 +4237,59 @@ var Atom3 = ({ id, data }) => {
2577
4237
  data.text
2578
4238
  );
2579
4239
  };
2580
- var config11 = {
4240
+ var config13 = {
2581
4241
  displayName: "TextAtom",
2582
4242
  type: "atom",
2583
4243
  isInnerSequence: false
2584
4244
  };
2585
4245
 
2586
4246
  // src/components/atoms/VideoAtom.tsx
2587
- import React17, { useMemo as useMemo10 } from "react";
2588
- import { staticFile as staticFile2, useCurrentFrame as useCurrentFrame5, useVideoConfig as useVideoConfig5, OffthreadVideo, Loop as Loop2 } from "remotion";
2589
- import { z } from "zod";
2590
- var VideoAtomDataProps = z.object({
2591
- src: z.string(),
4247
+ import React23, { useMemo as useMemo12 } from "react";
4248
+ import { staticFile as staticFile3, useCurrentFrame as useCurrentFrame9, useVideoConfig as useVideoConfig9, OffthreadVideo, Loop as Loop2 } from "remotion";
4249
+ import { z as z6 } from "zod";
4250
+ var VideoAtomDataProps = z6.object({
4251
+ src: z6.string(),
2592
4252
  // Video source URL
2593
- srcDuration: z.number().optional(),
4253
+ srcDuration: z6.number().optional(),
2594
4254
  // Video duration in seconds (or to say it more accurately, each iteration duration in a loop))
2595
- style: z.record(z.string(), z.any()).optional(),
4255
+ style: z6.record(z6.string(), z6.any()).optional(),
2596
4256
  // CSS styles object
2597
- containerClassName: z.string().optional(),
4257
+ containerClassName: z6.string().optional(),
2598
4258
  // CSS class names
2599
- className: z.string().optional(),
4259
+ className: z6.string().optional(),
2600
4260
  // CSS class names
2601
- startFrom: z.number().optional(),
4261
+ startFrom: z6.number().optional(),
2602
4262
  // Start playback from this time (seconds)
2603
- endAt: z.number().optional(),
4263
+ endAt: z6.number().optional(),
2604
4264
  // End playback at this time (seconds)
2605
- playbackRate: z.number().optional(),
4265
+ playbackRate: z6.number().optional(),
2606
4266
  // Playback speed multiplier
2607
- volume: z.number().optional(),
4267
+ volume: z6.number().optional(),
2608
4268
  // Volume level (0-1)
2609
- muted: z.boolean().optional(),
4269
+ muted: z6.boolean().optional(),
2610
4270
  // Mute video audio
2611
- loop: z.boolean().optional(),
4271
+ loop: z6.boolean().optional(),
2612
4272
  // Whether to loop the video
2613
- fit: z.enum(["contain", "cover", "fill", "none", "scale-down"]).optional()
4273
+ fit: z6.enum(["contain", "cover", "fill", "none", "scale-down"]).optional()
2614
4274
  // Object fit style
2615
4275
  });
2616
- var Atom4 = ({ data, id, context }) => {
2617
- const { fps } = useVideoConfig5();
4276
+ var Atom5 = ({ data, id, context }) => {
4277
+ const { fps } = useVideoConfig9();
2618
4278
  const overrideStyles = useAnimatedStyles(id);
2619
- const frame = useCurrentFrame5();
2620
- const source = useMemo10(() => {
4279
+ const frame = useCurrentFrame9();
4280
+ const source = useMemo12(() => {
2621
4281
  if (data.src.startsWith("http")) {
2622
4282
  return data.src;
2623
4283
  }
2624
- return staticFile2(data.src);
4284
+ return staticFile3(data.src);
2625
4285
  }, [data.src]);
2626
- const trimBefore = useMemo10(() => {
4286
+ const trimBefore = useMemo12(() => {
2627
4287
  return data.startFrom ? data.startFrom * fps : void 0;
2628
4288
  }, [data.startFrom, fps]);
2629
- const trimAfter = useMemo10(() => {
4289
+ const trimAfter = useMemo12(() => {
2630
4290
  return data.endAt ? data.endAt * fps : void 0;
2631
4291
  }, [data.endAt, fps]);
2632
- const videoComponent = /* @__PURE__ */ React17.createElement(
4292
+ const videoComponent = /* @__PURE__ */ React23.createElement(
2633
4293
  OffthreadVideo,
2634
4294
  {
2635
4295
  className: data.className,
@@ -2642,7 +4302,7 @@ var Atom4 = ({ data, id, context }) => {
2642
4302
  muted: data.muted
2643
4303
  }
2644
4304
  );
2645
- const videoWithStyles = data.containerClassName ? videoComponent : /* @__PURE__ */ React17.createElement(
4305
+ const videoWithStyles = data.containerClassName ? videoComponent : /* @__PURE__ */ React23.createElement(
2646
4306
  OffthreadVideo,
2647
4307
  {
2648
4308
  className: data.className,
@@ -2656,53 +4316,53 @@ var Atom4 = ({ data, id, context }) => {
2656
4316
  }
2657
4317
  );
2658
4318
  if (data.loop) {
2659
- return /* @__PURE__ */ React17.createElement(Loop2, { times: Infinity, durationInFrames: data.srcDuration ? data.srcDuration * fps : context.timing?.durationInFrames, layout: "none" }, data.containerClassName ? /* @__PURE__ */ React17.createElement("div", { className: data.containerClassName, style: overrideStyles }, videoComponent) : videoWithStyles);
4319
+ return /* @__PURE__ */ React23.createElement(Loop2, { times: Infinity, durationInFrames: data.srcDuration ? data.srcDuration * fps : context.timing?.durationInFrames, layout: "none" }, data.containerClassName ? /* @__PURE__ */ React23.createElement("div", { className: data.containerClassName, style: overrideStyles }, videoComponent) : videoWithStyles);
2660
4320
  }
2661
- return data.containerClassName ? /* @__PURE__ */ React17.createElement("div", { className: data.containerClassName, style: overrideStyles }, videoComponent) : videoWithStyles;
4321
+ return data.containerClassName ? /* @__PURE__ */ React23.createElement("div", { className: data.containerClassName, style: overrideStyles }, videoComponent) : videoWithStyles;
2662
4322
  };
2663
- var config12 = {
4323
+ var config14 = {
2664
4324
  displayName: "VideoAtom",
2665
4325
  type: "atom",
2666
4326
  isInnerSequence: false
2667
4327
  };
2668
4328
 
2669
4329
  // src/components/atoms/AudioAtom.tsx
2670
- import React18, { useMemo as useMemo11 } from "react";
2671
- import { Audio, staticFile as staticFile3, useCurrentFrame as useCurrentFrame6, useVideoConfig as useVideoConfig6 } from "remotion";
2672
- import { z as z2 } from "zod";
2673
- var AudioAtomMutedRangeProps = z2.object({
2674
- type: z2.literal("range"),
2675
- values: z2.array(z2.object({
2676
- start: z2.number(),
4330
+ import React24, { useMemo as useMemo13 } from "react";
4331
+ import { Audio, staticFile as staticFile4, useCurrentFrame as useCurrentFrame10, useVideoConfig as useVideoConfig10 } from "remotion";
4332
+ import { z as z7 } from "zod";
4333
+ var AudioAtomMutedRangeProps = z7.object({
4334
+ type: z7.literal("range"),
4335
+ values: z7.array(z7.object({
4336
+ start: z7.number(),
2677
4337
  // Start time in seconds
2678
- end: z2.number()
4338
+ end: z7.number()
2679
4339
  // End time in seconds
2680
4340
  }))
2681
4341
  });
2682
- var AudioAtomMutedFullProps = z2.object({
2683
- type: z2.literal("full"),
2684
- value: z2.boolean()
4342
+ var AudioAtomMutedFullProps = z7.object({
4343
+ type: z7.literal("full"),
4344
+ value: z7.boolean()
2685
4345
  // true = muted, false = unmuted
2686
4346
  });
2687
- var AudioAtomDataProps = z2.object({
2688
- src: z2.string(),
4347
+ var AudioAtomDataProps = z7.object({
4348
+ src: z7.string(),
2689
4349
  // Audio source URL
2690
- startFrom: z2.number().optional(),
4350
+ startFrom: z7.number().optional(),
2691
4351
  // Start playback from this time (seconds)
2692
- endAt: z2.number().optional(),
4352
+ endAt: z7.number().optional(),
2693
4353
  // End playback at this time (seconds)
2694
- volume: z2.number().optional(),
4354
+ volume: z7.number().optional(),
2695
4355
  // Volume level (0-1)
2696
- playbackRate: z2.number().optional(),
4356
+ playbackRate: z7.number().optional(),
2697
4357
  // Playback speed multiplier
2698
- muted: z2.union([AudioAtomMutedFullProps, AudioAtomMutedRangeProps]).optional()
4358
+ muted: z7.union([AudioAtomMutedFullProps, AudioAtomMutedRangeProps]).optional()
2699
4359
  // Mute configuration
2700
4360
  });
2701
- var Atom5 = ({ data }) => {
2702
- const { fps } = useVideoConfig6();
4361
+ var Atom6 = ({ data }) => {
4362
+ const { fps } = useVideoConfig10();
2703
4363
  const { muted } = data;
2704
- const frame = useCurrentFrame6();
2705
- const isMuted = useMemo11(() => {
4364
+ const frame = useCurrentFrame10();
4365
+ const isMuted = useMemo13(() => {
2706
4366
  if (muted?.type === "full") {
2707
4367
  return muted.value;
2708
4368
  }
@@ -2713,15 +4373,15 @@ var Atom5 = ({ data }) => {
2713
4373
  }
2714
4374
  return false;
2715
4375
  }, [muted, frame, fps]);
2716
- const source = useMemo11(() => {
4376
+ const source = useMemo13(() => {
2717
4377
  if (data.src.startsWith("http")) {
2718
4378
  return data.src;
2719
4379
  }
2720
- return staticFile3(data.src);
4380
+ return staticFile4(data.src);
2721
4381
  }, [data.src]);
2722
4382
  return (
2723
4383
  // @ts-ignore
2724
- /* @__PURE__ */ React18.createElement(
4384
+ /* @__PURE__ */ React24.createElement(
2725
4385
  Audio,
2726
4386
  {
2727
4387
  src: source,
@@ -2734,37 +4394,37 @@ var Atom5 = ({ data }) => {
2734
4394
  )
2735
4395
  );
2736
4396
  };
2737
- var config13 = {
4397
+ var config15 = {
2738
4398
  displayName: "AudioAtom",
2739
4399
  type: "atom",
2740
4400
  isInnerSequence: false
2741
4401
  };
2742
4402
 
2743
4403
  // src/components/atoms/LottieAtom.tsx
2744
- import React19, { useMemo as useMemo12, useState as useState4, useEffect as useEffect4 } from "react";
2745
- import { continueRender as continueRender4, delayRender as delayRender5, staticFile as staticFile4, useCurrentFrame as useCurrentFrame7, useVideoConfig as useVideoConfig7 } from "remotion";
4404
+ import React25, { useMemo as useMemo14, useState as useState8, useEffect as useEffect8 } from "react";
4405
+ import { continueRender as continueRender4, delayRender as delayRender5, staticFile as staticFile5, useCurrentFrame as useCurrentFrame11, useVideoConfig as useVideoConfig11 } from "remotion";
2746
4406
  import { Lottie } from "@remotion/lottie";
2747
- import { z as z3 } from "zod";
2748
- var LottieAtomDataProps = z3.object({
2749
- src: z3.string(),
4407
+ import { z as z8 } from "zod";
4408
+ var LottieAtomDataProps = z8.object({
4409
+ src: z8.string(),
2750
4410
  // Lottie JSON source URL or local path
2751
- style: z3.record(z3.string(), z3.any()).optional(),
4411
+ style: z8.record(z8.string(), z8.any()).optional(),
2752
4412
  // CSS styles object
2753
- className: z3.string().optional(),
4413
+ className: z8.string().optional(),
2754
4414
  // CSS class names
2755
- loop: z3.boolean().optional(),
4415
+ loop: z8.boolean().optional(),
2756
4416
  // Whether to loop the animation (handled by Remotion timeline)
2757
- playbackRate: z3.number().optional(),
4417
+ playbackRate: z8.number().optional(),
2758
4418
  // Playback speed multiplier (default: 1)
2759
- direction: z3.enum(["forward", "reverse"]).optional()
4419
+ direction: z8.enum(["forward", "reverse"]).optional()
2760
4420
  // Animation direction
2761
4421
  });
2762
4422
  var useLottieData = (src) => {
2763
- const [animationData, setAnimationData] = useState4(null);
2764
- const [isLoading, setIsLoading] = useState4(true);
2765
- const [hasError, setHasError] = useState4(false);
2766
- const [handle] = useState4(() => delayRender5("Loading Lottie animation"));
2767
- useEffect4(() => {
4423
+ const [animationData, setAnimationData] = useState8(null);
4424
+ const [isLoading, setIsLoading] = useState8(true);
4425
+ const [hasError, setHasError] = useState8(false);
4426
+ const [handle] = useState8(() => delayRender5("Loading Lottie animation"));
4427
+ useEffect8(() => {
2768
4428
  if (!src) {
2769
4429
  console.error("LottieAtom: No source provided");
2770
4430
  setHasError(true);
@@ -2774,7 +4434,7 @@ var useLottieData = (src) => {
2774
4434
  }
2775
4435
  setIsLoading(true);
2776
4436
  setHasError(false);
2777
- const sourceUrl = src.startsWith("http") ? src : staticFile4(src);
4437
+ const sourceUrl = src.startsWith("http") ? src : staticFile5(src);
2778
4438
  fetch(sourceUrl, {
2779
4439
  mode: "cors",
2780
4440
  credentials: "omit"
@@ -2801,12 +4461,12 @@ var useLottieData = (src) => {
2801
4461
  }, [src, handle]);
2802
4462
  return { animationData, isLoading, hasError };
2803
4463
  };
2804
- var Atom6 = ({ data, id }) => {
2805
- const { fps } = useVideoConfig7();
2806
- const frame = useCurrentFrame7();
4464
+ var Atom7 = ({ data, id }) => {
4465
+ const { fps } = useVideoConfig11();
4466
+ const frame = useCurrentFrame11();
2807
4467
  const overrideStyles = useAnimatedStyles(id);
2808
4468
  const { animationData, isLoading, hasError } = useLottieData(data.src);
2809
- const effectiveFrame = useMemo12(() => {
4469
+ const effectiveFrame = useMemo14(() => {
2810
4470
  const playbackRate = data.playbackRate || 1;
2811
4471
  const direction = data.direction || "forward";
2812
4472
  if (direction === "reverse") {
@@ -2814,12 +4474,12 @@ var Atom6 = ({ data, id }) => {
2814
4474
  }
2815
4475
  return frame * playbackRate;
2816
4476
  }, [frame, data.playbackRate, data.direction]);
2817
- const enhancedStyle = useMemo12(() => ({
4477
+ const enhancedStyle = useMemo14(() => ({
2818
4478
  ...data.style,
2819
4479
  ...overrideStyles
2820
4480
  }), [data.style, overrideStyles]);
2821
4481
  if (isLoading) {
2822
- return /* @__PURE__ */ React19.createElement(
4482
+ return /* @__PURE__ */ React25.createElement(
2823
4483
  "div",
2824
4484
  {
2825
4485
  className: data.className,
@@ -2835,7 +4495,7 @@ var Atom6 = ({ data, id }) => {
2835
4495
  }
2836
4496
  if (hasError || !animationData) {
2837
4497
  console.warn(`LottieAtom: Failed to render animation from ${data.src}`);
2838
- return /* @__PURE__ */ React19.createElement(
4498
+ return /* @__PURE__ */ React25.createElement(
2839
4499
  "div",
2840
4500
  {
2841
4501
  className: data.className,
@@ -2855,7 +4515,7 @@ var Atom6 = ({ data, id }) => {
2855
4515
  "\u26A0\uFE0F Lottie Error"
2856
4516
  );
2857
4517
  }
2858
- return /* @__PURE__ */ React19.createElement(
4518
+ return /* @__PURE__ */ React25.createElement(
2859
4519
  Lottie,
2860
4520
  {
2861
4521
  animationData,
@@ -2864,49 +4524,84 @@ var Atom6 = ({ data, id }) => {
2864
4524
  }
2865
4525
  );
2866
4526
  };
2867
- var config14 = {
4527
+ var config16 = {
2868
4528
  displayName: "LottieAtom",
2869
4529
  type: "atom",
2870
4530
  isInnerSequence: false
2871
4531
  };
2872
4532
 
4533
+ // src/components/atoms/HTMLBlockAtom.tsx
4534
+ import React26 from "react";
4535
+ var Atom8 = ({ id, data }) => {
4536
+ const overrideStyles = useAnimatedStyles(id);
4537
+ const combinedStyle = {
4538
+ ...data.style,
4539
+ ...overrideStyles
4540
+ };
4541
+ return /* @__PURE__ */ React26.createElement(
4542
+ "div",
4543
+ {
4544
+ className: data.className,
4545
+ style: combinedStyle,
4546
+ dangerouslySetInnerHTML: { __html: data.html }
4547
+ }
4548
+ );
4549
+ };
4550
+ var config17 = {
4551
+ displayName: "HTMLBlockAtom",
4552
+ type: "atom",
4553
+ isInnerSequence: false
4554
+ };
4555
+
2873
4556
  // src/components/atoms/index.ts
2874
4557
  registerComponent(
2875
- config9.displayName,
2876
- Atom,
2877
- "atom",
2878
- config9
2879
- );
2880
- registerComponent(
2881
- config10.displayName,
4558
+ config11.displayName,
2882
4559
  Atom2,
2883
4560
  "atom",
2884
- config10
4561
+ config11
2885
4562
  );
2886
- registerComponent(config11.displayName, Atom3, "atom", config11);
2887
4563
  registerComponent(
2888
4564
  config12.displayName,
2889
- Atom4,
4565
+ Atom3,
2890
4566
  "atom",
2891
4567
  config12
2892
4568
  );
4569
+ registerComponent(config13.displayName, Atom4, "atom", config13);
2893
4570
  registerComponent(
2894
- config13.displayName,
4571
+ config14.displayName,
2895
4572
  Atom5,
2896
4573
  "atom",
2897
- config13
4574
+ config14
2898
4575
  );
2899
4576
  registerComponent(
2900
- config14.displayName,
4577
+ config15.displayName,
2901
4578
  Atom6,
2902
4579
  "atom",
2903
- config14
4580
+ config15
4581
+ );
4582
+ registerComponent(
4583
+ config16.displayName,
4584
+ Atom7,
4585
+ "atom",
4586
+ config16
4587
+ );
4588
+ registerComponent(
4589
+ config9.displayName,
4590
+ Atom,
4591
+ "atom",
4592
+ config9
4593
+ );
4594
+ registerComponent(
4595
+ config17.displayName,
4596
+ Atom8,
4597
+ "atom",
4598
+ config17
2904
4599
  );
2905
4600
 
2906
4601
  // src/hooks/useComponentRegistry.ts
2907
- import { useMemo as useMemo13 } from "react";
4602
+ import { useMemo as useMemo15 } from "react";
2908
4603
  var useComponentRegistry = () => {
2909
- return useMemo13(() => {
4604
+ return useMemo15(() => {
2910
4605
  return {
2911
4606
  registerComponent: componentRegistry.registerComponent.bind(componentRegistry),
2912
4607
  registerPackage: componentRegistry.registerPackage.bind(componentRegistry),
@@ -2917,13 +4612,13 @@ var useComponentRegistry = () => {
2917
4612
  };
2918
4613
 
2919
4614
  // src/hooks/useBoundaryCalculation.ts
2920
- import { useMemo as useMemo14 } from "react";
4615
+ import { useMemo as useMemo16 } from "react";
2921
4616
  var useBoundaryCalculation = ({
2922
4617
  parentBoundaries,
2923
4618
  constraints,
2924
4619
  layout
2925
4620
  }) => {
2926
- return useMemo14(() => {
4621
+ return useMemo16(() => {
2927
4622
  const { x, y, width, height } = parentBoundaries;
2928
4623
  const calculatedX = typeof constraints.x === "number" ? constraints.x : x;
2929
4624
  const calculatedY = typeof constraints.y === "number" ? constraints.y : y;
@@ -3034,16 +4729,16 @@ var needsProxying = (url) => {
3034
4729
 
3035
4730
  // src/templates/rings/NextjsLogo.tsx
3036
4731
  import { evolvePath } from "@remotion/paths";
3037
- import React22, { useMemo as useMemo15 } from "react";
3038
- import { interpolate as interpolate5, spring as spring5, useCurrentFrame as useCurrentFrame9, useVideoConfig as useVideoConfig9 } from "remotion";
4732
+ import React29, { useMemo as useMemo17 } from "react";
4733
+ import { interpolate as interpolate5, spring as spring5, useCurrentFrame as useCurrentFrame13, useVideoConfig as useVideoConfig13 } from "remotion";
3039
4734
 
3040
4735
  // src/templates/rings/RippleOutLayout.tsx
3041
- import React21 from "react";
3042
- import { spring as spring4, useCurrentFrame as useCurrentFrame8, useVideoConfig as useVideoConfig8, Sequence as Sequence2, AbsoluteFill as AbsoluteFill4 } from "remotion";
3043
- import { z as z4 } from "zod";
3044
- var RippleOutTransitionSchema = z4.object({
3045
- progress: z4.number().min(0).max(1),
3046
- logoOut: z4.number().min(0).max(1)
4736
+ import React28 from "react";
4737
+ import { spring as spring4, useCurrentFrame as useCurrentFrame12, useVideoConfig as useVideoConfig12, Sequence as Sequence2, AbsoluteFill as AbsoluteFill4 } from "remotion";
4738
+ import { z as z9 } from "zod";
4739
+ var RippleOutTransitionSchema = z9.object({
4740
+ progress: z9.number().min(0).max(1),
4741
+ logoOut: z9.number().min(0).max(1)
3047
4742
  });
3048
4743
  var defaultRippleOutData = {
3049
4744
  progress: 0,
@@ -3061,10 +4756,10 @@ var RippleOutLayout = ({ data, context, children }) => {
3061
4756
  transitionStart,
3062
4757
  transitionDuration
3063
4758
  } = data || { transitionStart: 2, transitionDuration: 1 };
3064
- const frame = useCurrentFrame8();
3065
- const { fps } = useVideoConfig8();
4759
+ const frame = useCurrentFrame12();
4760
+ const { fps } = useVideoConfig12();
3066
4761
  const { hierarchy } = useRenderContext();
3067
- React21.useEffect(() => {
4762
+ React28.useEffect(() => {
3068
4763
  loadGoogleFont("Inter", {
3069
4764
  subsets: ["latin"],
3070
4765
  weights: ["400", "700"]
@@ -3085,14 +4780,14 @@ var RippleOutLayout = ({ data, context, children }) => {
3085
4780
  progress: logoOut,
3086
4781
  logoOut
3087
4782
  };
3088
- const childrenArray = React21.Children.toArray(children).filter(
3089
- (child) => React21.isValidElement(child)
4783
+ const childrenArray = React28.Children.toArray(children).filter(
4784
+ (child) => React28.isValidElement(child)
3090
4785
  );
3091
4786
  const [from, to] = childrenArray;
3092
- return /* @__PURE__ */ React21.createElement(LayoutContext.Provider, { value: transitionData }, /* @__PURE__ */ React21.createElement(AbsoluteFill4, { style: {
4787
+ return /* @__PURE__ */ React28.createElement(LayoutContext.Provider, { value: transitionData }, /* @__PURE__ */ React28.createElement(AbsoluteFill4, { style: {
3093
4788
  ...container,
3094
4789
  ...context?.boundaries
3095
- } }, /* @__PURE__ */ React21.createElement(Sequence2, { name: from.props.componentId + " - " + from.props.id, from: 0, durationInFrames: transitionStartFrame + transitionDurationFrames }, from), /* @__PURE__ */ React21.createElement(Sequence2, { name: to.props.componentId + " - " + to.props.id, from: transitionStartFrame + transitionDurationFrames / 2 }, to)));
4790
+ } }, /* @__PURE__ */ React28.createElement(Sequence2, { name: from.props.componentId + " - " + from.props.id, from: 0, durationInFrames: transitionStartFrame + transitionDurationFrames }, from), /* @__PURE__ */ React28.createElement(Sequence2, { name: to.props.componentId + " - " + to.props.id, from: transitionStartFrame + transitionDurationFrames / 2 }, to)));
3096
4791
  };
3097
4792
  var rippleOutLayoutConfig = {
3098
4793
  displayName: "RippleOutLayout",
@@ -3108,8 +4803,8 @@ var nStroke = "M149.508 157.52L69.142 54H54V125.97H66.1136V69.3836L139.999 164.8
3108
4803
  var NextjsLogo = () => {
3109
4804
  const { logoOut } = useRippleOutLayout();
3110
4805
  const outProgress = logoOut;
3111
- const { fps } = useVideoConfig9();
3112
- const frame = useCurrentFrame9();
4806
+ const { fps } = useVideoConfig13();
4807
+ const frame = useCurrentFrame13();
3113
4808
  const evolve1 = spring5({
3114
4809
  fps,
3115
4810
  frame,
@@ -3133,7 +4828,7 @@ var NextjsLogo = () => {
3133
4828
  },
3134
4829
  durationInFrames: 30
3135
4830
  });
3136
- const style = useMemo15(() => {
4831
+ const style = useMemo17(() => {
3137
4832
  return {
3138
4833
  height: 140,
3139
4834
  borderRadius: 70,
@@ -3149,7 +4844,7 @@ var NextjsLogo = () => {
3149
4844
  interpolate5(evolve3, [0, 1], [0, 0.7]),
3150
4845
  thirdPath
3151
4846
  );
3152
- return /* @__PURE__ */ React22.createElement("svg", { style, fill: "none", viewBox: "0 0 180 180" }, /* @__PURE__ */ React22.createElement("mask", { height: "180", id: "mask", style: mask, width: "180", x: "0", y: "0" }, /* @__PURE__ */ React22.createElement("circle", { cx: "90", cy: "90", fill: "black", r: "90" })), /* @__PURE__ */ React22.createElement("mask", { id: "n-mask", style: mask }, /* @__PURE__ */ React22.createElement("path", { d: nStroke, fill: "black" })), /* @__PURE__ */ React22.createElement("g", { mask: "url(#mask)" }, /* @__PURE__ */ React22.createElement("circle", { cx: "90", cy: "90", fill: "black", r: "90" }), /* @__PURE__ */ React22.createElement("g", { stroke: "url(#gradient0)", mask: "url(#n-mask)" }, /* @__PURE__ */ React22.createElement(
4847
+ return /* @__PURE__ */ React29.createElement("svg", { style, fill: "none", viewBox: "0 0 180 180" }, /* @__PURE__ */ React29.createElement("mask", { height: "180", id: "mask", style: mask, width: "180", x: "0", y: "0" }, /* @__PURE__ */ React29.createElement("circle", { cx: "90", cy: "90", fill: "black", r: "90" })), /* @__PURE__ */ React29.createElement("mask", { id: "n-mask", style: mask }, /* @__PURE__ */ React29.createElement("path", { d: nStroke, fill: "black" })), /* @__PURE__ */ React29.createElement("g", { mask: "url(#mask)" }, /* @__PURE__ */ React29.createElement("circle", { cx: "90", cy: "90", fill: "black", r: "90" }), /* @__PURE__ */ React29.createElement("g", { stroke: "url(#gradient0)", mask: "url(#n-mask)" }, /* @__PURE__ */ React29.createElement(
3153
4848
  "path",
3154
4849
  {
3155
4850
  strokeWidth: "12.1136",
@@ -3157,7 +4852,7 @@ var NextjsLogo = () => {
3157
4852
  strokeDasharray: evolution1.strokeDasharray,
3158
4853
  strokeDashoffset: evolution1.strokeDashoffset
3159
4854
  }
3160
- ), /* @__PURE__ */ React22.createElement(
4855
+ ), /* @__PURE__ */ React29.createElement(
3161
4856
  "path",
3162
4857
  {
3163
4858
  strokeWidth: 12.1136,
@@ -3165,7 +4860,7 @@ var NextjsLogo = () => {
3165
4860
  strokeDasharray: evolution2.strokeDasharray,
3166
4861
  strokeDashoffset: evolution2.strokeDashoffset
3167
4862
  }
3168
- )), /* @__PURE__ */ React22.createElement(
4863
+ )), /* @__PURE__ */ React29.createElement(
3169
4864
  "path",
3170
4865
  {
3171
4866
  stroke: "url(#gradient1)",
@@ -3174,7 +4869,7 @@ var NextjsLogo = () => {
3174
4869
  strokeDashoffset: evolution3.strokeDashoffset,
3175
4870
  strokeWidth: "12"
3176
4871
  }
3177
- )), /* @__PURE__ */ React22.createElement("defs", null, /* @__PURE__ */ React22.createElement(
4872
+ )), /* @__PURE__ */ React29.createElement("defs", null, /* @__PURE__ */ React29.createElement(
3178
4873
  "linearGradient",
3179
4874
  {
3180
4875
  gradientUnits: "userSpaceOnUse",
@@ -3184,9 +4879,9 @@ var NextjsLogo = () => {
3184
4879
  y1: "116.5",
3185
4880
  y2: "160.5"
3186
4881
  },
3187
- /* @__PURE__ */ React22.createElement("stop", { stopColor: "white" }),
3188
- /* @__PURE__ */ React22.createElement("stop", { offset: "1", stopColor: "white", stopOpacity: "0" })
3189
- ), /* @__PURE__ */ React22.createElement(
4882
+ /* @__PURE__ */ React29.createElement("stop", { stopColor: "white" }),
4883
+ /* @__PURE__ */ React29.createElement("stop", { offset: "1", stopColor: "white", stopOpacity: "0" })
4884
+ ), /* @__PURE__ */ React29.createElement(
3190
4885
  "linearGradient",
3191
4886
  {
3192
4887
  gradientUnits: "userSpaceOnUse",
@@ -3196,8 +4891,8 @@ var NextjsLogo = () => {
3196
4891
  y1: "54",
3197
4892
  y2: "106.875"
3198
4893
  },
3199
- /* @__PURE__ */ React22.createElement("stop", { stopColor: "white" }),
3200
- /* @__PURE__ */ React22.createElement("stop", { offset: "1", stopColor: "white", stopOpacity: "0" })
4894
+ /* @__PURE__ */ React29.createElement("stop", { stopColor: "white" }),
4895
+ /* @__PURE__ */ React29.createElement("stop", { offset: "1", stopColor: "white", stopOpacity: "0" })
3201
4896
  )));
3202
4897
  };
3203
4898
  var nextjsLogoConfig = {
@@ -3207,14 +4902,14 @@ var nextjsLogoConfig = {
3207
4902
  };
3208
4903
 
3209
4904
  // src/templates/rings/Rings.tsx
3210
- import React23 from "react";
3211
- import { AbsoluteFill as AbsoluteFill5, interpolateColors as interpolateColors2, useVideoConfig as useVideoConfig10 } from "remotion";
4905
+ import React30 from "react";
4906
+ import { AbsoluteFill as AbsoluteFill5, interpolateColors as interpolateColors2, useVideoConfig as useVideoConfig14 } from "remotion";
3212
4907
  var RadialGradient = ({ radius, color }) => {
3213
4908
  const height = radius * 2;
3214
4909
  const width = radius * 2;
3215
4910
  return (
3216
4911
  // @ts-ignore
3217
- /* @__PURE__ */ React23.createElement(
4912
+ /* @__PURE__ */ React30.createElement(
3218
4913
  AbsoluteFill5,
3219
4914
  {
3220
4915
  style: {
@@ -3222,7 +4917,7 @@ var RadialGradient = ({ radius, color }) => {
3222
4917
  alignItems: "center"
3223
4918
  }
3224
4919
  },
3225
- /* @__PURE__ */ React23.createElement(
4920
+ /* @__PURE__ */ React30.createElement(
3226
4921
  "div",
3227
4922
  {
3228
4923
  style: {
@@ -3242,10 +4937,10 @@ var Rings = ({ context, data }) => {
3242
4937
  const { logoOut } = useRippleOutLayout();
3243
4938
  const outProgress = logoOut;
3244
4939
  const scale = 1 / (1 - outProgress);
3245
- const { height } = useVideoConfig10();
4940
+ const { height } = useVideoConfig14();
3246
4941
  return (
3247
4942
  // @ts-ignore
3248
- /* @__PURE__ */ React23.createElement(
4943
+ /* @__PURE__ */ React30.createElement(
3249
4944
  AbsoluteFill5,
3250
4945
  {
3251
4946
  style: {
@@ -3254,7 +4949,7 @@ var Rings = ({ context, data }) => {
3254
4949
  }
3255
4950
  },
3256
4951
  new Array(5).fill(true).map((_, i) => {
3257
- return /* @__PURE__ */ React23.createElement(
4952
+ return /* @__PURE__ */ React30.createElement(
3258
4953
  RadialGradient,
3259
4954
  {
3260
4955
  key: i,
@@ -3273,13 +4968,13 @@ var ringsConfig = {
3273
4968
  };
3274
4969
 
3275
4970
  // src/templates/rings/TextFade.tsx
3276
- import React24, { useMemo as useMemo16 } from "react";
4971
+ import React31, { useMemo as useMemo18 } from "react";
3277
4972
  import {
3278
4973
  AbsoluteFill as AbsoluteFill6,
3279
4974
  interpolate as interpolate6,
3280
4975
  spring as spring6,
3281
- useCurrentFrame as useCurrentFrame10,
3282
- useVideoConfig as useVideoConfig11
4976
+ useCurrentFrame as useCurrentFrame14,
4977
+ useVideoConfig as useVideoConfig15
3283
4978
  } from "remotion";
3284
4979
  var TextFade = (props) => {
3285
4980
  const { children, context, data } = props;
@@ -3288,8 +4983,8 @@ var TextFade = (props) => {
3288
4983
  duration: 1
3289
4984
  }
3290
4985
  };
3291
- const { fps } = useVideoConfig11();
3292
- const frame = useCurrentFrame10();
4986
+ const { fps } = useVideoConfig15();
4987
+ const frame = useCurrentFrame14();
3293
4988
  const progress = spring6({
3294
4989
  fps,
3295
4990
  frame,
@@ -3301,7 +4996,7 @@ var TextFade = (props) => {
3301
4996
  const rightStop = interpolate6(progress, [0, 1], [200, 0]);
3302
4997
  const leftStop = Math.max(0, rightStop - 60);
3303
4998
  const maskImage = `linear-gradient(-45deg, transparent ${leftStop}%, black ${rightStop}%)`;
3304
- const container2 = useMemo16(() => {
4999
+ const container2 = useMemo18(() => {
3305
5000
  return {
3306
5001
  width: "100%",
3307
5002
  height: "100%",
@@ -3309,7 +5004,7 @@ var TextFade = (props) => {
3309
5004
  alignItems: "center"
3310
5005
  };
3311
5006
  }, []);
3312
- const content = useMemo16(() => {
5007
+ const content = useMemo18(() => {
3313
5008
  return {
3314
5009
  ...context?.boundaries,
3315
5010
  maskImage,
@@ -3321,7 +5016,7 @@ var TextFade = (props) => {
3321
5016
  }, [maskImage]);
3322
5017
  return (
3323
5018
  // @ts-ignore
3324
- /* @__PURE__ */ React24.createElement(AbsoluteFill6, { style: container2 }, /* @__PURE__ */ React24.createElement("div", { style: content }, children))
5019
+ /* @__PURE__ */ React31.createElement(AbsoluteFill6, { style: container2 }, /* @__PURE__ */ React31.createElement("div", { style: content }, children))
3325
5020
  );
3326
5021
  };
3327
5022
  var textFadeConfig = {
@@ -3352,234 +5047,11 @@ registerComponent(
3352
5047
  );
3353
5048
 
3354
5049
  // src/templates/waveform/components/WaveformCircle.tsx
3355
- import React26, { useMemo as useMemo18 } from "react";
3356
-
3357
- // src/templates/waveform/Waveform.tsx
3358
- import React25, { createContext as createContext5, useContext as useContext6 } from "react";
3359
- import { useCurrentFrame as useCurrentFrame11, useVideoConfig as useVideoConfig12 } from "remotion";
3360
-
3361
- // src/templates/waveform/hooks/useWaveformData.ts
3362
- import { useMemo as useMemo17 } from "react";
3363
- import {
3364
- useAudioData,
3365
- visualizeAudioWaveform,
3366
- visualizeAudio
3367
- } from "@remotion/media-utils";
3368
- import { staticFile as staticFile5 } from "remotion";
3369
- var isValidPowerOfTwo = (num) => {
3370
- return num > 0 && (num & num - 1) === 0;
3371
- };
3372
- var getClosestPowerOfTwo = (num) => {
3373
- if (num <= 0) return 32;
3374
- let power = 1;
3375
- while (power < num) {
3376
- power *= 2;
3377
- }
3378
- const lower = power / 2;
3379
- const upper = power;
3380
- return Math.abs(num - lower) < Math.abs(num - upper) ? lower : upper;
3381
- };
3382
- var useWaveformData = (config15) => {
3383
- const {
3384
- audioSrc,
3385
- numberOfSamples,
3386
- windowInSeconds,
3387
- dataOffsetInSeconds = 0,
3388
- normalize = false,
3389
- frame,
3390
- fps,
3391
- posterize,
3392
- includeFrequencyData = false,
3393
- minDb = -100,
3394
- maxDb = -30
3395
- } = config15;
3396
- const { root } = useComposition();
3397
- const validatedNumberOfSamples = useMemo17(() => {
3398
- if (!isValidPowerOfTwo(numberOfSamples)) {
3399
- console.warn(
3400
- `numberOfSamples must be a power of 2. Adjusting ${numberOfSamples} to ${getClosestPowerOfTwo(numberOfSamples)}`
3401
- );
3402
- return getClosestPowerOfTwo(numberOfSamples);
3403
- }
3404
- return numberOfSamples;
3405
- }, [numberOfSamples]);
3406
- const { source, audioStartsFrom } = useMemo17(() => {
3407
- if (audioSrc.startsWith("http")) {
3408
- return { source: audioSrc, audioStartsFrom: void 0 };
3409
- }
3410
- if (audioSrc.startsWith("ref:")) {
3411
- const matchingComponent = findMatchingComponents(root, [
3412
- audioSrc.replace("ref:", "")
3413
- ]);
3414
- if (matchingComponent.length > 0) {
3415
- const firstMatchingComponent = matchingComponent[0];
3416
- if (firstMatchingComponent.componentId === "AudioAtom") {
3417
- return {
3418
- source: firstMatchingComponent.data.src,
3419
- audioStartsFrom: firstMatchingComponent.data?.startFrom ?? void 0
3420
- };
3421
- }
3422
- if (firstMatchingComponent.type === "layout" || firstMatchingComponent.type === "scene") {
3423
- const audioComponents = findMatchingComponentsByQuery(
3424
- firstMatchingComponent.childrenData,
3425
- { componentId: "AudioAtom" }
3426
- );
3427
- if (audioComponents.length > 0) {
3428
- return {
3429
- source: audioComponents[0].data.src,
3430
- audioStartsFrom: audioComponents[0].data?.startFrom ?? void 0
3431
- };
3432
- }
3433
- }
3434
- }
3435
- }
3436
- return { source: staticFile5(audioSrc), audioStartsFrom: void 0 };
3437
- }, [audioSrc]);
3438
- const audioData = useAudioData(source);
3439
- const adjustedFrame = useMemo17(() => {
3440
- if (posterize && posterize > 1) {
3441
- return Math.round(frame / posterize) * posterize;
3442
- }
3443
- let offset = 0;
3444
- if (audioStartsFrom && audioStartsFrom != 0) {
3445
- offset += Math.round(audioStartsFrom * fps);
3446
- }
3447
- if (dataOffsetInSeconds != 0) {
3448
- offset += Math.round(dataOffsetInSeconds * fps);
3449
- }
3450
- return frame + offset;
3451
- }, [frame, posterize, dataOffsetInSeconds, audioStartsFrom]);
3452
- const waveformData = useMemo17(() => {
3453
- if (!audioData) return null;
3454
- try {
3455
- const waveform = visualizeAudioWaveform({
3456
- fps,
3457
- frame: adjustedFrame,
3458
- audioData,
3459
- numberOfSamples: validatedNumberOfSamples,
3460
- windowInSeconds,
3461
- dataOffsetInSeconds: 0,
3462
- normalize
3463
- });
3464
- return waveform;
3465
- } catch (error2) {
3466
- console.error("Error generating waveform:", error2);
3467
- return null;
3468
- }
3469
- }, [
3470
- audioData,
3471
- adjustedFrame,
3472
- fps,
3473
- validatedNumberOfSamples,
3474
- windowInSeconds,
3475
- dataOffsetInSeconds,
3476
- normalize
3477
- ]);
3478
- const {
3479
- frequencyData,
3480
- amplitudes,
3481
- bass,
3482
- mid,
3483
- treble,
3484
- bassValues,
3485
- midValues,
3486
- trebleValues
3487
- } = useMemo17(() => {
3488
- if (!audioData || !includeFrequencyData) {
3489
- return {
3490
- frequencyData: null,
3491
- amplitudes: null,
3492
- bass: null,
3493
- mid: null,
3494
- treble: null,
3495
- bassValues: null,
3496
- midValues: null,
3497
- trebleValues: null
3498
- };
3499
- }
3500
- try {
3501
- const frequencyData2 = visualizeAudio({
3502
- fps,
3503
- frame: adjustedFrame,
3504
- audioData,
3505
- numberOfSamples: validatedNumberOfSamples
3506
- });
3507
- const { sampleRate } = audioData;
3508
- const bassValues2 = [];
3509
- const midValues2 = [];
3510
- const trebleValues2 = [];
3511
- for (let i = 0; i < frequencyData2.length; i++) {
3512
- const freq = i * sampleRate / (2 * frequencyData2.length);
3513
- const value = frequencyData2[i];
3514
- if (freq >= 0 && freq < 250) {
3515
- bassValues2.push(value * 2.5);
3516
- } else if (freq >= 250 && freq < 4e3) {
3517
- midValues2.push(value * 3);
3518
- midValues2.push(value * 4.5);
3519
- midValues2.push(value * 5);
3520
- } else if (freq >= 4e3 && freq < sampleRate / 2) {
3521
- trebleValues2.push(value * 30);
3522
- }
3523
- }
3524
- const getAverage = (arr) => arr.length > 0 ? arr.reduce((a, b) => a + b, 0) / arr.length : 0;
3525
- const bass2 = getAverage(bassValues2);
3526
- const mid2 = getAverage(midValues2);
3527
- const treble2 = getAverage(trebleValues2);
3528
- const amplitudes2 = frequencyData2.map((value) => {
3529
- const db = 20 * Math.log10(value);
3530
- const scaled = (db - minDb) / (maxDb - minDb);
3531
- return Math.max(0, Math.min(1, scaled));
3532
- });
3533
- return {
3534
- frequencyData: frequencyData2,
3535
- amplitudes: amplitudes2,
3536
- bass: bass2,
3537
- mid: mid2,
3538
- treble: treble2,
3539
- bassValues: bassValues2,
3540
- midValues: midValues2,
3541
- trebleValues: trebleValues2.reverse()
3542
- };
3543
- } catch (error2) {
3544
- console.error("Error generating frequency data:", error2);
3545
- return {
3546
- frequencyData: null,
3547
- amplitudes: null,
3548
- bass: null,
3549
- mid: null,
3550
- treble: null
3551
- };
3552
- }
3553
- }, [
3554
- audioData,
3555
- includeFrequencyData,
3556
- adjustedFrame,
3557
- fps,
3558
- validatedNumberOfSamples,
3559
- windowInSeconds,
3560
- dataOffsetInSeconds,
3561
- minDb,
3562
- maxDb
3563
- ]);
3564
- const isLoading = !audioData;
3565
- const error = audioData === null && !isLoading ? "Failed to load audio data" : null;
3566
- return {
3567
- waveformData,
3568
- frequencyData,
3569
- amplitudes,
3570
- audioData,
3571
- isLoading,
3572
- error,
3573
- bass,
3574
- bassValues,
3575
- mid,
3576
- midValues,
3577
- treble,
3578
- trebleValues
3579
- };
3580
- };
5050
+ import React33, { useMemo as useMemo19 } from "react";
3581
5051
 
3582
5052
  // src/templates/waveform/Waveform.tsx
5053
+ import React32, { createContext as createContext5, useContext as useContext6 } from "react";
5054
+ import { useCurrentFrame as useCurrentFrame15, useVideoConfig as useVideoConfig16 } from "remotion";
3583
5055
  var WaveformContext = createContext5(null);
3584
5056
  var useWaveformContext = () => {
3585
5057
  const context = useContext6(WaveformContext);
@@ -3589,26 +5061,27 @@ var useWaveformContext = () => {
3589
5061
  return context;
3590
5062
  };
3591
5063
  var Waveform = ({
3592
- config: config15,
5064
+ config: config18,
3593
5065
  children,
3594
5066
  className = "",
3595
5067
  style = {}
3596
5068
  }) => {
3597
- const frame = useCurrentFrame11();
3598
- const { width: videoWidth, height: videoHeight, fps } = useVideoConfig12();
5069
+ const frame = useCurrentFrame15();
5070
+ const { width: videoWidth, height: videoHeight, fps } = useVideoConfig16();
3599
5071
  const { waveformData, frequencyData, amplitudes, audioData, bass, mid, treble, bassValues, midValues, trebleValues } = useWaveformData({
3600
- audioSrc: config15.audioSrc,
3601
- numberOfSamples: config15.numberOfSamples || 128,
3602
- windowInSeconds: config15.windowInSeconds || 1 / fps,
3603
- dataOffsetInSeconds: config15.dataOffsetInSeconds || 0,
3604
- normalize: config15.normalize || false,
5072
+ audioSrc: config18.audioSrc,
5073
+ numberOfSamples: config18.numberOfSamples || 128,
5074
+ windowInSeconds: config18.windowInSeconds || 1 / fps,
5075
+ dataOffsetInSeconds: config18.dataOffsetInSeconds || 0,
5076
+ normalize: config18.normalize || false,
3605
5077
  frame,
3606
5078
  fps,
3607
- posterize: config15.posterize,
3608
- includeFrequencyData: config15.useFrequencyData || false
5079
+ posterize: config18.posterize,
5080
+ includeFrequencyData: config18.useFrequencyData || false,
5081
+ smoothNormalisation: config18.smoothNormalisation
3609
5082
  });
3610
- const width = config15.width || videoWidth;
3611
- const height = config15.height || videoHeight;
5083
+ const width = config18.width || videoWidth;
5084
+ const height = config18.height || videoHeight;
3612
5085
  const contextValue = {
3613
5086
  waveformData,
3614
5087
  frequencyData,
@@ -3616,7 +5089,7 @@ var Waveform = ({
3616
5089
  audioData,
3617
5090
  frame,
3618
5091
  fps,
3619
- config: config15,
5092
+ config: config18,
3620
5093
  width,
3621
5094
  height,
3622
5095
  bass,
@@ -3626,7 +5099,7 @@ var Waveform = ({
3626
5099
  midValues,
3627
5100
  trebleValues
3628
5101
  };
3629
- return /* @__PURE__ */ React25.createElement(WaveformContext.Provider, { value: contextValue }, /* @__PURE__ */ React25.createElement(
5102
+ return /* @__PURE__ */ React32.createElement(WaveformContext.Provider, { value: contextValue }, /* @__PURE__ */ React32.createElement(
3630
5103
  "div",
3631
5104
  {
3632
5105
  className: `relative ${className}`,
@@ -3634,7 +5107,7 @@ var Waveform = ({
3634
5107
  width,
3635
5108
  height,
3636
5109
  position: "relative",
3637
- backgroundColor: config15.backgroundColor || "transparent",
5110
+ backgroundColor: config18.backgroundColor || "transparent",
3638
5111
  ...style
3639
5112
  }
3640
5113
  },
@@ -3645,7 +5118,7 @@ var Waveform = ({
3645
5118
  // src/templates/waveform/components/WaveformCircle.tsx
3646
5119
  var WaveformCircle = ({ data }) => {
3647
5120
  const {
3648
- config: config15,
5121
+ config: config18,
3649
5122
  className = "",
3650
5123
  style = {},
3651
5124
  strokeColor = "#FF6B6B",
@@ -3662,7 +5135,7 @@ var WaveformCircle = ({ data }) => {
3662
5135
  gradientStartColor,
3663
5136
  gradientEndColor
3664
5137
  } = data;
3665
- return /* @__PURE__ */ React26.createElement(Waveform, { config: config15, className, style }, /* @__PURE__ */ React26.createElement(
5138
+ return /* @__PURE__ */ React33.createElement(Waveform, { config: config18, className, style }, /* @__PURE__ */ React33.createElement(
3666
5139
  WaveformCircleContent,
3667
5140
  {
3668
5141
  strokeColor,
@@ -3701,7 +5174,7 @@ var WaveformCircleContent = ({
3701
5174
  const circleCenterX = width * (centerX || 50) / 100;
3702
5175
  const circleCenterY = height * (centerY || 50) / 100;
3703
5176
  const rotation = frame * (rotationSpeed || 0) % 360;
3704
- const circularPath = useMemo18(() => {
5177
+ const circularPath = useMemo19(() => {
3705
5178
  if (!waveformData) return "";
3706
5179
  const totalAngle = (endAngle || 360) - (startAngle || 0);
3707
5180
  const angleStep = totalAngle / waveformData.length;
@@ -3723,11 +5196,11 @@ var WaveformCircleContent = ({
3723
5196
  return path;
3724
5197
  }, [waveformData, circleRadius, circleCenterX, circleCenterY, startAngle, endAngle, rotation, amplitude]);
3725
5198
  if (!waveformData) {
3726
- return /* @__PURE__ */ React26.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading circular waveform...");
5199
+ return /* @__PURE__ */ React33.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading circular waveform...");
3727
5200
  }
3728
5201
  const gradientId = "circle-waveform-gradient";
3729
5202
  const hasGradient = gradientStartColor && gradientEndColor;
3730
- return /* @__PURE__ */ React26.createElement(
5203
+ return /* @__PURE__ */ React33.createElement(
3731
5204
  "svg",
3732
5205
  {
3733
5206
  width,
@@ -3735,8 +5208,8 @@ var WaveformCircleContent = ({
3735
5208
  className: "absolute inset-0",
3736
5209
  style: { pointerEvents: "none" }
3737
5210
  },
3738
- hasGradient && /* @__PURE__ */ React26.createElement("defs", null, /* @__PURE__ */ React26.createElement("linearGradient", { id: gradientId, x1: "0%", y1: "0%", x2: "100%", y2: "0%" }, /* @__PURE__ */ React26.createElement("stop", { offset: "0%", stopColor: gradientStartColor }), /* @__PURE__ */ React26.createElement("stop", { offset: "100%", stopColor: gradientEndColor }))),
3739
- /* @__PURE__ */ React26.createElement(
5211
+ hasGradient && /* @__PURE__ */ React33.createElement("defs", null, /* @__PURE__ */ React33.createElement("linearGradient", { id: gradientId, x1: "0%", y1: "0%", x2: "100%", y2: "0%" }, /* @__PURE__ */ React33.createElement("stop", { offset: "0%", stopColor: gradientStartColor }), /* @__PURE__ */ React33.createElement("stop", { offset: "100%", stopColor: gradientEndColor }))),
5212
+ /* @__PURE__ */ React33.createElement(
3740
5213
  "path",
3741
5214
  {
3742
5215
  d: circularPath,
@@ -3752,10 +5225,10 @@ var WaveformCircleContent = ({
3752
5225
  };
3753
5226
 
3754
5227
  // src/templates/waveform/components/WaveformHistogram.tsx
3755
- import React27 from "react";
5228
+ import React34 from "react";
3756
5229
  var WaveformHistogram = ({ data }) => {
3757
5230
  const {
3758
- config: config15,
5231
+ config: config18,
3759
5232
  className = "",
3760
5233
  style = {},
3761
5234
  barColor = "#FF6B6B",
@@ -3774,7 +5247,7 @@ var WaveformHistogram = ({ data }) => {
3774
5247
  gradientStyle = "normal",
3775
5248
  waveDirection = "right-to-left"
3776
5249
  } = data;
3777
- return /* @__PURE__ */ React27.createElement(Waveform, { config: config15, className, style }, /* @__PURE__ */ React27.createElement(
5250
+ return /* @__PURE__ */ React34.createElement(Waveform, { config: config18, className, style }, /* @__PURE__ */ React34.createElement(
3778
5251
  WaveformHistogramContent,
3779
5252
  {
3780
5253
  barColor,
@@ -3815,7 +5288,7 @@ var WaveformHistogramContent = ({
3815
5288
  const { waveformData, frequencyData, amplitudes, width, height } = useWaveformContext();
3816
5289
  const dataToUse = amplitudes || waveformData;
3817
5290
  if (!dataToUse) {
3818
- return /* @__PURE__ */ React27.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading histogram...");
5291
+ return /* @__PURE__ */ React34.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading histogram...");
3819
5292
  }
3820
5293
  let directedData = waveDirection === "left-to-right" ? dataToUse.slice(1).reverse() : dataToUse;
3821
5294
  const frequencies = horizontalSymmetry ? [...directedData, ...directedData.slice(1).reverse()] : Array(multiplier).fill(directedData).flat();
@@ -3839,7 +5312,7 @@ var WaveformHistogramContent = ({
3839
5312
  },
3840
5313
  opacity: gradientStyle === "mirrored" && !growUpwards ? 0.25 : 1
3841
5314
  };
3842
- return /* @__PURE__ */ React27.createElement("div", { style: containerStyle2 }, frequencies.map((value, index) => /* @__PURE__ */ React27.createElement(
5315
+ return /* @__PURE__ */ React34.createElement("div", { style: containerStyle2 }, frequencies.map((value, index) => /* @__PURE__ */ React34.createElement(
3843
5316
  "div",
3844
5317
  {
3845
5318
  key: index,
@@ -3871,7 +5344,7 @@ var WaveformHistogramContent = ({
3871
5344
  width: "100%",
3872
5345
  left: 0
3873
5346
  };
3874
- return /* @__PURE__ */ React27.createElement(React27.Fragment, null, /* @__PURE__ */ React27.createElement("div", { style: topHalfStyle }, /* @__PURE__ */ React27.createElement(Bars, { growUpwards: true })), /* @__PURE__ */ React27.createElement("div", { style: bottomHalfStyle }, /* @__PURE__ */ React27.createElement(Bars, { growUpwards: false })));
5347
+ return /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement("div", { style: topHalfStyle }, /* @__PURE__ */ React34.createElement(Bars, { growUpwards: true })), /* @__PURE__ */ React34.createElement("div", { style: bottomHalfStyle }, /* @__PURE__ */ React34.createElement(Bars, { growUpwards: false })));
3875
5348
  }
3876
5349
  const containerStyle = {
3877
5350
  width: "100%",
@@ -3880,14 +5353,14 @@ var WaveformHistogramContent = ({
3880
5353
  height: `${height / 2}px`,
3881
5354
  left: 0
3882
5355
  };
3883
- return /* @__PURE__ */ React27.createElement("div", { style: containerStyle }, /* @__PURE__ */ React27.createElement(Bars, { growUpwards: true }));
5356
+ return /* @__PURE__ */ React34.createElement("div", { style: containerStyle }, /* @__PURE__ */ React34.createElement(Bars, { growUpwards: true }));
3884
5357
  };
3885
5358
 
3886
5359
  // src/templates/waveform/components/WaveformHistogramRanged.tsx
3887
- import React28 from "react";
5360
+ import React35 from "react";
3888
5361
  var WaveformHistogramRanged = ({ data }) => {
3889
5362
  const {
3890
- config: config15,
5363
+ config: config18,
3891
5364
  className = "",
3892
5365
  style = {},
3893
5366
  barColor = "#FF6B6B",
@@ -3911,7 +5384,7 @@ var WaveformHistogramRanged = ({ data }) => {
3911
5384
  horizontalSymmetry = false,
3912
5385
  waveDirection = "right-to-left"
3913
5386
  } = data;
3914
- return /* @__PURE__ */ React28.createElement(Waveform, { config: config15, className, style }, /* @__PURE__ */ React28.createElement(
5387
+ return /* @__PURE__ */ React35.createElement(Waveform, { config: config18, className, style }, /* @__PURE__ */ React35.createElement(
3915
5388
  WaveformHistogramRangedContent,
3916
5389
  {
3917
5390
  barColor,
@@ -3961,7 +5434,7 @@ var WaveformHistogramRangedContent = ({
3961
5434
  }) => {
3962
5435
  const { amplitudes, bassValues, midValues, trebleValues, height } = useWaveformContext();
3963
5436
  if (!amplitudes || !bassValues || !midValues || !trebleValues) {
3964
- return /* @__PURE__ */ React28.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading frequency data...");
5437
+ return /* @__PURE__ */ React35.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading frequency data...");
3965
5438
  }
3966
5439
  const bassFrequencies = bassValues;
3967
5440
  const midFrequencies = midValues;
@@ -3985,12 +5458,12 @@ var WaveformHistogramRangedContent = ({
3985
5458
  },
3986
5459
  opacity: gradientStyle === "mirrored" && !growUpwards ? 0.25 : 1
3987
5460
  };
3988
- return /* @__PURE__ */ React28.createElement("div", { style: containerStyle2 }, unifiedWaveform.map((value, index) => {
5461
+ return /* @__PURE__ */ React35.createElement("div", { style: containerStyle2 }, unifiedWaveform.map((value, index) => {
3989
5462
  const rangeName = index === 0 ? "Bass" : index === 1 ? "Mid" : "Treble";
3990
5463
  const styleGradientProp = gradientStartColor && gradientEndColor ? {
3991
5464
  background: `linear-gradient(${gradientDirection === "horizontal" ? gradientStyle === "mirrored" ? "to right" : growUpwards ? "to right" : "to left" : gradientStyle === "normal" ? growUpwards ? "to top" : "to bottom" : "to bottom"}, ${gradientStartColor}, ${gradientEndColor})`
3992
5465
  } : { backgroundColor: barColor };
3993
- return /* @__PURE__ */ React28.createElement(
5466
+ return /* @__PURE__ */ React35.createElement(
3994
5467
  "div",
3995
5468
  {
3996
5469
  key: index,
@@ -4008,7 +5481,7 @@ var WaveformHistogramRangedContent = ({
4008
5481
  },
4009
5482
  title: `${rangeName}: ${(value * 100).toFixed(1)}%`
4010
5483
  },
4011
- rangeLabels && /* @__PURE__ */ React28.createElement("div", { style: {
5484
+ rangeLabels && /* @__PURE__ */ React35.createElement("div", { style: {
4012
5485
  position: "absolute",
4013
5486
  bottom: growUpwards ? "-20px" : "auto",
4014
5487
  top: growUpwards ? "auto" : "-20px",
@@ -4036,7 +5509,7 @@ var WaveformHistogramRangedContent = ({
4036
5509
  width: "100%",
4037
5510
  left: 0
4038
5511
  };
4039
- return /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement("div", { style: topHalfStyle }, /* @__PURE__ */ React28.createElement(Bars, { growUpwards: true })), /* @__PURE__ */ React28.createElement("div", { style: bottomHalfStyle }, /* @__PURE__ */ React28.createElement(Bars, { growUpwards: false })));
5512
+ return /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement("div", { style: topHalfStyle }, /* @__PURE__ */ React35.createElement(Bars, { growUpwards: true })), /* @__PURE__ */ React35.createElement("div", { style: bottomHalfStyle }, /* @__PURE__ */ React35.createElement(Bars, { growUpwards: false })));
4040
5513
  }
4041
5514
  const containerStyle = {
4042
5515
  width: "100%",
@@ -4045,13 +5518,13 @@ var WaveformHistogramRangedContent = ({
4045
5518
  height: `${height / 2}px`,
4046
5519
  left: 0
4047
5520
  };
4048
- return /* @__PURE__ */ React28.createElement("div", { style: containerStyle }, /* @__PURE__ */ React28.createElement(Bars, { growUpwards: true }));
5521
+ return /* @__PURE__ */ React35.createElement("div", { style: containerStyle }, /* @__PURE__ */ React35.createElement(Bars, { growUpwards: true }));
4049
5522
  };
4050
5523
 
4051
5524
  // src/templates/waveform/components/WaveformLine.tsx
4052
- import React29, { useMemo as useMemo19 } from "react";
5525
+ import React36, { useMemo as useMemo20 } from "react";
4053
5526
  import { createSmoothSvgPath } from "@remotion/media-utils";
4054
- import { useCurrentFrame as useCurrentFrame12, useVideoConfig as useVideoConfig13 } from "remotion";
5527
+ import { useCurrentFrame as useCurrentFrame16, useVideoConfig as useVideoConfig17 } from "remotion";
4055
5528
  var detectBeat = (frequencyData, amplitudes, threshold = 0.7, bpm, frame = 0, fps = 30) => {
4056
5529
  if (!frequencyData || !amplitudes || frequencyData.length === 0) return false;
4057
5530
  if (bpm) {
@@ -4083,7 +5556,7 @@ var easingFunctions = {
4083
5556
  };
4084
5557
  var WaveformLine = ({ data }) => {
4085
5558
  const {
4086
- config: config15,
5559
+ config: config18,
4087
5560
  className = "",
4088
5561
  style = {},
4089
5562
  strokeColor = "#FF6B6B",
@@ -4111,7 +5584,7 @@ var WaveformLine = ({ data }) => {
4111
5584
  pulseColor = "#FFD700",
4112
5585
  pulseScale = 1.2
4113
5586
  } = data;
4114
- return /* @__PURE__ */ React29.createElement(Waveform, { config: config15, className, style }, /* @__PURE__ */ React29.createElement(
5587
+ return /* @__PURE__ */ React36.createElement(Waveform, { config: config18, className, style }, /* @__PURE__ */ React36.createElement(
4115
5588
  WaveformLineContent,
4116
5589
  {
4117
5590
  strokeColor,
@@ -4167,14 +5640,14 @@ var WaveformLineContent = ({
4167
5640
  pulseColor,
4168
5641
  pulseScale
4169
5642
  }) => {
4170
- const { waveformData, frequencyData, amplitudes, width, height, config: config15, frame, fps } = useWaveformContext();
4171
- const currentFrame = useCurrentFrame12();
4172
- const videoConfig = useVideoConfig13();
4173
- const isBeat = useMemo19(() => {
5643
+ const { waveformData, frequencyData, amplitudes, width, height, config: config18, frame, fps } = useWaveformContext();
5644
+ const currentFrame = useCurrentFrame16();
5645
+ const videoConfig = useVideoConfig17();
5646
+ const isBeat = useMemo20(() => {
4174
5647
  if (!beatSync || !frequencyData || !amplitudes) return false;
4175
5648
  return detectBeat(frequencyData, amplitudes, beatThreshold, bpm, currentFrame, fps);
4176
5649
  }, [beatSync, frequencyData, amplitudes, beatThreshold, bpm, currentFrame, fps]);
4177
- const beatProgress = useMemo19(() => {
5650
+ const beatProgress = useMemo20(() => {
4178
5651
  if (!isBeat || !beatAnimationDuration) return 0;
4179
5652
  const beatStartFrame = Math.floor(currentFrame / beatAnimationDuration) * beatAnimationDuration;
4180
5653
  const progress = (currentFrame - beatStartFrame) / beatAnimationDuration;
@@ -4184,19 +5657,19 @@ var WaveformLineContent = ({
4184
5657
  }
4185
5658
  return clampedProgress;
4186
5659
  }, [isBeat, currentFrame, beatAnimationDuration, smoothAnimation]);
4187
- const currentBeatMultiplier = useMemo19(() => {
5660
+ const currentBeatMultiplier = useMemo20(() => {
4188
5661
  if (!beatSync || !isBeat || !beatAmplitudeMultiplier || !amplitudeCurve) return 1;
4189
5662
  const easing = easingFunctions[amplitudeCurve];
4190
5663
  const easedProgress = easing(beatProgress);
4191
5664
  return 1 + (beatAmplitudeMultiplier - 1) * (1 - easedProgress);
4192
5665
  }, [beatSync, isBeat, beatProgress, beatAmplitudeMultiplier, amplitudeCurve]);
4193
- const smoothFactor = useMemo19(() => {
5666
+ const smoothFactor = useMemo20(() => {
4194
5667
  if (!beatSync) {
4195
5668
  return 0.3;
4196
5669
  }
4197
5670
  return smoothAnimation ? 0.7 : 1;
4198
5671
  }, [beatSync, smoothAnimation]);
4199
- const waveformPaths = useMemo19(() => {
5672
+ const waveformPaths = useMemo20(() => {
4200
5673
  if (!waveformData) return [];
4201
5674
  const paths = [];
4202
5675
  const segments = waveSegments || 1;
@@ -4212,8 +5685,8 @@ var WaveformLineContent = ({
4212
5685
  const points = waveformData.map((y, index) => {
4213
5686
  const progress = index / (waveformData.length - 1);
4214
5687
  const x = segmentStart + progress * segmentDataWidth + offset;
4215
- let animatedAmplitude = y * (config15.amplitude || 1) * currentBeatMultiplier * speed;
4216
- const baseAmplitude = y * (config15.amplitude || 1) * speed;
5688
+ let animatedAmplitude = y * (config18.amplitude || 1) * currentBeatMultiplier * speed;
5689
+ const baseAmplitude = y * (config18.amplitude || 1) * speed;
4217
5690
  const beatAmplitude = animatedAmplitude - baseAmplitude;
4218
5691
  animatedAmplitude = baseAmplitude + beatAmplitude * smoothFactor;
4219
5692
  const yPos = waveDirection === "horizontal" ? animatedAmplitude * height / 2 + height / 2 : animatedAmplitude * width / 2 + width / 2;
@@ -4223,11 +5696,11 @@ var WaveformLineContent = ({
4223
5696
  paths.push({ path, segmentIndex: i });
4224
5697
  }
4225
5698
  return paths;
4226
- }, [waveformData, width, height, config15.amplitude, currentBeatMultiplier, animationSpeed, waveSegments, waveSpacing, waveOffset, waveDirection, smoothFactor]);
5699
+ }, [waveformData, width, height, config18.amplitude, currentBeatMultiplier, animationSpeed, waveSegments, waveSpacing, waveOffset, waveDirection, smoothFactor]);
4227
5700
  if (!waveformData) {
4228
- return /* @__PURE__ */ React29.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading waveform...");
5701
+ return /* @__PURE__ */ React36.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading waveform...");
4229
5702
  }
4230
- return /* @__PURE__ */ React29.createElement(
5703
+ return /* @__PURE__ */ React36.createElement(
4231
5704
  "svg",
4232
5705
  {
4233
5706
  width,
@@ -4235,7 +5708,7 @@ var WaveformLineContent = ({
4235
5708
  className: "absolute inset-0",
4236
5709
  style: { pointerEvents: "none" }
4237
5710
  },
4238
- centerLine && /* @__PURE__ */ React29.createElement(
5711
+ centerLine && /* @__PURE__ */ React36.createElement(
4239
5712
  "line",
4240
5713
  {
4241
5714
  x1: waveDirection === "horizontal" ? 0 : width / 2,
@@ -4247,7 +5720,7 @@ var WaveformLineContent = ({
4247
5720
  opacity: 0.3
4248
5721
  }
4249
5722
  ),
4250
- waveformPaths.map(({ path, segmentIndex }) => /* @__PURE__ */ React29.createElement("g", { key: segmentIndex }, pulseOnBeat && isBeat && /* @__PURE__ */ React29.createElement(
5723
+ waveformPaths.map(({ path, segmentIndex }) => /* @__PURE__ */ React36.createElement("g", { key: segmentIndex }, pulseOnBeat && isBeat && /* @__PURE__ */ React36.createElement(
4251
5724
  "path",
4252
5725
  {
4253
5726
  d: path,
@@ -4258,7 +5731,7 @@ var WaveformLineContent = ({
4258
5731
  fill: "none",
4259
5732
  opacity: (opacity || 1) * (1 - beatProgress)
4260
5733
  }
4261
- ), /* @__PURE__ */ React29.createElement(
5734
+ ), /* @__PURE__ */ React36.createElement(
4262
5735
  "path",
4263
5736
  {
4264
5737
  d: path,
@@ -4319,19 +5792,19 @@ registerComponent("WaveformCircle", WaveformCircle, "atom", {
4319
5792
 
4320
5793
  // src/components/Composition.tsx
4321
5794
  import { Player as RemotionPlayer } from "@remotion/player";
4322
- import React30 from "react";
5795
+ import React37 from "react";
4323
5796
  import { AbsoluteFill as AbsoluteFill7, Composition as RemotionComposition } from "remotion";
4324
- import z5 from "zod";
4325
- var CompositionLayout = ({ childrenData, style, config: config15 }) => {
4326
- return /* @__PURE__ */ React30.createElement(
5797
+ import z10 from "zod";
5798
+ var CompositionLayout = ({ childrenData, style, config: config18 }) => {
5799
+ return /* @__PURE__ */ React37.createElement(
4327
5800
  CompositionProvider,
4328
5801
  {
4329
5802
  value: {
4330
5803
  root: childrenData,
4331
- duration: config15.duration
5804
+ duration: config18.duration
4332
5805
  }
4333
5806
  },
4334
- /* @__PURE__ */ React30.createElement(AbsoluteFill7, { style }, childrenData?.map((component) => /* @__PURE__ */ React30.createElement(
5807
+ /* @__PURE__ */ React37.createElement(AbsoluteFill7, { style }, childrenData?.map((component) => /* @__PURE__ */ React37.createElement(
4335
5808
  ComponentRenderer,
4336
5809
  {
4337
5810
  key: component.id,
@@ -4371,26 +5844,26 @@ var calculateCompositionLayoutMetadata = async ({ props, defaultProps, abortSign
4371
5844
  var Composition = ({
4372
5845
  id,
4373
5846
  childrenData,
4374
- config: config15,
5847
+ config: config18,
4375
5848
  style
4376
5849
  }) => {
4377
- return /* @__PURE__ */ React30.createElement(
5850
+ return /* @__PURE__ */ React37.createElement(
4378
5851
  RemotionComposition,
4379
5852
  {
4380
5853
  id,
4381
5854
  component: CompositionLayout,
4382
- durationInFrames: Math.round(config15.duration * config15.fps),
4383
- fps: config15.fps,
4384
- width: config15.width ?? 1080,
4385
- height: config15.height ?? 1920,
4386
- defaultProps: { childrenData, style, config: config15 },
5855
+ durationInFrames: Math.round(config18.duration * config18.fps),
5856
+ fps: config18.fps,
5857
+ width: config18.width ?? 1080,
5858
+ height: config18.height ?? 1920,
5859
+ defaultProps: { childrenData, style, config: config18 },
4387
5860
  calculateMetadata: calculateCompositionLayoutMetadata,
4388
- schema: z5.object({})
5861
+ schema: z10.object({})
4389
5862
  }
4390
5863
  );
4391
5864
  };
4392
5865
  var Player = (props) => {
4393
- return /* @__PURE__ */ React30.createElement(
5866
+ return /* @__PURE__ */ React37.createElement(
4394
5867
  RemotionPlayer,
4395
5868
  {
4396
5869
  component: CompositionLayout,
@@ -4403,24 +5876,32 @@ var Player = (props) => {
4403
5876
  );
4404
5877
  };
4405
5878
  export {
4406
- Atom5 as AudioAtom,
4407
- config13 as AudioAtomConfig,
5879
+ Atom6 as AudioAtom,
5880
+ config15 as AudioAtomConfig,
4408
5881
  Layout as BaseLayout,
4409
- config8 as BaseLayoutConfig,
5882
+ config10 as BaseLayoutConfig,
4410
5883
  BlurEffect,
4411
5884
  config2 as BlurEffectConfig,
5885
+ Atom as CanvasAtom,
5886
+ config9 as CanvasAtomConfig,
5887
+ CanvasContentAwareReveal,
5888
+ CanvasGlitchEffect,
5889
+ CanvasParticleEffect,
5890
+ CanvasWipeReveal,
4412
5891
  ComponentRenderer,
4413
5892
  Composition,
4414
5893
  CompositionLayout,
4415
5894
  CompositionProvider,
4416
5895
  Frame,
4417
5896
  GenericEffectPresets,
4418
- Atom2 as ImageAtom,
4419
- config10 as ImageAtomConfig,
5897
+ Atom8 as HTMLBlockAtom,
5898
+ config17 as HTMLBlockAtomConfig,
5899
+ Atom3 as ImageAtom,
5900
+ config12 as ImageAtomConfig,
4420
5901
  LoopEffect,
4421
5902
  config3 as LoopEffectConfig,
4422
- Atom6 as LottieAtom,
4423
- config14 as LottieAtomConfig,
5903
+ Atom7 as LottieAtom,
5904
+ config16 as LottieAtomConfig,
4424
5905
  NextjsLogo,
4425
5906
  PanEffect,
4426
5907
  config4 as PanEffectConfig,
@@ -4430,19 +5911,21 @@ export {
4430
5911
  SceneFrame,
4431
5912
  ShakeEffect,
4432
5913
  config6 as ShakeEffectConfig,
4433
- Atom as ShapeAtom,
4434
- config9 as ShapeAtomConfig,
5914
+ Atom2 as ShapeAtom,
5915
+ config11 as ShapeAtomConfig,
4435
5916
  StretchEffect,
4436
5917
  config7 as StretchEffectConfig,
4437
- Atom3 as TextAtom,
4438
- config11 as TextAtomConfig,
5918
+ Atom4 as TextAtom,
5919
+ config13 as TextAtomConfig,
4439
5920
  TextFade,
4440
5921
  UniversalEffect,
4441
5922
  UniversalEffectProvider,
4442
- Atom4 as VideoAtom,
4443
- config12 as VideoAtomConfig,
5923
+ Atom5 as VideoAtom,
5924
+ config14 as VideoAtomConfig,
4444
5925
  Waveform,
4445
5926
  WaveformCircle,
5927
+ WaveformEffect,
5928
+ config8 as WaveformEffectConfig,
4446
5929
  WaveformHistogram,
4447
5930
  WaveformHistogramRanged,
4448
5931
  WaveformLine,