@evatril/video-templates 2.0.1 → 2.0.2
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/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { Sequence, useVideoConfig, Audio, staticFile } from "remotion";
|
|
2
|
+
import { Sequence, useVideoConfig, Audio, staticFile,AbsoluteFill } from "remotion";
|
|
3
3
|
import { F20012026_01 } from "../Frames/F20012026_01.jsx";
|
|
4
4
|
import { F20012026_02 } from "../Frames/F20012026_02.jsx";
|
|
5
5
|
import { F20012026_03 } from "../Frames/F20012026_03.jsx";
|
|
6
6
|
import { InkSmokeTransition20012026 } from "../Elements/InkSmokeTransition20012026.jsx";
|
|
7
|
+
import { usePreloadImages } from "../hooks/usePreloadImages.js";
|
|
7
8
|
|
|
8
9
|
export const T20012026_01 = ({
|
|
9
10
|
event,
|
|
@@ -17,109 +18,115 @@ export const T20012026_01 = ({
|
|
|
17
18
|
}) => {
|
|
18
19
|
const { durationInFrames } = useVideoConfig();
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
const whoIsCreating =
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
// Detect creator safely
|
|
22
|
+
const whoIsCreating =
|
|
23
|
+
event?.occasion_data?.who_is_creating ??
|
|
24
|
+
event?.who_is_creating;
|
|
24
25
|
|
|
25
|
-
const isBrideCreating =
|
|
26
|
-
|
|
26
|
+
const isBrideCreating =
|
|
27
|
+
whoIsCreating === "Bride" || !whoIsCreating;
|
|
27
28
|
|
|
28
|
-
// Names
|
|
29
|
-
const brideName =
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
// Names
|
|
30
|
+
const brideName =
|
|
31
|
+
event?.occasion_data?.bride_name ??
|
|
32
|
+
event?.bride_name ??
|
|
33
|
+
formData?.bride_name ??
|
|
34
|
+
"";
|
|
34
35
|
|
|
35
|
-
const groomName =
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
const groomName =
|
|
37
|
+
event?.occasion_data?.groom_name ??
|
|
38
|
+
event?.groom_name ??
|
|
39
|
+
formData?.groom_name ??
|
|
40
|
+
"";
|
|
40
41
|
|
|
41
|
-
const firstName = isBrideCreating ? brideName : groomName;
|
|
42
|
-
const secondName = isBrideCreating ? groomName : brideName;
|
|
42
|
+
const firstName = isBrideCreating ? brideName : groomName;
|
|
43
|
+
const secondName = isBrideCreating ? groomName : brideName;
|
|
43
44
|
|
|
44
|
-
// Side notes (safe)
|
|
45
|
-
const firstSideNote = isBrideCreating
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
// Side notes (safe)
|
|
46
|
+
const firstSideNote = isBrideCreating
|
|
47
|
+
? formData?.bride_side_note || ""
|
|
48
|
+
: formData?.groom_side_note || "";
|
|
48
49
|
|
|
49
|
-
const secondSideNote = isBrideCreating
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
const secondSideNote = isBrideCreating
|
|
51
|
+
? formData?.groom_side_note || ""
|
|
52
|
+
: formData?.bride_side_note || "";
|
|
52
53
|
|
|
53
|
-
// Venue (safe)
|
|
54
|
-
const venueName =
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const venueAddress =
|
|
58
|
-
venue?.address || formData?.venue_address || "";
|
|
54
|
+
// Venue (safe)
|
|
55
|
+
const venueName =
|
|
56
|
+
venue?.name || formData?.venue_name || "";
|
|
59
57
|
|
|
58
|
+
const venueAddress =
|
|
59
|
+
venue?.address || formData?.venue_address || "";
|
|
60
60
|
|
|
61
61
|
const framesPerPage = Math.floor(durationInFrames / 3);
|
|
62
62
|
const transitionDuration = Math.floor(framesPerPage * 0.25); // ~1 sec
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
/>
|
|
80
|
-
</Sequence>
|
|
81
|
-
|
|
82
|
-
<Sequence
|
|
83
|
-
from={framesPerPage}
|
|
84
|
-
durationInFrames={framesPerPage}
|
|
85
|
-
>
|
|
86
|
-
<F20012026_02
|
|
87
|
-
firstName={firstName}
|
|
88
|
-
secondName={secondName}
|
|
89
|
-
firstSideNote={firstSideNote}
|
|
90
|
-
secondSideNote={secondSideNote}
|
|
91
|
-
invitationMessage={invitationMessage}
|
|
92
|
-
occasionDate={occasionDate}
|
|
93
|
-
fadeInDuration={transitionDuration}
|
|
94
|
-
/>
|
|
95
|
-
</Sequence>
|
|
64
|
+
usePreloadImages([
|
|
65
|
+
staticFile("video-images/20012026-bg.png"),
|
|
66
|
+
staticFile("video-images/20012026-bride.png"),
|
|
67
|
+
staticFile("video-images/20012026-butterfly.png"),
|
|
68
|
+
staticFile("video-images/20012026-couple-walk.png"),
|
|
69
|
+
staticFile("video-images/20012026-curtain-floral.png"),
|
|
70
|
+
staticFile("video-images/20012026-floral-left.png"),
|
|
71
|
+
staticFile("video-images/20012026-floral-right.png"),
|
|
72
|
+
staticFile("video-images/20012026-groom.png"),
|
|
73
|
+
staticFile("video-images/20012026-opening-gate.png"),
|
|
74
|
+
staticFile("video-images/20012026-peacock.png"),
|
|
75
|
+
staticFile("video-images/20012026-tree-left.png"),
|
|
76
|
+
staticFile("video-images/20012026-tree-right.png"),
|
|
77
|
+
staticFile("video-images/20012026-wedding-gate.png"),
|
|
78
|
+
]);
|
|
96
79
|
|
|
97
|
-
|
|
98
|
-
<
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
<Sequence from={framesPerPage * 2} durationInFrames={framesPerPage}>
|
|
106
|
-
<F20012026_03
|
|
107
|
-
eventDateTime={eventDateTime}
|
|
108
|
-
venueName={venueName}
|
|
109
|
-
venueAddress={venueAddress}
|
|
110
|
-
familyMember={familyMember}
|
|
80
|
+
return (
|
|
81
|
+
<AbsoluteFill style={{ backgroundColor: "#1a1a1a" }}>
|
|
82
|
+
{/* 🎵 Background Music */}
|
|
83
|
+
<Audio
|
|
84
|
+
src={staticFile("video-images/wedding.mp3")}
|
|
85
|
+
startFrom={30}
|
|
86
|
+
endAt={900}
|
|
87
|
+
volume={0.4}
|
|
111
88
|
/>
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
89
|
+
<Sequence from={0} durationInFrames={framesPerPage + 1}>
|
|
90
|
+
<F20012026_01
|
|
91
|
+
firstName={firstName}
|
|
92
|
+
secondName={secondName}
|
|
93
|
+
welcomeMessage={welcomeMessage}
|
|
94
|
+
eventDateTime={eventDateTime}
|
|
95
|
+
/>
|
|
96
|
+
</Sequence>
|
|
97
|
+
|
|
98
|
+
<Sequence from={framesPerPage} durationInFrames={framesPerPage + 1}>
|
|
99
|
+
<F20012026_02
|
|
100
|
+
firstName={firstName}
|
|
101
|
+
secondName={secondName}
|
|
102
|
+
firstSideNote={firstSideNote}
|
|
103
|
+
secondSideNote={secondSideNote}
|
|
104
|
+
invitationMessage={invitationMessage}
|
|
105
|
+
occasionDate={occasionDate}
|
|
106
|
+
fadeInDuration={transitionDuration}
|
|
107
|
+
/>
|
|
108
|
+
</Sequence>
|
|
109
|
+
|
|
110
|
+
{/* ☁️ TRANSITION: SCENE 1 ➜ 2 */}
|
|
111
|
+
<Sequence from={framesPerPage - 1} durationInFrames={transitionDuration + 2}
|
|
118
112
|
>
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
113
|
+
<InkSmokeTransition20012026 />
|
|
114
|
+
</Sequence>
|
|
115
|
+
|
|
116
|
+
<Sequence from={framesPerPage * 2} durationInFrames={framesPerPage + 1}>
|
|
117
|
+
<F20012026_03
|
|
118
|
+
eventDateTime={eventDateTime}
|
|
119
|
+
venueName={venueName}
|
|
120
|
+
venueAddress={venueAddress}
|
|
121
|
+
familyMember={familyMember}
|
|
122
|
+
/>
|
|
123
|
+
</Sequence>
|
|
124
|
+
|
|
125
|
+
{/* ☁️ TRANSITION: SCENE 2 ➜ 3 */}
|
|
126
|
+
<Sequence from={framesPerPage * 2 - 1} durationInFrames={transitionDuration + 2}>
|
|
127
|
+
<InkSmokeTransition20012026 />
|
|
128
|
+
</Sequence>
|
|
129
|
+
|
|
130
|
+
</AbsoluteFill>
|
|
124
131
|
);
|
|
125
132
|
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { useState, useEffect } from "react";
|
|
2
|
+
import { delayRender, continueRender } from "remotion";
|
|
3
|
+
|
|
4
|
+
export const usePreloadImages = (imageSources) => {
|
|
5
|
+
const [handle] = useState(() => delayRender("Preloading images"));
|
|
6
|
+
const [loaded, setLoaded] = useState(false);
|
|
7
|
+
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
let cancelled = false;
|
|
10
|
+
|
|
11
|
+
const done = () => {
|
|
12
|
+
if (!cancelled) {
|
|
13
|
+
setLoaded(true);
|
|
14
|
+
continueRender(handle);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
if (!imageSources || imageSources.length === 0) {
|
|
19
|
+
done();
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
Promise.all(
|
|
24
|
+
imageSources.map(
|
|
25
|
+
(src) =>
|
|
26
|
+
new Promise((resolve) => {
|
|
27
|
+
const img = new Image();
|
|
28
|
+
img.onload = resolve;
|
|
29
|
+
img.onerror = resolve;
|
|
30
|
+
img.src = src;
|
|
31
|
+
}),
|
|
32
|
+
),
|
|
33
|
+
)
|
|
34
|
+
.then(done)
|
|
35
|
+
.catch(done);
|
|
36
|
+
|
|
37
|
+
return () => {
|
|
38
|
+
cancelled = true;
|
|
39
|
+
continueRender(handle); // 🔥 safety cleanup
|
|
40
|
+
};
|
|
41
|
+
}, [handle, imageSources]);
|
|
42
|
+
|
|
43
|
+
return loaded;
|
|
44
|
+
};
|