返回 html-video
index.html
1 <!doctype html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8" />
5 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6 <title>Warm Grain - Hyperframes</title>
7 <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
8 <style>
9 body,
10 html {
11 margin: 0;
12 padding: 0;
13 width: 1920px;
14 height: 1080px;
15 overflow: hidden;
16 background-color: #f5f0e0; /* Cream background */
17 font-family: "Outfit", "Lexend", sans-serif;
18 }
19
20 #main-composition {
21 position: relative;
22 width: 1920px;
23 height: 1080px;
24 overflow: hidden;
25 }
26
27 /* Paper texture and Grain overlay */
28 #grain-overlay-comp {
29 position: absolute;
30 top: 0;
31 left: 0;
32 width: 100%;
33 height: 100%;
34 pointer-events: none;
35 z-index: 100;
36 }
37
38 /* Grain animation */
39 @keyframes grain-noise {
40 0%,
41 100% {
42 transform: translate(0, 0);
43 }
44 10% {
45 transform: translate(-5%, -5%);
46 }
47 20% {
48 transform: translate(-10%, 5%);
49 }
50 30% {
51 transform: translate(5%, -10%);
52 }
53 40% {
54 transform: translate(-5%, 15%);
55 }
56 50% {
57 transform: translate(-10%, 5%);
58 }
59 60% {
60 transform: translate(15%, 0);
61 }
62 70% {
63 transform: translate(0, 10%);
64 }
65 80% {
66 transform: translate(-15%, 0);
67 }
68 90% {
69 transform: translate(10%, 5%);
70 }
71 }
72
73 .grain-texture {
74 position: absolute;
75 top: -50%;
76 left: -50%;
77 width: 200%;
78 height: 200%;
79 background: url("https://www.transparenttextures.com/patterns/natural-paper.png");
80 opacity: 0.15;
81 animation: grain-noise 0.5s steps(1) infinite;
82 }
83
84 #a-roll {
85 position: absolute;
86 border-radius: 16px;
87 object-fit: cover;
88 box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
89 }
90
91 .comp-layer {
92 position: absolute;
93 top: 0;
94 left: 0;
95 width: 100%;
96 height: 100%;
97 pointer-events: none;
98 }
99 </style>
100 </head>
101 <body>
102 <div
103 id="main-composition"
104 data-composition-id="main-video"
105 data-width="1920"
106 data-height="1080"
107 data-start="0"
108 data-duration="__VIDEO_DURATION__"
109 >
110 <!-- Background Layer -->
111 <div
112 id="grain-overlay-comp"
113 data-composition-id="grain-overlay"
114 data-width="1920"
115 data-height="1080"
116 data-start="0"
117 data-duration="__VIDEO_DURATION__"
118 data-track-index="100"
119 >
120 <div class="grain-texture"></div>
121 <script>
122 const grainTl = gsap.timeline({ paused: true });
123 window.__timelines = window.__timelines || {};
124 window.__timelines["grain-overlay"] = grainTl;
125 </script>
126 </div>
127
128 <!-- A-Roll Video (muted — audio is separate) -->
129 <video
130 id="a-roll"
131 src="__VIDEO_SRC__"
132 muted
133 playsinline
134 data-start="0"
135 data-duration="__VIDEO_DURATION__"
136 data-track-index="0"
137 ></video>
138 <audio
139 id="a-roll-audio"
140 src="__VIDEO_SRC__"
141 data-start="0"
142 data-duration="__VIDEO_DURATION__"
143 data-track-index="5"
144 data-volume="1"
145 ></audio>
146
147 <!-- Compositions -->
148 <div
149 id="intro-layer"
150 class="comp-layer"
151 data-composition-id="intro"
152 data-composition-src="compositions/intro.html"
153 data-start="0"
154 data-duration="2.5"
155 data-track-index="1"
156 ></div>
157
158 <div
159 id="graphics-layer"
160 class="comp-layer"
161 data-composition-id="graphics"
162 data-composition-src="compositions/graphics.html"
163 data-start="0"
164 data-duration="__VIDEO_DURATION__"
165 data-track-index="2"
166 ></div>
167
168 <div
169 id="captions-layer"
170 class="comp-layer"
171 data-composition-id="captions"
172 data-composition-src="compositions/captions.html"
173 data-start="0"
174 data-duration="__VIDEO_DURATION__"
175 data-track-index="3"
176 ></div>
177
178 <script>
179 const tl = gsap.timeline({ paused: true });
180
181 // A-Roll Framing Strategy
182 // 1. 0s-1.8s: Intro scale up from small (60%) to medium (80%) - Shifted right slightly to clear speaker card
183 // 2. 1.8s-4.6s: Grid view / Shift Left (x: 600, scale: 70%) for 47% graphic
184 // 3. 4.6s-8.8s: Shift Center-Bottom (y: 800, scale: 70%) for 62% graphic (top)
185 // 4. 8.8s-14s: Shift Right (x: 1320, scale: 75%) for Editing Skills graphic (left)
186 // 5. 14s-17s: Final Reveal (Center, scale: 100%)
187
188 // Initial state
189 gsap.set("#a-roll", {
190 x: 1100,
191 y: 540,
192 xPercent: -50,
193 yPercent: -50,
194 width: 1920 * 0.6,
195 height: 1080 * 0.6,
196 });
197
198 // 1. Intro Scale Up (0s - 1.8s)
199 tl.to(
200 "#a-roll",
201 {
202 x: 1200,
203 width: 1920 * 0.8,
204 height: 1080 * 0.8,
205 duration: 1.8,
206 ease: "power2.inOut",
207 },
208 0,
209 );
210
211 // 2. Moment 1: 47% Graphic Trigger (1.8s) - Shift Left
212 tl.to(
213 "#a-roll",
214 {
215 x: 600,
216 y: 540,
217 width: 1920 * 0.7,
218 height: 1080 * 0.7,
219 duration: 0.5,
220 ease: "power2.inOut",
221 },
222 1.8,
223 );
224
225 // 3. Moment 2: 62% Graphic Trigger (4.6s) - Shift Center-Bottom
226 tl.to(
227 "#a-roll",
228 {
229 x: 960,
230 y: 750,
231 width: 1920 * 0.7,
232 height: 1080 * 0.7,
233 duration: 0.5,
234 ease: "power2.inOut",
235 },
236 4.6,
237 );
238
239 // 4. Moment 3: Editing Skills Trigger (8.8s) - Shift Right
240 tl.to(
241 "#a-roll",
242 {
243 x: 1320,
244 y: 540,
245 width: 1920 * 0.75,
246 height: 1080 * 0.75,
247 duration: 0.5,
248 ease: "power2.inOut",
249 },
250 8.8,
251 );
252
253 // 5. Final Reveal (14s - 17s)
254 tl.to(
255 "#a-roll",
256 {
257 x: 960,
258 y: 540,
259 width: 1920 * 1.0,
260 height: 1080 * 1.0,
261 duration: 1.0,
262 ease: "power2.inOut",
263 },
264 14,
265 );
266
267 window.__timelines["main-video"] = tl;
268 </script>
269 </div>
270 </body>
271 </html>
272
272 lines HTML