@remotion/transitions 4.0.496 → 4.0.497

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.
@@ -85,7 +85,7 @@ import {
85
85
  Internals,
86
86
  useDelayRender
87
87
  } from "remotion";
88
- import { jsx as jsx2 } from "react/jsx-runtime";
88
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
89
89
  var HtmlInCanvasPresentation = ({
90
90
  children,
91
91
  onElementImage,
@@ -101,6 +101,7 @@ var HtmlInCanvasPresentation = ({
101
101
  throw new Error(HTML_IN_CANVAS_UNSUPPORTED_MESSAGE);
102
102
  }
103
103
  const canvasRef = useRef(null);
104
+ const outputCanvasRef = useRef(null);
104
105
  const canvasSubtreeStyle = useMemo2(() => {
105
106
  return {
106
107
  width: "100%",
@@ -112,7 +113,21 @@ var HtmlInCanvasPresentation = ({
112
113
  bottom: 0
113
114
  };
114
115
  }, []);
115
- const [offscreenCanvas] = useState(() => new OffscreenCanvas(1, 1));
116
+ const outputCanvasStyle = useMemo2(() => {
117
+ return {
118
+ width: "100%",
119
+ height: "100%",
120
+ position: "absolute",
121
+ top: 0,
122
+ left: 0,
123
+ right: 0,
124
+ bottom: 0,
125
+ pointerEvents: "none"
126
+ };
127
+ }, []);
128
+ const captureCanvasRef = useRef(null);
129
+ const captureContextRef = useRef(null);
130
+ const [shaderCanvas] = useState(() => new OffscreenCanvas(1, 1));
116
131
  const passedPropsRef = useRef(passedProps);
117
132
  passedPropsRef.current = passedProps;
118
133
  const memoizedEffects = Internals.useMemoizedEffects({
@@ -121,33 +136,58 @@ var HtmlInCanvasPresentation = ({
121
136
  });
122
137
  const effectsRef = useRef(memoizedEffects);
123
138
  effectsRef.current = memoizedEffects;
124
- const [instance] = useState(() => shader(offscreenCanvas));
139
+ const [instance] = useState(() => shader(shaderCanvas));
125
140
  useLayoutEffect(() => {
141
+ const canvas = canvasRef.current;
142
+ if (!canvas) {
143
+ return () => {
144
+ instance.cleanup();
145
+ };
146
+ }
147
+ const captureCanvas = canvas.transferControlToOffscreen();
148
+ const captureContext = captureCanvas.getContext("2d");
149
+ if (!captureContext) {
150
+ throw new Error("Failed to create capture canvas context");
151
+ }
152
+ captureCanvasRef.current = captureCanvas;
153
+ captureContextRef.current = captureContext;
126
154
  return () => {
127
155
  instance.cleanup();
156
+ captureCanvasRef.current = null;
157
+ captureContextRef.current = null;
128
158
  };
129
- }, [offscreenCanvas, instance]);
159
+ }, [instance]);
130
160
  const chainState = Internals.useEffectChainState();
131
161
  const { delayRender, continueRender } = useDelayRender();
132
162
  const draw = useCallback(async (prevImage, nextImage, progress) => {
133
- if (!canvasRef.current) {
163
+ const outputCanvas = outputCanvasRef.current;
164
+ if (!outputCanvas) {
134
165
  throw new Error("Canvas not found");
135
166
  }
136
167
  const handle = delayRender("onPaint");
168
+ const clearOutput = () => {
169
+ const context = outputCanvas.getContext("2d");
170
+ if (!context) {
171
+ throw new Error("Failed to create output canvas context");
172
+ }
173
+ context.clearRect(0, 0, outputCanvas.width, outputCanvas.height);
174
+ };
137
175
  if (!prevImage && !nextImage) {
138
- continueRender(handle);
139
176
  instance.clear();
177
+ clearOutput();
178
+ continueRender(handle);
140
179
  return;
141
180
  }
142
181
  const width = prevImage?.width ?? nextImage?.width ?? 0;
143
182
  const height = prevImage?.height ?? nextImage?.height ?? 0;
144
183
  if (width === 0 || height === 0) {
145
- continueRender(handle);
146
184
  instance.clear();
185
+ clearOutput();
186
+ continueRender(handle);
147
187
  return;
148
188
  }
149
- offscreenCanvas.width = width;
150
- offscreenCanvas.height = height;
189
+ shaderCanvas.width = width;
190
+ shaderCanvas.height = height;
151
191
  instance.draw({
152
192
  prevImage,
153
193
  nextImage,
@@ -158,14 +198,14 @@ var HtmlInCanvasPresentation = ({
158
198
  });
159
199
  await Internals.runEffectChain({
160
200
  state: chainState.get(width, height),
161
- source: offscreenCanvas,
201
+ source: shaderCanvas,
162
202
  effects: effectsRef.current ?? [],
163
203
  width,
164
204
  height,
165
- output: canvasRef.current
205
+ output: outputCanvas
166
206
  });
167
207
  continueRender(handle);
168
- }, [chainState, instance, offscreenCanvas, continueRender, delayRender]);
208
+ }, [chainState, continueRender, delayRender, instance, shaderCanvas]);
169
209
  const passThrough = bothEnteringAndExiting && presentationDirection === "exiting";
170
210
  useLayoutEffect(() => {
171
211
  if (passThrough) {
@@ -178,11 +218,19 @@ var HtmlInCanvasPresentation = ({
178
218
  canvas.layoutSubtree = true;
179
219
  const onPaint = () => {
180
220
  const firstChild = canvas.firstChild;
181
- if (!firstChild) {
221
+ const captureCanvas = captureCanvasRef.current;
222
+ const captureContext = captureContextRef.current;
223
+ if (!firstChild || !captureCanvas || !captureContext) {
182
224
  return;
183
225
  }
184
226
  const elementImage = canvas.captureElementImage(firstChild);
185
- onElementImage(elementImage, draw);
227
+ try {
228
+ captureContext.reset();
229
+ captureContext.drawElementImage(elementImage, 0, 0);
230
+ } finally {
231
+ elementImage.close();
232
+ }
233
+ onElementImage(captureCanvas, draw);
186
234
  };
187
235
  canvas.addEventListener("paint", onPaint);
188
236
  return () => {
@@ -216,20 +264,39 @@ var HtmlInCanvasPresentation = ({
216
264
  return;
217
265
  }
218
266
  const observer = new ResizeObserver(([entry]) => {
219
- canvas.width = entry.devicePixelContentBoxSize[0].inlineSize;
220
- canvas.height = entry.devicePixelContentBoxSize[0].blockSize;
267
+ const outputCanvas = outputCanvasRef.current;
268
+ const captureCanvas = captureCanvasRef.current;
269
+ if (!outputCanvas || !captureCanvas) {
270
+ return;
271
+ }
272
+ const width = entry.devicePixelContentBoxSize[0].inlineSize;
273
+ const height = entry.devicePixelContentBoxSize[0].blockSize;
274
+ captureCanvas.width = width;
275
+ captureCanvas.height = height;
276
+ outputCanvas.width = width;
277
+ outputCanvas.height = height;
278
+ canvas.requestPaint?.();
221
279
  });
222
280
  observer.observe(canvas, { box: "device-pixel-content-box" });
281
+ return () => {
282
+ observer.disconnect();
283
+ };
223
284
  }, [passThrough]);
224
285
  if (passThrough) {
225
286
  return children;
226
287
  }
227
- return /* @__PURE__ */ jsx2(AbsoluteFill2, {
228
- children: /* @__PURE__ */ jsx2("canvas", {
229
- ref: canvasRef,
230
- style: canvasSubtreeStyle,
231
- children
232
- })
288
+ return /* @__PURE__ */ jsxs(AbsoluteFill2, {
289
+ children: [
290
+ /* @__PURE__ */ jsx2("canvas", {
291
+ ref: canvasRef,
292
+ style: canvasSubtreeStyle,
293
+ children
294
+ }),
295
+ /* @__PURE__ */ jsx2("canvas", {
296
+ ref: outputCanvasRef,
297
+ style: outputCanvasStyle
298
+ })
299
+ ]
233
300
  });
234
301
  };
235
302
  var makeHtmlInCanvasPresentation = (shader) => {
@@ -251,6 +318,11 @@ var makeHtmlInCanvasPresentation = (shader) => {
251
318
  };
252
319
  };
253
320
 
321
+ // src/presentations/upload-element-image.ts
322
+ var uploadElementImage = (gl, elementImage) => {
323
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, elementImage);
324
+ };
325
+
254
326
  // src/presentations/cross-zoom.tsx
255
327
  var DEFAULT_STRENGTH = 0.4;
256
328
  var VERTEX_SHADER = `#version 300 es
@@ -429,13 +501,13 @@ var crossZoomShader = (canvas) => {
429
501
  gl.activeTexture(gl.TEXTURE0);
430
502
  gl.bindTexture(gl.TEXTURE_2D, prevTex);
431
503
  if (prevImage) {
432
- gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, prevImage);
504
+ uploadElementImage(gl, prevImage);
433
505
  }
434
506
  gl.uniform1i(uPrev, 0);
435
507
  gl.activeTexture(gl.TEXTURE1);
436
508
  gl.bindTexture(gl.TEXTURE_2D, nextTex);
437
509
  if (nextImage) {
438
- gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, nextImage);
510
+ uploadElementImage(gl, nextImage);
439
511
  }
440
512
  gl.uniform1i(uNext, 1);
441
513
  gl.uniform1f(uTime, effectiveTime);
@@ -597,13 +669,13 @@ var dreamyZoomShader = (canvas) => {
597
669
  gl.activeTexture(gl.TEXTURE0);
598
670
  gl.bindTexture(gl.TEXTURE_2D, prevTex);
599
671
  if (prevImage) {
600
- gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, prevImage);
672
+ uploadElementImage(gl, prevImage);
601
673
  }
602
674
  gl.uniform1i(uPrev, 0);
603
675
  gl.activeTexture(gl.TEXTURE1);
604
676
  gl.bindTexture(gl.TEXTURE_2D, nextTex);
605
677
  if (nextImage) {
606
- gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, nextImage);
678
+ uploadElementImage(gl, nextImage);
607
679
  }
608
680
  gl.uniform1i(uNext, 1);
609
681
  gl.uniform1f(uTime, effectiveTime);
@@ -864,13 +936,13 @@ var filmBurnShader = (canvas) => {
864
936
  gl.activeTexture(gl.TEXTURE0);
865
937
  gl.bindTexture(gl.TEXTURE_2D, prevTex);
866
938
  if (prevImage) {
867
- gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, prevImage);
939
+ uploadElementImage(gl, prevImage);
868
940
  }
869
941
  gl.uniform1i(uPrev, 0);
870
942
  gl.activeTexture(gl.TEXTURE1);
871
943
  gl.bindTexture(gl.TEXTURE_2D, nextTex);
872
944
  if (nextImage) {
873
- gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, nextImage);
945
+ uploadElementImage(gl, nextImage);
874
946
  }
875
947
  gl.uniform1i(uNext, 1);
876
948
  gl.uniform1f(uTime, effectiveTime);
@@ -1029,13 +1101,13 @@ var linearBlurShader = (canvas) => {
1029
1101
  gl.activeTexture(gl.TEXTURE0);
1030
1102
  gl.bindTexture(gl.TEXTURE_2D, prevTex);
1031
1103
  if (prevImage) {
1032
- gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, prevImage);
1104
+ uploadElementImage(gl, prevImage);
1033
1105
  }
1034
1106
  gl.uniform1i(uPrev, 0);
1035
1107
  gl.activeTexture(gl.TEXTURE1);
1036
1108
  gl.bindTexture(gl.TEXTURE_2D, nextTex);
1037
1109
  if (nextImage) {
1038
- gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, nextImage);
1110
+ uploadElementImage(gl, nextImage);
1039
1111
  }
1040
1112
  gl.uniform1i(uNext, 1);
1041
1113
  gl.uniform1f(uTime, effectiveTime);
@@ -1153,7 +1225,7 @@ import { NoReactInternals } from "remotion/no-react";
1153
1225
  var validateDurationInFrames = NoReactInternals.validateDurationInFrames;
1154
1226
 
1155
1227
  // src/TransitionSeries.tsx
1156
- import { jsx as jsx4, jsxs, Fragment } from "react/jsx-runtime";
1228
+ import { jsx as jsx4, jsxs as jsxs2, Fragment } from "react/jsx-runtime";
1157
1229
  var { SequenceWithoutSchema } = Internals2;
1158
1230
  var TransitionSeriesTransitionInner = ({
1159
1231
  stack = null,
@@ -1197,6 +1269,7 @@ var transitionSeriesSequenceSchema = {
1197
1269
  hidden: Internals2.sequenceSchema.hidden,
1198
1270
  showInTimeline: Internals2.sequenceSchema.showInTimeline,
1199
1271
  freeze: Internals2.freezeField,
1272
+ trimBefore: Internals2.sequenceSchema.trimBefore,
1200
1273
  layout: Internals2.sequenceSchema.layout
1201
1274
  };
1202
1275
  var SeriesSequenceInner = ({
@@ -1377,7 +1450,7 @@ var TransitionSeriesChildren = ({
1377
1450
  _remotionInternalRender: (transitionProps) => {
1378
1451
  const transitionDuration = transitionProps.timing.getDurationInFrames({ fps });
1379
1452
  const transitionFrom = startFrame + transitionOffsets - transitionDuration;
1380
- return /* @__PURE__ */ jsxs(Fragment, {
1453
+ return /* @__PURE__ */ jsxs2(Fragment, {
1381
1454
  children: [
1382
1455
  transitionDuration > 0 ? /* @__PURE__ */ jsx4(SequenceWithoutSchema, {
1383
1456
  from: transitionFrom,
@@ -1460,7 +1533,7 @@ var TransitionSeriesChildren = ({
1460
1533
  }
1461
1534
  }
1462
1535
  const renderSequenceAndRest = (sequence) => {
1463
- return /* @__PURE__ */ jsxs(Fragment, {
1536
+ return /* @__PURE__ */ jsxs2(Fragment, {
1464
1537
  children: [
1465
1538
  sequence,
1466
1539
  renderNext({
@@ -7,7 +7,7 @@ import {
7
7
  Internals,
8
8
  useDelayRender
9
9
  } from "remotion";
10
- import { jsx } from "react/jsx-runtime";
10
+ import { jsx, jsxs } from "react/jsx-runtime";
11
11
  var HtmlInCanvasPresentation = ({
12
12
  children,
13
13
  onElementImage,
@@ -23,6 +23,7 @@ var HtmlInCanvasPresentation = ({
23
23
  throw new Error(HTML_IN_CANVAS_UNSUPPORTED_MESSAGE);
24
24
  }
25
25
  const canvasRef = useRef(null);
26
+ const outputCanvasRef = useRef(null);
26
27
  const canvasSubtreeStyle = useMemo(() => {
27
28
  return {
28
29
  width: "100%",
@@ -34,7 +35,21 @@ var HtmlInCanvasPresentation = ({
34
35
  bottom: 0
35
36
  };
36
37
  }, []);
37
- const [offscreenCanvas] = useState(() => new OffscreenCanvas(1, 1));
38
+ const outputCanvasStyle = useMemo(() => {
39
+ return {
40
+ width: "100%",
41
+ height: "100%",
42
+ position: "absolute",
43
+ top: 0,
44
+ left: 0,
45
+ right: 0,
46
+ bottom: 0,
47
+ pointerEvents: "none"
48
+ };
49
+ }, []);
50
+ const captureCanvasRef = useRef(null);
51
+ const captureContextRef = useRef(null);
52
+ const [shaderCanvas] = useState(() => new OffscreenCanvas(1, 1));
38
53
  const passedPropsRef = useRef(passedProps);
39
54
  passedPropsRef.current = passedProps;
40
55
  const memoizedEffects = Internals.useMemoizedEffects({
@@ -43,33 +58,58 @@ var HtmlInCanvasPresentation = ({
43
58
  });
44
59
  const effectsRef = useRef(memoizedEffects);
45
60
  effectsRef.current = memoizedEffects;
46
- const [instance] = useState(() => shader(offscreenCanvas));
61
+ const [instance] = useState(() => shader(shaderCanvas));
47
62
  useLayoutEffect(() => {
63
+ const canvas = canvasRef.current;
64
+ if (!canvas) {
65
+ return () => {
66
+ instance.cleanup();
67
+ };
68
+ }
69
+ const captureCanvas = canvas.transferControlToOffscreen();
70
+ const captureContext = captureCanvas.getContext("2d");
71
+ if (!captureContext) {
72
+ throw new Error("Failed to create capture canvas context");
73
+ }
74
+ captureCanvasRef.current = captureCanvas;
75
+ captureContextRef.current = captureContext;
48
76
  return () => {
49
77
  instance.cleanup();
78
+ captureCanvasRef.current = null;
79
+ captureContextRef.current = null;
50
80
  };
51
- }, [offscreenCanvas, instance]);
81
+ }, [instance]);
52
82
  const chainState = Internals.useEffectChainState();
53
83
  const { delayRender, continueRender } = useDelayRender();
54
84
  const draw = useCallback(async (prevImage, nextImage, progress) => {
55
- if (!canvasRef.current) {
85
+ const outputCanvas = outputCanvasRef.current;
86
+ if (!outputCanvas) {
56
87
  throw new Error("Canvas not found");
57
88
  }
58
89
  const handle = delayRender("onPaint");
90
+ const clearOutput = () => {
91
+ const context = outputCanvas.getContext("2d");
92
+ if (!context) {
93
+ throw new Error("Failed to create output canvas context");
94
+ }
95
+ context.clearRect(0, 0, outputCanvas.width, outputCanvas.height);
96
+ };
59
97
  if (!prevImage && !nextImage) {
60
- continueRender(handle);
61
98
  instance.clear();
99
+ clearOutput();
100
+ continueRender(handle);
62
101
  return;
63
102
  }
64
103
  const width = prevImage?.width ?? nextImage?.width ?? 0;
65
104
  const height = prevImage?.height ?? nextImage?.height ?? 0;
66
105
  if (width === 0 || height === 0) {
67
- continueRender(handle);
68
106
  instance.clear();
107
+ clearOutput();
108
+ continueRender(handle);
69
109
  return;
70
110
  }
71
- offscreenCanvas.width = width;
72
- offscreenCanvas.height = height;
111
+ shaderCanvas.width = width;
112
+ shaderCanvas.height = height;
73
113
  instance.draw({
74
114
  prevImage,
75
115
  nextImage,
@@ -80,14 +120,14 @@ var HtmlInCanvasPresentation = ({
80
120
  });
81
121
  await Internals.runEffectChain({
82
122
  state: chainState.get(width, height),
83
- source: offscreenCanvas,
123
+ source: shaderCanvas,
84
124
  effects: effectsRef.current ?? [],
85
125
  width,
86
126
  height,
87
- output: canvasRef.current
127
+ output: outputCanvas
88
128
  });
89
129
  continueRender(handle);
90
- }, [chainState, instance, offscreenCanvas, continueRender, delayRender]);
130
+ }, [chainState, continueRender, delayRender, instance, shaderCanvas]);
91
131
  const passThrough = bothEnteringAndExiting && presentationDirection === "exiting";
92
132
  useLayoutEffect(() => {
93
133
  if (passThrough) {
@@ -100,11 +140,19 @@ var HtmlInCanvasPresentation = ({
100
140
  canvas.layoutSubtree = true;
101
141
  const onPaint = () => {
102
142
  const firstChild = canvas.firstChild;
103
- if (!firstChild) {
143
+ const captureCanvas = captureCanvasRef.current;
144
+ const captureContext = captureContextRef.current;
145
+ if (!firstChild || !captureCanvas || !captureContext) {
104
146
  return;
105
147
  }
106
148
  const elementImage = canvas.captureElementImage(firstChild);
107
- onElementImage(elementImage, draw);
149
+ try {
150
+ captureContext.reset();
151
+ captureContext.drawElementImage(elementImage, 0, 0);
152
+ } finally {
153
+ elementImage.close();
154
+ }
155
+ onElementImage(captureCanvas, draw);
108
156
  };
109
157
  canvas.addEventListener("paint", onPaint);
110
158
  return () => {
@@ -138,20 +186,39 @@ var HtmlInCanvasPresentation = ({
138
186
  return;
139
187
  }
140
188
  const observer = new ResizeObserver(([entry]) => {
141
- canvas.width = entry.devicePixelContentBoxSize[0].inlineSize;
142
- canvas.height = entry.devicePixelContentBoxSize[0].blockSize;
189
+ const outputCanvas = outputCanvasRef.current;
190
+ const captureCanvas = captureCanvasRef.current;
191
+ if (!outputCanvas || !captureCanvas) {
192
+ return;
193
+ }
194
+ const width = entry.devicePixelContentBoxSize[0].inlineSize;
195
+ const height = entry.devicePixelContentBoxSize[0].blockSize;
196
+ captureCanvas.width = width;
197
+ captureCanvas.height = height;
198
+ outputCanvas.width = width;
199
+ outputCanvas.height = height;
200
+ canvas.requestPaint?.();
143
201
  });
144
202
  observer.observe(canvas, { box: "device-pixel-content-box" });
203
+ return () => {
204
+ observer.disconnect();
205
+ };
145
206
  }, [passThrough]);
146
207
  if (passThrough) {
147
208
  return children;
148
209
  }
149
- return /* @__PURE__ */ jsx(AbsoluteFill, {
150
- children: /* @__PURE__ */ jsx("canvas", {
151
- ref: canvasRef,
152
- style: canvasSubtreeStyle,
153
- children
154
- })
210
+ return /* @__PURE__ */ jsxs(AbsoluteFill, {
211
+ children: [
212
+ /* @__PURE__ */ jsx("canvas", {
213
+ ref: canvasRef,
214
+ style: canvasSubtreeStyle,
215
+ children
216
+ }),
217
+ /* @__PURE__ */ jsx("canvas", {
218
+ ref: outputCanvasRef,
219
+ style: outputCanvasStyle
220
+ })
221
+ ]
155
222
  });
156
223
  };
157
224
  var makeHtmlInCanvasPresentation = (shader) => {
@@ -173,6 +240,11 @@ var makeHtmlInCanvasPresentation = (shader) => {
173
240
  };
174
241
  };
175
242
 
243
+ // src/presentations/upload-element-image.ts
244
+ var uploadElementImage = (gl, elementImage) => {
245
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, elementImage);
246
+ };
247
+
176
248
  // src/presentations/linear-blur.tsx
177
249
  var VERTEX_SHADER = `#version 300 es
178
250
  in vec2 a_pos;
@@ -317,13 +389,13 @@ var linearBlurShader = (canvas) => {
317
389
  gl.activeTexture(gl.TEXTURE0);
318
390
  gl.bindTexture(gl.TEXTURE_2D, prevTex);
319
391
  if (prevImage) {
320
- gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, prevImage);
392
+ uploadElementImage(gl, prevImage);
321
393
  }
322
394
  gl.uniform1i(uPrev, 0);
323
395
  gl.activeTexture(gl.TEXTURE1);
324
396
  gl.bindTexture(gl.TEXTURE_2D, nextTex);
325
397
  if (nextImage) {
326
- gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, nextImage);
398
+ uploadElementImage(gl, nextImage);
327
399
  }
328
400
  gl.uniform1i(uNext, 1);
329
401
  gl.uniform1f(uTime, effectiveTime);