@microfox/remotion 1.2.2 → 1.2.5
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/CHANGELOG.md +21 -0
- package/dist/index.d.mts +257 -20
- package/dist/index.d.ts +257 -20
- package/dist/index.js +2328 -807
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2272 -761
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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,
|
|
8
|
-
this.registry[name] = { component, config:
|
|
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:
|
|
13
|
+
this.packageRegistry[packageName][name] = { component, config: config18 };
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
-
registerEffect(name, component,
|
|
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
|
-
|
|
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:
|
|
37
|
-
this.registry[`${packageName}:${name}`] = { component, config:
|
|
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,
|
|
52
|
+
var registerComponent = (name, component, type, config18 = { displayName: "" }, packageName) => {
|
|
53
53
|
componentRegistry.registerComponent(
|
|
54
54
|
name,
|
|
55
55
|
component,
|
|
56
56
|
type,
|
|
57
|
-
|
|
57
|
+
config18,
|
|
58
58
|
packageName
|
|
59
59
|
);
|
|
60
60
|
};
|
|
61
|
-
var registerEffect = (name, component,
|
|
62
|
-
componentRegistry.registerEffect(name, component,
|
|
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);
|
|
@@ -84,6 +84,13 @@ var useComposition = () => {
|
|
|
84
84
|
|
|
85
85
|
// src/core/context/timing.ts
|
|
86
86
|
import { ALL_FORMATS, Input, UrlSource } from "mediabunny";
|
|
87
|
+
var durationCache = /* @__PURE__ */ new Map();
|
|
88
|
+
var getDurationCacheKey = (src, startFrom, endAt, playbackRate) => {
|
|
89
|
+
const startFromStr = startFrom === void 0 ? "undefined" : String(startFrom);
|
|
90
|
+
const endAtStr = endAt === void 0 ? "undefined" : String(endAt);
|
|
91
|
+
const playbackRateStr = playbackRate === void 0 ? "1" : String(playbackRate);
|
|
92
|
+
return `${src}|${startFromStr}|${endAtStr}|${playbackRateStr}`;
|
|
93
|
+
};
|
|
87
94
|
var findMatchingComponents = (childrenData, targetIds) => {
|
|
88
95
|
const matches = [];
|
|
89
96
|
const searchRecursively = (components) => {
|
|
@@ -126,34 +133,48 @@ var findMatchingComponentsByQuery = (childrenData, query) => {
|
|
|
126
133
|
};
|
|
127
134
|
var calculateComponentDuration = async (component) => {
|
|
128
135
|
const src = component.data.src;
|
|
129
|
-
if (src
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
source: new UrlSource(src)
|
|
133
|
-
});
|
|
134
|
-
const audioDuration = await audioInput.computeDuration();
|
|
135
|
-
let trimmedDuration = audioDuration;
|
|
136
|
-
if (component.data.startFrom || component.data.endAt) {
|
|
137
|
-
trimmedDuration = audioDuration - (component.data.startFrom || 0) - (component.data.endAt ? audioDuration - (component.data.endAt || 0) : 0);
|
|
138
|
-
}
|
|
136
|
+
if (src?.startsWith("http")) {
|
|
137
|
+
const startFrom = component.data.startFrom;
|
|
138
|
+
const endAt = component.data.endAt;
|
|
139
139
|
const playbackRate = component.data.playbackRate || 1;
|
|
140
|
-
const
|
|
141
|
-
|
|
140
|
+
const cacheKey = getDurationCacheKey(src, startFrom, endAt, playbackRate);
|
|
141
|
+
if (durationCache.has(cacheKey)) {
|
|
142
|
+
return durationCache.get(cacheKey);
|
|
143
|
+
}
|
|
144
|
+
const calculationPromise = (async () => {
|
|
145
|
+
const audioInput = new Input({
|
|
146
|
+
formats: ALL_FORMATS,
|
|
147
|
+
source: new UrlSource(src)
|
|
148
|
+
});
|
|
149
|
+
const audioDuration = await audioInput.computeDuration();
|
|
150
|
+
let trimmedDuration = audioDuration;
|
|
151
|
+
if (startFrom || endAt) {
|
|
152
|
+
trimmedDuration = audioDuration - (startFrom || 0) - (endAt ? audioDuration - (endAt || 0) : 0);
|
|
153
|
+
}
|
|
154
|
+
const effectiveDuration = trimmedDuration / playbackRate;
|
|
155
|
+
return effectiveDuration;
|
|
156
|
+
})();
|
|
157
|
+
durationCache.set(cacheKey, calculationPromise);
|
|
158
|
+
return calculationPromise;
|
|
142
159
|
} else {
|
|
143
160
|
}
|
|
144
161
|
};
|
|
145
|
-
var calculateDuration = async (childrenData,
|
|
162
|
+
var calculateDuration = async (childrenData, config18) => {
|
|
146
163
|
let calculatedDuration = void 0;
|
|
147
|
-
const targetIds = Array.isArray(
|
|
164
|
+
const targetIds = Array.isArray(config18.fitDurationTo) ? config18.fitDurationTo : [config18.fitDurationTo];
|
|
148
165
|
const matchingComponents = findMatchingComponents(
|
|
149
166
|
childrenData || [],
|
|
150
167
|
targetIds
|
|
151
168
|
);
|
|
152
169
|
if (matchingComponents.length === 1) {
|
|
153
170
|
if (matchingComponents[0].type === "atom" && (matchingComponents[0].componentId === "AudioAtom" || matchingComponents[0].componentId === "VideoAtom")) {
|
|
154
|
-
|
|
155
|
-
matchingComponents[0]
|
|
156
|
-
|
|
171
|
+
if (matchingComponents[0].context?.timing?.duration) {
|
|
172
|
+
calculatedDuration = matchingComponents[0].context.timing.duration;
|
|
173
|
+
} else {
|
|
174
|
+
calculatedDuration = await calculateComponentDuration(
|
|
175
|
+
matchingComponents[0]
|
|
176
|
+
);
|
|
177
|
+
}
|
|
157
178
|
}
|
|
158
179
|
if ((matchingComponents[0].type === "scene" || matchingComponents[0].type === "layout") && matchingComponents[0].context?.timing?.duration) {
|
|
159
180
|
calculatedDuration = matchingComponents[0].context.timing.duration;
|
|
@@ -162,6 +183,7 @@ var calculateDuration = async (childrenData, config15) => {
|
|
|
162
183
|
return calculatedDuration;
|
|
163
184
|
};
|
|
164
185
|
var setDurationsInContext = async (root) => {
|
|
186
|
+
durationCache.clear();
|
|
165
187
|
const iterateRecursively = async (components, onlyScene = false) => {
|
|
166
188
|
const updatedComponents = [];
|
|
167
189
|
for (const component of components) {
|
|
@@ -173,12 +195,15 @@ var setDurationsInContext = async (root) => {
|
|
|
173
195
|
);
|
|
174
196
|
}
|
|
175
197
|
if (updatedComponent.context?.timing?.fitDurationTo?.length > 0 && !onlyScene && updatedComponent.context?.timing?.fitDurationTo != updatedComponent.id && updatedComponent.context?.timing?.fitDurationTo != "this" && updatedComponent.context?.timing?.fitDurationTo != "fill") {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
198
|
+
let duration = updatedComponent.context?.timing?.duration;
|
|
199
|
+
if (!duration) {
|
|
200
|
+
duration = await calculateDuration(
|
|
201
|
+
updatedComponent.childrenData,
|
|
202
|
+
{
|
|
203
|
+
fitDurationTo: updatedComponent.context?.timing?.fitDurationTo
|
|
204
|
+
}
|
|
205
|
+
);
|
|
206
|
+
}
|
|
182
207
|
updatedComponent = {
|
|
183
208
|
...updatedComponent,
|
|
184
209
|
context: {
|
|
@@ -201,6 +226,8 @@ var setDurationsInContext = async (root) => {
|
|
|
201
226
|
(acc, child) => acc + (child.context?.timing?.duration ?? 0),
|
|
202
227
|
0
|
|
203
228
|
) ?? 10;
|
|
229
|
+
} else {
|
|
230
|
+
duration = updatedComponent.context.timing.duration;
|
|
204
231
|
}
|
|
205
232
|
if (duration !== void 0) {
|
|
206
233
|
updatedComponent.context = {
|
|
@@ -214,7 +241,13 @@ var setDurationsInContext = async (root) => {
|
|
|
214
241
|
}
|
|
215
242
|
if (updatedComponent.type === "atom" && !onlyScene) {
|
|
216
243
|
if (updatedComponent.componentId === "VideoAtom" || updatedComponent.componentId === "AudioAtom") {
|
|
217
|
-
const
|
|
244
|
+
const needsDurationCalculation = !updatedComponent.context?.timing?.duration || updatedComponent.data?.loop && !updatedComponent.data?.srcDuration;
|
|
245
|
+
let mediaDuration;
|
|
246
|
+
if (needsDurationCalculation) {
|
|
247
|
+
mediaDuration = await calculateComponentDuration(updatedComponent);
|
|
248
|
+
} else {
|
|
249
|
+
mediaDuration = updatedComponent.context?.timing?.duration;
|
|
250
|
+
}
|
|
218
251
|
if (!updatedComponent.context?.timing?.fitDurationTo) {
|
|
219
252
|
updatedComponent.context = {
|
|
220
253
|
...updatedComponent.context || {},
|
|
@@ -225,9 +258,9 @@ var setDurationsInContext = async (root) => {
|
|
|
225
258
|
};
|
|
226
259
|
updatedComponent.data = {
|
|
227
260
|
...updatedComponent.data,
|
|
228
|
-
...updatedComponent.data.loop ? { srcDuration: mediaDuration } : {}
|
|
261
|
+
...updatedComponent.data.loop && mediaDuration ? { srcDuration: mediaDuration } : {}
|
|
229
262
|
};
|
|
230
|
-
} else if (updatedComponent.context?.timing?.fitDurationTo) {
|
|
263
|
+
} else if (updatedComponent.context?.timing?.fitDurationTo && mediaDuration) {
|
|
231
264
|
updatedComponent.data = {
|
|
232
265
|
...updatedComponent.data,
|
|
233
266
|
srcDuration: mediaDuration
|
|
@@ -498,8 +531,8 @@ var ComponentRenderer = ({
|
|
|
498
531
|
context
|
|
499
532
|
};
|
|
500
533
|
if (type === "layout") {
|
|
501
|
-
const
|
|
502
|
-
const isInnerSequence =
|
|
534
|
+
const config18 = getComponentConfig(componentId);
|
|
535
|
+
const isInnerSequence = config18?.isInnerSequence;
|
|
503
536
|
if (isInnerSequence) {
|
|
504
537
|
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
538
|
}
|
|
@@ -542,7 +575,7 @@ var SceneFrame = ({ children }) => {
|
|
|
542
575
|
};
|
|
543
576
|
|
|
544
577
|
// src/components/layouts/BaseLayout.tsx
|
|
545
|
-
import
|
|
578
|
+
import React19, { Children, useMemo as useMemo9 } from "react";
|
|
546
579
|
import { AbsoluteFill as AbsoluteFill3 } from "remotion";
|
|
547
580
|
|
|
548
581
|
// src/components/effects/BlurEffect.tsx
|
|
@@ -557,10 +590,45 @@ var parseFunctionsString = (functions) => {
|
|
|
557
590
|
if (!functions) {
|
|
558
591
|
return result;
|
|
559
592
|
}
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
593
|
+
let i = 0;
|
|
594
|
+
while (i < functions.length) {
|
|
595
|
+
while (i < functions.length && /\s/.test(functions[i])) {
|
|
596
|
+
i++;
|
|
597
|
+
}
|
|
598
|
+
if (i >= functions.length) break;
|
|
599
|
+
const nameStart = i;
|
|
600
|
+
while (i < functions.length && /[\w-]/.test(functions[i])) {
|
|
601
|
+
i++;
|
|
602
|
+
}
|
|
603
|
+
if (i === nameStart) break;
|
|
604
|
+
const functionName = functions.substring(nameStart, i);
|
|
605
|
+
while (i < functions.length && /\s/.test(functions[i])) {
|
|
606
|
+
i++;
|
|
607
|
+
}
|
|
608
|
+
if (i >= functions.length || functions[i] !== "(") {
|
|
609
|
+
break;
|
|
610
|
+
}
|
|
611
|
+
i++;
|
|
612
|
+
let depth = 1;
|
|
613
|
+
const contentStart = i;
|
|
614
|
+
while (i < functions.length && depth > 0) {
|
|
615
|
+
if (functions[i] === "(") {
|
|
616
|
+
depth++;
|
|
617
|
+
} else if (functions[i] === ")") {
|
|
618
|
+
depth--;
|
|
619
|
+
}
|
|
620
|
+
if (depth > 0) {
|
|
621
|
+
i++;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
if (depth === 0) {
|
|
625
|
+
const content = functions.substring(contentStart, i);
|
|
626
|
+
const fullFunction = `${functionName}(${content})`;
|
|
627
|
+
result.set(functionName, fullFunction);
|
|
628
|
+
i++;
|
|
629
|
+
} else {
|
|
630
|
+
break;
|
|
631
|
+
}
|
|
564
632
|
}
|
|
565
633
|
return result;
|
|
566
634
|
};
|
|
@@ -724,11 +792,20 @@ var parseHexColor = (hex) => {
|
|
|
724
792
|
var parseRgbaColor = (rgba) => {
|
|
725
793
|
const match = rgba.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)/);
|
|
726
794
|
if (match) {
|
|
795
|
+
let alpha = 1;
|
|
796
|
+
if (match[4]) {
|
|
797
|
+
const alphaValue = parseFloat(match[4]);
|
|
798
|
+
if (alphaValue > 1) {
|
|
799
|
+
alpha = Math.max(0, Math.min(1, alphaValue / 100));
|
|
800
|
+
} else {
|
|
801
|
+
alpha = Math.max(0, Math.min(1, alphaValue));
|
|
802
|
+
}
|
|
803
|
+
}
|
|
727
804
|
return {
|
|
728
805
|
r: Math.max(0, Math.min(255, parseInt(match[1], 10))),
|
|
729
806
|
g: Math.max(0, Math.min(255, parseInt(match[2], 10))),
|
|
730
807
|
b: Math.max(0, Math.min(255, parseInt(match[3], 10))),
|
|
731
|
-
a:
|
|
808
|
+
a: alpha
|
|
732
809
|
};
|
|
733
810
|
}
|
|
734
811
|
return { r: 0, g: 0, b: 0, a: 1 };
|
|
@@ -742,14 +819,21 @@ var parseColor = (color) => {
|
|
|
742
819
|
}
|
|
743
820
|
return { r: 0, g: 0, b: 0, a: 1 };
|
|
744
821
|
};
|
|
745
|
-
var rgbaToString = (color) => {
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
822
|
+
var rgbaToString = (color, preserveFormat) => {
|
|
823
|
+
const r = Math.round(color.r);
|
|
824
|
+
const g = Math.round(color.g);
|
|
825
|
+
const b = Math.round(color.b);
|
|
826
|
+
const a = color.a;
|
|
827
|
+
if (preserveFormat) {
|
|
828
|
+
if (preserveFormat.hasSpaces) {
|
|
829
|
+
return `rgba(${r}, ${g}, ${b}, ${a})`;
|
|
830
|
+
} else {
|
|
831
|
+
return `rgba(${r},${g},${b},${a})`;
|
|
832
|
+
}
|
|
750
833
|
}
|
|
834
|
+
return `rgba(${r}, ${g}, ${b}, ${a})`;
|
|
751
835
|
};
|
|
752
|
-
var interpolateColors = (color1, color2, progress) => {
|
|
836
|
+
var interpolateColors = (color1, color2, progress, preserveFormat) => {
|
|
753
837
|
const parsedColor1 = parseColor(color1);
|
|
754
838
|
const parsedColor2 = parseColor(color2);
|
|
755
839
|
const interpolatedColor = {
|
|
@@ -758,7 +842,75 @@ var interpolateColors = (color1, color2, progress) => {
|
|
|
758
842
|
b: interpolate(progress, [0, 1], [parsedColor1.b, parsedColor2.b]),
|
|
759
843
|
a: interpolate(progress, [0, 1], [parsedColor1.a, parsedColor2.a])
|
|
760
844
|
};
|
|
761
|
-
return rgbaToString(interpolatedColor);
|
|
845
|
+
return rgbaToString(interpolatedColor, preserveFormat);
|
|
846
|
+
};
|
|
847
|
+
var findColorsInString = (str) => {
|
|
848
|
+
const matches = [];
|
|
849
|
+
const rgbaPattern = /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)/g;
|
|
850
|
+
let match;
|
|
851
|
+
rgbaPattern.lastIndex = 0;
|
|
852
|
+
while ((match = rgbaPattern.exec(str)) !== null) {
|
|
853
|
+
matches.push({
|
|
854
|
+
fullMatch: match[0],
|
|
855
|
+
color: match[0],
|
|
856
|
+
startIndex: match.index,
|
|
857
|
+
endIndex: match.index + match[0].length
|
|
858
|
+
});
|
|
859
|
+
}
|
|
860
|
+
const hexPattern = /#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b/g;
|
|
861
|
+
hexPattern.lastIndex = 0;
|
|
862
|
+
while ((match = hexPattern.exec(str)) !== null) {
|
|
863
|
+
matches.push({
|
|
864
|
+
fullMatch: match[0],
|
|
865
|
+
color: match[0],
|
|
866
|
+
startIndex: match.index,
|
|
867
|
+
endIndex: match.index + match[0].length
|
|
868
|
+
});
|
|
869
|
+
}
|
|
870
|
+
return matches.sort((a, b) => a.startIndex - b.startIndex);
|
|
871
|
+
};
|
|
872
|
+
var interpolateColorsInString = (str1, str2, progress) => {
|
|
873
|
+
const colors1 = findColorsInString(str1);
|
|
874
|
+
const colors2 = findColorsInString(str2);
|
|
875
|
+
if (colors1.length === 0 && colors2.length === 0) {
|
|
876
|
+
return str1;
|
|
877
|
+
}
|
|
878
|
+
if (colors1.length === 0 || colors2.length === 0) {
|
|
879
|
+
return str1;
|
|
880
|
+
}
|
|
881
|
+
const minLength = Math.min(colors1.length, colors2.length);
|
|
882
|
+
const replacements = [];
|
|
883
|
+
for (let i = 0; i < minLength; i++) {
|
|
884
|
+
const color1 = colors1[i];
|
|
885
|
+
const color2 = colors2[i];
|
|
886
|
+
const originalColor = color1.color;
|
|
887
|
+
const hasSpaces = originalColor.includes(", ");
|
|
888
|
+
const interpolatedColor = interpolateColors(color1.color, color2.color, progress, { hasSpaces });
|
|
889
|
+
replacements.push({
|
|
890
|
+
startIndex: color1.startIndex,
|
|
891
|
+
endIndex: color1.endIndex,
|
|
892
|
+
replacement: interpolatedColor
|
|
893
|
+
});
|
|
894
|
+
}
|
|
895
|
+
replacements.sort((a, b) => b.startIndex - a.startIndex);
|
|
896
|
+
let result = str1;
|
|
897
|
+
for (const replacement of replacements) {
|
|
898
|
+
const originalSubstring = result.substring(replacement.startIndex, replacement.endIndex);
|
|
899
|
+
const expectedColor = colors1.find((c) => c.startIndex === replacement.startIndex);
|
|
900
|
+
if (expectedColor && (originalSubstring === expectedColor.color || originalSubstring.trim().match(/^rgba?\(/i))) {
|
|
901
|
+
result = result.substring(0, replacement.startIndex) + replacement.replacement + result.substring(replacement.endIndex);
|
|
902
|
+
} else {
|
|
903
|
+
const currentColors = findColorsInString(result);
|
|
904
|
+
const matchingColor = currentColors.find(
|
|
905
|
+
(c) => Math.abs(c.startIndex - replacement.startIndex) < 30
|
|
906
|
+
// Allow some offset
|
|
907
|
+
);
|
|
908
|
+
if (matchingColor) {
|
|
909
|
+
result = result.substring(0, matchingColor.startIndex) + replacement.replacement + result.substring(matchingColor.endIndex);
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
return result;
|
|
762
914
|
};
|
|
763
915
|
var calculateAnimatedValue = (ranges, progress, key) => {
|
|
764
916
|
const sortedRanges = [...ranges].sort((a, b) => a.prog - b.prog);
|
|
@@ -794,6 +946,11 @@ var calculateAnimatedValue = (ranges, progress, key) => {
|
|
|
794
946
|
if (isColor(currentValue) && isColor(nextValue)) {
|
|
795
947
|
return interpolateColors(currentValue, nextValue, localProgress);
|
|
796
948
|
}
|
|
949
|
+
const colors1 = findColorsInString(currentValue);
|
|
950
|
+
const colors2 = findColorsInString(nextValue);
|
|
951
|
+
if (colors1.length > 0 || colors2.length > 0) {
|
|
952
|
+
return interpolateColorsInString(currentValue, nextValue, localProgress);
|
|
953
|
+
}
|
|
797
954
|
const getUnitAndValue = (str) => {
|
|
798
955
|
const units = ["vmax", "vmin", "rem", "deg", "bpm", "vh", "vw", "px", "em", "ms", "hz", "db", "fr", "s", "%"];
|
|
799
956
|
for (const unit of units) {
|
|
@@ -842,7 +999,7 @@ var rangesToCSSProperties = (ranges, progress) => {
|
|
|
842
999
|
const value = calculateAnimatedValue(keyRanges, progress, key);
|
|
843
1000
|
switch (key) {
|
|
844
1001
|
case "scale":
|
|
845
|
-
styles.transform =
|
|
1002
|
+
styles.transform = `${styles.transform || ""} scale(${value})`.trim();
|
|
846
1003
|
break;
|
|
847
1004
|
case "rotate":
|
|
848
1005
|
const rotateValue = typeof value === "string" && value.includes("deg") ? value : `${value}deg`;
|
|
@@ -1748,209 +1905,1721 @@ var config7 = {
|
|
|
1748
1905
|
}
|
|
1749
1906
|
};
|
|
1750
1907
|
|
|
1751
|
-
// src/components/effects/
|
|
1752
|
-
|
|
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
|
-
};
|
|
1908
|
+
// src/components/effects/WaveformEffect.tsx
|
|
1909
|
+
import React13, { useMemo as useMemo8 } from "react";
|
|
1951
1910
|
|
|
1952
|
-
// src/
|
|
1953
|
-
|
|
1911
|
+
// src/templates/waveform/hooks/useWaveformData.ts
|
|
1912
|
+
import { useMemo as useMemo7 } from "react";
|
|
1913
|
+
import {
|
|
1914
|
+
useAudioData,
|
|
1915
|
+
visualizeAudioWaveform,
|
|
1916
|
+
visualizeAudio
|
|
1917
|
+
} from "@remotion/media-utils";
|
|
1918
|
+
import { staticFile } from "remotion";
|
|
1919
|
+
var isValidPowerOfTwo = (num) => {
|
|
1920
|
+
return num > 0 && (num & num - 1) === 0;
|
|
1921
|
+
};
|
|
1922
|
+
var getClosestPowerOfTwo = (num) => {
|
|
1923
|
+
if (num <= 0) return 32;
|
|
1924
|
+
let power = 1;
|
|
1925
|
+
while (power < num) {
|
|
1926
|
+
power *= 2;
|
|
1927
|
+
}
|
|
1928
|
+
const lower = power / 2;
|
|
1929
|
+
const upper = power;
|
|
1930
|
+
return Math.abs(num - lower) < Math.abs(num - upper) ? lower : upper;
|
|
1931
|
+
};
|
|
1932
|
+
var useWaveformData = (config18) => {
|
|
1933
|
+
const {
|
|
1934
|
+
audioSrc,
|
|
1935
|
+
numberOfSamples,
|
|
1936
|
+
windowInSeconds,
|
|
1937
|
+
dataOffsetInSeconds = 0,
|
|
1938
|
+
normalize = false,
|
|
1939
|
+
frame,
|
|
1940
|
+
fps,
|
|
1941
|
+
posterize,
|
|
1942
|
+
includeFrequencyData = false,
|
|
1943
|
+
minDb = -100,
|
|
1944
|
+
maxDb = -30,
|
|
1945
|
+
smoothNormalisation = 1
|
|
1946
|
+
} = config18;
|
|
1947
|
+
const { root } = useComposition();
|
|
1948
|
+
const validatedNumberOfSamples = useMemo7(() => {
|
|
1949
|
+
if (!isValidPowerOfTwo(numberOfSamples)) {
|
|
1950
|
+
console.warn(
|
|
1951
|
+
`numberOfSamples must be a power of 2. Adjusting ${numberOfSamples} to ${getClosestPowerOfTwo(numberOfSamples)}`
|
|
1952
|
+
);
|
|
1953
|
+
return getClosestPowerOfTwo(numberOfSamples);
|
|
1954
|
+
}
|
|
1955
|
+
return numberOfSamples;
|
|
1956
|
+
}, [numberOfSamples]);
|
|
1957
|
+
const { source, audioStartsFrom } = useMemo7(() => {
|
|
1958
|
+
if (audioSrc.startsWith("http")) {
|
|
1959
|
+
return { source: audioSrc, audioStartsFrom: void 0 };
|
|
1960
|
+
}
|
|
1961
|
+
if (audioSrc.startsWith("ref:")) {
|
|
1962
|
+
const matchingComponent = findMatchingComponents(root, [
|
|
1963
|
+
audioSrc.replace("ref:", "")
|
|
1964
|
+
]);
|
|
1965
|
+
if (matchingComponent.length > 0) {
|
|
1966
|
+
const firstMatchingComponent = matchingComponent[0];
|
|
1967
|
+
if (firstMatchingComponent.componentId === "AudioAtom") {
|
|
1968
|
+
return {
|
|
1969
|
+
source: firstMatchingComponent.data.src,
|
|
1970
|
+
audioStartsFrom: firstMatchingComponent.data?.startFrom ?? void 0
|
|
1971
|
+
};
|
|
1972
|
+
}
|
|
1973
|
+
if (firstMatchingComponent.type === "layout" || firstMatchingComponent.type === "scene") {
|
|
1974
|
+
const audioComponents = findMatchingComponentsByQuery(
|
|
1975
|
+
firstMatchingComponent.childrenData,
|
|
1976
|
+
{ componentId: "AudioAtom" }
|
|
1977
|
+
);
|
|
1978
|
+
if (audioComponents.length > 0) {
|
|
1979
|
+
return {
|
|
1980
|
+
source: audioComponents[0].data.src,
|
|
1981
|
+
audioStartsFrom: audioComponents[0].data?.startFrom ?? void 0
|
|
1982
|
+
};
|
|
1983
|
+
}
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
return { source: staticFile(audioSrc), audioStartsFrom: void 0 };
|
|
1988
|
+
}, [audioSrc]);
|
|
1989
|
+
const audioData = useAudioData(source);
|
|
1990
|
+
const adjustedFrame = useMemo7(() => {
|
|
1991
|
+
if (posterize && posterize > 1) {
|
|
1992
|
+
return Math.round(frame / posterize) * posterize;
|
|
1993
|
+
}
|
|
1994
|
+
let offset = 0;
|
|
1995
|
+
if (audioStartsFrom && audioStartsFrom != 0) {
|
|
1996
|
+
offset += Math.round(audioStartsFrom * fps);
|
|
1997
|
+
}
|
|
1998
|
+
if (dataOffsetInSeconds != 0) {
|
|
1999
|
+
offset += Math.round(dataOffsetInSeconds * fps);
|
|
2000
|
+
}
|
|
2001
|
+
return frame + offset;
|
|
2002
|
+
}, [frame, posterize, dataOffsetInSeconds, audioStartsFrom]);
|
|
2003
|
+
const waveformData = useMemo7(() => {
|
|
2004
|
+
if (!audioData) return null;
|
|
2005
|
+
try {
|
|
2006
|
+
const baseSmoothingFrames = 3;
|
|
2007
|
+
const smoothingFrames = smoothNormalisation > 0 ? Math.floor(smoothNormalisation * baseSmoothingFrames) : 0;
|
|
2008
|
+
const samples = [];
|
|
2009
|
+
if (smoothingFrames === 0) {
|
|
2010
|
+
const waveform = visualizeAudioWaveform({
|
|
2011
|
+
fps,
|
|
2012
|
+
frame: adjustedFrame,
|
|
2013
|
+
audioData,
|
|
2014
|
+
numberOfSamples: validatedNumberOfSamples,
|
|
2015
|
+
windowInSeconds,
|
|
2016
|
+
dataOffsetInSeconds: 0,
|
|
2017
|
+
normalize
|
|
2018
|
+
});
|
|
2019
|
+
return waveform;
|
|
2020
|
+
}
|
|
2021
|
+
for (let offset = -smoothingFrames; offset <= smoothingFrames; offset++) {
|
|
2022
|
+
const sampleFrame = adjustedFrame + offset;
|
|
2023
|
+
if (sampleFrame >= 0) {
|
|
2024
|
+
try {
|
|
2025
|
+
const waveform = visualizeAudioWaveform({
|
|
2026
|
+
fps,
|
|
2027
|
+
frame: sampleFrame,
|
|
2028
|
+
audioData,
|
|
2029
|
+
numberOfSamples: validatedNumberOfSamples,
|
|
2030
|
+
windowInSeconds,
|
|
2031
|
+
dataOffsetInSeconds: 0,
|
|
2032
|
+
normalize
|
|
2033
|
+
});
|
|
2034
|
+
if (waveform && waveform.length > 0) {
|
|
2035
|
+
samples.push(waveform);
|
|
2036
|
+
}
|
|
2037
|
+
} catch (e) {
|
|
2038
|
+
}
|
|
2039
|
+
}
|
|
2040
|
+
}
|
|
2041
|
+
if (samples.length === 0) {
|
|
2042
|
+
const waveform = visualizeAudioWaveform({
|
|
2043
|
+
fps,
|
|
2044
|
+
frame: adjustedFrame,
|
|
2045
|
+
audioData,
|
|
2046
|
+
numberOfSamples: validatedNumberOfSamples,
|
|
2047
|
+
windowInSeconds,
|
|
2048
|
+
dataOffsetInSeconds: 0,
|
|
2049
|
+
normalize
|
|
2050
|
+
});
|
|
2051
|
+
return waveform;
|
|
2052
|
+
}
|
|
2053
|
+
const averaged = new Array(validatedNumberOfSamples).fill(0);
|
|
2054
|
+
for (let i = 0; i < validatedNumberOfSamples; i++) {
|
|
2055
|
+
let sum = 0;
|
|
2056
|
+
let count = 0;
|
|
2057
|
+
for (const sample of samples) {
|
|
2058
|
+
if (sample[i] !== void 0) {
|
|
2059
|
+
sum += sample[i];
|
|
2060
|
+
count++;
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
averaged[i] = count > 0 ? sum / count : 0;
|
|
2064
|
+
}
|
|
2065
|
+
return averaged;
|
|
2066
|
+
} catch (error2) {
|
|
2067
|
+
console.error("Error generating waveform:", error2);
|
|
2068
|
+
return null;
|
|
2069
|
+
}
|
|
2070
|
+
}, [
|
|
2071
|
+
audioData,
|
|
2072
|
+
adjustedFrame,
|
|
2073
|
+
fps,
|
|
2074
|
+
validatedNumberOfSamples,
|
|
2075
|
+
windowInSeconds,
|
|
2076
|
+
dataOffsetInSeconds,
|
|
2077
|
+
normalize,
|
|
2078
|
+
smoothNormalisation
|
|
2079
|
+
]);
|
|
2080
|
+
const {
|
|
2081
|
+
frequencyData,
|
|
2082
|
+
amplitudes,
|
|
2083
|
+
bass,
|
|
2084
|
+
mid,
|
|
2085
|
+
treble,
|
|
2086
|
+
bassValues,
|
|
2087
|
+
midValues,
|
|
2088
|
+
trebleValues
|
|
2089
|
+
} = useMemo7(() => {
|
|
2090
|
+
if (!audioData || !includeFrequencyData) {
|
|
2091
|
+
return {
|
|
2092
|
+
frequencyData: null,
|
|
2093
|
+
amplitudes: null,
|
|
2094
|
+
bass: null,
|
|
2095
|
+
mid: null,
|
|
2096
|
+
treble: null,
|
|
2097
|
+
bassValues: null,
|
|
2098
|
+
midValues: null,
|
|
2099
|
+
trebleValues: null
|
|
2100
|
+
};
|
|
2101
|
+
}
|
|
2102
|
+
try {
|
|
2103
|
+
const baseSmoothingFrames = 3;
|
|
2104
|
+
const smoothingFrames = smoothNormalisation > 0 ? Math.floor(smoothNormalisation * baseSmoothingFrames) : 0;
|
|
2105
|
+
const frequencySamples = [];
|
|
2106
|
+
let frequencyData2;
|
|
2107
|
+
if (smoothingFrames === 0) {
|
|
2108
|
+
frequencyData2 = visualizeAudio({
|
|
2109
|
+
fps,
|
|
2110
|
+
frame: adjustedFrame,
|
|
2111
|
+
audioData,
|
|
2112
|
+
numberOfSamples: validatedNumberOfSamples
|
|
2113
|
+
});
|
|
2114
|
+
} else {
|
|
2115
|
+
for (let offset = -smoothingFrames; offset <= smoothingFrames; offset++) {
|
|
2116
|
+
const sampleFrame = adjustedFrame + offset;
|
|
2117
|
+
if (sampleFrame >= 0) {
|
|
2118
|
+
try {
|
|
2119
|
+
const freqData = visualizeAudio({
|
|
2120
|
+
fps,
|
|
2121
|
+
frame: sampleFrame,
|
|
2122
|
+
audioData,
|
|
2123
|
+
numberOfSamples: validatedNumberOfSamples
|
|
2124
|
+
});
|
|
2125
|
+
if (freqData && freqData.length > 0) {
|
|
2126
|
+
frequencySamples.push(freqData);
|
|
2127
|
+
}
|
|
2128
|
+
} catch (e) {
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
if (frequencySamples.length === 0) {
|
|
2133
|
+
frequencyData2 = visualizeAudio({
|
|
2134
|
+
fps,
|
|
2135
|
+
frame: adjustedFrame,
|
|
2136
|
+
audioData,
|
|
2137
|
+
numberOfSamples: validatedNumberOfSamples
|
|
2138
|
+
});
|
|
2139
|
+
} else {
|
|
2140
|
+
frequencyData2 = new Array(validatedNumberOfSamples).fill(0);
|
|
2141
|
+
for (let i = 0; i < validatedNumberOfSamples; i++) {
|
|
2142
|
+
let sum = 0;
|
|
2143
|
+
let count = 0;
|
|
2144
|
+
for (const sample of frequencySamples) {
|
|
2145
|
+
if (sample[i] !== void 0) {
|
|
2146
|
+
sum += sample[i];
|
|
2147
|
+
count++;
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
frequencyData2[i] = count > 0 ? sum / count : 0;
|
|
2151
|
+
}
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2154
|
+
const { sampleRate } = audioData;
|
|
2155
|
+
const bassValues2 = [];
|
|
2156
|
+
const midValues2 = [];
|
|
2157
|
+
const trebleValues2 = [];
|
|
2158
|
+
for (let i = 0; i < frequencyData2.length; i++) {
|
|
2159
|
+
const freq = i * sampleRate / (2 * frequencyData2.length);
|
|
2160
|
+
const value = frequencyData2[i];
|
|
2161
|
+
if (freq >= 0 && freq < 250) {
|
|
2162
|
+
bassValues2.push(value * 2.5);
|
|
2163
|
+
} else if (freq >= 250 && freq < 4e3) {
|
|
2164
|
+
midValues2.push(value * 3);
|
|
2165
|
+
midValues2.push(value * 4.5);
|
|
2166
|
+
midValues2.push(value * 5);
|
|
2167
|
+
} else if (freq >= 4e3 && freq < sampleRate / 2) {
|
|
2168
|
+
trebleValues2.push(value * 30);
|
|
2169
|
+
}
|
|
2170
|
+
}
|
|
2171
|
+
const getAverage = (arr) => arr.length > 0 ? arr.reduce((a, b) => a + b, 0) / arr.length : 0;
|
|
2172
|
+
const bass2 = getAverage(bassValues2);
|
|
2173
|
+
const mid2 = getAverage(midValues2);
|
|
2174
|
+
const treble2 = getAverage(trebleValues2);
|
|
2175
|
+
const amplitudes2 = frequencyData2.map((value) => {
|
|
2176
|
+
const db = 20 * Math.log10(value);
|
|
2177
|
+
const scaled = (db - minDb) / (maxDb - minDb);
|
|
2178
|
+
return Math.max(0, Math.min(1, scaled));
|
|
2179
|
+
});
|
|
2180
|
+
return {
|
|
2181
|
+
frequencyData: frequencyData2,
|
|
2182
|
+
amplitudes: amplitudes2,
|
|
2183
|
+
bass: bass2,
|
|
2184
|
+
mid: mid2,
|
|
2185
|
+
treble: treble2,
|
|
2186
|
+
bassValues: bassValues2,
|
|
2187
|
+
midValues: midValues2,
|
|
2188
|
+
trebleValues: trebleValues2.reverse()
|
|
2189
|
+
};
|
|
2190
|
+
} catch (error2) {
|
|
2191
|
+
console.error("Error generating frequency data:", error2);
|
|
2192
|
+
return {
|
|
2193
|
+
frequencyData: null,
|
|
2194
|
+
amplitudes: null,
|
|
2195
|
+
bass: null,
|
|
2196
|
+
mid: null,
|
|
2197
|
+
treble: null
|
|
2198
|
+
};
|
|
2199
|
+
}
|
|
2200
|
+
}, [
|
|
2201
|
+
audioData,
|
|
2202
|
+
includeFrequencyData,
|
|
2203
|
+
adjustedFrame,
|
|
2204
|
+
fps,
|
|
2205
|
+
validatedNumberOfSamples,
|
|
2206
|
+
windowInSeconds,
|
|
2207
|
+
dataOffsetInSeconds,
|
|
2208
|
+
minDb,
|
|
2209
|
+
maxDb,
|
|
2210
|
+
smoothNormalisation
|
|
2211
|
+
]);
|
|
2212
|
+
const isLoading = !audioData;
|
|
2213
|
+
const error = audioData === null && !isLoading ? "Failed to load audio data" : null;
|
|
2214
|
+
return {
|
|
2215
|
+
waveformData,
|
|
2216
|
+
frequencyData,
|
|
2217
|
+
amplitudes,
|
|
2218
|
+
audioData,
|
|
2219
|
+
isLoading,
|
|
2220
|
+
error,
|
|
2221
|
+
bass,
|
|
2222
|
+
bassValues,
|
|
2223
|
+
mid,
|
|
2224
|
+
midValues,
|
|
2225
|
+
treble,
|
|
2226
|
+
trebleValues
|
|
2227
|
+
};
|
|
2228
|
+
};
|
|
2229
|
+
|
|
2230
|
+
// src/components/effects/WaveformEffect.tsx
|
|
2231
|
+
var WaveformEffect = ({
|
|
2232
|
+
id,
|
|
2233
|
+
componentId,
|
|
2234
|
+
type,
|
|
2235
|
+
data,
|
|
2236
|
+
children,
|
|
2237
|
+
context
|
|
2238
|
+
}) => {
|
|
2239
|
+
const { progress, frame, mode, targetIds, effectData, fps } = useUniversalAnimation(data, context);
|
|
2240
|
+
const {
|
|
2241
|
+
audioSrc,
|
|
2242
|
+
numberOfSamples = 128,
|
|
2243
|
+
windowInSeconds,
|
|
2244
|
+
dataOffsetInSeconds = 0,
|
|
2245
|
+
normalize = false,
|
|
2246
|
+
useFrequencyData = true,
|
|
2247
|
+
audioProperty = "bass",
|
|
2248
|
+
sensitivity = 1,
|
|
2249
|
+
threshold = 0,
|
|
2250
|
+
smoothing = 0.5,
|
|
2251
|
+
smoothNormalisation = 1,
|
|
2252
|
+
effectType = "zoom",
|
|
2253
|
+
intensity = 1,
|
|
2254
|
+
minValue,
|
|
2255
|
+
maxValue,
|
|
2256
|
+
shakeAxis = "both",
|
|
2257
|
+
baseScale = 1,
|
|
2258
|
+
baseBrightness = 1,
|
|
2259
|
+
rotationRange = 15
|
|
2260
|
+
} = effectData;
|
|
2261
|
+
const parentContext = useUniversalEffectOptional();
|
|
2262
|
+
const analysisWindow = smoothNormalisation === 0 ? windowInSeconds || 1 / fps : windowInSeconds || Math.max(1 / fps, 0.05);
|
|
2263
|
+
const { bass, mid, treble, waveformData } = useWaveformData({
|
|
2264
|
+
audioSrc,
|
|
2265
|
+
numberOfSamples,
|
|
2266
|
+
windowInSeconds: analysisWindow,
|
|
2267
|
+
dataOffsetInSeconds,
|
|
2268
|
+
normalize,
|
|
2269
|
+
frame,
|
|
2270
|
+
fps,
|
|
2271
|
+
includeFrequencyData: useFrequencyData,
|
|
2272
|
+
smoothNormalisation
|
|
2273
|
+
});
|
|
2274
|
+
const audioIntensity = useMemo8(() => {
|
|
2275
|
+
let rawValue = 0;
|
|
2276
|
+
switch (audioProperty) {
|
|
2277
|
+
case "bass":
|
|
2278
|
+
rawValue = bass || 0;
|
|
2279
|
+
break;
|
|
2280
|
+
case "mid":
|
|
2281
|
+
rawValue = mid || 0;
|
|
2282
|
+
break;
|
|
2283
|
+
case "treble":
|
|
2284
|
+
rawValue = treble || 0;
|
|
2285
|
+
break;
|
|
2286
|
+
case "waveform":
|
|
2287
|
+
if (waveformData && waveformData.length > 0) {
|
|
2288
|
+
rawValue = waveformData.reduce((sum, val) => sum + Math.abs(val), 0) / waveformData.length;
|
|
2289
|
+
}
|
|
2290
|
+
break;
|
|
2291
|
+
case "frequency":
|
|
2292
|
+
rawValue = bass || 0;
|
|
2293
|
+
break;
|
|
2294
|
+
default:
|
|
2295
|
+
rawValue = bass || 0;
|
|
2296
|
+
}
|
|
2297
|
+
const thresholdedValue = Math.max(0, rawValue - threshold);
|
|
2298
|
+
const sensitizedValue = thresholdedValue * sensitivity;
|
|
2299
|
+
return Math.min(1, Math.max(0, sensitizedValue));
|
|
2300
|
+
}, [audioProperty, bass, mid, treble, waveformData, threshold, sensitivity]);
|
|
2301
|
+
const smoothedIntensity = useMemo8(() => {
|
|
2302
|
+
if (smoothNormalisation === 0) {
|
|
2303
|
+
return audioIntensity;
|
|
2304
|
+
}
|
|
2305
|
+
const smoothingPower = 1 + smoothing * 2;
|
|
2306
|
+
const smoothed = Math.pow(audioIntensity, smoothingPower);
|
|
2307
|
+
const baseline = 0.1;
|
|
2308
|
+
const filtered = smoothed * (1 - baseline * smoothing) + baseline * smoothing;
|
|
2309
|
+
return Math.min(1, Math.max(0, filtered));
|
|
2310
|
+
}, [audioIntensity, smoothing, smoothNormalisation]);
|
|
2311
|
+
const animatedStyles = useMemo8(() => {
|
|
2312
|
+
const intensityValue = smoothedIntensity || audioIntensity;
|
|
2313
|
+
let effectValue = intensityValue * intensity;
|
|
2314
|
+
if (minValue !== void 0 || maxValue !== void 0) {
|
|
2315
|
+
const defaultMin = effectType === "zoom" || effectType === "scale" ? baseScale : 0;
|
|
2316
|
+
const defaultMax = effectType === "zoom" || effectType === "scale" ? baseScale + intensity : intensity;
|
|
2317
|
+
const min = minValue !== void 0 ? minValue : defaultMin;
|
|
2318
|
+
const max = maxValue !== void 0 ? maxValue : defaultMax;
|
|
2319
|
+
effectValue = min + intensityValue * (max - min);
|
|
2320
|
+
} else {
|
|
2321
|
+
switch (effectType) {
|
|
2322
|
+
case "zoom":
|
|
2323
|
+
case "scale":
|
|
2324
|
+
effectValue = baseScale + intensityValue * intensity;
|
|
2325
|
+
break;
|
|
2326
|
+
case "exposure":
|
|
2327
|
+
effectValue = baseBrightness + intensityValue * intensity;
|
|
2328
|
+
break;
|
|
2329
|
+
case "blur":
|
|
2330
|
+
effectValue = intensityValue * intensity * 10;
|
|
2331
|
+
break;
|
|
2332
|
+
case "rotate":
|
|
2333
|
+
effectValue = (intensityValue - 0.5) * 2 * rotationRange;
|
|
2334
|
+
break;
|
|
2335
|
+
case "translateX":
|
|
2336
|
+
case "translateY":
|
|
2337
|
+
effectValue = (intensityValue - 0.5) * 2 * intensity * 50;
|
|
2338
|
+
break;
|
|
2339
|
+
default:
|
|
2340
|
+
effectValue = intensityValue * intensity;
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
const styles = {};
|
|
2344
|
+
switch (effectType) {
|
|
2345
|
+
case "zoom":
|
|
2346
|
+
case "scale":
|
|
2347
|
+
styles.transform = `scale(${effectValue})`;
|
|
2348
|
+
break;
|
|
2349
|
+
case "shake":
|
|
2350
|
+
const shakeFrequency = 0.1;
|
|
2351
|
+
const shakeTime = frame * shakeFrequency;
|
|
2352
|
+
const shakeAmplitude = intensityValue * intensity * 20;
|
|
2353
|
+
const shakeX = shakeAxis === "x" || shakeAxis === "both" ? Math.sin(shakeTime * 2.3) * shakeAmplitude : 0;
|
|
2354
|
+
const shakeY = shakeAxis === "y" || shakeAxis === "both" ? Math.cos(shakeTime * 1.7) * shakeAmplitude : 0;
|
|
2355
|
+
styles.transform = `translateX(${shakeX}px) translateY(${shakeY}px)`;
|
|
2356
|
+
break;
|
|
2357
|
+
case "exposure":
|
|
2358
|
+
styles.filter = `brightness(${effectValue})`;
|
|
2359
|
+
break;
|
|
2360
|
+
case "blur":
|
|
2361
|
+
styles.filter = `blur(${effectValue}px)`;
|
|
2362
|
+
break;
|
|
2363
|
+
case "rotate":
|
|
2364
|
+
styles.transform = `rotate(${effectValue}deg)`;
|
|
2365
|
+
break;
|
|
2366
|
+
case "translateX":
|
|
2367
|
+
styles.transform = `translateX(${effectValue}px)`;
|
|
2368
|
+
break;
|
|
2369
|
+
case "translateY":
|
|
2370
|
+
styles.transform = `translateY(${effectValue}px)`;
|
|
2371
|
+
break;
|
|
2372
|
+
default:
|
|
2373
|
+
styles.transform = `scale(${effectValue})`;
|
|
2374
|
+
}
|
|
2375
|
+
if (parentContext && mode === "provider") {
|
|
2376
|
+
const combinedStyles = mergeCSSStyles_default(parentContext.animatedStyles, styles);
|
|
2377
|
+
return combinedStyles;
|
|
2378
|
+
}
|
|
2379
|
+
return styles;
|
|
2380
|
+
}, [
|
|
2381
|
+
smoothedIntensity,
|
|
2382
|
+
audioIntensity,
|
|
2383
|
+
effectType,
|
|
2384
|
+
intensity,
|
|
2385
|
+
minValue,
|
|
2386
|
+
maxValue,
|
|
2387
|
+
baseScale,
|
|
2388
|
+
baseBrightness,
|
|
2389
|
+
rotationRange,
|
|
2390
|
+
shakeAxis,
|
|
2391
|
+
mode,
|
|
2392
|
+
parentContext?.animatedStyles,
|
|
2393
|
+
frame
|
|
2394
|
+
// Add frame dependency for shake effect
|
|
2395
|
+
]);
|
|
2396
|
+
const contextValue = useMemo8(
|
|
2397
|
+
() => ({
|
|
2398
|
+
animatedStyles,
|
|
2399
|
+
targetIds,
|
|
2400
|
+
effectType: "waveform"
|
|
2401
|
+
}),
|
|
2402
|
+
[animatedStyles, targetIds]
|
|
2403
|
+
);
|
|
2404
|
+
if (mode === "provider") {
|
|
2405
|
+
return /* @__PURE__ */ React13.createElement(UniversalEffectContext.Provider, { value: contextValue }, children);
|
|
2406
|
+
}
|
|
2407
|
+
return /* @__PURE__ */ React13.createElement("div", { ...effectData.props, style: animatedStyles }, children);
|
|
2408
|
+
};
|
|
2409
|
+
var config8 = {
|
|
2410
|
+
displayName: "waveform",
|
|
2411
|
+
description: "Waveform-driven effect that reacts to audio data (bass, mid, treble, waveform)",
|
|
2412
|
+
isInnerSequence: false,
|
|
2413
|
+
props: {
|
|
2414
|
+
audioSrc: {
|
|
2415
|
+
type: "string",
|
|
2416
|
+
required: true,
|
|
2417
|
+
description: "Audio source URL or ref:componentId"
|
|
2418
|
+
},
|
|
2419
|
+
audioProperty: {
|
|
2420
|
+
type: "enum",
|
|
2421
|
+
values: ["bass", "mid", "treble", "waveform", "frequency"],
|
|
2422
|
+
default: "bass",
|
|
2423
|
+
description: "Which audio property to react to"
|
|
2424
|
+
},
|
|
2425
|
+
effectType: {
|
|
2426
|
+
type: "enum",
|
|
2427
|
+
values: ["zoom", "shake", "exposure", "blur", "scale", "rotate", "translateX", "translateY"],
|
|
2428
|
+
default: "zoom",
|
|
2429
|
+
description: "Type of effect to apply"
|
|
2430
|
+
},
|
|
2431
|
+
intensity: {
|
|
2432
|
+
type: "number",
|
|
2433
|
+
default: 1,
|
|
2434
|
+
description: "Effect intensity multiplier"
|
|
2435
|
+
},
|
|
2436
|
+
sensitivity: {
|
|
2437
|
+
type: "number",
|
|
2438
|
+
default: 1,
|
|
2439
|
+
description: "Sensitivity multiplier for audio detection"
|
|
2440
|
+
},
|
|
2441
|
+
threshold: {
|
|
2442
|
+
type: "number",
|
|
2443
|
+
default: 0,
|
|
2444
|
+
description: "Minimum audio value to trigger effect"
|
|
2445
|
+
},
|
|
2446
|
+
smoothing: {
|
|
2447
|
+
type: "number",
|
|
2448
|
+
default: 0.5,
|
|
2449
|
+
description: "Smoothing factor (0-1) for audio data"
|
|
2450
|
+
},
|
|
2451
|
+
smoothNormalisation: {
|
|
2452
|
+
type: "number",
|
|
2453
|
+
default: 1,
|
|
2454
|
+
description: "Frame-based smoothing control (0 = no smoothing, 1 = default, >1 = more smoothing)"
|
|
2455
|
+
}
|
|
2456
|
+
}
|
|
2457
|
+
};
|
|
2458
|
+
|
|
2459
|
+
// src/components/effects/CanvasWipeReveal.tsx
|
|
2460
|
+
import React15, { useEffect, useRef, useState } from "react";
|
|
2461
|
+
import { useCurrentFrame as useCurrentFrame4, useVideoConfig as useVideoConfig5 } from "remotion";
|
|
2462
|
+
import { z as z2 } from "zod";
|
|
2463
|
+
|
|
2464
|
+
// src/components/atoms/CanvasAtom.tsx
|
|
2465
|
+
import React14 from "react";
|
|
2466
|
+
import { z } from "zod";
|
|
2467
|
+
var CanvasAtomDataProps = z.object({
|
|
2468
|
+
className: z.string().optional(),
|
|
2469
|
+
style: z.record(z.string(), z.any()).optional()
|
|
2470
|
+
});
|
|
2471
|
+
var Atom = React14.forwardRef(({ data, id }, ref) => {
|
|
2472
|
+
const { className, style } = data;
|
|
2473
|
+
return /* @__PURE__ */ React14.createElement("canvas", { ref, className, style, id });
|
|
2474
|
+
});
|
|
2475
|
+
var config9 = {
|
|
2476
|
+
displayName: "CanvasAtom",
|
|
2477
|
+
type: "atom",
|
|
2478
|
+
isInnerSequence: false,
|
|
2479
|
+
props: CanvasAtomDataProps
|
|
2480
|
+
// The config points to the Zod schema for data
|
|
2481
|
+
};
|
|
2482
|
+
|
|
2483
|
+
// src/components/effects/CanvasWipeReveal.tsx
|
|
2484
|
+
var mulberry32 = (seed) => {
|
|
2485
|
+
return () => {
|
|
2486
|
+
let t = seed += 1831565813;
|
|
2487
|
+
t = Math.imul(t ^ t >>> 15, t | 1);
|
|
2488
|
+
t ^= t + Math.imul(t ^ t >>> 7, t | 61);
|
|
2489
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
2490
|
+
};
|
|
2491
|
+
};
|
|
2492
|
+
var CanvasWipeRevealProps = z2.object({
|
|
2493
|
+
imageUrl: z2.string().url(),
|
|
2494
|
+
revealDurationInFrames: z2.number().min(1),
|
|
2495
|
+
revealType: z2.enum(["wipe", "radial"]).default("wipe"),
|
|
2496
|
+
angle: z2.number().default(0),
|
|
2497
|
+
fit: z2.enum(["cover", "contain"]).default("cover"),
|
|
2498
|
+
edgeStyle: z2.enum(["straight", "organic", "burn"]).default("straight"),
|
|
2499
|
+
edgeWaviness: z2.number().default(30),
|
|
2500
|
+
edgeFrequency: z2.number().default(4),
|
|
2501
|
+
backgroundColor: z2.string().default("rgba(0,0,0,0)"),
|
|
2502
|
+
burnGlow: z2.boolean().default(true),
|
|
2503
|
+
burnGlowColor: z2.string().default("#ff6600"),
|
|
2504
|
+
burnGlowIntensity: z2.number().default(1),
|
|
2505
|
+
organicRandomAmplitude: z2.boolean().default(true),
|
|
2506
|
+
organicRandomWavelength: z2.boolean().default(false)
|
|
2507
|
+
});
|
|
2508
|
+
var CanvasWipeReveal = ({ data, id }) => {
|
|
2509
|
+
const {
|
|
2510
|
+
imageUrl,
|
|
2511
|
+
revealDurationInFrames,
|
|
2512
|
+
revealType,
|
|
2513
|
+
angle,
|
|
2514
|
+
fit,
|
|
2515
|
+
edgeStyle,
|
|
2516
|
+
edgeWaviness,
|
|
2517
|
+
edgeFrequency,
|
|
2518
|
+
backgroundColor,
|
|
2519
|
+
burnGlow,
|
|
2520
|
+
burnGlowColor,
|
|
2521
|
+
burnGlowIntensity,
|
|
2522
|
+
organicRandomAmplitude,
|
|
2523
|
+
organicRandomWavelength
|
|
2524
|
+
} = data;
|
|
2525
|
+
const frame = useCurrentFrame4();
|
|
2526
|
+
const { width, height } = useVideoConfig5();
|
|
2527
|
+
const canvasRef = useRef(null);
|
|
2528
|
+
const [image, setImage] = useState(null);
|
|
2529
|
+
useEffect(() => {
|
|
2530
|
+
const img = new window.Image();
|
|
2531
|
+
img.crossOrigin = "Anonymous";
|
|
2532
|
+
img.src = imageUrl;
|
|
2533
|
+
img.onload = () => setImage(img);
|
|
2534
|
+
}, [imageUrl]);
|
|
2535
|
+
useEffect(() => {
|
|
2536
|
+
if (!canvasRef.current || !image) return;
|
|
2537
|
+
const context = canvasRef.current.getContext("2d");
|
|
2538
|
+
if (!context) return;
|
|
2539
|
+
context.canvas.width = width;
|
|
2540
|
+
context.canvas.height = height;
|
|
2541
|
+
context.fillStyle = backgroundColor;
|
|
2542
|
+
context.fillRect(0, 0, width, height);
|
|
2543
|
+
const progress = Math.min(frame / revealDurationInFrames, 1);
|
|
2544
|
+
if (progress === 0 && backgroundColor === "rgba(0,0,0,0)") return;
|
|
2545
|
+
const seed = id.split("").reduce((acc, char) => acc + char.charCodeAt(0), 0);
|
|
2546
|
+
context.save();
|
|
2547
|
+
context.beginPath();
|
|
2548
|
+
if (revealType === "radial") {
|
|
2549
|
+
const baseRadius = Math.sqrt(width * width + height * height) / 2 * progress;
|
|
2550
|
+
if (edgeStyle === "organic") {
|
|
2551
|
+
const points = 120;
|
|
2552
|
+
const random = mulberry32(seed);
|
|
2553
|
+
const amplitudes = Array.from(
|
|
2554
|
+
{ length: points + 1 },
|
|
2555
|
+
() => organicRandomAmplitude ? 0.5 + random() : 1
|
|
2556
|
+
);
|
|
2557
|
+
const wavelengths = Array.from(
|
|
2558
|
+
{ length: points + 1 },
|
|
2559
|
+
() => organicRandomWavelength ? 0.5 + random() * 1.5 : 1
|
|
2560
|
+
);
|
|
2561
|
+
for (let i = 0; i <= points; i++) {
|
|
2562
|
+
const p = i / points;
|
|
2563
|
+
const angle2 = p * Math.PI * 2;
|
|
2564
|
+
const wave = Math.sin(
|
|
2565
|
+
p * Math.PI * edgeFrequency * wavelengths[i] + frame * 0.1
|
|
2566
|
+
) * edgeWaviness * progress * amplitudes[i];
|
|
2567
|
+
const radius = baseRadius + wave;
|
|
2568
|
+
const x = width / 2 + Math.cos(angle2) * radius;
|
|
2569
|
+
const y = height / 2 + Math.sin(angle2) * radius;
|
|
2570
|
+
if (i === 0) context.moveTo(x, y);
|
|
2571
|
+
else context.lineTo(x, y);
|
|
2572
|
+
}
|
|
2573
|
+
context.closePath();
|
|
2574
|
+
} else if (edgeStyle === "burn") {
|
|
2575
|
+
const points = 120;
|
|
2576
|
+
const random = mulberry32(seed);
|
|
2577
|
+
const randomValues = Array.from({ length: points + 1 }, () => random());
|
|
2578
|
+
const phaseOffsets = Array.from(
|
|
2579
|
+
{ length: points + 1 },
|
|
2580
|
+
() => random() * Math.PI * 2
|
|
2581
|
+
);
|
|
2582
|
+
const sparklePoints = [];
|
|
2583
|
+
for (let i = 0; i <= points; i++) {
|
|
2584
|
+
const p = i / points;
|
|
2585
|
+
const angle2 = p * Math.PI * 2;
|
|
2586
|
+
const flicker = Math.sin(frame * 0.3 + phaseOffsets[i]);
|
|
2587
|
+
const burnOffset = (randomValues[i] * 2 - 1) * flicker * edgeWaviness * progress;
|
|
2588
|
+
const radius = baseRadius + burnOffset;
|
|
2589
|
+
const x = width / 2 + Math.cos(angle2) * radius;
|
|
2590
|
+
const y = height / 2 + Math.sin(angle2) * radius;
|
|
2591
|
+
if (burnGlow && i % 5 === 0 && flicker > 0.3) {
|
|
2592
|
+
sparklePoints.push({ x, y, intensity: flicker });
|
|
2593
|
+
}
|
|
2594
|
+
if (i === 0) context.moveTo(x, y);
|
|
2595
|
+
else context.lineTo(x, y);
|
|
2596
|
+
}
|
|
2597
|
+
context.closePath();
|
|
2598
|
+
if (burnGlow && sparklePoints.length > 0) {
|
|
2599
|
+
sparklePoints.forEach((point) => {
|
|
2600
|
+
const glowSize = 3 + point.intensity * 5 * burnGlowIntensity;
|
|
2601
|
+
if (isFinite(point.x) && isFinite(point.y) && isFinite(glowSize) && glowSize > 0) {
|
|
2602
|
+
const gradient = context.createRadialGradient(
|
|
2603
|
+
point.x,
|
|
2604
|
+
point.y,
|
|
2605
|
+
0,
|
|
2606
|
+
point.x,
|
|
2607
|
+
point.y,
|
|
2608
|
+
glowSize
|
|
2609
|
+
);
|
|
2610
|
+
gradient.addColorStop(0, burnGlowColor);
|
|
2611
|
+
gradient.addColorStop(0.5, burnGlowColor + "80");
|
|
2612
|
+
gradient.addColorStop(1, burnGlowColor + "00");
|
|
2613
|
+
context.fillStyle = gradient;
|
|
2614
|
+
context.fillRect(
|
|
2615
|
+
point.x - glowSize,
|
|
2616
|
+
point.y - glowSize,
|
|
2617
|
+
glowSize * 2,
|
|
2618
|
+
glowSize * 2
|
|
2619
|
+
);
|
|
2620
|
+
}
|
|
2621
|
+
});
|
|
2622
|
+
}
|
|
2623
|
+
} else {
|
|
2624
|
+
context.arc(width / 2, height / 2, baseRadius, 0, Math.PI * 2);
|
|
2625
|
+
}
|
|
2626
|
+
} else {
|
|
2627
|
+
const angleInRadians = angle * Math.PI / 180;
|
|
2628
|
+
const diagonal = Math.sqrt(width * width + height * height);
|
|
2629
|
+
context.translate(width / 2, height / 2);
|
|
2630
|
+
context.rotate(angleInRadians);
|
|
2631
|
+
const wipeEdgePosition = progress * diagonal - diagonal / 2;
|
|
2632
|
+
if (edgeStyle === "burn") {
|
|
2633
|
+
const points = 100;
|
|
2634
|
+
const random = mulberry32(seed);
|
|
2635
|
+
const randomValues = Array.from({ length: points + 1 }, () => random());
|
|
2636
|
+
const phaseOffsets = Array.from(
|
|
2637
|
+
{ length: points + 1 },
|
|
2638
|
+
() => random() * Math.PI * 2
|
|
2639
|
+
);
|
|
2640
|
+
const edgePoints = [];
|
|
2641
|
+
context.moveTo(wipeEdgePosition, -diagonal / 2);
|
|
2642
|
+
for (let i = 0; i <= points; i++) {
|
|
2643
|
+
const p = i / points;
|
|
2644
|
+
const y = (p - 0.5) * diagonal;
|
|
2645
|
+
const flicker = Math.sin(frame * 0.3 + phaseOffsets[i]);
|
|
2646
|
+
const x = wipeEdgePosition + (randomValues[i] * 2 - 1) * flicker * edgeWaviness;
|
|
2647
|
+
context.lineTo(x, y);
|
|
2648
|
+
edgePoints.push({ x, y });
|
|
2649
|
+
}
|
|
2650
|
+
context.lineTo(wipeEdgePosition, diagonal / 2);
|
|
2651
|
+
context.lineTo(-diagonal / 2, diagonal / 2);
|
|
2652
|
+
context.lineTo(-diagonal / 2, -diagonal / 2);
|
|
2653
|
+
context.closePath();
|
|
2654
|
+
if (burnGlow && progress > 0.01) {
|
|
2655
|
+
const random2 = mulberry32(seed + frame);
|
|
2656
|
+
for (let i = 0; i < edgePoints.length; i += 3) {
|
|
2657
|
+
const point = edgePoints[i];
|
|
2658
|
+
const flicker = Math.sin(frame * 0.3 + phaseOffsets[i]);
|
|
2659
|
+
if (flicker > 0.2) {
|
|
2660
|
+
const glowSize = 4 + random2() * 6 * flicker * burnGlowIntensity;
|
|
2661
|
+
if (isFinite(point.x) && isFinite(point.y) && isFinite(glowSize) && glowSize > 0) {
|
|
2662
|
+
const gradient = context.createRadialGradient(
|
|
2663
|
+
point.x,
|
|
2664
|
+
point.y,
|
|
2665
|
+
0,
|
|
2666
|
+
point.x,
|
|
2667
|
+
point.y,
|
|
2668
|
+
glowSize
|
|
2669
|
+
);
|
|
2670
|
+
gradient.addColorStop(0, burnGlowColor);
|
|
2671
|
+
gradient.addColorStop(0.4, burnGlowColor + "CC");
|
|
2672
|
+
gradient.addColorStop(1, burnGlowColor + "00");
|
|
2673
|
+
context.fillStyle = gradient;
|
|
2674
|
+
context.fillRect(
|
|
2675
|
+
point.x - glowSize,
|
|
2676
|
+
point.y - glowSize,
|
|
2677
|
+
glowSize * 2,
|
|
2678
|
+
glowSize * 2
|
|
2679
|
+
);
|
|
2680
|
+
if (random2() > 0.85) {
|
|
2681
|
+
const sparkleSize = 2 + random2() * 3;
|
|
2682
|
+
context.fillStyle = "#ffffff";
|
|
2683
|
+
context.fillRect(
|
|
2684
|
+
point.x - sparkleSize / 2,
|
|
2685
|
+
point.y - sparkleSize / 2,
|
|
2686
|
+
sparkleSize,
|
|
2687
|
+
sparkleSize
|
|
2688
|
+
);
|
|
2689
|
+
}
|
|
2690
|
+
}
|
|
2691
|
+
}
|
|
2692
|
+
}
|
|
2693
|
+
}
|
|
2694
|
+
} else if (edgeStyle === "organic") {
|
|
2695
|
+
const points = 100;
|
|
2696
|
+
const random = mulberry32(seed);
|
|
2697
|
+
const amplitudes = Array.from(
|
|
2698
|
+
{ length: points + 1 },
|
|
2699
|
+
() => organicRandomAmplitude ? 0.5 + random() : 1
|
|
2700
|
+
);
|
|
2701
|
+
const wavelengths = Array.from(
|
|
2702
|
+
{ length: points + 1 },
|
|
2703
|
+
() => organicRandomWavelength ? 0.5 + random() * 1.5 : 1
|
|
2704
|
+
);
|
|
2705
|
+
context.moveTo(wipeEdgePosition, -diagonal / 2);
|
|
2706
|
+
for (let i = 0; i <= points; i++) {
|
|
2707
|
+
const p = i / points;
|
|
2708
|
+
const y = (p - 0.5) * diagonal;
|
|
2709
|
+
const wave = Math.sin(
|
|
2710
|
+
p * edgeFrequency * wavelengths[i] * Math.PI + frame * 0.1
|
|
2711
|
+
) * edgeWaviness * amplitudes[i];
|
|
2712
|
+
context.lineTo(wipeEdgePosition + wave, y);
|
|
2713
|
+
}
|
|
2714
|
+
context.lineTo(wipeEdgePosition, diagonal / 2);
|
|
2715
|
+
context.lineTo(-diagonal / 2, diagonal / 2);
|
|
2716
|
+
context.lineTo(-diagonal / 2, -diagonal / 2);
|
|
2717
|
+
context.closePath();
|
|
2718
|
+
} else {
|
|
2719
|
+
context.rect(
|
|
2720
|
+
-diagonal / 2,
|
|
2721
|
+
-diagonal / 2,
|
|
2722
|
+
wipeEdgePosition + diagonal / 2,
|
|
2723
|
+
diagonal
|
|
2724
|
+
);
|
|
2725
|
+
}
|
|
2726
|
+
context.rotate(-angleInRadians);
|
|
2727
|
+
context.translate(-width / 2, -height / 2);
|
|
2728
|
+
}
|
|
2729
|
+
context.clip();
|
|
2730
|
+
let sx = 0, sy = 0, sWidth = image.width, sHeight = image.height;
|
|
2731
|
+
if (fit === "cover") {
|
|
2732
|
+
const imgAspect = image.width / image.height;
|
|
2733
|
+
const canvasAspect = width / height;
|
|
2734
|
+
if (imgAspect > canvasAspect) {
|
|
2735
|
+
sWidth = image.height * canvasAspect;
|
|
2736
|
+
sx = (image.width - sWidth) / 2;
|
|
2737
|
+
} else {
|
|
2738
|
+
sHeight = image.width / canvasAspect;
|
|
2739
|
+
sy = (image.height - sHeight) / 2;
|
|
2740
|
+
}
|
|
2741
|
+
}
|
|
2742
|
+
context.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, width, height);
|
|
2743
|
+
context.restore();
|
|
2744
|
+
}, [
|
|
2745
|
+
frame,
|
|
2746
|
+
image,
|
|
2747
|
+
width,
|
|
2748
|
+
height,
|
|
2749
|
+
revealDurationInFrames,
|
|
2750
|
+
fit,
|
|
2751
|
+
revealType,
|
|
2752
|
+
angle,
|
|
2753
|
+
edgeStyle,
|
|
2754
|
+
edgeWaviness,
|
|
2755
|
+
edgeFrequency,
|
|
2756
|
+
id,
|
|
2757
|
+
backgroundColor,
|
|
2758
|
+
burnGlow,
|
|
2759
|
+
burnGlowColor,
|
|
2760
|
+
burnGlowIntensity,
|
|
2761
|
+
organicRandomAmplitude,
|
|
2762
|
+
organicRandomWavelength
|
|
2763
|
+
]);
|
|
2764
|
+
return /* @__PURE__ */ React15.createElement(Atom, { ref: canvasRef, data: { className: "w-full h-full" }, id });
|
|
2765
|
+
};
|
|
2766
|
+
|
|
2767
|
+
// src/components/effects/CanvasContentAwareReveal.tsx
|
|
2768
|
+
import React16, { useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
2769
|
+
import { useCurrentFrame as useCurrentFrame5, useVideoConfig as useVideoConfig6 } from "remotion";
|
|
2770
|
+
import { z as z3 } from "zod";
|
|
2771
|
+
var CanvasContentAwareRevealProps = z3.object({
|
|
2772
|
+
imageUrl: z3.string().url(),
|
|
2773
|
+
revealDurationInFrames: z3.number().min(1),
|
|
2774
|
+
fit: z3.enum(["cover", "contain"]).default("cover"),
|
|
2775
|
+
backgroundColor: z3.string().default("rgba(0,0,0,0)"),
|
|
2776
|
+
burnColorOrder: z3.enum(["vibgyor", "luminance", "random"]).default("vibgyor"),
|
|
2777
|
+
revealMode: z3.enum(["color", "direction", "combined"]).default("combined").describe("Reveal mode: color-only, direction-only, or combined"),
|
|
2778
|
+
direction: z3.enum(["horizontal", "vertical", "diagonal-down", "diagonal-up", "top-to-bottom"]).default("top-to-bottom"),
|
|
2779
|
+
directionLayers: z3.number().default(10).describe("Number of layers for horizontal/vertical patterns")
|
|
2780
|
+
});
|
|
2781
|
+
var CanvasContentAwareReveal = ({ data, id }) => {
|
|
2782
|
+
const {
|
|
2783
|
+
imageUrl,
|
|
2784
|
+
revealDurationInFrames,
|
|
2785
|
+
fit,
|
|
2786
|
+
backgroundColor,
|
|
2787
|
+
burnColorOrder,
|
|
2788
|
+
revealMode,
|
|
2789
|
+
direction,
|
|
2790
|
+
directionLayers
|
|
2791
|
+
} = data;
|
|
2792
|
+
const frame = useCurrentFrame5();
|
|
2793
|
+
const { width, height } = useVideoConfig6();
|
|
2794
|
+
const canvasRef = useRef2(null);
|
|
2795
|
+
const [image, setImage] = useState2(null);
|
|
2796
|
+
const [pixelBurnMap, setPixelBurnMap] = useState2(null);
|
|
2797
|
+
const [isProcessing, setIsProcessing] = useState2(false);
|
|
2798
|
+
const burnMapGeneratedRef = useRef2(false);
|
|
2799
|
+
const rgbToHsv = (r, g, b) => {
|
|
2800
|
+
r /= 255;
|
|
2801
|
+
g /= 255;
|
|
2802
|
+
b /= 255;
|
|
2803
|
+
const max = Math.max(r, g, b), min = Math.min(r, g, b), delta = max - min;
|
|
2804
|
+
let h = 0;
|
|
2805
|
+
if (delta !== 0) {
|
|
2806
|
+
if (max === r) h = (g - b) / delta % 6;
|
|
2807
|
+
else if (max === g) h = (b - r) / delta + 2;
|
|
2808
|
+
else h = (r - g) / delta + 4;
|
|
2809
|
+
h *= 60;
|
|
2810
|
+
if (h < 0) h += 360;
|
|
2811
|
+
}
|
|
2812
|
+
return [h, max === 0 ? 0 : delta / max, max];
|
|
2813
|
+
};
|
|
2814
|
+
const getLuminance = (r, g, b) => 0.299 * r + 0.587 * g + 0.114 * b;
|
|
2815
|
+
const hueToVibgyorOrder = (hue) => {
|
|
2816
|
+
if (hue >= 260 && hue <= 290) return 0;
|
|
2817
|
+
if (hue >= 240 && hue < 260) return 0.15;
|
|
2818
|
+
if (hue >= 200 && hue < 240) return 0.3;
|
|
2819
|
+
if (hue >= 120 && hue < 200) return 0.5;
|
|
2820
|
+
if (hue >= 50 && hue < 120) return 0.65;
|
|
2821
|
+
if (hue >= 20 && hue < 50) return 0.8;
|
|
2822
|
+
if (hue >= 290 || hue < 20) return 1;
|
|
2823
|
+
return hue / 360;
|
|
2824
|
+
};
|
|
2825
|
+
useEffect2(() => {
|
|
2826
|
+
const img = new window.Image();
|
|
2827
|
+
img.crossOrigin = "Anonymous";
|
|
2828
|
+
img.src = imageUrl;
|
|
2829
|
+
img.onload = () => {
|
|
2830
|
+
setImage(img);
|
|
2831
|
+
burnMapGeneratedRef.current = false;
|
|
2832
|
+
};
|
|
2833
|
+
}, [imageUrl]);
|
|
2834
|
+
useEffect2(() => {
|
|
2835
|
+
if (!image || isProcessing || burnMapGeneratedRef.current) return;
|
|
2836
|
+
setIsProcessing(true);
|
|
2837
|
+
setTimeout(() => {
|
|
2838
|
+
try {
|
|
2839
|
+
const canvas = document.createElement("canvas");
|
|
2840
|
+
const ctx = canvas.getContext("2d");
|
|
2841
|
+
if (!ctx) return;
|
|
2842
|
+
canvas.width = image.width;
|
|
2843
|
+
canvas.height = image.height;
|
|
2844
|
+
ctx.drawImage(image, 0, 0);
|
|
2845
|
+
const imageData = ctx.getImageData(0, 0, image.width, image.height);
|
|
2846
|
+
const pixels = imageData.data;
|
|
2847
|
+
const burnMap = new Float32Array(image.width * image.height);
|
|
2848
|
+
const rawValues = [];
|
|
2849
|
+
for (let i = 0; i < pixels.length; i += 4) {
|
|
2850
|
+
const pixelIndex = i / 4;
|
|
2851
|
+
const [r, g, b] = [pixels[i], pixels[i + 1], pixels[i + 2]];
|
|
2852
|
+
let burnValue = 0;
|
|
2853
|
+
if (burnColorOrder === "vibgyor") {
|
|
2854
|
+
const [h, s] = rgbToHsv(r, g, b);
|
|
2855
|
+
burnValue = hueToVibgyorOrder(h) * s + 0.5 * (1 - s);
|
|
2856
|
+
} else if (burnColorOrder === "luminance") {
|
|
2857
|
+
burnValue = getLuminance(r, g, b) / 255;
|
|
2858
|
+
} else {
|
|
2859
|
+
burnValue = pixelIndex * 2654435761 % 2147483648 / 2147483648;
|
|
2860
|
+
}
|
|
2861
|
+
rawValues.push(burnValue);
|
|
2862
|
+
}
|
|
2863
|
+
const numBuckets = 200;
|
|
2864
|
+
const buckets = new Array(numBuckets).fill(0);
|
|
2865
|
+
rawValues.forEach((val) => {
|
|
2866
|
+
buckets[Math.min(Math.floor(val * numBuckets), numBuckets - 1)]++;
|
|
2867
|
+
});
|
|
2868
|
+
const cumulative = new Array(numBuckets);
|
|
2869
|
+
cumulative[0] = buckets[0];
|
|
2870
|
+
for (let i = 1; i < numBuckets; i++) {
|
|
2871
|
+
cumulative[i] = cumulative[i - 1] + buckets[i];
|
|
2872
|
+
}
|
|
2873
|
+
rawValues.forEach((val, idx) => {
|
|
2874
|
+
const bucket = Math.min(Math.floor(val * numBuckets), numBuckets - 1);
|
|
2875
|
+
burnMap[idx] = cumulative[bucket] / (image.width * image.height);
|
|
2876
|
+
});
|
|
2877
|
+
if (revealMode === "direction" || revealMode === "combined") {
|
|
2878
|
+
for (let idx = 0; idx < image.width * image.height; idx++) {
|
|
2879
|
+
const x = idx % image.width;
|
|
2880
|
+
const y = Math.floor(idx / image.width);
|
|
2881
|
+
let directionValue = 0;
|
|
2882
|
+
if (direction === "horizontal") {
|
|
2883
|
+
const layer = Math.floor(y / (image.height / directionLayers));
|
|
2884
|
+
const isReverse = layer % 2 === 1;
|
|
2885
|
+
const xNorm = isReverse ? (image.width - x) / image.width : x / image.width;
|
|
2886
|
+
directionValue = layer / directionLayers + xNorm / directionLayers;
|
|
2887
|
+
} else if (direction === "vertical") {
|
|
2888
|
+
const layer = Math.floor(x / (image.width / directionLayers));
|
|
2889
|
+
const isReverse = layer % 2 === 1;
|
|
2890
|
+
const yNorm = isReverse ? (image.height - y) / image.height : y / image.height;
|
|
2891
|
+
directionValue = layer / directionLayers + yNorm / directionLayers;
|
|
2892
|
+
} else if (direction === "top-to-bottom") {
|
|
2893
|
+
directionValue = y / image.height;
|
|
2894
|
+
} else if (direction === "diagonal-down") {
|
|
2895
|
+
directionValue = (x + y) / (image.width + image.height);
|
|
2896
|
+
} else {
|
|
2897
|
+
directionValue = (x + (image.height - y)) / (image.width + image.height);
|
|
2898
|
+
}
|
|
2899
|
+
burnMap[idx] = revealMode === "combined" ? burnMap[idx] * 0.6 + directionValue * 0.4 : directionValue;
|
|
2900
|
+
}
|
|
2901
|
+
let minVal = burnMap[0];
|
|
2902
|
+
let maxVal = burnMap[0];
|
|
2903
|
+
for (let i = 1; i < burnMap.length; i++) {
|
|
2904
|
+
if (burnMap[i] < minVal) minVal = burnMap[i];
|
|
2905
|
+
if (burnMap[i] > maxVal) maxVal = burnMap[i];
|
|
2906
|
+
}
|
|
2907
|
+
const range = maxVal - minVal;
|
|
2908
|
+
if (range > 0) {
|
|
2909
|
+
for (let i = 0; i < burnMap.length; i++) {
|
|
2910
|
+
burnMap[i] = (burnMap[i] - minVal) / range;
|
|
2911
|
+
}
|
|
2912
|
+
}
|
|
2913
|
+
}
|
|
2914
|
+
setPixelBurnMap(burnMap);
|
|
2915
|
+
burnMapGeneratedRef.current = true;
|
|
2916
|
+
} finally {
|
|
2917
|
+
setIsProcessing(false);
|
|
2918
|
+
}
|
|
2919
|
+
}, 0);
|
|
2920
|
+
}, [
|
|
2921
|
+
image,
|
|
2922
|
+
burnColorOrder,
|
|
2923
|
+
revealMode,
|
|
2924
|
+
direction,
|
|
2925
|
+
directionLayers
|
|
2926
|
+
]);
|
|
2927
|
+
useEffect2(() => {
|
|
2928
|
+
if (!canvasRef.current || !image || !pixelBurnMap) return;
|
|
2929
|
+
const context = canvasRef.current.getContext("2d");
|
|
2930
|
+
if (!context) return;
|
|
2931
|
+
context.canvas.width = width;
|
|
2932
|
+
context.canvas.height = height;
|
|
2933
|
+
context.fillStyle = backgroundColor;
|
|
2934
|
+
context.fillRect(0, 0, width, height);
|
|
2935
|
+
const progress = Math.min(frame / revealDurationInFrames, 1);
|
|
2936
|
+
if (progress >= 1) {
|
|
2937
|
+
let sx2 = 0, sy2 = 0, sWidth2 = image.width, sHeight2 = image.height;
|
|
2938
|
+
if (fit === "cover") {
|
|
2939
|
+
const imgAspect = image.width / image.height;
|
|
2940
|
+
const canvasAspect = width / height;
|
|
2941
|
+
if (imgAspect > canvasAspect) {
|
|
2942
|
+
sWidth2 = image.height * canvasAspect;
|
|
2943
|
+
sx2 = (image.width - sWidth2) / 2;
|
|
2944
|
+
} else {
|
|
2945
|
+
sHeight2 = image.width / canvasAspect;
|
|
2946
|
+
sy2 = (image.height - sHeight2) / 2;
|
|
2947
|
+
}
|
|
2948
|
+
}
|
|
2949
|
+
context.drawImage(image, sx2, sy2, sWidth2, sHeight2, 0, 0, width, height);
|
|
2950
|
+
return;
|
|
2951
|
+
}
|
|
2952
|
+
const tempCanvas = document.createElement("canvas");
|
|
2953
|
+
tempCanvas.width = image.width;
|
|
2954
|
+
tempCanvas.height = image.height;
|
|
2955
|
+
const tempCtx = tempCanvas.getContext("2d");
|
|
2956
|
+
if (!tempCtx) return;
|
|
2957
|
+
tempCtx.drawImage(image, 0, 0);
|
|
2958
|
+
const imageData = tempCtx.getImageData(0, 0, image.width, image.height);
|
|
2959
|
+
const pixels = imageData.data;
|
|
2960
|
+
const transitionWidth = Math.max(
|
|
2961
|
+
0.02,
|
|
2962
|
+
Math.min(0.15, 3 / (revealDurationInFrames / 100))
|
|
2963
|
+
);
|
|
2964
|
+
for (let i = 0; i < pixels.length; i += 4) {
|
|
2965
|
+
const pixelIndex = i / 4;
|
|
2966
|
+
const burnProgress = (progress - pixelBurnMap[pixelIndex]) / transitionWidth;
|
|
2967
|
+
pixels[i + 3] = Math.floor(
|
|
2968
|
+
pixels[i + 3] * Math.max(0, Math.min(1, burnProgress))
|
|
2969
|
+
);
|
|
2970
|
+
}
|
|
2971
|
+
tempCtx.putImageData(imageData, 0, 0);
|
|
2972
|
+
let sx = 0, sy = 0, sWidth = image.width, sHeight = image.height;
|
|
2973
|
+
if (fit === "cover") {
|
|
2974
|
+
const imgAspect = image.width / image.height;
|
|
2975
|
+
const canvasAspect = width / height;
|
|
2976
|
+
if (imgAspect > canvasAspect) {
|
|
2977
|
+
sWidth = image.height * canvasAspect;
|
|
2978
|
+
sx = (image.width - sWidth) / 2;
|
|
2979
|
+
} else {
|
|
2980
|
+
sHeight = image.width / canvasAspect;
|
|
2981
|
+
sy = (image.height - sHeight) / 2;
|
|
2982
|
+
}
|
|
2983
|
+
}
|
|
2984
|
+
context.drawImage(tempCanvas, sx, sy, sWidth, sHeight, 0, 0, width, height);
|
|
2985
|
+
}, [
|
|
2986
|
+
frame,
|
|
2987
|
+
image,
|
|
2988
|
+
width,
|
|
2989
|
+
height,
|
|
2990
|
+
pixelBurnMap,
|
|
2991
|
+
revealDurationInFrames,
|
|
2992
|
+
fit,
|
|
2993
|
+
backgroundColor
|
|
2994
|
+
]);
|
|
2995
|
+
return /* @__PURE__ */ React16.createElement(Atom, { ref: canvasRef, data: { className: "w-full h-full" }, id });
|
|
2996
|
+
};
|
|
2997
|
+
|
|
2998
|
+
// src/components/effects/CanvasGlitchEffect.tsx
|
|
2999
|
+
import React17, { useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
|
|
3000
|
+
import { useCurrentFrame as useCurrentFrame6, useVideoConfig as useVideoConfig7 } from "remotion";
|
|
3001
|
+
import { z as z4 } from "zod";
|
|
3002
|
+
var CanvasGlitchEffectProps = z4.object({
|
|
3003
|
+
imageUrl: z4.string().url(),
|
|
3004
|
+
durationInFrames: z4.number().min(1),
|
|
3005
|
+
fit: z4.enum(["cover", "contain"]).default("cover"),
|
|
3006
|
+
backgroundColor: z4.string().default("rgba(0,0,0,0)"),
|
|
3007
|
+
glitchType: z4.enum(["rgb-shift", "slice", "corrupt", "static", "scan"]).default("rgb-shift"),
|
|
3008
|
+
intensity: z4.number().default(10).describe("Intensity of glitch effect"),
|
|
3009
|
+
frequency: z4.number().default(0.3).describe("How often glitches occur (0-1)"),
|
|
3010
|
+
continuous: z4.boolean().default(false).describe("Continuous glitch vs periodic"),
|
|
3011
|
+
glitchStartFrame: z4.number().default(0).describe("Frame to start glitching"),
|
|
3012
|
+
glitchEndFrame: z4.number().default(-1).describe("Frame to end glitching (-1 = duration)")
|
|
3013
|
+
});
|
|
3014
|
+
var CanvasGlitchEffect = ({ data, id }) => {
|
|
3015
|
+
const {
|
|
3016
|
+
imageUrl,
|
|
3017
|
+
durationInFrames,
|
|
3018
|
+
fit,
|
|
3019
|
+
backgroundColor,
|
|
3020
|
+
glitchType,
|
|
3021
|
+
intensity,
|
|
3022
|
+
frequency,
|
|
3023
|
+
continuous,
|
|
3024
|
+
glitchStartFrame,
|
|
3025
|
+
glitchEndFrame
|
|
3026
|
+
} = data;
|
|
3027
|
+
const frame = useCurrentFrame6();
|
|
3028
|
+
const { width, height } = useVideoConfig7();
|
|
3029
|
+
const canvasRef = useRef3(null);
|
|
3030
|
+
const [image, setImage] = useState3(null);
|
|
3031
|
+
useEffect3(() => {
|
|
3032
|
+
const img = new window.Image();
|
|
3033
|
+
img.crossOrigin = "Anonymous";
|
|
3034
|
+
img.src = imageUrl;
|
|
3035
|
+
img.onload = () => setImage(img);
|
|
3036
|
+
}, [imageUrl]);
|
|
3037
|
+
useEffect3(() => {
|
|
3038
|
+
if (!canvasRef.current || !image) return;
|
|
3039
|
+
const context = canvasRef.current.getContext("2d");
|
|
3040
|
+
if (!context) return;
|
|
3041
|
+
context.canvas.width = width;
|
|
3042
|
+
context.canvas.height = height;
|
|
3043
|
+
context.fillStyle = backgroundColor;
|
|
3044
|
+
context.fillRect(0, 0, width, height);
|
|
3045
|
+
const endFrame = glitchEndFrame === -1 ? durationInFrames : glitchEndFrame;
|
|
3046
|
+
const isInGlitchRange = frame >= glitchStartFrame && frame <= endFrame;
|
|
3047
|
+
const seed = Math.floor(frame / 3);
|
|
3048
|
+
const random = (seed * 9301 + 49297) % 233280 / 233280;
|
|
3049
|
+
const isGlitching = isInGlitchRange && (continuous || random < frequency);
|
|
3050
|
+
let sx = 0, sy = 0, sWidth = image.width, sHeight = image.height;
|
|
3051
|
+
if (fit === "cover") {
|
|
3052
|
+
const imgAspect = image.width / image.height;
|
|
3053
|
+
const canvasAspect = width / height;
|
|
3054
|
+
if (imgAspect > canvasAspect) {
|
|
3055
|
+
sWidth = image.height * canvasAspect;
|
|
3056
|
+
sx = (image.width - sWidth) / 2;
|
|
3057
|
+
} else {
|
|
3058
|
+
sHeight = image.width / canvasAspect;
|
|
3059
|
+
sy = (image.height - sHeight) / 2;
|
|
3060
|
+
}
|
|
3061
|
+
}
|
|
3062
|
+
if (!isGlitching) {
|
|
3063
|
+
context.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, width, height);
|
|
3064
|
+
return;
|
|
3065
|
+
}
|
|
3066
|
+
if (glitchType === "rgb-shift") {
|
|
3067
|
+
const tempCanvas = document.createElement("canvas");
|
|
3068
|
+
tempCanvas.width = image.width;
|
|
3069
|
+
tempCanvas.height = image.height;
|
|
3070
|
+
const tempCtx = tempCanvas.getContext("2d");
|
|
3071
|
+
if (!tempCtx) return;
|
|
3072
|
+
tempCtx.drawImage(image, 0, 0);
|
|
3073
|
+
const imageData = tempCtx.getImageData(0, 0, image.width, image.height);
|
|
3074
|
+
const pixels = imageData.data;
|
|
3075
|
+
const shift = intensity * (random * 2 - 1);
|
|
3076
|
+
const redData = tempCtx.createImageData(image.width, image.height);
|
|
3077
|
+
const greenData = tempCtx.createImageData(image.width, image.height);
|
|
3078
|
+
const blueData = tempCtx.createImageData(image.width, image.height);
|
|
3079
|
+
for (let i = 0; i < pixels.length; i += 4) {
|
|
3080
|
+
redData.data[i] = pixels[i];
|
|
3081
|
+
redData.data[i + 3] = pixels[i + 3];
|
|
3082
|
+
greenData.data[i + 1] = pixels[i + 1];
|
|
3083
|
+
greenData.data[i + 3] = pixels[i + 3];
|
|
3084
|
+
blueData.data[i + 2] = pixels[i + 2];
|
|
3085
|
+
blueData.data[i + 3] = pixels[i + 3];
|
|
3086
|
+
}
|
|
3087
|
+
context.save();
|
|
3088
|
+
context.globalCompositeOperation = "screen";
|
|
3089
|
+
tempCtx.putImageData(redData, 0, 0);
|
|
3090
|
+
context.drawImage(
|
|
3091
|
+
tempCanvas,
|
|
3092
|
+
sx + shift,
|
|
3093
|
+
sy,
|
|
3094
|
+
sWidth,
|
|
3095
|
+
sHeight,
|
|
3096
|
+
shift,
|
|
3097
|
+
0,
|
|
3098
|
+
width,
|
|
3099
|
+
height
|
|
3100
|
+
);
|
|
3101
|
+
tempCtx.putImageData(greenData, 0, 0);
|
|
3102
|
+
context.drawImage(
|
|
3103
|
+
tempCanvas,
|
|
3104
|
+
sx,
|
|
3105
|
+
sy,
|
|
3106
|
+
sWidth,
|
|
3107
|
+
sHeight,
|
|
3108
|
+
0,
|
|
3109
|
+
0,
|
|
3110
|
+
width,
|
|
3111
|
+
height
|
|
3112
|
+
);
|
|
3113
|
+
tempCtx.putImageData(blueData, 0, 0);
|
|
3114
|
+
context.drawImage(
|
|
3115
|
+
tempCanvas,
|
|
3116
|
+
sx - shift,
|
|
3117
|
+
sy,
|
|
3118
|
+
sWidth,
|
|
3119
|
+
sHeight,
|
|
3120
|
+
-shift,
|
|
3121
|
+
0,
|
|
3122
|
+
width,
|
|
3123
|
+
height
|
|
3124
|
+
);
|
|
3125
|
+
context.restore();
|
|
3126
|
+
} else if (glitchType === "slice") {
|
|
3127
|
+
const sliceCount = 20;
|
|
3128
|
+
const sliceHeight = height / sliceCount;
|
|
3129
|
+
for (let i = 0; i < sliceCount; i++) {
|
|
3130
|
+
const offset = (random * 2 - 1) * intensity * (i % 2 === 0 ? 1 : -1);
|
|
3131
|
+
const sy_slice = sy + sHeight / sliceCount * i;
|
|
3132
|
+
const dy = sliceHeight * i;
|
|
3133
|
+
context.drawImage(
|
|
3134
|
+
image,
|
|
3135
|
+
sx,
|
|
3136
|
+
sy_slice,
|
|
3137
|
+
sWidth,
|
|
3138
|
+
sHeight / sliceCount,
|
|
3139
|
+
offset,
|
|
3140
|
+
dy,
|
|
3141
|
+
width,
|
|
3142
|
+
sliceHeight
|
|
3143
|
+
);
|
|
3144
|
+
}
|
|
3145
|
+
} else if (glitchType === "corrupt") {
|
|
3146
|
+
context.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, width, height);
|
|
3147
|
+
const blockCount = Math.floor(intensity / 2);
|
|
3148
|
+
for (let i = 0; i < blockCount; i++) {
|
|
3149
|
+
const blockW = Math.random() * width * 0.3;
|
|
3150
|
+
const blockH = Math.random() * height * 0.2;
|
|
3151
|
+
const blockX = Math.random() * (width - blockW);
|
|
3152
|
+
const blockY = Math.random() * (height - blockH);
|
|
3153
|
+
const sourceX = Math.random() * (width - blockW);
|
|
3154
|
+
const sourceY = Math.random() * (height - blockH);
|
|
3155
|
+
try {
|
|
3156
|
+
const imgData = context.getImageData(
|
|
3157
|
+
sourceX,
|
|
3158
|
+
sourceY,
|
|
3159
|
+
blockW,
|
|
3160
|
+
blockH
|
|
3161
|
+
);
|
|
3162
|
+
context.putImageData(imgData, blockX, blockY);
|
|
3163
|
+
} catch (e) {
|
|
3164
|
+
}
|
|
3165
|
+
}
|
|
3166
|
+
} else if (glitchType === "static") {
|
|
3167
|
+
context.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, width, height);
|
|
3168
|
+
const imageData = context.getImageData(0, 0, width, height);
|
|
3169
|
+
const pixels = imageData.data;
|
|
3170
|
+
for (let i = 0; i < pixels.length; i += 4) {
|
|
3171
|
+
if (Math.random() < intensity / 100) {
|
|
3172
|
+
const noise = Math.random() * 255;
|
|
3173
|
+
pixels[i] = noise;
|
|
3174
|
+
pixels[i + 1] = noise;
|
|
3175
|
+
pixels[i + 2] = noise;
|
|
3176
|
+
}
|
|
3177
|
+
}
|
|
3178
|
+
context.putImageData(imageData, 0, 0);
|
|
3179
|
+
} else if (glitchType === "scan") {
|
|
3180
|
+
context.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, width, height);
|
|
3181
|
+
const scanY = frame * 5 % height;
|
|
3182
|
+
context.fillStyle = `rgba(255, 255, 255, ${intensity / 100})`;
|
|
3183
|
+
context.fillRect(0, scanY, width, 3);
|
|
3184
|
+
const distortY = Math.max(0, scanY - 10);
|
|
3185
|
+
const distortHeight = Math.min(20, height - distortY);
|
|
3186
|
+
if (distortHeight > 0) {
|
|
3187
|
+
try {
|
|
3188
|
+
const imgData = context.getImageData(
|
|
3189
|
+
0,
|
|
3190
|
+
distortY,
|
|
3191
|
+
width,
|
|
3192
|
+
distortHeight
|
|
3193
|
+
);
|
|
3194
|
+
const shiftAmount = intensity * (random * 2 - 1);
|
|
3195
|
+
context.putImageData(imgData, shiftAmount, distortY);
|
|
3196
|
+
} catch (e) {
|
|
3197
|
+
}
|
|
3198
|
+
}
|
|
3199
|
+
}
|
|
3200
|
+
}, [
|
|
3201
|
+
frame,
|
|
3202
|
+
image,
|
|
3203
|
+
width,
|
|
3204
|
+
height,
|
|
3205
|
+
durationInFrames,
|
|
3206
|
+
fit,
|
|
3207
|
+
backgroundColor,
|
|
3208
|
+
glitchType,
|
|
3209
|
+
intensity,
|
|
3210
|
+
frequency,
|
|
3211
|
+
continuous,
|
|
3212
|
+
glitchStartFrame,
|
|
3213
|
+
glitchEndFrame
|
|
3214
|
+
]);
|
|
3215
|
+
return /* @__PURE__ */ React17.createElement(Atom, { ref: canvasRef, data: { className: "w-full h-full" }, id });
|
|
3216
|
+
};
|
|
3217
|
+
|
|
3218
|
+
// src/components/effects/CanvasParticleEffect.tsx
|
|
3219
|
+
import React18, { useEffect as useEffect4, useRef as useRef4, useState as useState4 } from "react";
|
|
3220
|
+
import { useCurrentFrame as useCurrentFrame7, useVideoConfig as useVideoConfig8 } from "remotion";
|
|
3221
|
+
import { z as z5 } from "zod";
|
|
3222
|
+
var CanvasParticleEffectProps = z5.object({
|
|
3223
|
+
imageUrl: z5.string().url(),
|
|
3224
|
+
revealDurationInFrames: z5.number().min(1),
|
|
3225
|
+
fit: z5.enum(["cover", "contain"]).default("cover"),
|
|
3226
|
+
backgroundColor: z5.string().default("rgba(0,0,0,0)"),
|
|
3227
|
+
particleCount: z5.number().default(2e3).describe("Number of particles"),
|
|
3228
|
+
particleSize: z5.number().default(3).describe("Size of each particle"),
|
|
3229
|
+
particleEffect: z5.enum(["assemble", "disassemble", "explode", "pixelate"]).default("assemble"),
|
|
3230
|
+
assembleFrom: z5.enum(["center", "edges", "random", "bottom"]).default("random"),
|
|
3231
|
+
speed: z5.number().default(1).describe("Animation speed multiplier"),
|
|
3232
|
+
rotation: z5.boolean().default(false).describe("Add rotation to particles")
|
|
3233
|
+
});
|
|
3234
|
+
var CanvasParticleEffect = ({ data, id }) => {
|
|
3235
|
+
const {
|
|
3236
|
+
imageUrl,
|
|
3237
|
+
revealDurationInFrames,
|
|
3238
|
+
fit,
|
|
3239
|
+
backgroundColor,
|
|
3240
|
+
particleCount,
|
|
3241
|
+
particleSize,
|
|
3242
|
+
particleEffect,
|
|
3243
|
+
assembleFrom,
|
|
3244
|
+
speed,
|
|
3245
|
+
rotation
|
|
3246
|
+
} = data;
|
|
3247
|
+
const frame = useCurrentFrame7();
|
|
3248
|
+
const { width, height } = useVideoConfig8();
|
|
3249
|
+
const canvasRef = useRef4(null);
|
|
3250
|
+
const [image, setImage] = useState4(null);
|
|
3251
|
+
const [particles, setParticles] = useState4(null);
|
|
3252
|
+
useEffect4(() => {
|
|
3253
|
+
const img = new window.Image();
|
|
3254
|
+
img.crossOrigin = "Anonymous";
|
|
3255
|
+
img.src = imageUrl;
|
|
3256
|
+
img.onload = () => setImage(img);
|
|
3257
|
+
}, [imageUrl]);
|
|
3258
|
+
useEffect4(() => {
|
|
3259
|
+
if (!image) return;
|
|
3260
|
+
const canvas = document.createElement("canvas");
|
|
3261
|
+
const ctx = canvas.getContext("2d");
|
|
3262
|
+
if (!ctx) return;
|
|
3263
|
+
canvas.width = image.width;
|
|
3264
|
+
canvas.height = image.height;
|
|
3265
|
+
ctx.drawImage(image, 0, 0);
|
|
3266
|
+
const imageData = ctx.getImageData(0, 0, image.width, image.height);
|
|
3267
|
+
const pixels = imageData.data;
|
|
3268
|
+
const particleArray = [];
|
|
3269
|
+
const step = Math.floor(
|
|
3270
|
+
Math.sqrt(image.width * image.height / particleCount)
|
|
3271
|
+
);
|
|
3272
|
+
for (let y = 0; y < image.height; y += step) {
|
|
3273
|
+
for (let x = 0; x < image.width; x += step) {
|
|
3274
|
+
const i = (y * image.width + x) * 4;
|
|
3275
|
+
const [r, g, b, a] = [
|
|
3276
|
+
pixels[i],
|
|
3277
|
+
pixels[i + 1],
|
|
3278
|
+
pixels[i + 2],
|
|
3279
|
+
pixels[i + 3]
|
|
3280
|
+
];
|
|
3281
|
+
if (a > 128) {
|
|
3282
|
+
const targetX = x;
|
|
3283
|
+
const targetY = y;
|
|
3284
|
+
let startX = targetX, startY = targetY;
|
|
3285
|
+
if (particleEffect === "assemble") {
|
|
3286
|
+
if (assembleFrom === "center") {
|
|
3287
|
+
startX = image.width / 2;
|
|
3288
|
+
startY = image.height / 2;
|
|
3289
|
+
} else if (assembleFrom === "edges") {
|
|
3290
|
+
const edge = Math.floor(Math.random() * 4);
|
|
3291
|
+
if (edge === 0) {
|
|
3292
|
+
startX = 0;
|
|
3293
|
+
startY = Math.random() * image.height;
|
|
3294
|
+
} else if (edge === 1) {
|
|
3295
|
+
startX = image.width;
|
|
3296
|
+
startY = Math.random() * image.height;
|
|
3297
|
+
} else if (edge === 2) {
|
|
3298
|
+
startX = Math.random() * image.width;
|
|
3299
|
+
startY = 0;
|
|
3300
|
+
} else {
|
|
3301
|
+
startX = Math.random() * image.width;
|
|
3302
|
+
startY = image.height;
|
|
3303
|
+
}
|
|
3304
|
+
} else if (assembleFrom === "bottom") {
|
|
3305
|
+
startX = targetX;
|
|
3306
|
+
startY = image.height + Math.random() * 200;
|
|
3307
|
+
} else {
|
|
3308
|
+
startX = Math.random() * image.width;
|
|
3309
|
+
startY = Math.random() * image.height;
|
|
3310
|
+
}
|
|
3311
|
+
}
|
|
3312
|
+
particleArray.push({
|
|
3313
|
+
x: startX,
|
|
3314
|
+
y: startY,
|
|
3315
|
+
targetX,
|
|
3316
|
+
targetY,
|
|
3317
|
+
color: `rgba(${r},${g},${b},${a / 255})`,
|
|
3318
|
+
startX,
|
|
3319
|
+
startY,
|
|
3320
|
+
angle: Math.random() * Math.PI * 2
|
|
3321
|
+
});
|
|
3322
|
+
}
|
|
3323
|
+
}
|
|
3324
|
+
}
|
|
3325
|
+
setParticles(particleArray);
|
|
3326
|
+
}, [image, particleCount, particleEffect, assembleFrom]);
|
|
3327
|
+
useEffect4(() => {
|
|
3328
|
+
if (!canvasRef.current || !image || !particles) return;
|
|
3329
|
+
const context = canvasRef.current.getContext("2d");
|
|
3330
|
+
if (!context) return;
|
|
3331
|
+
context.canvas.width = width;
|
|
3332
|
+
context.canvas.height = height;
|
|
3333
|
+
context.fillStyle = backgroundColor;
|
|
3334
|
+
context.fillRect(0, 0, width, height);
|
|
3335
|
+
const progress = Math.min(frame / revealDurationInFrames * speed, 1);
|
|
3336
|
+
if (progress >= 1 && particleEffect === "assemble") {
|
|
3337
|
+
const scaleX2 = width / image.width;
|
|
3338
|
+
const scaleY2 = height / image.height;
|
|
3339
|
+
let scale2 = scaleX2;
|
|
3340
|
+
let offsetX2 = 0, offsetY2 = 0;
|
|
3341
|
+
if (fit === "cover") {
|
|
3342
|
+
scale2 = Math.max(scaleX2, scaleY2);
|
|
3343
|
+
offsetX2 = (width - image.width * scale2) / 2;
|
|
3344
|
+
offsetY2 = (height - image.height * scale2) / 2;
|
|
3345
|
+
} else {
|
|
3346
|
+
scale2 = Math.min(scaleX2, scaleY2);
|
|
3347
|
+
offsetX2 = (width - image.width * scale2) / 2;
|
|
3348
|
+
offsetY2 = (height - image.height * scale2) / 2;
|
|
3349
|
+
}
|
|
3350
|
+
context.save();
|
|
3351
|
+
context.translate(offsetX2, offsetY2);
|
|
3352
|
+
context.scale(scale2, scale2);
|
|
3353
|
+
context.drawImage(image, 0, 0);
|
|
3354
|
+
context.restore();
|
|
3355
|
+
return;
|
|
3356
|
+
}
|
|
3357
|
+
const easeProgress = particleEffect === "explode" ? progress * progress * (3 - 2 * progress) : 1 - Math.pow(1 - progress, 3);
|
|
3358
|
+
const scaleX = width / image.width;
|
|
3359
|
+
const scaleY = height / image.height;
|
|
3360
|
+
let scale = scaleX;
|
|
3361
|
+
let offsetX = 0, offsetY = 0;
|
|
3362
|
+
if (fit === "cover") {
|
|
3363
|
+
scale = Math.max(scaleX, scaleY);
|
|
3364
|
+
offsetX = (width - image.width * scale) / 2;
|
|
3365
|
+
offsetY = (height - image.height * scale) / 2;
|
|
3366
|
+
} else {
|
|
3367
|
+
scale = Math.min(scaleX, scaleY);
|
|
3368
|
+
offsetX = (width - image.width * scale) / 2;
|
|
3369
|
+
offsetY = (height - image.height * scale) / 2;
|
|
3370
|
+
}
|
|
3371
|
+
particles.forEach((particle) => {
|
|
3372
|
+
let x, y;
|
|
3373
|
+
if (particleEffect === "assemble") {
|
|
3374
|
+
x = particle.startX + (particle.targetX - particle.startX) * easeProgress;
|
|
3375
|
+
y = particle.startY + (particle.targetY - particle.startY) * easeProgress;
|
|
3376
|
+
} else if (particleEffect === "disassemble") {
|
|
3377
|
+
const reverseProgress = 1 - easeProgress;
|
|
3378
|
+
x = particle.targetX + (particle.startX - particle.targetX) * (1 - reverseProgress);
|
|
3379
|
+
y = particle.targetY + (particle.startY - particle.targetY) * (1 - reverseProgress);
|
|
3380
|
+
} else if (particleEffect === "explode") {
|
|
3381
|
+
const dx = particle.targetX - image.width / 2;
|
|
3382
|
+
const dy = particle.targetY - image.height / 2;
|
|
3383
|
+
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
3384
|
+
const explosionDist = dist * easeProgress * 3;
|
|
3385
|
+
x = particle.targetX + dx / dist * explosionDist;
|
|
3386
|
+
y = particle.targetY + dy / dist * explosionDist;
|
|
3387
|
+
} else {
|
|
3388
|
+
x = particle.targetX;
|
|
3389
|
+
y = particle.targetY;
|
|
3390
|
+
}
|
|
3391
|
+
const finalX = x * scale + offsetX;
|
|
3392
|
+
const finalY = y * scale + offsetY;
|
|
3393
|
+
context.save();
|
|
3394
|
+
context.translate(finalX, finalY);
|
|
3395
|
+
if (rotation && particleEffect !== "pixelate") {
|
|
3396
|
+
context.rotate(particle.angle * easeProgress);
|
|
3397
|
+
}
|
|
3398
|
+
const size = particleEffect === "pixelate" ? particleSize * (1 + (1 - easeProgress) * 3) : particleSize;
|
|
3399
|
+
context.fillStyle = particle.color;
|
|
3400
|
+
context.fillRect(-size / 2, -size / 2, size, size);
|
|
3401
|
+
context.restore();
|
|
3402
|
+
});
|
|
3403
|
+
}, [
|
|
3404
|
+
frame,
|
|
3405
|
+
image,
|
|
3406
|
+
width,
|
|
3407
|
+
height,
|
|
3408
|
+
particles,
|
|
3409
|
+
revealDurationInFrames,
|
|
3410
|
+
fit,
|
|
3411
|
+
backgroundColor,
|
|
3412
|
+
particleSize,
|
|
3413
|
+
particleEffect,
|
|
3414
|
+
speed,
|
|
3415
|
+
rotation
|
|
3416
|
+
]);
|
|
3417
|
+
return /* @__PURE__ */ React18.createElement(Atom, { ref: canvasRef, data: { className: "w-full h-full" }, id });
|
|
3418
|
+
};
|
|
3419
|
+
|
|
3420
|
+
// src/components/effects/GenericPresets.ts
|
|
3421
|
+
var fadeInPreset = [
|
|
3422
|
+
{ key: "opacity", val: 0, prog: 0 },
|
|
3423
|
+
{ key: "opacity", val: 1, prog: 1 }
|
|
3424
|
+
];
|
|
3425
|
+
var fadeOutPreset = [
|
|
3426
|
+
{ key: "opacity", val: 1, prog: 0 },
|
|
3427
|
+
{ key: "opacity", val: 0, prog: 1 }
|
|
3428
|
+
];
|
|
3429
|
+
var scaleInPreset = [
|
|
3430
|
+
{ key: "scale", val: 0, prog: 0 },
|
|
3431
|
+
{ key: "scale", val: 1, prog: 1 }
|
|
3432
|
+
];
|
|
3433
|
+
var scaleOutPreset = [
|
|
3434
|
+
{ key: "scale", val: 1, prog: 0 },
|
|
3435
|
+
{ key: "scale", val: 0, prog: 1 }
|
|
3436
|
+
];
|
|
3437
|
+
var slideInLeftPreset = [
|
|
3438
|
+
{ key: "translateX", val: -100, prog: 0 },
|
|
3439
|
+
{ key: "translateX", val: 0, prog: 1 }
|
|
3440
|
+
];
|
|
3441
|
+
var slideInRightPreset = [
|
|
3442
|
+
{ key: "translateX", val: 100, prog: 0 },
|
|
3443
|
+
{ key: "translateX", val: 0, prog: 1 }
|
|
3444
|
+
];
|
|
3445
|
+
var slideInTopPreset = [
|
|
3446
|
+
{ key: "translateY", val: -100, prog: 0 },
|
|
3447
|
+
{ key: "translateY", val: 0, prog: 1 }
|
|
3448
|
+
];
|
|
3449
|
+
var slideInBottomPreset = [
|
|
3450
|
+
{ key: "translateY", val: 100, prog: 0 },
|
|
3451
|
+
{ key: "translateY", val: 0, prog: 1 }
|
|
3452
|
+
];
|
|
3453
|
+
var bouncePreset = [
|
|
3454
|
+
{ key: "scale", val: 0, prog: 0 },
|
|
3455
|
+
{ key: "scale", val: 1.2, prog: 0.6 },
|
|
3456
|
+
{ key: "scale", val: 1, prog: 1 }
|
|
3457
|
+
];
|
|
3458
|
+
var pulsePreset = [
|
|
3459
|
+
{ key: "scale", val: 1, prog: 0 },
|
|
3460
|
+
{ key: "scale", val: 1.1, prog: 0.5 },
|
|
3461
|
+
{ key: "scale", val: 1, prog: 1 }
|
|
3462
|
+
];
|
|
3463
|
+
var rotateInPreset = [
|
|
3464
|
+
{ key: "rotate", val: -180, prog: 0 },
|
|
3465
|
+
{ key: "rotate", val: 0, prog: 1 }
|
|
3466
|
+
];
|
|
3467
|
+
var blurInPreset = [
|
|
3468
|
+
{ key: "blur", val: 10, prog: 0 },
|
|
3469
|
+
{ key: "blur", val: 0, prog: 1 }
|
|
3470
|
+
];
|
|
3471
|
+
var fadeInScalePreset = [
|
|
3472
|
+
{ key: "opacity", val: 0, prog: 0 },
|
|
3473
|
+
{ key: "opacity", val: 1, prog: 1 },
|
|
3474
|
+
{ key: "scale", val: 0.8, prog: 0 },
|
|
3475
|
+
{ key: "scale", val: 1, prog: 1 }
|
|
3476
|
+
];
|
|
3477
|
+
var slideInFadePreset = [
|
|
3478
|
+
{ key: "translateX", val: -50, prog: 0 },
|
|
3479
|
+
{ key: "translateX", val: 0, prog: 1 },
|
|
3480
|
+
{ key: "opacity", val: 0, prog: 0 },
|
|
3481
|
+
{ key: "opacity", val: 1, prog: 1 }
|
|
3482
|
+
];
|
|
3483
|
+
var slideInLeftStringPreset = [
|
|
3484
|
+
{ key: "translateX", val: "-100px", prog: 0 },
|
|
3485
|
+
{ key: "translateX", val: "0px", prog: 1 }
|
|
3486
|
+
];
|
|
3487
|
+
var slideInRightStringPreset = [
|
|
3488
|
+
{ key: "translateX", val: "100px", prog: 0 },
|
|
3489
|
+
{ key: "translateX", val: "0px", prog: 1 }
|
|
3490
|
+
];
|
|
3491
|
+
var slideInTopStringPreset = [
|
|
3492
|
+
{ key: "translateY", val: "-100px", prog: 0 },
|
|
3493
|
+
{ key: "translateY", val: "0px", prog: 1 }
|
|
3494
|
+
];
|
|
3495
|
+
var slideInBottomStringPreset = [
|
|
3496
|
+
{ key: "translateY", val: "100px", prog: 0 },
|
|
3497
|
+
{ key: "translateY", val: "0px", prog: 1 }
|
|
3498
|
+
];
|
|
3499
|
+
var rotateInStringPreset = [
|
|
3500
|
+
{ key: "rotate", val: "-180deg", prog: 0 },
|
|
3501
|
+
{ key: "rotate", val: "0deg", prog: 1 }
|
|
3502
|
+
];
|
|
3503
|
+
var blurInStringPreset = [
|
|
3504
|
+
{ key: "blur", val: "10px", prog: 0 },
|
|
3505
|
+
{ key: "blur", val: "0px", prog: 1 }
|
|
3506
|
+
];
|
|
3507
|
+
var scaleInStringPreset = [
|
|
3508
|
+
{ key: "scale", val: 0, prog: 0 },
|
|
3509
|
+
{ key: "scale", val: 1, prog: 1 }
|
|
3510
|
+
];
|
|
3511
|
+
var slideInLeftResponsivePreset = [
|
|
3512
|
+
{ key: "translateX", val: "-50vw", prog: 0 },
|
|
3513
|
+
{ key: "translateX", val: "0vw", prog: 1 }
|
|
3514
|
+
];
|
|
3515
|
+
var slideInTopResponsivePreset = [
|
|
3516
|
+
{ key: "translateY", val: "-50vh", prog: 0 },
|
|
3517
|
+
{ key: "translateY", val: "0vh", prog: 1 }
|
|
3518
|
+
];
|
|
3519
|
+
var backgroundColorPreset = [
|
|
3520
|
+
{ key: "backgroundColor", val: "#ff0000", prog: 0 },
|
|
3521
|
+
{ key: "backgroundColor", val: "#0000ff", prog: 1 }
|
|
3522
|
+
];
|
|
3523
|
+
var borderRadiusPreset = [
|
|
3524
|
+
{ key: "borderRadius", val: "0px", prog: 0 },
|
|
3525
|
+
{ key: "borderRadius", val: "50px", prog: 1 }
|
|
3526
|
+
];
|
|
3527
|
+
var boxShadowPreset = [
|
|
3528
|
+
{ key: "boxShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
|
|
3529
|
+
{ key: "boxShadow", val: "10px 10px 20px rgba(0,0,0,0.5)", prog: 1 }
|
|
3530
|
+
];
|
|
3531
|
+
var fontSizePreset = [
|
|
3532
|
+
{ key: "fontSize", val: "12px", prog: 0 },
|
|
3533
|
+
{ key: "fontSize", val: "24px", prog: 1 }
|
|
3534
|
+
];
|
|
3535
|
+
var letterSpacingPreset = [
|
|
3536
|
+
{ key: "letterSpacing", val: "0px", prog: 0 },
|
|
3537
|
+
{ key: "letterSpacing", val: "5px", prog: 1 }
|
|
3538
|
+
];
|
|
3539
|
+
var lineHeightPreset = [
|
|
3540
|
+
{ key: "lineHeight", val: "1", prog: 0 },
|
|
3541
|
+
{ key: "lineHeight", val: "2", prog: 1 }
|
|
3542
|
+
];
|
|
3543
|
+
var textShadowPreset = [
|
|
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 widthPreset = [
|
|
3548
|
+
{ key: "width", val: "0px", prog: 0 },
|
|
3549
|
+
{ key: "width", val: "100%", prog: 1 }
|
|
3550
|
+
];
|
|
3551
|
+
var heightPreset = [
|
|
3552
|
+
{ key: "height", val: "0px", prog: 0 },
|
|
3553
|
+
{ key: "height", val: "100%", prog: 1 }
|
|
3554
|
+
];
|
|
3555
|
+
var marginPreset = [
|
|
3556
|
+
{ key: "margin", val: "0px", prog: 0 },
|
|
3557
|
+
{ key: "margin", val: "20px", prog: 1 }
|
|
3558
|
+
];
|
|
3559
|
+
var paddingPreset = [
|
|
3560
|
+
{ key: "padding", val: "0px", prog: 0 },
|
|
3561
|
+
{ key: "padding", val: "20px", prog: 1 }
|
|
3562
|
+
];
|
|
3563
|
+
var morphingCardPreset = [
|
|
3564
|
+
{ key: "borderRadius", val: "0px", prog: 0 },
|
|
3565
|
+
{ key: "borderRadius", val: "20px", prog: 0.5 },
|
|
3566
|
+
{ key: "borderRadius", val: "50px", prog: 1 },
|
|
3567
|
+
{ key: "boxShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
|
|
3568
|
+
{ key: "boxShadow", val: "0px 10px 30px rgba(0,0,0,0.3)", prog: 1 },
|
|
3569
|
+
{ key: "backgroundColor", val: "#ffffff", prog: 0 },
|
|
3570
|
+
{ key: "backgroundColor", val: "#f0f0f0", prog: 1 }
|
|
3571
|
+
];
|
|
3572
|
+
var textRevealPreset = [
|
|
3573
|
+
{ key: "opacity", val: 0, prog: 0 },
|
|
3574
|
+
{ key: "opacity", val: 1, prog: 1 },
|
|
3575
|
+
{ key: "letterSpacing", val: "10px", prog: 0 },
|
|
3576
|
+
{ key: "letterSpacing", val: "0px", prog: 1 },
|
|
3577
|
+
{ key: "textShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
|
|
3578
|
+
{ key: "textShadow", val: "2px 2px 4px rgba(0,0,0,0.5)", prog: 1 }
|
|
3579
|
+
];
|
|
3580
|
+
var GenericEffectPresets = {
|
|
3581
|
+
fadeInPreset,
|
|
3582
|
+
fadeOutPreset,
|
|
3583
|
+
scaleInPreset,
|
|
3584
|
+
scaleOutPreset,
|
|
3585
|
+
slideInLeftPreset,
|
|
3586
|
+
slideInRightPreset,
|
|
3587
|
+
slideInTopPreset,
|
|
3588
|
+
slideInBottomPreset,
|
|
3589
|
+
bouncePreset,
|
|
3590
|
+
pulsePreset,
|
|
3591
|
+
rotateInPreset,
|
|
3592
|
+
blurInPreset,
|
|
3593
|
+
fadeInScalePreset,
|
|
3594
|
+
slideInFadePreset,
|
|
3595
|
+
// String-based presets
|
|
3596
|
+
slideInLeftStringPreset,
|
|
3597
|
+
slideInRightStringPreset,
|
|
3598
|
+
slideInTopStringPreset,
|
|
3599
|
+
slideInBottomStringPreset,
|
|
3600
|
+
rotateInStringPreset,
|
|
3601
|
+
blurInStringPreset,
|
|
3602
|
+
scaleInStringPreset,
|
|
3603
|
+
slideInLeftResponsivePreset,
|
|
3604
|
+
slideInTopResponsivePreset,
|
|
3605
|
+
// Custom CSS property presets
|
|
3606
|
+
backgroundColorPreset,
|
|
3607
|
+
borderRadiusPreset,
|
|
3608
|
+
boxShadowPreset,
|
|
3609
|
+
fontSizePreset,
|
|
3610
|
+
letterSpacingPreset,
|
|
3611
|
+
lineHeightPreset,
|
|
3612
|
+
textShadowPreset,
|
|
3613
|
+
widthPreset,
|
|
3614
|
+
heightPreset,
|
|
3615
|
+
marginPreset,
|
|
3616
|
+
paddingPreset,
|
|
3617
|
+
morphingCardPreset,
|
|
3618
|
+
textRevealPreset
|
|
3619
|
+
};
|
|
3620
|
+
|
|
3621
|
+
// src/components/effects/index.ts
|
|
3622
|
+
registerEffect(config2.displayName, BlurEffect, config2);
|
|
1954
3623
|
registerEffect(config3.displayName, LoopEffect, config3);
|
|
1955
3624
|
registerEffect(config4.displayName, PanEffect, config4);
|
|
1956
3625
|
registerEffect(config5.displayName, ZoomEffect, config5);
|
|
@@ -1961,13 +3630,22 @@ registerEffect(
|
|
|
1961
3630
|
StretchEffect,
|
|
1962
3631
|
config7
|
|
1963
3632
|
);
|
|
3633
|
+
registerEffect(
|
|
3634
|
+
config8.displayName,
|
|
3635
|
+
WaveformEffect,
|
|
3636
|
+
config8
|
|
3637
|
+
);
|
|
3638
|
+
registerEffect("CanvasWipeReveal", CanvasWipeReveal);
|
|
3639
|
+
registerEffect("CanvasContentAwareReveal", CanvasContentAwareReveal);
|
|
3640
|
+
registerEffect("CanvasParticleEffect", CanvasParticleEffect);
|
|
3641
|
+
registerEffect("CanvasGlitchEffect", CanvasGlitchEffect);
|
|
1964
3642
|
|
|
1965
3643
|
// src/components/layouts/BaseLayout.tsx
|
|
1966
3644
|
var Layout = ({ id, children, data, context }) => {
|
|
1967
3645
|
const { containerProps = {}, childrenProps = [], repeatChildrenProps = {} } = data;
|
|
1968
3646
|
const overrideStyles = useAnimatedStyles(id);
|
|
1969
3647
|
const childrenArray = Children.toArray(children);
|
|
1970
|
-
const enhancedStyle =
|
|
3648
|
+
const enhancedStyle = useMemo9(
|
|
1971
3649
|
() => ({
|
|
1972
3650
|
...!context?.boundaries?.reset ? context?.boundaries : {},
|
|
1973
3651
|
...containerProps.style,
|
|
@@ -1981,7 +3659,7 @@ var Layout = ({ id, children, data, context }) => {
|
|
|
1981
3659
|
);
|
|
1982
3660
|
if (Object.keys(repeatChildrenProps).length <= 0 && childrenProps.length <= 0) {
|
|
1983
3661
|
if (data.isAbsoluteFill) {
|
|
1984
|
-
return /* @__PURE__ */
|
|
3662
|
+
return /* @__PURE__ */ React19.createElement(
|
|
1985
3663
|
AbsoluteFill3,
|
|
1986
3664
|
{
|
|
1987
3665
|
...containerProps,
|
|
@@ -1990,25 +3668,25 @@ var Layout = ({ id, children, data, context }) => {
|
|
|
1990
3668
|
childrenArray
|
|
1991
3669
|
);
|
|
1992
3670
|
}
|
|
1993
|
-
return /* @__PURE__ */
|
|
3671
|
+
return /* @__PURE__ */ React19.createElement(
|
|
1994
3672
|
"div",
|
|
1995
3673
|
{
|
|
1996
3674
|
id,
|
|
1997
3675
|
...containerProps,
|
|
1998
3676
|
style: enhancedStyle
|
|
1999
3677
|
},
|
|
2000
|
-
childrenArray.map((child, index) => /* @__PURE__ */
|
|
3678
|
+
childrenArray.map((child, index) => /* @__PURE__ */ React19.createElement(React19.Fragment, { key: index }, child))
|
|
2001
3679
|
);
|
|
2002
3680
|
}
|
|
2003
3681
|
if (data.isAbsoluteFill) {
|
|
2004
|
-
return /* @__PURE__ */
|
|
3682
|
+
return /* @__PURE__ */ React19.createElement(
|
|
2005
3683
|
AbsoluteFill3,
|
|
2006
3684
|
{
|
|
2007
3685
|
id,
|
|
2008
3686
|
...containerProps,
|
|
2009
3687
|
style: enhancedStyle
|
|
2010
3688
|
},
|
|
2011
|
-
childrenArray.map((child, index) => /* @__PURE__ */
|
|
3689
|
+
childrenArray.map((child, index) => /* @__PURE__ */ React19.createElement(
|
|
2012
3690
|
"div",
|
|
2013
3691
|
{
|
|
2014
3692
|
key: index,
|
|
@@ -2018,14 +3696,14 @@ var Layout = ({ id, children, data, context }) => {
|
|
|
2018
3696
|
))
|
|
2019
3697
|
);
|
|
2020
3698
|
}
|
|
2021
|
-
return /* @__PURE__ */
|
|
3699
|
+
return /* @__PURE__ */ React19.createElement(
|
|
2022
3700
|
"div",
|
|
2023
3701
|
{
|
|
2024
3702
|
id,
|
|
2025
3703
|
...containerProps,
|
|
2026
3704
|
style: enhancedStyle
|
|
2027
3705
|
},
|
|
2028
|
-
childrenArray.map((child, index) => /* @__PURE__ */
|
|
3706
|
+
childrenArray.map((child, index) => /* @__PURE__ */ React19.createElement(
|
|
2029
3707
|
"div",
|
|
2030
3708
|
{
|
|
2031
3709
|
key: index,
|
|
@@ -2035,7 +3713,7 @@ var Layout = ({ id, children, data, context }) => {
|
|
|
2035
3713
|
))
|
|
2036
3714
|
);
|
|
2037
3715
|
};
|
|
2038
|
-
var
|
|
3716
|
+
var config10 = {
|
|
2039
3717
|
displayName: "BaseLayout",
|
|
2040
3718
|
type: "layout",
|
|
2041
3719
|
isInnerSequence: false
|
|
@@ -2043,17 +3721,17 @@ var config8 = {
|
|
|
2043
3721
|
|
|
2044
3722
|
// src/components/layouts/index.ts
|
|
2045
3723
|
registerComponent(
|
|
2046
|
-
|
|
3724
|
+
config10.displayName,
|
|
2047
3725
|
Layout,
|
|
2048
3726
|
"layout",
|
|
2049
|
-
|
|
3727
|
+
config10
|
|
2050
3728
|
);
|
|
2051
3729
|
|
|
2052
3730
|
// src/components/atoms/ShapeAtom.tsx
|
|
2053
|
-
import
|
|
2054
|
-
import { Easing as Easing4, interpolate as interpolate4, useCurrentFrame as
|
|
2055
|
-
var
|
|
2056
|
-
const frame =
|
|
3731
|
+
import React20 from "react";
|
|
3732
|
+
import { Easing as Easing4, interpolate as interpolate4, useCurrentFrame as useCurrentFrame8 } from "remotion";
|
|
3733
|
+
var Atom2 = ({ data }) => {
|
|
3734
|
+
const frame = useCurrentFrame8();
|
|
2057
3735
|
const { shape, color, rotation, style } = data;
|
|
2058
3736
|
const rotationStyle = rotation ? {
|
|
2059
3737
|
transform: `rotate(${interpolate4(
|
|
@@ -2075,22 +3753,22 @@ var Atom = ({ data }) => {
|
|
|
2075
3753
|
};
|
|
2076
3754
|
switch (shape) {
|
|
2077
3755
|
case "circle":
|
|
2078
|
-
return /* @__PURE__ */
|
|
3756
|
+
return /* @__PURE__ */ React20.createElement("div", { style: { ...baseStyle, backgroundColor: color, borderRadius: "50%" } });
|
|
2079
3757
|
case "rectangle":
|
|
2080
|
-
return /* @__PURE__ */
|
|
3758
|
+
return /* @__PURE__ */ React20.createElement("div", { style: { ...baseStyle, backgroundColor: color } });
|
|
2081
3759
|
default:
|
|
2082
3760
|
return null;
|
|
2083
3761
|
}
|
|
2084
3762
|
};
|
|
2085
|
-
var
|
|
3763
|
+
var config11 = {
|
|
2086
3764
|
displayName: "ShapeAtom",
|
|
2087
3765
|
type: "atom",
|
|
2088
3766
|
isInnerSequence: false
|
|
2089
3767
|
};
|
|
2090
3768
|
|
|
2091
3769
|
// src/components/atoms/ImageAtom.tsx
|
|
2092
|
-
import
|
|
2093
|
-
import { continueRender, delayRender, Img, staticFile } from "remotion";
|
|
3770
|
+
import React21, { useMemo as useMemo10, useState as useState5, useEffect as useEffect5 } from "react";
|
|
3771
|
+
import { continueRender, delayRender, Img, staticFile as staticFile2 } from "remotion";
|
|
2094
3772
|
var CORS_PROXIES = [
|
|
2095
3773
|
"https://thingproxy.freeboard.io/fetch/",
|
|
2096
3774
|
"https://api.allorigins.win/raw?url=",
|
|
@@ -2100,11 +3778,11 @@ var getCorsProxyUrl = (url) => {
|
|
|
2100
3778
|
return `${CORS_PROXIES[0]}${encodeURIComponent(url)}`;
|
|
2101
3779
|
};
|
|
2102
3780
|
var useImageSource = (src, proxySrc) => {
|
|
2103
|
-
const [imageSource, setImageSource] =
|
|
2104
|
-
const [isLoading, setIsLoading] =
|
|
2105
|
-
const [hasError, setHasError] =
|
|
2106
|
-
const [handle] =
|
|
2107
|
-
|
|
3781
|
+
const [imageSource, setImageSource] = useState5(src);
|
|
3782
|
+
const [isLoading, setIsLoading] = useState5(false);
|
|
3783
|
+
const [hasError, setHasError] = useState5(false);
|
|
3784
|
+
const [handle] = useState5(() => delayRender("Loading image"));
|
|
3785
|
+
useEffect5(() => {
|
|
2108
3786
|
if (!src.startsWith("http")) {
|
|
2109
3787
|
setImageSource(src);
|
|
2110
3788
|
continueRender(handle);
|
|
@@ -2140,20 +3818,20 @@ var useImageSource = (src, proxySrc) => {
|
|
|
2140
3818
|
}, [src, proxySrc, handle]);
|
|
2141
3819
|
return { imageSource, isLoading, hasError };
|
|
2142
3820
|
};
|
|
2143
|
-
var
|
|
3821
|
+
var Atom3 = ({ data, id }) => {
|
|
2144
3822
|
const overrideStyles = useAnimatedStyles(id);
|
|
2145
3823
|
const { imageSource, isLoading, hasError } = useImageSource(data.src, data.proxySrc);
|
|
2146
|
-
const source =
|
|
3824
|
+
const source = useMemo10(() => {
|
|
2147
3825
|
if (data.src.startsWith("http")) {
|
|
2148
3826
|
return imageSource;
|
|
2149
3827
|
}
|
|
2150
|
-
return
|
|
3828
|
+
return staticFile2(data.src);
|
|
2151
3829
|
}, [data.src, imageSource]);
|
|
2152
|
-
const enhancedStyle =
|
|
3830
|
+
const enhancedStyle = useMemo10(() => ({
|
|
2153
3831
|
...data.style,
|
|
2154
3832
|
...overrideStyles
|
|
2155
3833
|
}), [data.style, overrideStyles, isLoading, hasError]);
|
|
2156
|
-
return /* @__PURE__ */
|
|
3834
|
+
return /* @__PURE__ */ React21.createElement(
|
|
2157
3835
|
Img,
|
|
2158
3836
|
{
|
|
2159
3837
|
className: data.className,
|
|
@@ -2167,18 +3845,18 @@ var Atom2 = ({ data, id }) => {
|
|
|
2167
3845
|
}
|
|
2168
3846
|
);
|
|
2169
3847
|
};
|
|
2170
|
-
var
|
|
3848
|
+
var config12 = {
|
|
2171
3849
|
displayName: "ImageAtom",
|
|
2172
3850
|
type: "atom",
|
|
2173
3851
|
isInnerSequence: false
|
|
2174
3852
|
};
|
|
2175
3853
|
|
|
2176
3854
|
// src/components/atoms/TextAtom.tsx
|
|
2177
|
-
import
|
|
3855
|
+
import React22, { useEffect as useEffect7, useMemo as useMemo11, useState as useState7 } from "react";
|
|
2178
3856
|
import { delayRender as delayRender3, continueRender as continueRender3 } from "remotion";
|
|
2179
3857
|
|
|
2180
3858
|
// src/hooks/useFontLoader.ts
|
|
2181
|
-
import { useState as
|
|
3859
|
+
import { useState as useState6, useEffect as useEffect6, useCallback } from "react";
|
|
2182
3860
|
import { delayRender as delayRender2, continueRender as continueRender2 } from "remotion";
|
|
2183
3861
|
|
|
2184
3862
|
// src/utils/fontUtils.ts
|
|
@@ -2320,7 +3998,7 @@ var getNormalizedFontName = (fontFamily) => {
|
|
|
2320
3998
|
|
|
2321
3999
|
// src/hooks/useFontLoader.ts
|
|
2322
4000
|
var useFontLoader = (options = {}) => {
|
|
2323
|
-
const [state, setState] =
|
|
4001
|
+
const [state, setState] = useState6({
|
|
2324
4002
|
loadedFonts: /* @__PURE__ */ new Map(),
|
|
2325
4003
|
loadingFonts: /* @__PURE__ */ new Set(),
|
|
2326
4004
|
errorFonts: /* @__PURE__ */ new Map()
|
|
@@ -2479,14 +4157,14 @@ var useFontLoader = (options = {}) => {
|
|
|
2479
4157
|
};
|
|
2480
4158
|
var useFont = (fontFamily, options = {}) => {
|
|
2481
4159
|
const { loadFont, isFontReady, getFontFamily, getFontError, ...rest } = useFontLoader(options);
|
|
2482
|
-
const [isLoaded, setIsLoaded] =
|
|
2483
|
-
const [error, setError] =
|
|
2484
|
-
const [renderHandle] =
|
|
4160
|
+
const [isLoaded, setIsLoaded] = useState6(false);
|
|
4161
|
+
const [error, setError] = useState6(null);
|
|
4162
|
+
const [renderHandle] = useState6(
|
|
2485
4163
|
() => delayRender2(`Loading font: ${fontFamily}`)
|
|
2486
4164
|
);
|
|
2487
4165
|
const initialFontFamily = getFontFamily(fontFamily, options) || `"${fontFamily}", sans-serif`;
|
|
2488
|
-
const [fontFamilyValue, setFontFamilyValue] =
|
|
2489
|
-
|
|
4166
|
+
const [fontFamilyValue, setFontFamilyValue] = useState6(initialFontFamily);
|
|
4167
|
+
useEffect6(() => {
|
|
2490
4168
|
const loadFontAsync = async () => {
|
|
2491
4169
|
try {
|
|
2492
4170
|
const cssValue = await loadFont(fontFamily, options);
|
|
@@ -2521,10 +4199,10 @@ var useFont = (fontFamily, options = {}) => {
|
|
|
2521
4199
|
};
|
|
2522
4200
|
|
|
2523
4201
|
// src/components/atoms/TextAtom.tsx
|
|
2524
|
-
var
|
|
4202
|
+
var Atom4 = ({ id, data }) => {
|
|
2525
4203
|
const overrideStyles = useAnimatedStyles(id);
|
|
2526
|
-
const [isFontLoading, setIsFontLoading] =
|
|
2527
|
-
const [renderHandle] =
|
|
4204
|
+
const [isFontLoading, setIsFontLoading] = useState7(false);
|
|
4205
|
+
const [renderHandle] = useState7(
|
|
2528
4206
|
() => delayRender3(`Loading font: ${data.font?.family}`)
|
|
2529
4207
|
);
|
|
2530
4208
|
const { isLoaded, error, isReady, fontFamily } = useFont(
|
|
@@ -2544,7 +4222,7 @@ var Atom3 = ({ id, data }) => {
|
|
|
2544
4222
|
}
|
|
2545
4223
|
}
|
|
2546
4224
|
);
|
|
2547
|
-
|
|
4225
|
+
useEffect7(() => {
|
|
2548
4226
|
if (data.font?.family) {
|
|
2549
4227
|
if (isReady || isLoaded) {
|
|
2550
4228
|
setIsFontLoading(false);
|
|
@@ -2553,7 +4231,7 @@ var Atom3 = ({ id, data }) => {
|
|
|
2553
4231
|
}
|
|
2554
4232
|
}
|
|
2555
4233
|
}, [data.font, isReady, isLoaded, error]);
|
|
2556
|
-
const enhancedStyle =
|
|
4234
|
+
const enhancedStyle = useMemo11(() => {
|
|
2557
4235
|
const baseStyle = {
|
|
2558
4236
|
fontFamily,
|
|
2559
4237
|
...data.style
|
|
@@ -2574,12 +4252,12 @@ var Atom3 = ({ id, data }) => {
|
|
|
2574
4252
|
};
|
|
2575
4253
|
}, [fontFamily, data.style, data.gradient, overrideStyles]);
|
|
2576
4254
|
if (isFontLoading && data.loadingState?.showLoadingIndicator) {
|
|
2577
|
-
return /* @__PURE__ */
|
|
4255
|
+
return /* @__PURE__ */ React22.createElement("div", { style: enhancedStyle, className: data.className }, /* @__PURE__ */ React22.createElement("span", { style: data.loadingState.loadingStyle }, data.loadingState.loadingText || "Loading..."));
|
|
2578
4256
|
}
|
|
2579
4257
|
if (error && data.errorState?.showErrorIndicator) {
|
|
2580
|
-
return /* @__PURE__ */
|
|
4258
|
+
return /* @__PURE__ */ React22.createElement("div", { style: enhancedStyle, className: data.className }, /* @__PURE__ */ React22.createElement("span", { style: data.errorState.errorStyle }, data.errorState.errorText || data.text));
|
|
2581
4259
|
}
|
|
2582
|
-
return /* @__PURE__ */
|
|
4260
|
+
return /* @__PURE__ */ React22.createElement(
|
|
2583
4261
|
"div",
|
|
2584
4262
|
{
|
|
2585
4263
|
style: enhancedStyle,
|
|
@@ -2592,59 +4270,59 @@ var Atom3 = ({ id, data }) => {
|
|
|
2592
4270
|
data.text
|
|
2593
4271
|
);
|
|
2594
4272
|
};
|
|
2595
|
-
var
|
|
4273
|
+
var config13 = {
|
|
2596
4274
|
displayName: "TextAtom",
|
|
2597
4275
|
type: "atom",
|
|
2598
4276
|
isInnerSequence: false
|
|
2599
4277
|
};
|
|
2600
4278
|
|
|
2601
4279
|
// src/components/atoms/VideoAtom.tsx
|
|
2602
|
-
import
|
|
2603
|
-
import { staticFile as
|
|
2604
|
-
import { z } from "zod";
|
|
2605
|
-
var VideoAtomDataProps =
|
|
2606
|
-
src:
|
|
4280
|
+
import React23, { useMemo as useMemo12 } from "react";
|
|
4281
|
+
import { staticFile as staticFile3, useCurrentFrame as useCurrentFrame9, useVideoConfig as useVideoConfig9, OffthreadVideo, Loop as Loop2 } from "remotion";
|
|
4282
|
+
import { z as z6 } from "zod";
|
|
4283
|
+
var VideoAtomDataProps = z6.object({
|
|
4284
|
+
src: z6.string(),
|
|
2607
4285
|
// Video source URL
|
|
2608
|
-
srcDuration:
|
|
4286
|
+
srcDuration: z6.number().optional(),
|
|
2609
4287
|
// Video duration in seconds (or to say it more accurately, each iteration duration in a loop))
|
|
2610
|
-
style:
|
|
4288
|
+
style: z6.record(z6.string(), z6.any()).optional(),
|
|
2611
4289
|
// CSS styles object
|
|
2612
|
-
containerClassName:
|
|
4290
|
+
containerClassName: z6.string().optional(),
|
|
2613
4291
|
// CSS class names
|
|
2614
|
-
className:
|
|
4292
|
+
className: z6.string().optional(),
|
|
2615
4293
|
// CSS class names
|
|
2616
|
-
startFrom:
|
|
4294
|
+
startFrom: z6.number().optional(),
|
|
2617
4295
|
// Start playback from this time (seconds)
|
|
2618
|
-
endAt:
|
|
4296
|
+
endAt: z6.number().optional(),
|
|
2619
4297
|
// End playback at this time (seconds)
|
|
2620
|
-
playbackRate:
|
|
4298
|
+
playbackRate: z6.number().optional(),
|
|
2621
4299
|
// Playback speed multiplier
|
|
2622
|
-
volume:
|
|
4300
|
+
volume: z6.number().optional(),
|
|
2623
4301
|
// Volume level (0-1)
|
|
2624
|
-
muted:
|
|
4302
|
+
muted: z6.boolean().optional(),
|
|
2625
4303
|
// Mute video audio
|
|
2626
|
-
loop:
|
|
4304
|
+
loop: z6.boolean().optional(),
|
|
2627
4305
|
// Whether to loop the video
|
|
2628
|
-
fit:
|
|
4306
|
+
fit: z6.enum(["contain", "cover", "fill", "none", "scale-down"]).optional()
|
|
2629
4307
|
// Object fit style
|
|
2630
4308
|
});
|
|
2631
|
-
var
|
|
2632
|
-
const { fps } =
|
|
4309
|
+
var Atom5 = ({ data, id, context }) => {
|
|
4310
|
+
const { fps } = useVideoConfig9();
|
|
2633
4311
|
const overrideStyles = useAnimatedStyles(id);
|
|
2634
|
-
const frame =
|
|
2635
|
-
const source =
|
|
4312
|
+
const frame = useCurrentFrame9();
|
|
4313
|
+
const source = useMemo12(() => {
|
|
2636
4314
|
if (data.src.startsWith("http")) {
|
|
2637
4315
|
return data.src;
|
|
2638
4316
|
}
|
|
2639
|
-
return
|
|
4317
|
+
return staticFile3(data.src);
|
|
2640
4318
|
}, [data.src]);
|
|
2641
|
-
const trimBefore =
|
|
4319
|
+
const trimBefore = useMemo12(() => {
|
|
2642
4320
|
return data.startFrom ? data.startFrom * fps : void 0;
|
|
2643
4321
|
}, [data.startFrom, fps]);
|
|
2644
|
-
const trimAfter =
|
|
4322
|
+
const trimAfter = useMemo12(() => {
|
|
2645
4323
|
return data.endAt ? data.endAt * fps : void 0;
|
|
2646
4324
|
}, [data.endAt, fps]);
|
|
2647
|
-
const videoComponent = /* @__PURE__ */
|
|
4325
|
+
const videoComponent = /* @__PURE__ */ React23.createElement(
|
|
2648
4326
|
OffthreadVideo,
|
|
2649
4327
|
{
|
|
2650
4328
|
className: data.className,
|
|
@@ -2657,7 +4335,7 @@ var Atom4 = ({ data, id, context }) => {
|
|
|
2657
4335
|
muted: data.muted
|
|
2658
4336
|
}
|
|
2659
4337
|
);
|
|
2660
|
-
const videoWithStyles = data.containerClassName ? videoComponent : /* @__PURE__ */
|
|
4338
|
+
const videoWithStyles = data.containerClassName ? videoComponent : /* @__PURE__ */ React23.createElement(
|
|
2661
4339
|
OffthreadVideo,
|
|
2662
4340
|
{
|
|
2663
4341
|
className: data.className,
|
|
@@ -2671,53 +4349,53 @@ var Atom4 = ({ data, id, context }) => {
|
|
|
2671
4349
|
}
|
|
2672
4350
|
);
|
|
2673
4351
|
if (data.loop) {
|
|
2674
|
-
return /* @__PURE__ */
|
|
4352
|
+
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);
|
|
2675
4353
|
}
|
|
2676
|
-
return data.containerClassName ? /* @__PURE__ */
|
|
4354
|
+
return data.containerClassName ? /* @__PURE__ */ React23.createElement("div", { className: data.containerClassName, style: overrideStyles }, videoComponent) : videoWithStyles;
|
|
2677
4355
|
};
|
|
2678
|
-
var
|
|
4356
|
+
var config14 = {
|
|
2679
4357
|
displayName: "VideoAtom",
|
|
2680
4358
|
type: "atom",
|
|
2681
4359
|
isInnerSequence: false
|
|
2682
4360
|
};
|
|
2683
4361
|
|
|
2684
4362
|
// src/components/atoms/AudioAtom.tsx
|
|
2685
|
-
import
|
|
2686
|
-
import { Audio, staticFile as
|
|
2687
|
-
import { z as
|
|
2688
|
-
var AudioAtomMutedRangeProps =
|
|
2689
|
-
type:
|
|
2690
|
-
values:
|
|
2691
|
-
start:
|
|
4363
|
+
import React24, { useMemo as useMemo13 } from "react";
|
|
4364
|
+
import { Audio, staticFile as staticFile4, useCurrentFrame as useCurrentFrame10, useVideoConfig as useVideoConfig10 } from "remotion";
|
|
4365
|
+
import { z as z7 } from "zod";
|
|
4366
|
+
var AudioAtomMutedRangeProps = z7.object({
|
|
4367
|
+
type: z7.literal("range"),
|
|
4368
|
+
values: z7.array(z7.object({
|
|
4369
|
+
start: z7.number(),
|
|
2692
4370
|
// Start time in seconds
|
|
2693
|
-
end:
|
|
4371
|
+
end: z7.number()
|
|
2694
4372
|
// End time in seconds
|
|
2695
4373
|
}))
|
|
2696
4374
|
});
|
|
2697
|
-
var AudioAtomMutedFullProps =
|
|
2698
|
-
type:
|
|
2699
|
-
value:
|
|
4375
|
+
var AudioAtomMutedFullProps = z7.object({
|
|
4376
|
+
type: z7.literal("full"),
|
|
4377
|
+
value: z7.boolean()
|
|
2700
4378
|
// true = muted, false = unmuted
|
|
2701
4379
|
});
|
|
2702
|
-
var AudioAtomDataProps =
|
|
2703
|
-
src:
|
|
4380
|
+
var AudioAtomDataProps = z7.object({
|
|
4381
|
+
src: z7.string(),
|
|
2704
4382
|
// Audio source URL
|
|
2705
|
-
startFrom:
|
|
4383
|
+
startFrom: z7.number().optional(),
|
|
2706
4384
|
// Start playback from this time (seconds)
|
|
2707
|
-
endAt:
|
|
4385
|
+
endAt: z7.number().optional(),
|
|
2708
4386
|
// End playback at this time (seconds)
|
|
2709
|
-
volume:
|
|
4387
|
+
volume: z7.number().optional(),
|
|
2710
4388
|
// Volume level (0-1)
|
|
2711
|
-
playbackRate:
|
|
4389
|
+
playbackRate: z7.number().optional(),
|
|
2712
4390
|
// Playback speed multiplier
|
|
2713
|
-
muted:
|
|
4391
|
+
muted: z7.union([AudioAtomMutedFullProps, AudioAtomMutedRangeProps]).optional()
|
|
2714
4392
|
// Mute configuration
|
|
2715
4393
|
});
|
|
2716
|
-
var
|
|
2717
|
-
const { fps } =
|
|
4394
|
+
var Atom6 = ({ data }) => {
|
|
4395
|
+
const { fps } = useVideoConfig10();
|
|
2718
4396
|
const { muted } = data;
|
|
2719
|
-
const frame =
|
|
2720
|
-
const isMuted =
|
|
4397
|
+
const frame = useCurrentFrame10();
|
|
4398
|
+
const isMuted = useMemo13(() => {
|
|
2721
4399
|
if (muted?.type === "full") {
|
|
2722
4400
|
return muted.value;
|
|
2723
4401
|
}
|
|
@@ -2728,15 +4406,15 @@ var Atom5 = ({ data }) => {
|
|
|
2728
4406
|
}
|
|
2729
4407
|
return false;
|
|
2730
4408
|
}, [muted, frame, fps]);
|
|
2731
|
-
const source =
|
|
4409
|
+
const source = useMemo13(() => {
|
|
2732
4410
|
if (data.src.startsWith("http")) {
|
|
2733
4411
|
return data.src;
|
|
2734
4412
|
}
|
|
2735
|
-
return
|
|
4413
|
+
return staticFile4(data.src);
|
|
2736
4414
|
}, [data.src]);
|
|
2737
4415
|
return (
|
|
2738
4416
|
// @ts-ignore
|
|
2739
|
-
/* @__PURE__ */
|
|
4417
|
+
/* @__PURE__ */ React24.createElement(
|
|
2740
4418
|
Audio,
|
|
2741
4419
|
{
|
|
2742
4420
|
src: source,
|
|
@@ -2749,37 +4427,37 @@ var Atom5 = ({ data }) => {
|
|
|
2749
4427
|
)
|
|
2750
4428
|
);
|
|
2751
4429
|
};
|
|
2752
|
-
var
|
|
4430
|
+
var config15 = {
|
|
2753
4431
|
displayName: "AudioAtom",
|
|
2754
4432
|
type: "atom",
|
|
2755
4433
|
isInnerSequence: false
|
|
2756
4434
|
};
|
|
2757
4435
|
|
|
2758
4436
|
// src/components/atoms/LottieAtom.tsx
|
|
2759
|
-
import
|
|
2760
|
-
import { continueRender as continueRender4, delayRender as delayRender5, staticFile as
|
|
4437
|
+
import React25, { useMemo as useMemo14, useState as useState8, useEffect as useEffect8 } from "react";
|
|
4438
|
+
import { continueRender as continueRender4, delayRender as delayRender5, staticFile as staticFile5, useCurrentFrame as useCurrentFrame11, useVideoConfig as useVideoConfig11 } from "remotion";
|
|
2761
4439
|
import { Lottie } from "@remotion/lottie";
|
|
2762
|
-
import { z as
|
|
2763
|
-
var LottieAtomDataProps =
|
|
2764
|
-
src:
|
|
4440
|
+
import { z as z8 } from "zod";
|
|
4441
|
+
var LottieAtomDataProps = z8.object({
|
|
4442
|
+
src: z8.string(),
|
|
2765
4443
|
// Lottie JSON source URL or local path
|
|
2766
|
-
style:
|
|
4444
|
+
style: z8.record(z8.string(), z8.any()).optional(),
|
|
2767
4445
|
// CSS styles object
|
|
2768
|
-
className:
|
|
4446
|
+
className: z8.string().optional(),
|
|
2769
4447
|
// CSS class names
|
|
2770
|
-
loop:
|
|
4448
|
+
loop: z8.boolean().optional(),
|
|
2771
4449
|
// Whether to loop the animation (handled by Remotion timeline)
|
|
2772
|
-
playbackRate:
|
|
4450
|
+
playbackRate: z8.number().optional(),
|
|
2773
4451
|
// Playback speed multiplier (default: 1)
|
|
2774
|
-
direction:
|
|
4452
|
+
direction: z8.enum(["forward", "reverse"]).optional()
|
|
2775
4453
|
// Animation direction
|
|
2776
4454
|
});
|
|
2777
4455
|
var useLottieData = (src) => {
|
|
2778
|
-
const [animationData, setAnimationData] =
|
|
2779
|
-
const [isLoading, setIsLoading] =
|
|
2780
|
-
const [hasError, setHasError] =
|
|
2781
|
-
const [handle] =
|
|
2782
|
-
|
|
4456
|
+
const [animationData, setAnimationData] = useState8(null);
|
|
4457
|
+
const [isLoading, setIsLoading] = useState8(true);
|
|
4458
|
+
const [hasError, setHasError] = useState8(false);
|
|
4459
|
+
const [handle] = useState8(() => delayRender5("Loading Lottie animation"));
|
|
4460
|
+
useEffect8(() => {
|
|
2783
4461
|
if (!src) {
|
|
2784
4462
|
console.error("LottieAtom: No source provided");
|
|
2785
4463
|
setHasError(true);
|
|
@@ -2789,7 +4467,7 @@ var useLottieData = (src) => {
|
|
|
2789
4467
|
}
|
|
2790
4468
|
setIsLoading(true);
|
|
2791
4469
|
setHasError(false);
|
|
2792
|
-
const sourceUrl = src.startsWith("http") ? src :
|
|
4470
|
+
const sourceUrl = src.startsWith("http") ? src : staticFile5(src);
|
|
2793
4471
|
fetch(sourceUrl, {
|
|
2794
4472
|
mode: "cors",
|
|
2795
4473
|
credentials: "omit"
|
|
@@ -2816,12 +4494,12 @@ var useLottieData = (src) => {
|
|
|
2816
4494
|
}, [src, handle]);
|
|
2817
4495
|
return { animationData, isLoading, hasError };
|
|
2818
4496
|
};
|
|
2819
|
-
var
|
|
2820
|
-
const { fps } =
|
|
2821
|
-
const frame =
|
|
4497
|
+
var Atom7 = ({ data, id }) => {
|
|
4498
|
+
const { fps } = useVideoConfig11();
|
|
4499
|
+
const frame = useCurrentFrame11();
|
|
2822
4500
|
const overrideStyles = useAnimatedStyles(id);
|
|
2823
4501
|
const { animationData, isLoading, hasError } = useLottieData(data.src);
|
|
2824
|
-
const effectiveFrame =
|
|
4502
|
+
const effectiveFrame = useMemo14(() => {
|
|
2825
4503
|
const playbackRate = data.playbackRate || 1;
|
|
2826
4504
|
const direction = data.direction || "forward";
|
|
2827
4505
|
if (direction === "reverse") {
|
|
@@ -2829,12 +4507,12 @@ var Atom6 = ({ data, id }) => {
|
|
|
2829
4507
|
}
|
|
2830
4508
|
return frame * playbackRate;
|
|
2831
4509
|
}, [frame, data.playbackRate, data.direction]);
|
|
2832
|
-
const enhancedStyle =
|
|
4510
|
+
const enhancedStyle = useMemo14(() => ({
|
|
2833
4511
|
...data.style,
|
|
2834
4512
|
...overrideStyles
|
|
2835
4513
|
}), [data.style, overrideStyles]);
|
|
2836
4514
|
if (isLoading) {
|
|
2837
|
-
return /* @__PURE__ */
|
|
4515
|
+
return /* @__PURE__ */ React25.createElement(
|
|
2838
4516
|
"div",
|
|
2839
4517
|
{
|
|
2840
4518
|
className: data.className,
|
|
@@ -2850,7 +4528,7 @@ var Atom6 = ({ data, id }) => {
|
|
|
2850
4528
|
}
|
|
2851
4529
|
if (hasError || !animationData) {
|
|
2852
4530
|
console.warn(`LottieAtom: Failed to render animation from ${data.src}`);
|
|
2853
|
-
return /* @__PURE__ */
|
|
4531
|
+
return /* @__PURE__ */ React25.createElement(
|
|
2854
4532
|
"div",
|
|
2855
4533
|
{
|
|
2856
4534
|
className: data.className,
|
|
@@ -2870,7 +4548,7 @@ var Atom6 = ({ data, id }) => {
|
|
|
2870
4548
|
"\u26A0\uFE0F Lottie Error"
|
|
2871
4549
|
);
|
|
2872
4550
|
}
|
|
2873
|
-
return /* @__PURE__ */
|
|
4551
|
+
return /* @__PURE__ */ React25.createElement(
|
|
2874
4552
|
Lottie,
|
|
2875
4553
|
{
|
|
2876
4554
|
animationData,
|
|
@@ -2879,49 +4557,84 @@ var Atom6 = ({ data, id }) => {
|
|
|
2879
4557
|
}
|
|
2880
4558
|
);
|
|
2881
4559
|
};
|
|
2882
|
-
var
|
|
4560
|
+
var config16 = {
|
|
2883
4561
|
displayName: "LottieAtom",
|
|
2884
4562
|
type: "atom",
|
|
2885
4563
|
isInnerSequence: false
|
|
2886
4564
|
};
|
|
2887
4565
|
|
|
4566
|
+
// src/components/atoms/HTMLBlockAtom.tsx
|
|
4567
|
+
import React26 from "react";
|
|
4568
|
+
var Atom8 = ({ id, data }) => {
|
|
4569
|
+
const overrideStyles = useAnimatedStyles(id);
|
|
4570
|
+
const combinedStyle = {
|
|
4571
|
+
...data.style,
|
|
4572
|
+
...overrideStyles
|
|
4573
|
+
};
|
|
4574
|
+
return /* @__PURE__ */ React26.createElement(
|
|
4575
|
+
"div",
|
|
4576
|
+
{
|
|
4577
|
+
className: data.className,
|
|
4578
|
+
style: combinedStyle,
|
|
4579
|
+
dangerouslySetInnerHTML: { __html: data.html }
|
|
4580
|
+
}
|
|
4581
|
+
);
|
|
4582
|
+
};
|
|
4583
|
+
var config17 = {
|
|
4584
|
+
displayName: "HTMLBlockAtom",
|
|
4585
|
+
type: "atom",
|
|
4586
|
+
isInnerSequence: false
|
|
4587
|
+
};
|
|
4588
|
+
|
|
2888
4589
|
// src/components/atoms/index.ts
|
|
2889
4590
|
registerComponent(
|
|
2890
|
-
|
|
2891
|
-
Atom,
|
|
2892
|
-
"atom",
|
|
2893
|
-
config9
|
|
2894
|
-
);
|
|
2895
|
-
registerComponent(
|
|
2896
|
-
config10.displayName,
|
|
4591
|
+
config11.displayName,
|
|
2897
4592
|
Atom2,
|
|
2898
4593
|
"atom",
|
|
2899
|
-
|
|
4594
|
+
config11
|
|
2900
4595
|
);
|
|
2901
|
-
registerComponent(config11.displayName, Atom3, "atom", config11);
|
|
2902
4596
|
registerComponent(
|
|
2903
4597
|
config12.displayName,
|
|
2904
|
-
|
|
4598
|
+
Atom3,
|
|
2905
4599
|
"atom",
|
|
2906
4600
|
config12
|
|
2907
4601
|
);
|
|
4602
|
+
registerComponent(config13.displayName, Atom4, "atom", config13);
|
|
2908
4603
|
registerComponent(
|
|
2909
|
-
|
|
4604
|
+
config14.displayName,
|
|
2910
4605
|
Atom5,
|
|
2911
4606
|
"atom",
|
|
2912
|
-
|
|
4607
|
+
config14
|
|
2913
4608
|
);
|
|
2914
4609
|
registerComponent(
|
|
2915
|
-
|
|
4610
|
+
config15.displayName,
|
|
2916
4611
|
Atom6,
|
|
2917
4612
|
"atom",
|
|
2918
|
-
|
|
4613
|
+
config15
|
|
4614
|
+
);
|
|
4615
|
+
registerComponent(
|
|
4616
|
+
config16.displayName,
|
|
4617
|
+
Atom7,
|
|
4618
|
+
"atom",
|
|
4619
|
+
config16
|
|
4620
|
+
);
|
|
4621
|
+
registerComponent(
|
|
4622
|
+
config9.displayName,
|
|
4623
|
+
Atom,
|
|
4624
|
+
"atom",
|
|
4625
|
+
config9
|
|
4626
|
+
);
|
|
4627
|
+
registerComponent(
|
|
4628
|
+
config17.displayName,
|
|
4629
|
+
Atom8,
|
|
4630
|
+
"atom",
|
|
4631
|
+
config17
|
|
2919
4632
|
);
|
|
2920
4633
|
|
|
2921
4634
|
// src/hooks/useComponentRegistry.ts
|
|
2922
|
-
import { useMemo as
|
|
4635
|
+
import { useMemo as useMemo15 } from "react";
|
|
2923
4636
|
var useComponentRegistry = () => {
|
|
2924
|
-
return
|
|
4637
|
+
return useMemo15(() => {
|
|
2925
4638
|
return {
|
|
2926
4639
|
registerComponent: componentRegistry.registerComponent.bind(componentRegistry),
|
|
2927
4640
|
registerPackage: componentRegistry.registerPackage.bind(componentRegistry),
|
|
@@ -2932,13 +4645,13 @@ var useComponentRegistry = () => {
|
|
|
2932
4645
|
};
|
|
2933
4646
|
|
|
2934
4647
|
// src/hooks/useBoundaryCalculation.ts
|
|
2935
|
-
import { useMemo as
|
|
4648
|
+
import { useMemo as useMemo16 } from "react";
|
|
2936
4649
|
var useBoundaryCalculation = ({
|
|
2937
4650
|
parentBoundaries,
|
|
2938
4651
|
constraints,
|
|
2939
4652
|
layout
|
|
2940
4653
|
}) => {
|
|
2941
|
-
return
|
|
4654
|
+
return useMemo16(() => {
|
|
2942
4655
|
const { x, y, width, height } = parentBoundaries;
|
|
2943
4656
|
const calculatedX = typeof constraints.x === "number" ? constraints.x : x;
|
|
2944
4657
|
const calculatedY = typeof constraints.y === "number" ? constraints.y : y;
|
|
@@ -3049,16 +4762,16 @@ var needsProxying = (url) => {
|
|
|
3049
4762
|
|
|
3050
4763
|
// src/templates/rings/NextjsLogo.tsx
|
|
3051
4764
|
import { evolvePath } from "@remotion/paths";
|
|
3052
|
-
import
|
|
3053
|
-
import { interpolate as interpolate5, spring as spring5, useCurrentFrame as
|
|
4765
|
+
import React29, { useMemo as useMemo17 } from "react";
|
|
4766
|
+
import { interpolate as interpolate5, spring as spring5, useCurrentFrame as useCurrentFrame13, useVideoConfig as useVideoConfig13 } from "remotion";
|
|
3054
4767
|
|
|
3055
4768
|
// src/templates/rings/RippleOutLayout.tsx
|
|
3056
|
-
import
|
|
3057
|
-
import { spring as spring4, useCurrentFrame as
|
|
3058
|
-
import { z as
|
|
3059
|
-
var RippleOutTransitionSchema =
|
|
3060
|
-
progress:
|
|
3061
|
-
logoOut:
|
|
4769
|
+
import React28 from "react";
|
|
4770
|
+
import { spring as spring4, useCurrentFrame as useCurrentFrame12, useVideoConfig as useVideoConfig12, Sequence as Sequence2, AbsoluteFill as AbsoluteFill4 } from "remotion";
|
|
4771
|
+
import { z as z9 } from "zod";
|
|
4772
|
+
var RippleOutTransitionSchema = z9.object({
|
|
4773
|
+
progress: z9.number().min(0).max(1),
|
|
4774
|
+
logoOut: z9.number().min(0).max(1)
|
|
3062
4775
|
});
|
|
3063
4776
|
var defaultRippleOutData = {
|
|
3064
4777
|
progress: 0,
|
|
@@ -3076,10 +4789,10 @@ var RippleOutLayout = ({ data, context, children }) => {
|
|
|
3076
4789
|
transitionStart,
|
|
3077
4790
|
transitionDuration
|
|
3078
4791
|
} = data || { transitionStart: 2, transitionDuration: 1 };
|
|
3079
|
-
const frame =
|
|
3080
|
-
const { fps } =
|
|
4792
|
+
const frame = useCurrentFrame12();
|
|
4793
|
+
const { fps } = useVideoConfig12();
|
|
3081
4794
|
const { hierarchy } = useRenderContext();
|
|
3082
|
-
|
|
4795
|
+
React28.useEffect(() => {
|
|
3083
4796
|
loadGoogleFont("Inter", {
|
|
3084
4797
|
subsets: ["latin"],
|
|
3085
4798
|
weights: ["400", "700"]
|
|
@@ -3100,14 +4813,14 @@ var RippleOutLayout = ({ data, context, children }) => {
|
|
|
3100
4813
|
progress: logoOut,
|
|
3101
4814
|
logoOut
|
|
3102
4815
|
};
|
|
3103
|
-
const childrenArray =
|
|
3104
|
-
(child) =>
|
|
4816
|
+
const childrenArray = React28.Children.toArray(children).filter(
|
|
4817
|
+
(child) => React28.isValidElement(child)
|
|
3105
4818
|
);
|
|
3106
4819
|
const [from, to] = childrenArray;
|
|
3107
|
-
return /* @__PURE__ */
|
|
4820
|
+
return /* @__PURE__ */ React28.createElement(LayoutContext.Provider, { value: transitionData }, /* @__PURE__ */ React28.createElement(AbsoluteFill4, { style: {
|
|
3108
4821
|
...container,
|
|
3109
4822
|
...context?.boundaries
|
|
3110
|
-
} }, /* @__PURE__ */
|
|
4823
|
+
} }, /* @__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)));
|
|
3111
4824
|
};
|
|
3112
4825
|
var rippleOutLayoutConfig = {
|
|
3113
4826
|
displayName: "RippleOutLayout",
|
|
@@ -3123,8 +4836,8 @@ var nStroke = "M149.508 157.52L69.142 54H54V125.97H66.1136V69.3836L139.999 164.8
|
|
|
3123
4836
|
var NextjsLogo = () => {
|
|
3124
4837
|
const { logoOut } = useRippleOutLayout();
|
|
3125
4838
|
const outProgress = logoOut;
|
|
3126
|
-
const { fps } =
|
|
3127
|
-
const frame =
|
|
4839
|
+
const { fps } = useVideoConfig13();
|
|
4840
|
+
const frame = useCurrentFrame13();
|
|
3128
4841
|
const evolve1 = spring5({
|
|
3129
4842
|
fps,
|
|
3130
4843
|
frame,
|
|
@@ -3148,7 +4861,7 @@ var NextjsLogo = () => {
|
|
|
3148
4861
|
},
|
|
3149
4862
|
durationInFrames: 30
|
|
3150
4863
|
});
|
|
3151
|
-
const style =
|
|
4864
|
+
const style = useMemo17(() => {
|
|
3152
4865
|
return {
|
|
3153
4866
|
height: 140,
|
|
3154
4867
|
borderRadius: 70,
|
|
@@ -3164,7 +4877,7 @@ var NextjsLogo = () => {
|
|
|
3164
4877
|
interpolate5(evolve3, [0, 1], [0, 0.7]),
|
|
3165
4878
|
thirdPath
|
|
3166
4879
|
);
|
|
3167
|
-
return /* @__PURE__ */
|
|
4880
|
+
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(
|
|
3168
4881
|
"path",
|
|
3169
4882
|
{
|
|
3170
4883
|
strokeWidth: "12.1136",
|
|
@@ -3172,7 +4885,7 @@ var NextjsLogo = () => {
|
|
|
3172
4885
|
strokeDasharray: evolution1.strokeDasharray,
|
|
3173
4886
|
strokeDashoffset: evolution1.strokeDashoffset
|
|
3174
4887
|
}
|
|
3175
|
-
), /* @__PURE__ */
|
|
4888
|
+
), /* @__PURE__ */ React29.createElement(
|
|
3176
4889
|
"path",
|
|
3177
4890
|
{
|
|
3178
4891
|
strokeWidth: 12.1136,
|
|
@@ -3180,7 +4893,7 @@ var NextjsLogo = () => {
|
|
|
3180
4893
|
strokeDasharray: evolution2.strokeDasharray,
|
|
3181
4894
|
strokeDashoffset: evolution2.strokeDashoffset
|
|
3182
4895
|
}
|
|
3183
|
-
)), /* @__PURE__ */
|
|
4896
|
+
)), /* @__PURE__ */ React29.createElement(
|
|
3184
4897
|
"path",
|
|
3185
4898
|
{
|
|
3186
4899
|
stroke: "url(#gradient1)",
|
|
@@ -3189,7 +4902,7 @@ var NextjsLogo = () => {
|
|
|
3189
4902
|
strokeDashoffset: evolution3.strokeDashoffset,
|
|
3190
4903
|
strokeWidth: "12"
|
|
3191
4904
|
}
|
|
3192
|
-
)), /* @__PURE__ */
|
|
4905
|
+
)), /* @__PURE__ */ React29.createElement("defs", null, /* @__PURE__ */ React29.createElement(
|
|
3193
4906
|
"linearGradient",
|
|
3194
4907
|
{
|
|
3195
4908
|
gradientUnits: "userSpaceOnUse",
|
|
@@ -3199,9 +4912,9 @@ var NextjsLogo = () => {
|
|
|
3199
4912
|
y1: "116.5",
|
|
3200
4913
|
y2: "160.5"
|
|
3201
4914
|
},
|
|
3202
|
-
/* @__PURE__ */
|
|
3203
|
-
/* @__PURE__ */
|
|
3204
|
-
), /* @__PURE__ */
|
|
4915
|
+
/* @__PURE__ */ React29.createElement("stop", { stopColor: "white" }),
|
|
4916
|
+
/* @__PURE__ */ React29.createElement("stop", { offset: "1", stopColor: "white", stopOpacity: "0" })
|
|
4917
|
+
), /* @__PURE__ */ React29.createElement(
|
|
3205
4918
|
"linearGradient",
|
|
3206
4919
|
{
|
|
3207
4920
|
gradientUnits: "userSpaceOnUse",
|
|
@@ -3211,8 +4924,8 @@ var NextjsLogo = () => {
|
|
|
3211
4924
|
y1: "54",
|
|
3212
4925
|
y2: "106.875"
|
|
3213
4926
|
},
|
|
3214
|
-
/* @__PURE__ */
|
|
3215
|
-
/* @__PURE__ */
|
|
4927
|
+
/* @__PURE__ */ React29.createElement("stop", { stopColor: "white" }),
|
|
4928
|
+
/* @__PURE__ */ React29.createElement("stop", { offset: "1", stopColor: "white", stopOpacity: "0" })
|
|
3216
4929
|
)));
|
|
3217
4930
|
};
|
|
3218
4931
|
var nextjsLogoConfig = {
|
|
@@ -3222,14 +4935,14 @@ var nextjsLogoConfig = {
|
|
|
3222
4935
|
};
|
|
3223
4936
|
|
|
3224
4937
|
// src/templates/rings/Rings.tsx
|
|
3225
|
-
import
|
|
3226
|
-
import { AbsoluteFill as AbsoluteFill5, interpolateColors as interpolateColors2, useVideoConfig as
|
|
4938
|
+
import React30 from "react";
|
|
4939
|
+
import { AbsoluteFill as AbsoluteFill5, interpolateColors as interpolateColors2, useVideoConfig as useVideoConfig14 } from "remotion";
|
|
3227
4940
|
var RadialGradient = ({ radius, color }) => {
|
|
3228
4941
|
const height = radius * 2;
|
|
3229
4942
|
const width = radius * 2;
|
|
3230
4943
|
return (
|
|
3231
4944
|
// @ts-ignore
|
|
3232
|
-
/* @__PURE__ */
|
|
4945
|
+
/* @__PURE__ */ React30.createElement(
|
|
3233
4946
|
AbsoluteFill5,
|
|
3234
4947
|
{
|
|
3235
4948
|
style: {
|
|
@@ -3237,7 +4950,7 @@ var RadialGradient = ({ radius, color }) => {
|
|
|
3237
4950
|
alignItems: "center"
|
|
3238
4951
|
}
|
|
3239
4952
|
},
|
|
3240
|
-
/* @__PURE__ */
|
|
4953
|
+
/* @__PURE__ */ React30.createElement(
|
|
3241
4954
|
"div",
|
|
3242
4955
|
{
|
|
3243
4956
|
style: {
|
|
@@ -3257,10 +4970,10 @@ var Rings = ({ context, data }) => {
|
|
|
3257
4970
|
const { logoOut } = useRippleOutLayout();
|
|
3258
4971
|
const outProgress = logoOut;
|
|
3259
4972
|
const scale = 1 / (1 - outProgress);
|
|
3260
|
-
const { height } =
|
|
4973
|
+
const { height } = useVideoConfig14();
|
|
3261
4974
|
return (
|
|
3262
4975
|
// @ts-ignore
|
|
3263
|
-
/* @__PURE__ */
|
|
4976
|
+
/* @__PURE__ */ React30.createElement(
|
|
3264
4977
|
AbsoluteFill5,
|
|
3265
4978
|
{
|
|
3266
4979
|
style: {
|
|
@@ -3269,7 +4982,7 @@ var Rings = ({ context, data }) => {
|
|
|
3269
4982
|
}
|
|
3270
4983
|
},
|
|
3271
4984
|
new Array(5).fill(true).map((_, i) => {
|
|
3272
|
-
return /* @__PURE__ */
|
|
4985
|
+
return /* @__PURE__ */ React30.createElement(
|
|
3273
4986
|
RadialGradient,
|
|
3274
4987
|
{
|
|
3275
4988
|
key: i,
|
|
@@ -3288,13 +5001,13 @@ var ringsConfig = {
|
|
|
3288
5001
|
};
|
|
3289
5002
|
|
|
3290
5003
|
// src/templates/rings/TextFade.tsx
|
|
3291
|
-
import
|
|
5004
|
+
import React31, { useMemo as useMemo18 } from "react";
|
|
3292
5005
|
import {
|
|
3293
5006
|
AbsoluteFill as AbsoluteFill6,
|
|
3294
5007
|
interpolate as interpolate6,
|
|
3295
5008
|
spring as spring6,
|
|
3296
|
-
useCurrentFrame as
|
|
3297
|
-
useVideoConfig as
|
|
5009
|
+
useCurrentFrame as useCurrentFrame14,
|
|
5010
|
+
useVideoConfig as useVideoConfig15
|
|
3298
5011
|
} from "remotion";
|
|
3299
5012
|
var TextFade = (props) => {
|
|
3300
5013
|
const { children, context, data } = props;
|
|
@@ -3303,8 +5016,8 @@ var TextFade = (props) => {
|
|
|
3303
5016
|
duration: 1
|
|
3304
5017
|
}
|
|
3305
5018
|
};
|
|
3306
|
-
const { fps } =
|
|
3307
|
-
const frame =
|
|
5019
|
+
const { fps } = useVideoConfig15();
|
|
5020
|
+
const frame = useCurrentFrame14();
|
|
3308
5021
|
const progress = spring6({
|
|
3309
5022
|
fps,
|
|
3310
5023
|
frame,
|
|
@@ -3316,7 +5029,7 @@ var TextFade = (props) => {
|
|
|
3316
5029
|
const rightStop = interpolate6(progress, [0, 1], [200, 0]);
|
|
3317
5030
|
const leftStop = Math.max(0, rightStop - 60);
|
|
3318
5031
|
const maskImage = `linear-gradient(-45deg, transparent ${leftStop}%, black ${rightStop}%)`;
|
|
3319
|
-
const container2 =
|
|
5032
|
+
const container2 = useMemo18(() => {
|
|
3320
5033
|
return {
|
|
3321
5034
|
width: "100%",
|
|
3322
5035
|
height: "100%",
|
|
@@ -3324,7 +5037,7 @@ var TextFade = (props) => {
|
|
|
3324
5037
|
alignItems: "center"
|
|
3325
5038
|
};
|
|
3326
5039
|
}, []);
|
|
3327
|
-
const content =
|
|
5040
|
+
const content = useMemo18(() => {
|
|
3328
5041
|
return {
|
|
3329
5042
|
...context?.boundaries,
|
|
3330
5043
|
maskImage,
|
|
@@ -3336,7 +5049,7 @@ var TextFade = (props) => {
|
|
|
3336
5049
|
}, [maskImage]);
|
|
3337
5050
|
return (
|
|
3338
5051
|
// @ts-ignore
|
|
3339
|
-
/* @__PURE__ */
|
|
5052
|
+
/* @__PURE__ */ React31.createElement(AbsoluteFill6, { style: container2 }, /* @__PURE__ */ React31.createElement("div", { style: content }, children))
|
|
3340
5053
|
);
|
|
3341
5054
|
};
|
|
3342
5055
|
var textFadeConfig = {
|
|
@@ -3367,234 +5080,11 @@ registerComponent(
|
|
|
3367
5080
|
);
|
|
3368
5081
|
|
|
3369
5082
|
// src/templates/waveform/components/WaveformCircle.tsx
|
|
3370
|
-
import
|
|
3371
|
-
|
|
3372
|
-
// src/templates/waveform/Waveform.tsx
|
|
3373
|
-
import React25, { createContext as createContext5, useContext as useContext6 } from "react";
|
|
3374
|
-
import { useCurrentFrame as useCurrentFrame11, useVideoConfig as useVideoConfig12 } from "remotion";
|
|
3375
|
-
|
|
3376
|
-
// src/templates/waveform/hooks/useWaveformData.ts
|
|
3377
|
-
import { useMemo as useMemo17 } from "react";
|
|
3378
|
-
import {
|
|
3379
|
-
useAudioData,
|
|
3380
|
-
visualizeAudioWaveform,
|
|
3381
|
-
visualizeAudio
|
|
3382
|
-
} from "@remotion/media-utils";
|
|
3383
|
-
import { staticFile as staticFile5 } from "remotion";
|
|
3384
|
-
var isValidPowerOfTwo = (num) => {
|
|
3385
|
-
return num > 0 && (num & num - 1) === 0;
|
|
3386
|
-
};
|
|
3387
|
-
var getClosestPowerOfTwo = (num) => {
|
|
3388
|
-
if (num <= 0) return 32;
|
|
3389
|
-
let power = 1;
|
|
3390
|
-
while (power < num) {
|
|
3391
|
-
power *= 2;
|
|
3392
|
-
}
|
|
3393
|
-
const lower = power / 2;
|
|
3394
|
-
const upper = power;
|
|
3395
|
-
return Math.abs(num - lower) < Math.abs(num - upper) ? lower : upper;
|
|
3396
|
-
};
|
|
3397
|
-
var useWaveformData = (config15) => {
|
|
3398
|
-
const {
|
|
3399
|
-
audioSrc,
|
|
3400
|
-
numberOfSamples,
|
|
3401
|
-
windowInSeconds,
|
|
3402
|
-
dataOffsetInSeconds = 0,
|
|
3403
|
-
normalize = false,
|
|
3404
|
-
frame,
|
|
3405
|
-
fps,
|
|
3406
|
-
posterize,
|
|
3407
|
-
includeFrequencyData = false,
|
|
3408
|
-
minDb = -100,
|
|
3409
|
-
maxDb = -30
|
|
3410
|
-
} = config15;
|
|
3411
|
-
const { root } = useComposition();
|
|
3412
|
-
const validatedNumberOfSamples = useMemo17(() => {
|
|
3413
|
-
if (!isValidPowerOfTwo(numberOfSamples)) {
|
|
3414
|
-
console.warn(
|
|
3415
|
-
`numberOfSamples must be a power of 2. Adjusting ${numberOfSamples} to ${getClosestPowerOfTwo(numberOfSamples)}`
|
|
3416
|
-
);
|
|
3417
|
-
return getClosestPowerOfTwo(numberOfSamples);
|
|
3418
|
-
}
|
|
3419
|
-
return numberOfSamples;
|
|
3420
|
-
}, [numberOfSamples]);
|
|
3421
|
-
const { source, audioStartsFrom } = useMemo17(() => {
|
|
3422
|
-
if (audioSrc.startsWith("http")) {
|
|
3423
|
-
return { source: audioSrc, audioStartsFrom: void 0 };
|
|
3424
|
-
}
|
|
3425
|
-
if (audioSrc.startsWith("ref:")) {
|
|
3426
|
-
const matchingComponent = findMatchingComponents(root, [
|
|
3427
|
-
audioSrc.replace("ref:", "")
|
|
3428
|
-
]);
|
|
3429
|
-
if (matchingComponent.length > 0) {
|
|
3430
|
-
const firstMatchingComponent = matchingComponent[0];
|
|
3431
|
-
if (firstMatchingComponent.componentId === "AudioAtom") {
|
|
3432
|
-
return {
|
|
3433
|
-
source: firstMatchingComponent.data.src,
|
|
3434
|
-
audioStartsFrom: firstMatchingComponent.data?.startFrom ?? void 0
|
|
3435
|
-
};
|
|
3436
|
-
}
|
|
3437
|
-
if (firstMatchingComponent.type === "layout" || firstMatchingComponent.type === "scene") {
|
|
3438
|
-
const audioComponents = findMatchingComponentsByQuery(
|
|
3439
|
-
firstMatchingComponent.childrenData,
|
|
3440
|
-
{ componentId: "AudioAtom" }
|
|
3441
|
-
);
|
|
3442
|
-
if (audioComponents.length > 0) {
|
|
3443
|
-
return {
|
|
3444
|
-
source: audioComponents[0].data.src,
|
|
3445
|
-
audioStartsFrom: audioComponents[0].data?.startFrom ?? void 0
|
|
3446
|
-
};
|
|
3447
|
-
}
|
|
3448
|
-
}
|
|
3449
|
-
}
|
|
3450
|
-
}
|
|
3451
|
-
return { source: staticFile5(audioSrc), audioStartsFrom: void 0 };
|
|
3452
|
-
}, [audioSrc]);
|
|
3453
|
-
const audioData = useAudioData(source);
|
|
3454
|
-
const adjustedFrame = useMemo17(() => {
|
|
3455
|
-
if (posterize && posterize > 1) {
|
|
3456
|
-
return Math.round(frame / posterize) * posterize;
|
|
3457
|
-
}
|
|
3458
|
-
let offset = 0;
|
|
3459
|
-
if (audioStartsFrom && audioStartsFrom != 0) {
|
|
3460
|
-
offset += Math.round(audioStartsFrom * fps);
|
|
3461
|
-
}
|
|
3462
|
-
if (dataOffsetInSeconds != 0) {
|
|
3463
|
-
offset += Math.round(dataOffsetInSeconds * fps);
|
|
3464
|
-
}
|
|
3465
|
-
return frame + offset;
|
|
3466
|
-
}, [frame, posterize, dataOffsetInSeconds, audioStartsFrom]);
|
|
3467
|
-
const waveformData = useMemo17(() => {
|
|
3468
|
-
if (!audioData) return null;
|
|
3469
|
-
try {
|
|
3470
|
-
const waveform = visualizeAudioWaveform({
|
|
3471
|
-
fps,
|
|
3472
|
-
frame: adjustedFrame,
|
|
3473
|
-
audioData,
|
|
3474
|
-
numberOfSamples: validatedNumberOfSamples,
|
|
3475
|
-
windowInSeconds,
|
|
3476
|
-
dataOffsetInSeconds: 0,
|
|
3477
|
-
normalize
|
|
3478
|
-
});
|
|
3479
|
-
return waveform;
|
|
3480
|
-
} catch (error2) {
|
|
3481
|
-
console.error("Error generating waveform:", error2);
|
|
3482
|
-
return null;
|
|
3483
|
-
}
|
|
3484
|
-
}, [
|
|
3485
|
-
audioData,
|
|
3486
|
-
adjustedFrame,
|
|
3487
|
-
fps,
|
|
3488
|
-
validatedNumberOfSamples,
|
|
3489
|
-
windowInSeconds,
|
|
3490
|
-
dataOffsetInSeconds,
|
|
3491
|
-
normalize
|
|
3492
|
-
]);
|
|
3493
|
-
const {
|
|
3494
|
-
frequencyData,
|
|
3495
|
-
amplitudes,
|
|
3496
|
-
bass,
|
|
3497
|
-
mid,
|
|
3498
|
-
treble,
|
|
3499
|
-
bassValues,
|
|
3500
|
-
midValues,
|
|
3501
|
-
trebleValues
|
|
3502
|
-
} = useMemo17(() => {
|
|
3503
|
-
if (!audioData || !includeFrequencyData) {
|
|
3504
|
-
return {
|
|
3505
|
-
frequencyData: null,
|
|
3506
|
-
amplitudes: null,
|
|
3507
|
-
bass: null,
|
|
3508
|
-
mid: null,
|
|
3509
|
-
treble: null,
|
|
3510
|
-
bassValues: null,
|
|
3511
|
-
midValues: null,
|
|
3512
|
-
trebleValues: null
|
|
3513
|
-
};
|
|
3514
|
-
}
|
|
3515
|
-
try {
|
|
3516
|
-
const frequencyData2 = visualizeAudio({
|
|
3517
|
-
fps,
|
|
3518
|
-
frame: adjustedFrame,
|
|
3519
|
-
audioData,
|
|
3520
|
-
numberOfSamples: validatedNumberOfSamples
|
|
3521
|
-
});
|
|
3522
|
-
const { sampleRate } = audioData;
|
|
3523
|
-
const bassValues2 = [];
|
|
3524
|
-
const midValues2 = [];
|
|
3525
|
-
const trebleValues2 = [];
|
|
3526
|
-
for (let i = 0; i < frequencyData2.length; i++) {
|
|
3527
|
-
const freq = i * sampleRate / (2 * frequencyData2.length);
|
|
3528
|
-
const value = frequencyData2[i];
|
|
3529
|
-
if (freq >= 0 && freq < 250) {
|
|
3530
|
-
bassValues2.push(value * 2.5);
|
|
3531
|
-
} else if (freq >= 250 && freq < 4e3) {
|
|
3532
|
-
midValues2.push(value * 3);
|
|
3533
|
-
midValues2.push(value * 4.5);
|
|
3534
|
-
midValues2.push(value * 5);
|
|
3535
|
-
} else if (freq >= 4e3 && freq < sampleRate / 2) {
|
|
3536
|
-
trebleValues2.push(value * 30);
|
|
3537
|
-
}
|
|
3538
|
-
}
|
|
3539
|
-
const getAverage = (arr) => arr.length > 0 ? arr.reduce((a, b) => a + b, 0) / arr.length : 0;
|
|
3540
|
-
const bass2 = getAverage(bassValues2);
|
|
3541
|
-
const mid2 = getAverage(midValues2);
|
|
3542
|
-
const treble2 = getAverage(trebleValues2);
|
|
3543
|
-
const amplitudes2 = frequencyData2.map((value) => {
|
|
3544
|
-
const db = 20 * Math.log10(value);
|
|
3545
|
-
const scaled = (db - minDb) / (maxDb - minDb);
|
|
3546
|
-
return Math.max(0, Math.min(1, scaled));
|
|
3547
|
-
});
|
|
3548
|
-
return {
|
|
3549
|
-
frequencyData: frequencyData2,
|
|
3550
|
-
amplitudes: amplitudes2,
|
|
3551
|
-
bass: bass2,
|
|
3552
|
-
mid: mid2,
|
|
3553
|
-
treble: treble2,
|
|
3554
|
-
bassValues: bassValues2,
|
|
3555
|
-
midValues: midValues2,
|
|
3556
|
-
trebleValues: trebleValues2.reverse()
|
|
3557
|
-
};
|
|
3558
|
-
} catch (error2) {
|
|
3559
|
-
console.error("Error generating frequency data:", error2);
|
|
3560
|
-
return {
|
|
3561
|
-
frequencyData: null,
|
|
3562
|
-
amplitudes: null,
|
|
3563
|
-
bass: null,
|
|
3564
|
-
mid: null,
|
|
3565
|
-
treble: null
|
|
3566
|
-
};
|
|
3567
|
-
}
|
|
3568
|
-
}, [
|
|
3569
|
-
audioData,
|
|
3570
|
-
includeFrequencyData,
|
|
3571
|
-
adjustedFrame,
|
|
3572
|
-
fps,
|
|
3573
|
-
validatedNumberOfSamples,
|
|
3574
|
-
windowInSeconds,
|
|
3575
|
-
dataOffsetInSeconds,
|
|
3576
|
-
minDb,
|
|
3577
|
-
maxDb
|
|
3578
|
-
]);
|
|
3579
|
-
const isLoading = !audioData;
|
|
3580
|
-
const error = audioData === null && !isLoading ? "Failed to load audio data" : null;
|
|
3581
|
-
return {
|
|
3582
|
-
waveformData,
|
|
3583
|
-
frequencyData,
|
|
3584
|
-
amplitudes,
|
|
3585
|
-
audioData,
|
|
3586
|
-
isLoading,
|
|
3587
|
-
error,
|
|
3588
|
-
bass,
|
|
3589
|
-
bassValues,
|
|
3590
|
-
mid,
|
|
3591
|
-
midValues,
|
|
3592
|
-
treble,
|
|
3593
|
-
trebleValues
|
|
3594
|
-
};
|
|
3595
|
-
};
|
|
5083
|
+
import React33, { useMemo as useMemo19 } from "react";
|
|
3596
5084
|
|
|
3597
5085
|
// src/templates/waveform/Waveform.tsx
|
|
5086
|
+
import React32, { createContext as createContext5, useContext as useContext6 } from "react";
|
|
5087
|
+
import { useCurrentFrame as useCurrentFrame15, useVideoConfig as useVideoConfig16 } from "remotion";
|
|
3598
5088
|
var WaveformContext = createContext5(null);
|
|
3599
5089
|
var useWaveformContext = () => {
|
|
3600
5090
|
const context = useContext6(WaveformContext);
|
|
@@ -3604,26 +5094,27 @@ var useWaveformContext = () => {
|
|
|
3604
5094
|
return context;
|
|
3605
5095
|
};
|
|
3606
5096
|
var Waveform = ({
|
|
3607
|
-
config:
|
|
5097
|
+
config: config18,
|
|
3608
5098
|
children,
|
|
3609
5099
|
className = "",
|
|
3610
5100
|
style = {}
|
|
3611
5101
|
}) => {
|
|
3612
|
-
const frame =
|
|
3613
|
-
const { width: videoWidth, height: videoHeight, fps } =
|
|
5102
|
+
const frame = useCurrentFrame15();
|
|
5103
|
+
const { width: videoWidth, height: videoHeight, fps } = useVideoConfig16();
|
|
3614
5104
|
const { waveformData, frequencyData, amplitudes, audioData, bass, mid, treble, bassValues, midValues, trebleValues } = useWaveformData({
|
|
3615
|
-
audioSrc:
|
|
3616
|
-
numberOfSamples:
|
|
3617
|
-
windowInSeconds:
|
|
3618
|
-
dataOffsetInSeconds:
|
|
3619
|
-
normalize:
|
|
5105
|
+
audioSrc: config18.audioSrc,
|
|
5106
|
+
numberOfSamples: config18.numberOfSamples || 128,
|
|
5107
|
+
windowInSeconds: config18.windowInSeconds || 1 / fps,
|
|
5108
|
+
dataOffsetInSeconds: config18.dataOffsetInSeconds || 0,
|
|
5109
|
+
normalize: config18.normalize || false,
|
|
3620
5110
|
frame,
|
|
3621
5111
|
fps,
|
|
3622
|
-
posterize:
|
|
3623
|
-
includeFrequencyData:
|
|
5112
|
+
posterize: config18.posterize,
|
|
5113
|
+
includeFrequencyData: config18.useFrequencyData || false,
|
|
5114
|
+
smoothNormalisation: config18.smoothNormalisation
|
|
3624
5115
|
});
|
|
3625
|
-
const width =
|
|
3626
|
-
const height =
|
|
5116
|
+
const width = config18.width || videoWidth;
|
|
5117
|
+
const height = config18.height || videoHeight;
|
|
3627
5118
|
const contextValue = {
|
|
3628
5119
|
waveformData,
|
|
3629
5120
|
frequencyData,
|
|
@@ -3631,7 +5122,7 @@ var Waveform = ({
|
|
|
3631
5122
|
audioData,
|
|
3632
5123
|
frame,
|
|
3633
5124
|
fps,
|
|
3634
|
-
config:
|
|
5125
|
+
config: config18,
|
|
3635
5126
|
width,
|
|
3636
5127
|
height,
|
|
3637
5128
|
bass,
|
|
@@ -3641,7 +5132,7 @@ var Waveform = ({
|
|
|
3641
5132
|
midValues,
|
|
3642
5133
|
trebleValues
|
|
3643
5134
|
};
|
|
3644
|
-
return /* @__PURE__ */
|
|
5135
|
+
return /* @__PURE__ */ React32.createElement(WaveformContext.Provider, { value: contextValue }, /* @__PURE__ */ React32.createElement(
|
|
3645
5136
|
"div",
|
|
3646
5137
|
{
|
|
3647
5138
|
className: `relative ${className}`,
|
|
@@ -3649,7 +5140,7 @@ var Waveform = ({
|
|
|
3649
5140
|
width,
|
|
3650
5141
|
height,
|
|
3651
5142
|
position: "relative",
|
|
3652
|
-
backgroundColor:
|
|
5143
|
+
backgroundColor: config18.backgroundColor || "transparent",
|
|
3653
5144
|
...style
|
|
3654
5145
|
}
|
|
3655
5146
|
},
|
|
@@ -3660,7 +5151,7 @@ var Waveform = ({
|
|
|
3660
5151
|
// src/templates/waveform/components/WaveformCircle.tsx
|
|
3661
5152
|
var WaveformCircle = ({ data }) => {
|
|
3662
5153
|
const {
|
|
3663
|
-
config:
|
|
5154
|
+
config: config18,
|
|
3664
5155
|
className = "",
|
|
3665
5156
|
style = {},
|
|
3666
5157
|
strokeColor = "#FF6B6B",
|
|
@@ -3677,7 +5168,7 @@ var WaveformCircle = ({ data }) => {
|
|
|
3677
5168
|
gradientStartColor,
|
|
3678
5169
|
gradientEndColor
|
|
3679
5170
|
} = data;
|
|
3680
|
-
return /* @__PURE__ */
|
|
5171
|
+
return /* @__PURE__ */ React33.createElement(Waveform, { config: config18, className, style }, /* @__PURE__ */ React33.createElement(
|
|
3681
5172
|
WaveformCircleContent,
|
|
3682
5173
|
{
|
|
3683
5174
|
strokeColor,
|
|
@@ -3716,7 +5207,7 @@ var WaveformCircleContent = ({
|
|
|
3716
5207
|
const circleCenterX = width * (centerX || 50) / 100;
|
|
3717
5208
|
const circleCenterY = height * (centerY || 50) / 100;
|
|
3718
5209
|
const rotation = frame * (rotationSpeed || 0) % 360;
|
|
3719
|
-
const circularPath =
|
|
5210
|
+
const circularPath = useMemo19(() => {
|
|
3720
5211
|
if (!waveformData) return "";
|
|
3721
5212
|
const totalAngle = (endAngle || 360) - (startAngle || 0);
|
|
3722
5213
|
const angleStep = totalAngle / waveformData.length;
|
|
@@ -3738,11 +5229,11 @@ var WaveformCircleContent = ({
|
|
|
3738
5229
|
return path;
|
|
3739
5230
|
}, [waveformData, circleRadius, circleCenterX, circleCenterY, startAngle, endAngle, rotation, amplitude]);
|
|
3740
5231
|
if (!waveformData) {
|
|
3741
|
-
return /* @__PURE__ */
|
|
5232
|
+
return /* @__PURE__ */ React33.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading circular waveform...");
|
|
3742
5233
|
}
|
|
3743
5234
|
const gradientId = "circle-waveform-gradient";
|
|
3744
5235
|
const hasGradient = gradientStartColor && gradientEndColor;
|
|
3745
|
-
return /* @__PURE__ */
|
|
5236
|
+
return /* @__PURE__ */ React33.createElement(
|
|
3746
5237
|
"svg",
|
|
3747
5238
|
{
|
|
3748
5239
|
width,
|
|
@@ -3750,8 +5241,8 @@ var WaveformCircleContent = ({
|
|
|
3750
5241
|
className: "absolute inset-0",
|
|
3751
5242
|
style: { pointerEvents: "none" }
|
|
3752
5243
|
},
|
|
3753
|
-
hasGradient && /* @__PURE__ */
|
|
3754
|
-
/* @__PURE__ */
|
|
5244
|
+
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 }))),
|
|
5245
|
+
/* @__PURE__ */ React33.createElement(
|
|
3755
5246
|
"path",
|
|
3756
5247
|
{
|
|
3757
5248
|
d: circularPath,
|
|
@@ -3767,10 +5258,10 @@ var WaveformCircleContent = ({
|
|
|
3767
5258
|
};
|
|
3768
5259
|
|
|
3769
5260
|
// src/templates/waveform/components/WaveformHistogram.tsx
|
|
3770
|
-
import
|
|
5261
|
+
import React34 from "react";
|
|
3771
5262
|
var WaveformHistogram = ({ data }) => {
|
|
3772
5263
|
const {
|
|
3773
|
-
config:
|
|
5264
|
+
config: config18,
|
|
3774
5265
|
className = "",
|
|
3775
5266
|
style = {},
|
|
3776
5267
|
barColor = "#FF6B6B",
|
|
@@ -3783,13 +5274,14 @@ var WaveformHistogram = ({ data }) => {
|
|
|
3783
5274
|
histogramStyle = "centered",
|
|
3784
5275
|
amplitude = 1,
|
|
3785
5276
|
multiplier = 1,
|
|
5277
|
+
barSlant = 0,
|
|
3786
5278
|
gradientStartColor,
|
|
3787
5279
|
gradientEndColor,
|
|
3788
5280
|
gradientDirection = "vertical",
|
|
3789
5281
|
gradientStyle = "normal",
|
|
3790
5282
|
waveDirection = "right-to-left"
|
|
3791
5283
|
} = data;
|
|
3792
|
-
return /* @__PURE__ */
|
|
5284
|
+
return /* @__PURE__ */ React34.createElement(Waveform, { config: config18, className, style }, /* @__PURE__ */ React34.createElement(
|
|
3793
5285
|
WaveformHistogramContent,
|
|
3794
5286
|
{
|
|
3795
5287
|
barColor,
|
|
@@ -3806,7 +5298,8 @@ var WaveformHistogram = ({ data }) => {
|
|
|
3806
5298
|
gradientDirection,
|
|
3807
5299
|
multiplier,
|
|
3808
5300
|
gradientStyle,
|
|
3809
|
-
waveDirection
|
|
5301
|
+
waveDirection,
|
|
5302
|
+
barSlant
|
|
3810
5303
|
}
|
|
3811
5304
|
));
|
|
3812
5305
|
};
|
|
@@ -3825,12 +5318,13 @@ var WaveformHistogramContent = ({
|
|
|
3825
5318
|
gradientDirection,
|
|
3826
5319
|
multiplier,
|
|
3827
5320
|
gradientStyle,
|
|
3828
|
-
waveDirection
|
|
5321
|
+
waveDirection,
|
|
5322
|
+
barSlant
|
|
3829
5323
|
}) => {
|
|
3830
5324
|
const { waveformData, frequencyData, amplitudes, width, height } = useWaveformContext();
|
|
3831
5325
|
const dataToUse = amplitudes || waveformData;
|
|
3832
5326
|
if (!dataToUse) {
|
|
3833
|
-
return /* @__PURE__ */
|
|
5327
|
+
return /* @__PURE__ */ React34.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading histogram...");
|
|
3834
5328
|
}
|
|
3835
5329
|
let directedData = waveDirection === "left-to-right" ? dataToUse.slice(1).reverse() : dataToUse;
|
|
3836
5330
|
const frequencies = horizontalSymmetry ? [...directedData, ...directedData.slice(1).reverse()] : Array(multiplier).fill(directedData).flat();
|
|
@@ -3854,7 +5348,7 @@ var WaveformHistogramContent = ({
|
|
|
3854
5348
|
},
|
|
3855
5349
|
opacity: gradientStyle === "mirrored" && !growUpwards ? 0.25 : 1
|
|
3856
5350
|
};
|
|
3857
|
-
return /* @__PURE__ */
|
|
5351
|
+
return /* @__PURE__ */ React34.createElement("div", { style: containerStyle2 }, frequencies.map((value, index) => /* @__PURE__ */ React34.createElement(
|
|
3858
5352
|
"div",
|
|
3859
5353
|
{
|
|
3860
5354
|
key: index,
|
|
@@ -3866,7 +5360,9 @@ var WaveformHistogramContent = ({
|
|
|
3866
5360
|
Math.abs(value) * (height / 2) * (amplitude || 1)
|
|
3867
5361
|
)}px`,
|
|
3868
5362
|
borderRadius: growUpwards ? `${barBorderRadius}px ${barBorderRadius}px 0 0` : `0 0 ${barBorderRadius}px ${barBorderRadius}px`,
|
|
3869
|
-
opacity
|
|
5363
|
+
opacity,
|
|
5364
|
+
transform: barSlant ? `rotate(${barSlant}deg)` : void 0,
|
|
5365
|
+
transformOrigin: "center bottom"
|
|
3870
5366
|
}
|
|
3871
5367
|
}
|
|
3872
5368
|
)));
|
|
@@ -3886,7 +5382,7 @@ var WaveformHistogramContent = ({
|
|
|
3886
5382
|
width: "100%",
|
|
3887
5383
|
left: 0
|
|
3888
5384
|
};
|
|
3889
|
-
return /* @__PURE__ */
|
|
5385
|
+
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 })));
|
|
3890
5386
|
}
|
|
3891
5387
|
const containerStyle = {
|
|
3892
5388
|
width: "100%",
|
|
@@ -3895,14 +5391,14 @@ var WaveformHistogramContent = ({
|
|
|
3895
5391
|
height: `${height / 2}px`,
|
|
3896
5392
|
left: 0
|
|
3897
5393
|
};
|
|
3898
|
-
return /* @__PURE__ */
|
|
5394
|
+
return /* @__PURE__ */ React34.createElement("div", { style: containerStyle }, /* @__PURE__ */ React34.createElement(Bars, { growUpwards: true }));
|
|
3899
5395
|
};
|
|
3900
5396
|
|
|
3901
5397
|
// src/templates/waveform/components/WaveformHistogramRanged.tsx
|
|
3902
|
-
import
|
|
5398
|
+
import React35 from "react";
|
|
3903
5399
|
var WaveformHistogramRanged = ({ data }) => {
|
|
3904
5400
|
const {
|
|
3905
|
-
config:
|
|
5401
|
+
config: config18,
|
|
3906
5402
|
className = "",
|
|
3907
5403
|
style = {},
|
|
3908
5404
|
barColor = "#FF6B6B",
|
|
@@ -3924,9 +5420,10 @@ var WaveformHistogramRanged = ({ data }) => {
|
|
|
3924
5420
|
gradientDirection = "vertical",
|
|
3925
5421
|
gradientStyle = "normal",
|
|
3926
5422
|
horizontalSymmetry = false,
|
|
3927
|
-
waveDirection = "right-to-left"
|
|
5423
|
+
waveDirection = "right-to-left",
|
|
5424
|
+
barSlant = 0
|
|
3928
5425
|
} = data;
|
|
3929
|
-
return /* @__PURE__ */
|
|
5426
|
+
return /* @__PURE__ */ React35.createElement(Waveform, { config: config18, className, style }, /* @__PURE__ */ React35.createElement(
|
|
3930
5427
|
WaveformHistogramRangedContent,
|
|
3931
5428
|
{
|
|
3932
5429
|
barColor,
|
|
@@ -3948,7 +5445,8 @@ var WaveformHistogramRanged = ({ data }) => {
|
|
|
3948
5445
|
gradientDirection,
|
|
3949
5446
|
gradientStyle,
|
|
3950
5447
|
horizontalSymmetry,
|
|
3951
|
-
waveDirection
|
|
5448
|
+
waveDirection,
|
|
5449
|
+
barSlant
|
|
3952
5450
|
}
|
|
3953
5451
|
));
|
|
3954
5452
|
};
|
|
@@ -3972,11 +5470,12 @@ var WaveformHistogramRangedContent = ({
|
|
|
3972
5470
|
gradientDirection,
|
|
3973
5471
|
gradientStyle,
|
|
3974
5472
|
horizontalSymmetry,
|
|
3975
|
-
waveDirection
|
|
5473
|
+
waveDirection,
|
|
5474
|
+
barSlant
|
|
3976
5475
|
}) => {
|
|
3977
5476
|
const { amplitudes, bassValues, midValues, trebleValues, height } = useWaveformContext();
|
|
3978
5477
|
if (!amplitudes || !bassValues || !midValues || !trebleValues) {
|
|
3979
|
-
return /* @__PURE__ */
|
|
5478
|
+
return /* @__PURE__ */ React35.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading frequency data...");
|
|
3980
5479
|
}
|
|
3981
5480
|
const bassFrequencies = bassValues;
|
|
3982
5481
|
const midFrequencies = midValues;
|
|
@@ -4000,12 +5499,12 @@ var WaveformHistogramRangedContent = ({
|
|
|
4000
5499
|
},
|
|
4001
5500
|
opacity: gradientStyle === "mirrored" && !growUpwards ? 0.25 : 1
|
|
4002
5501
|
};
|
|
4003
|
-
return /* @__PURE__ */
|
|
5502
|
+
return /* @__PURE__ */ React35.createElement("div", { style: containerStyle2 }, unifiedWaveform.map((value, index) => {
|
|
4004
5503
|
const rangeName = index === 0 ? "Bass" : index === 1 ? "Mid" : "Treble";
|
|
4005
5504
|
const styleGradientProp = gradientStartColor && gradientEndColor ? {
|
|
4006
5505
|
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})`
|
|
4007
5506
|
} : { backgroundColor: barColor };
|
|
4008
|
-
return /* @__PURE__ */
|
|
5507
|
+
return /* @__PURE__ */ React35.createElement(
|
|
4009
5508
|
"div",
|
|
4010
5509
|
{
|
|
4011
5510
|
key: index,
|
|
@@ -4019,11 +5518,13 @@ var WaveformHistogramRangedContent = ({
|
|
|
4019
5518
|
)}px`,
|
|
4020
5519
|
borderRadius: growUpwards ? `${barBorderRadius}px ${barBorderRadius}px 0 0` : `0 0 ${barBorderRadius}px ${barBorderRadius}px`,
|
|
4021
5520
|
opacity,
|
|
4022
|
-
position: "relative"
|
|
5521
|
+
position: "relative",
|
|
5522
|
+
transform: barSlant ? `rotate(${barSlant}deg)` : void 0,
|
|
5523
|
+
transformOrigin: "center bottom"
|
|
4023
5524
|
},
|
|
4024
5525
|
title: `${rangeName}: ${(value * 100).toFixed(1)}%`
|
|
4025
5526
|
},
|
|
4026
|
-
rangeLabels && /* @__PURE__ */
|
|
5527
|
+
rangeLabels && /* @__PURE__ */ React35.createElement("div", { style: {
|
|
4027
5528
|
position: "absolute",
|
|
4028
5529
|
bottom: growUpwards ? "-20px" : "auto",
|
|
4029
5530
|
top: growUpwards ? "auto" : "-20px",
|
|
@@ -4051,7 +5552,7 @@ var WaveformHistogramRangedContent = ({
|
|
|
4051
5552
|
width: "100%",
|
|
4052
5553
|
left: 0
|
|
4053
5554
|
};
|
|
4054
|
-
return /* @__PURE__ */
|
|
5555
|
+
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 })));
|
|
4055
5556
|
}
|
|
4056
5557
|
const containerStyle = {
|
|
4057
5558
|
width: "100%",
|
|
@@ -4060,13 +5561,13 @@ var WaveformHistogramRangedContent = ({
|
|
|
4060
5561
|
height: `${height / 2}px`,
|
|
4061
5562
|
left: 0
|
|
4062
5563
|
};
|
|
4063
|
-
return /* @__PURE__ */
|
|
5564
|
+
return /* @__PURE__ */ React35.createElement("div", { style: containerStyle }, /* @__PURE__ */ React35.createElement(Bars, { growUpwards: true }));
|
|
4064
5565
|
};
|
|
4065
5566
|
|
|
4066
5567
|
// src/templates/waveform/components/WaveformLine.tsx
|
|
4067
|
-
import
|
|
5568
|
+
import React36, { useMemo as useMemo20 } from "react";
|
|
4068
5569
|
import { createSmoothSvgPath } from "@remotion/media-utils";
|
|
4069
|
-
import { useCurrentFrame as
|
|
5570
|
+
import { useCurrentFrame as useCurrentFrame16, useVideoConfig as useVideoConfig17 } from "remotion";
|
|
4070
5571
|
var detectBeat = (frequencyData, amplitudes, threshold = 0.7, bpm, frame = 0, fps = 30) => {
|
|
4071
5572
|
if (!frequencyData || !amplitudes || frequencyData.length === 0) return false;
|
|
4072
5573
|
if (bpm) {
|
|
@@ -4098,7 +5599,7 @@ var easingFunctions = {
|
|
|
4098
5599
|
};
|
|
4099
5600
|
var WaveformLine = ({ data }) => {
|
|
4100
5601
|
const {
|
|
4101
|
-
config:
|
|
5602
|
+
config: config18,
|
|
4102
5603
|
className = "",
|
|
4103
5604
|
style = {},
|
|
4104
5605
|
strokeColor = "#FF6B6B",
|
|
@@ -4126,7 +5627,7 @@ var WaveformLine = ({ data }) => {
|
|
|
4126
5627
|
pulseColor = "#FFD700",
|
|
4127
5628
|
pulseScale = 1.2
|
|
4128
5629
|
} = data;
|
|
4129
|
-
return /* @__PURE__ */
|
|
5630
|
+
return /* @__PURE__ */ React36.createElement(Waveform, { config: config18, className, style }, /* @__PURE__ */ React36.createElement(
|
|
4130
5631
|
WaveformLineContent,
|
|
4131
5632
|
{
|
|
4132
5633
|
strokeColor,
|
|
@@ -4182,14 +5683,14 @@ var WaveformLineContent = ({
|
|
|
4182
5683
|
pulseColor,
|
|
4183
5684
|
pulseScale
|
|
4184
5685
|
}) => {
|
|
4185
|
-
const { waveformData, frequencyData, amplitudes, width, height, config:
|
|
4186
|
-
const currentFrame =
|
|
4187
|
-
const videoConfig =
|
|
4188
|
-
const isBeat =
|
|
5686
|
+
const { waveformData, frequencyData, amplitudes, width, height, config: config18, frame, fps } = useWaveformContext();
|
|
5687
|
+
const currentFrame = useCurrentFrame16();
|
|
5688
|
+
const videoConfig = useVideoConfig17();
|
|
5689
|
+
const isBeat = useMemo20(() => {
|
|
4189
5690
|
if (!beatSync || !frequencyData || !amplitudes) return false;
|
|
4190
5691
|
return detectBeat(frequencyData, amplitudes, beatThreshold, bpm, currentFrame, fps);
|
|
4191
5692
|
}, [beatSync, frequencyData, amplitudes, beatThreshold, bpm, currentFrame, fps]);
|
|
4192
|
-
const beatProgress =
|
|
5693
|
+
const beatProgress = useMemo20(() => {
|
|
4193
5694
|
if (!isBeat || !beatAnimationDuration) return 0;
|
|
4194
5695
|
const beatStartFrame = Math.floor(currentFrame / beatAnimationDuration) * beatAnimationDuration;
|
|
4195
5696
|
const progress = (currentFrame - beatStartFrame) / beatAnimationDuration;
|
|
@@ -4199,19 +5700,19 @@ var WaveformLineContent = ({
|
|
|
4199
5700
|
}
|
|
4200
5701
|
return clampedProgress;
|
|
4201
5702
|
}, [isBeat, currentFrame, beatAnimationDuration, smoothAnimation]);
|
|
4202
|
-
const currentBeatMultiplier =
|
|
5703
|
+
const currentBeatMultiplier = useMemo20(() => {
|
|
4203
5704
|
if (!beatSync || !isBeat || !beatAmplitudeMultiplier || !amplitudeCurve) return 1;
|
|
4204
5705
|
const easing = easingFunctions[amplitudeCurve];
|
|
4205
5706
|
const easedProgress = easing(beatProgress);
|
|
4206
5707
|
return 1 + (beatAmplitudeMultiplier - 1) * (1 - easedProgress);
|
|
4207
5708
|
}, [beatSync, isBeat, beatProgress, beatAmplitudeMultiplier, amplitudeCurve]);
|
|
4208
|
-
const smoothFactor =
|
|
5709
|
+
const smoothFactor = useMemo20(() => {
|
|
4209
5710
|
if (!beatSync) {
|
|
4210
5711
|
return 0.3;
|
|
4211
5712
|
}
|
|
4212
5713
|
return smoothAnimation ? 0.7 : 1;
|
|
4213
5714
|
}, [beatSync, smoothAnimation]);
|
|
4214
|
-
const waveformPaths =
|
|
5715
|
+
const waveformPaths = useMemo20(() => {
|
|
4215
5716
|
if (!waveformData) return [];
|
|
4216
5717
|
const paths = [];
|
|
4217
5718
|
const segments = waveSegments || 1;
|
|
@@ -4227,8 +5728,8 @@ var WaveformLineContent = ({
|
|
|
4227
5728
|
const points = waveformData.map((y, index) => {
|
|
4228
5729
|
const progress = index / (waveformData.length - 1);
|
|
4229
5730
|
const x = segmentStart + progress * segmentDataWidth + offset;
|
|
4230
|
-
let animatedAmplitude = y * (
|
|
4231
|
-
const baseAmplitude = y * (
|
|
5731
|
+
let animatedAmplitude = y * (config18.amplitude || 1) * currentBeatMultiplier * speed;
|
|
5732
|
+
const baseAmplitude = y * (config18.amplitude || 1) * speed;
|
|
4232
5733
|
const beatAmplitude = animatedAmplitude - baseAmplitude;
|
|
4233
5734
|
animatedAmplitude = baseAmplitude + beatAmplitude * smoothFactor;
|
|
4234
5735
|
const yPos = waveDirection === "horizontal" ? animatedAmplitude * height / 2 + height / 2 : animatedAmplitude * width / 2 + width / 2;
|
|
@@ -4238,11 +5739,11 @@ var WaveformLineContent = ({
|
|
|
4238
5739
|
paths.push({ path, segmentIndex: i });
|
|
4239
5740
|
}
|
|
4240
5741
|
return paths;
|
|
4241
|
-
}, [waveformData, width, height,
|
|
5742
|
+
}, [waveformData, width, height, config18.amplitude, currentBeatMultiplier, animationSpeed, waveSegments, waveSpacing, waveOffset, waveDirection, smoothFactor]);
|
|
4242
5743
|
if (!waveformData) {
|
|
4243
|
-
return /* @__PURE__ */
|
|
5744
|
+
return /* @__PURE__ */ React36.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading waveform...");
|
|
4244
5745
|
}
|
|
4245
|
-
return /* @__PURE__ */
|
|
5746
|
+
return /* @__PURE__ */ React36.createElement(
|
|
4246
5747
|
"svg",
|
|
4247
5748
|
{
|
|
4248
5749
|
width,
|
|
@@ -4250,7 +5751,7 @@ var WaveformLineContent = ({
|
|
|
4250
5751
|
className: "absolute inset-0",
|
|
4251
5752
|
style: { pointerEvents: "none" }
|
|
4252
5753
|
},
|
|
4253
|
-
centerLine && /* @__PURE__ */
|
|
5754
|
+
centerLine && /* @__PURE__ */ React36.createElement(
|
|
4254
5755
|
"line",
|
|
4255
5756
|
{
|
|
4256
5757
|
x1: waveDirection === "horizontal" ? 0 : width / 2,
|
|
@@ -4262,7 +5763,7 @@ var WaveformLineContent = ({
|
|
|
4262
5763
|
opacity: 0.3
|
|
4263
5764
|
}
|
|
4264
5765
|
),
|
|
4265
|
-
waveformPaths.map(({ path, segmentIndex }) => /* @__PURE__ */
|
|
5766
|
+
waveformPaths.map(({ path, segmentIndex }) => /* @__PURE__ */ React36.createElement("g", { key: segmentIndex }, pulseOnBeat && isBeat && /* @__PURE__ */ React36.createElement(
|
|
4266
5767
|
"path",
|
|
4267
5768
|
{
|
|
4268
5769
|
d: path,
|
|
@@ -4273,7 +5774,7 @@ var WaveformLineContent = ({
|
|
|
4273
5774
|
fill: "none",
|
|
4274
5775
|
opacity: (opacity || 1) * (1 - beatProgress)
|
|
4275
5776
|
}
|
|
4276
|
-
), /* @__PURE__ */
|
|
5777
|
+
), /* @__PURE__ */ React36.createElement(
|
|
4277
5778
|
"path",
|
|
4278
5779
|
{
|
|
4279
5780
|
d: path,
|
|
@@ -4334,19 +5835,19 @@ registerComponent("WaveformCircle", WaveformCircle, "atom", {
|
|
|
4334
5835
|
|
|
4335
5836
|
// src/components/Composition.tsx
|
|
4336
5837
|
import { Player as RemotionPlayer } from "@remotion/player";
|
|
4337
|
-
import
|
|
5838
|
+
import React37 from "react";
|
|
4338
5839
|
import { AbsoluteFill as AbsoluteFill7, Composition as RemotionComposition } from "remotion";
|
|
4339
|
-
import
|
|
4340
|
-
var CompositionLayout = ({ childrenData, style, config:
|
|
4341
|
-
return /* @__PURE__ */
|
|
5840
|
+
import z10 from "zod";
|
|
5841
|
+
var CompositionLayout = ({ childrenData, style, config: config18 }) => {
|
|
5842
|
+
return /* @__PURE__ */ React37.createElement(
|
|
4342
5843
|
CompositionProvider,
|
|
4343
5844
|
{
|
|
4344
5845
|
value: {
|
|
4345
5846
|
root: childrenData,
|
|
4346
|
-
duration:
|
|
5847
|
+
duration: config18.duration
|
|
4347
5848
|
}
|
|
4348
5849
|
},
|
|
4349
|
-
/* @__PURE__ */
|
|
5850
|
+
/* @__PURE__ */ React37.createElement(AbsoluteFill7, { style }, childrenData?.map((component) => /* @__PURE__ */ React37.createElement(
|
|
4350
5851
|
ComponentRenderer,
|
|
4351
5852
|
{
|
|
4352
5853
|
key: component.id,
|
|
@@ -4386,26 +5887,26 @@ var calculateCompositionLayoutMetadata = async ({ props, defaultProps, abortSign
|
|
|
4386
5887
|
var Composition = ({
|
|
4387
5888
|
id,
|
|
4388
5889
|
childrenData,
|
|
4389
|
-
config:
|
|
5890
|
+
config: config18,
|
|
4390
5891
|
style
|
|
4391
5892
|
}) => {
|
|
4392
|
-
return /* @__PURE__ */
|
|
5893
|
+
return /* @__PURE__ */ React37.createElement(
|
|
4393
5894
|
RemotionComposition,
|
|
4394
5895
|
{
|
|
4395
5896
|
id,
|
|
4396
5897
|
component: CompositionLayout,
|
|
4397
|
-
durationInFrames: Math.round(
|
|
4398
|
-
fps:
|
|
4399
|
-
width:
|
|
4400
|
-
height:
|
|
4401
|
-
defaultProps: { childrenData, style, config:
|
|
5898
|
+
durationInFrames: Math.round(config18.duration * config18.fps),
|
|
5899
|
+
fps: config18.fps,
|
|
5900
|
+
width: config18.width ?? 1080,
|
|
5901
|
+
height: config18.height ?? 1920,
|
|
5902
|
+
defaultProps: { childrenData, style, config: config18 },
|
|
4402
5903
|
calculateMetadata: calculateCompositionLayoutMetadata,
|
|
4403
|
-
schema:
|
|
5904
|
+
schema: z10.object({})
|
|
4404
5905
|
}
|
|
4405
5906
|
);
|
|
4406
5907
|
};
|
|
4407
5908
|
var Player = (props) => {
|
|
4408
|
-
return /* @__PURE__ */
|
|
5909
|
+
return /* @__PURE__ */ React37.createElement(
|
|
4409
5910
|
RemotionPlayer,
|
|
4410
5911
|
{
|
|
4411
5912
|
component: CompositionLayout,
|
|
@@ -4418,24 +5919,32 @@ var Player = (props) => {
|
|
|
4418
5919
|
);
|
|
4419
5920
|
};
|
|
4420
5921
|
export {
|
|
4421
|
-
|
|
4422
|
-
|
|
5922
|
+
Atom6 as AudioAtom,
|
|
5923
|
+
config15 as AudioAtomConfig,
|
|
4423
5924
|
Layout as BaseLayout,
|
|
4424
|
-
|
|
5925
|
+
config10 as BaseLayoutConfig,
|
|
4425
5926
|
BlurEffect,
|
|
4426
5927
|
config2 as BlurEffectConfig,
|
|
5928
|
+
Atom as CanvasAtom,
|
|
5929
|
+
config9 as CanvasAtomConfig,
|
|
5930
|
+
CanvasContentAwareReveal,
|
|
5931
|
+
CanvasGlitchEffect,
|
|
5932
|
+
CanvasParticleEffect,
|
|
5933
|
+
CanvasWipeReveal,
|
|
4427
5934
|
ComponentRenderer,
|
|
4428
5935
|
Composition,
|
|
4429
5936
|
CompositionLayout,
|
|
4430
5937
|
CompositionProvider,
|
|
4431
5938
|
Frame,
|
|
4432
5939
|
GenericEffectPresets,
|
|
4433
|
-
|
|
4434
|
-
|
|
5940
|
+
Atom8 as HTMLBlockAtom,
|
|
5941
|
+
config17 as HTMLBlockAtomConfig,
|
|
5942
|
+
Atom3 as ImageAtom,
|
|
5943
|
+
config12 as ImageAtomConfig,
|
|
4435
5944
|
LoopEffect,
|
|
4436
5945
|
config3 as LoopEffectConfig,
|
|
4437
|
-
|
|
4438
|
-
|
|
5946
|
+
Atom7 as LottieAtom,
|
|
5947
|
+
config16 as LottieAtomConfig,
|
|
4439
5948
|
NextjsLogo,
|
|
4440
5949
|
PanEffect,
|
|
4441
5950
|
config4 as PanEffectConfig,
|
|
@@ -4445,19 +5954,21 @@ export {
|
|
|
4445
5954
|
SceneFrame,
|
|
4446
5955
|
ShakeEffect,
|
|
4447
5956
|
config6 as ShakeEffectConfig,
|
|
4448
|
-
|
|
4449
|
-
|
|
5957
|
+
Atom2 as ShapeAtom,
|
|
5958
|
+
config11 as ShapeAtomConfig,
|
|
4450
5959
|
StretchEffect,
|
|
4451
5960
|
config7 as StretchEffectConfig,
|
|
4452
|
-
|
|
4453
|
-
|
|
5961
|
+
Atom4 as TextAtom,
|
|
5962
|
+
config13 as TextAtomConfig,
|
|
4454
5963
|
TextFade,
|
|
4455
5964
|
UniversalEffect,
|
|
4456
5965
|
UniversalEffectProvider,
|
|
4457
|
-
|
|
4458
|
-
|
|
5966
|
+
Atom5 as VideoAtom,
|
|
5967
|
+
config14 as VideoAtomConfig,
|
|
4459
5968
|
Waveform,
|
|
4460
5969
|
WaveformCircle,
|
|
5970
|
+
WaveformEffect,
|
|
5971
|
+
config8 as WaveformEffectConfig,
|
|
4461
5972
|
WaveformHistogram,
|
|
4462
5973
|
WaveformHistogramRanged,
|
|
4463
5974
|
WaveformLine,
|