@remotion/effects 4.0.475 → 4.0.477

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.
@@ -1,4 +1,4 @@
1
- // src/rings.ts
1
+ // src/pattern.ts
2
2
  import { Internals } from "remotion";
3
3
 
4
4
  // src/validate-effect-param.ts
@@ -106,15 +106,499 @@ var parseColorRgba = (ctx, color) => {
106
106
  return [data[0], data[1], data[2], data[3]];
107
107
  };
108
108
 
109
- // src/rings.ts
109
+ // src/pattern.ts
110
110
  var { createEffect, createWebGL2ContextError } = Internals;
111
+ var DEFAULT_SCALE = 0.1;
112
+ var DEFAULT_CROP = 0;
113
+ var DEFAULT_GAP = 0;
114
+ var DEFAULT_OFFSET = 0;
115
+ var DEFAULT_OFFSET_EVERY = 0;
116
+ var DEFAULT_ORIGIN = [0, 0];
117
+ var DEFAULT_WRAP = true;
118
+ var patternSchema = {
119
+ scale: {
120
+ type: "number",
121
+ min: 0.001,
122
+ max: 2,
123
+ step: 0.01,
124
+ default: DEFAULT_SCALE,
125
+ description: "Scale",
126
+ hiddenFromList: false
127
+ },
128
+ cropLeft: {
129
+ type: "number",
130
+ step: 1,
131
+ default: DEFAULT_CROP,
132
+ description: "Crop left",
133
+ hiddenFromList: false
134
+ },
135
+ cropTop: {
136
+ type: "number",
137
+ step: 1,
138
+ default: DEFAULT_CROP,
139
+ description: "Crop top",
140
+ hiddenFromList: false
141
+ },
142
+ cropRight: {
143
+ type: "number",
144
+ step: 1,
145
+ default: DEFAULT_CROP,
146
+ description: "Crop right",
147
+ hiddenFromList: false
148
+ },
149
+ cropBottom: {
150
+ type: "number",
151
+ step: 1,
152
+ default: DEFAULT_CROP,
153
+ description: "Crop bottom",
154
+ hiddenFromList: false
155
+ },
156
+ gapX: {
157
+ type: "number",
158
+ step: 1,
159
+ default: DEFAULT_GAP,
160
+ description: "Gap X",
161
+ hiddenFromList: false
162
+ },
163
+ gapY: {
164
+ type: "number",
165
+ step: 1,
166
+ default: DEFAULT_GAP,
167
+ description: "Gap Y",
168
+ hiddenFromList: false
169
+ },
170
+ offsetU: {
171
+ type: "number",
172
+ step: 0.01,
173
+ default: DEFAULT_OFFSET,
174
+ description: "Offset U",
175
+ hiddenFromList: false
176
+ },
177
+ offsetV: {
178
+ type: "number",
179
+ step: 0.01,
180
+ default: DEFAULT_OFFSET,
181
+ description: "Offset V",
182
+ hiddenFromList: false
183
+ },
184
+ rowOffset: {
185
+ type: "number",
186
+ step: 1,
187
+ default: DEFAULT_OFFSET,
188
+ description: "Row offset",
189
+ hiddenFromList: false
190
+ },
191
+ rowOffsetEvery: {
192
+ type: "number",
193
+ min: 0,
194
+ step: 1,
195
+ default: DEFAULT_OFFSET_EVERY,
196
+ description: "Row offset every",
197
+ hiddenFromList: false
198
+ },
199
+ columnOffset: {
200
+ type: "number",
201
+ step: 1,
202
+ default: DEFAULT_OFFSET,
203
+ description: "Column offset",
204
+ hiddenFromList: false
205
+ },
206
+ columnOffsetEvery: {
207
+ type: "number",
208
+ min: 0,
209
+ step: 1,
210
+ default: DEFAULT_OFFSET_EVERY,
211
+ description: "Column offset every",
212
+ hiddenFromList: false
213
+ },
214
+ origin: {
215
+ type: "uv-coordinate",
216
+ min: 0,
217
+ max: 1,
218
+ step: 0.01,
219
+ default: DEFAULT_ORIGIN,
220
+ description: "Origin"
221
+ },
222
+ wrap: {
223
+ type: "boolean",
224
+ default: DEFAULT_WRAP,
225
+ description: "Wrap"
226
+ }
227
+ };
228
+ var resolve = (p) => ({
229
+ scale: p.scale ?? DEFAULT_SCALE,
230
+ cropLeft: p.cropLeft ?? DEFAULT_CROP,
231
+ cropTop: p.cropTop ?? DEFAULT_CROP,
232
+ cropRight: p.cropRight ?? DEFAULT_CROP,
233
+ cropBottom: p.cropBottom ?? DEFAULT_CROP,
234
+ gapX: p.gapX ?? DEFAULT_GAP,
235
+ gapY: p.gapY ?? DEFAULT_GAP,
236
+ offsetU: p.offsetU ?? DEFAULT_OFFSET,
237
+ offsetV: p.offsetV ?? DEFAULT_OFFSET,
238
+ rowOffset: p.rowOffset ?? DEFAULT_OFFSET,
239
+ rowOffsetEvery: p.rowOffsetEvery ?? DEFAULT_OFFSET_EVERY,
240
+ columnOffset: p.columnOffset ?? DEFAULT_OFFSET,
241
+ columnOffsetEvery: p.columnOffsetEvery ?? DEFAULT_OFFSET_EVERY,
242
+ origin: [...p.origin ?? DEFAULT_ORIGIN],
243
+ wrap: p.wrap ?? DEFAULT_WRAP
244
+ });
245
+ var assertOptionalUvCoordinate = (value, name) => {
246
+ if (value === undefined) {
247
+ return;
248
+ }
249
+ if (!Array.isArray(value) || value.length !== 2 || value.some((item) => typeof item !== "number" || !Number.isFinite(item))) {
250
+ throw new TypeError(`"${name}" must be a [number, number] tuple`);
251
+ }
252
+ };
253
+ var assertOptionalInteger = (value, name) => {
254
+ if (value === undefined) {
255
+ return;
256
+ }
257
+ if (!Number.isInteger(value)) {
258
+ throw new TypeError(`"${name}" must be an integer, but got ${JSON.stringify(value)}`);
259
+ }
260
+ };
261
+ var validatePositive = (value, name) => {
262
+ if (value <= 0) {
263
+ throw new TypeError(`"${name}" must be > 0`);
264
+ }
265
+ };
266
+ var validateAtLeast = (value, min, name) => {
267
+ if (value < min) {
268
+ throw new TypeError(`"${name}" must be >= ${min}, but got ${JSON.stringify(value)}`);
269
+ }
270
+ };
271
+ var validateNonNegative2 = (value, name) => {
272
+ if (value < 0) {
273
+ throw new TypeError(`"${name}" must be >= 0, but got ${JSON.stringify(value)}`);
274
+ }
275
+ };
276
+ var validatePatternParams = (params) => {
277
+ assertEffectParamsObject(params, "Pattern");
278
+ assertOptionalFiniteNumber(params.scale, "scale");
279
+ assertOptionalFiniteNumber(params.cropLeft, "cropLeft");
280
+ assertOptionalFiniteNumber(params.cropTop, "cropTop");
281
+ assertOptionalFiniteNumber(params.cropRight, "cropRight");
282
+ assertOptionalFiniteNumber(params.cropBottom, "cropBottom");
283
+ assertOptionalFiniteNumber(params.gapX, "gapX");
284
+ assertOptionalFiniteNumber(params.gapY, "gapY");
285
+ assertOptionalFiniteNumber(params.offsetU, "offsetU");
286
+ assertOptionalFiniteNumber(params.offsetV, "offsetV");
287
+ assertOptionalFiniteNumber(params.rowOffset, "rowOffset");
288
+ assertOptionalFiniteNumber(params.rowOffsetEvery, "rowOffsetEvery");
289
+ assertOptionalFiniteNumber(params.columnOffset, "columnOffset");
290
+ assertOptionalFiniteNumber(params.columnOffsetEvery, "columnOffsetEvery");
291
+ assertOptionalUvCoordinate(params.origin, "origin");
292
+ assertOptionalBoolean(params.wrap, "wrap");
293
+ assertOptionalInteger(params.rowOffsetEvery, "rowOffsetEvery");
294
+ assertOptionalInteger(params.columnOffsetEvery, "columnOffsetEvery");
295
+ const r = resolve(params);
296
+ validatePositive(r.scale, "scale");
297
+ validateNonNegative2(r.gapX, "gapX");
298
+ validateNonNegative2(r.gapY, "gapY");
299
+ validateAtLeast(r.rowOffsetEvery, 0, "rowOffsetEvery");
300
+ validateAtLeast(r.columnOffsetEvery, 0, "columnOffsetEvery");
301
+ validateUnitInterval(r.origin[0], "origin[0]");
302
+ validateUnitInterval(r.origin[1], "origin[1]");
303
+ };
304
+ var PATTERN_VS = `#version 300 es
305
+ in vec2 aPos;
306
+ in vec2 aUv;
307
+ out vec2 vUv;
308
+
309
+ void main() {
310
+ vUv = aUv;
311
+ gl_Position = vec4(aPos, 0.0, 1.0);
312
+ }
313
+ `;
314
+ var PATTERN_FS = `#version 300 es
315
+ precision highp float;
316
+
317
+ in vec2 vUv;
318
+ out vec4 fragColor;
319
+
320
+ uniform sampler2D uSource;
321
+ uniform vec2 uResolution;
322
+ uniform float uScale;
323
+ uniform vec4 uCrop;
324
+ uniform vec2 uGap;
325
+ uniform vec2 uOffset;
326
+ uniform vec2 uRowOffset;
327
+ uniform vec2 uColumnOffset;
328
+ uniform vec2 uOrigin;
329
+ uniform bool uWrap;
330
+
331
+ float positiveModulo(float value, float modulo) {
332
+ return mod(mod(value, modulo) + modulo, modulo);
333
+ }
334
+
335
+ float getPhase(float index, float every) {
336
+ if (every == 0.0) {
337
+ return index;
338
+ }
339
+
340
+ return positiveModulo(index, every);
341
+ }
342
+
343
+ bool sampleCell(vec2 cell, vec2 fragPx, vec2 cropStart, vec2 tileSize, vec2 pitch, vec2 originPx, out vec4 color) {
344
+ if (!uWrap && (cell.x < 0.0 || cell.y < 0.0)) {
345
+ return false;
346
+ }
347
+
348
+ float rowPhase = getPhase(cell.y, uRowOffset.y);
349
+ float columnPhase = getPhase(cell.x, uColumnOffset.y);
350
+ vec2 stagger = vec2(rowPhase * uRowOffset.x, columnPhase * uColumnOffset.x);
351
+ vec2 localPx = fragPx - originPx - stagger - cell * pitch;
352
+
353
+ if (localPx.x < 0.0 || localPx.y < 0.0 || localPx.x >= tileSize.x || localPx.y >= tileSize.y) {
354
+ return false;
355
+ }
356
+
357
+ vec2 sourcePx = cropStart + localPx / uScale;
358
+ vec2 sourceUv = vec2(sourcePx.x / uResolution.x, 1.0 - sourcePx.y / uResolution.y);
359
+
360
+ if (sourceUv.x < 0.0 || sourceUv.y < 0.0 || sourceUv.x > 1.0 || sourceUv.y > 1.0) {
361
+ return false;
362
+ }
363
+
364
+ color = texture(uSource, sourceUv);
365
+ return true;
366
+ }
367
+
368
+ void main() {
369
+ vec2 cropStart = uCrop.xy;
370
+ vec2 cropEnd = uResolution - uCrop.zw;
371
+ vec2 cropSize = max(cropEnd - cropStart, vec2(0.001));
372
+ vec2 tileSize = max(cropSize * uScale, vec2(0.001));
373
+ vec2 pitch = max(tileSize + uGap, vec2(0.001));
374
+ vec2 patternUv = vec2(vUv.x, 1.0 - vUv.y);
375
+ vec2 originPx = (uOrigin + uOffset) * uResolution;
376
+ vec2 fragPx = patternUv * uResolution;
377
+
378
+ vec2 gridPx = fragPx - originPx;
379
+ vec2 cell = floor(gridPx / pitch);
380
+
381
+ for (int i = 0; i < 4; i++) {
382
+ float rowPhase = getPhase(cell.y, uRowOffset.y);
383
+ float columnPhase = getPhase(cell.x, uColumnOffset.y);
384
+ vec2 stagger = vec2(rowPhase * uRowOffset.x, columnPhase * uColumnOffset.x);
385
+ vec2 adjustedGridPx = fragPx - originPx - stagger;
386
+ vec2 nextCell = floor(adjustedGridPx / pitch);
387
+
388
+ if (all(equal(nextCell, cell))) {
389
+ break;
390
+ }
391
+
392
+ cell = nextCell;
393
+ }
394
+
395
+ vec4 color = vec4(0.0);
396
+ for (int y = -4; y <= 4; y++) {
397
+ for (int x = -4; x <= 4; x++) {
398
+ if (sampleCell(cell + vec2(float(x), float(y)), fragPx, cropStart, tileSize, pitch, originPx, color)) {
399
+ fragColor = color;
400
+ return;
401
+ }
402
+ }
403
+ }
404
+
405
+ fragColor = vec4(0.0);
406
+ }
407
+ `;
408
+ var compileShader = (gl, type, source) => {
409
+ const shader = gl.createShader(type);
410
+ if (!shader) {
411
+ throw new Error("Failed to create WebGL shader");
412
+ }
413
+ gl.shaderSource(shader, source);
414
+ gl.compileShader(shader);
415
+ if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
416
+ const log = gl.getShaderInfoLog(shader);
417
+ gl.deleteShader(shader);
418
+ throw new Error(`Pattern shader compile failed: ${log ?? "(no log)"}`);
419
+ }
420
+ return shader;
421
+ };
422
+ var linkProgram = (gl, vs, fs) => {
423
+ const program = gl.createProgram();
424
+ if (!program) {
425
+ throw new Error("Failed to create WebGL program");
426
+ }
427
+ gl.attachShader(program, vs);
428
+ gl.attachShader(program, fs);
429
+ gl.linkProgram(program);
430
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
431
+ const log = gl.getProgramInfoLog(program);
432
+ gl.deleteProgram(program);
433
+ throw new Error(`Pattern program link failed: ${log ?? "(no log)"}`);
434
+ }
435
+ return program;
436
+ };
437
+ var pattern = createEffect({
438
+ type: "remotion/pattern",
439
+ label: "pattern()",
440
+ documentationLink: "https://www.remotion.dev/docs/effects/pattern",
441
+ backend: "webgl2",
442
+ calculateKey: (params) => {
443
+ const r = resolve(params);
444
+ return `pattern-${r.scale}-${r.cropLeft}-${r.cropTop}-${r.cropRight}-${r.cropBottom}-${r.gapX}-${r.gapY}-${r.offsetU}-${r.offsetV}-${r.rowOffset}-${r.rowOffsetEvery}-${r.columnOffset}-${r.columnOffsetEvery}-${r.origin[0]}-${r.origin[1]}-${r.wrap ? 1 : 0}`;
445
+ },
446
+ setup: (target) => {
447
+ const gl = target.getContext("webgl2", {
448
+ premultipliedAlpha: true,
449
+ alpha: true,
450
+ preserveDrawingBuffer: true
451
+ });
452
+ if (!gl) {
453
+ throw createWebGL2ContextError("pattern effect");
454
+ }
455
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
456
+ const vs = compileShader(gl, gl.VERTEX_SHADER, PATTERN_VS);
457
+ const fs = compileShader(gl, gl.FRAGMENT_SHADER, PATTERN_FS);
458
+ const program = linkProgram(gl, vs, fs);
459
+ gl.deleteShader(vs);
460
+ gl.deleteShader(fs);
461
+ const vao = gl.createVertexArray();
462
+ if (!vao) {
463
+ throw new Error("Failed to create WebGL vertex array");
464
+ }
465
+ gl.bindVertexArray(vao);
466
+ const data = new Float32Array([
467
+ -1,
468
+ -1,
469
+ 0,
470
+ 0,
471
+ 1,
472
+ -1,
473
+ 1,
474
+ 0,
475
+ -1,
476
+ 1,
477
+ 0,
478
+ 1,
479
+ 1,
480
+ 1,
481
+ 1,
482
+ 1
483
+ ]);
484
+ const vbo = gl.createBuffer();
485
+ if (!vbo) {
486
+ throw new Error("Failed to create WebGL buffer");
487
+ }
488
+ gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
489
+ gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
490
+ const aPos = gl.getAttribLocation(program, "aPos");
491
+ const aUv = gl.getAttribLocation(program, "aUv");
492
+ gl.enableVertexAttribArray(aPos);
493
+ gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 16, 0);
494
+ gl.enableVertexAttribArray(aUv);
495
+ gl.vertexAttribPointer(aUv, 2, gl.FLOAT, false, 16, 8);
496
+ gl.bindVertexArray(null);
497
+ const texture = gl.createTexture();
498
+ if (!texture) {
499
+ throw new Error("Failed to create WebGL texture");
500
+ }
501
+ gl.bindTexture(gl.TEXTURE_2D, texture);
502
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
503
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
504
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
505
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
506
+ gl.bindTexture(gl.TEXTURE_2D, null);
507
+ return {
508
+ gl,
509
+ program,
510
+ vao,
511
+ vbo,
512
+ texture,
513
+ uniforms: {
514
+ uSource: gl.getUniformLocation(program, "uSource"),
515
+ uResolution: gl.getUniformLocation(program, "uResolution"),
516
+ uScale: gl.getUniformLocation(program, "uScale"),
517
+ uCrop: gl.getUniformLocation(program, "uCrop"),
518
+ uGap: gl.getUniformLocation(program, "uGap"),
519
+ uOffset: gl.getUniformLocation(program, "uOffset"),
520
+ uRowOffset: gl.getUniformLocation(program, "uRowOffset"),
521
+ uColumnOffset: gl.getUniformLocation(program, "uColumnOffset"),
522
+ uOrigin: gl.getUniformLocation(program, "uOrigin"),
523
+ uWrap: gl.getUniformLocation(program, "uWrap")
524
+ }
525
+ };
526
+ },
527
+ apply: ({ source, width, height, params, state, flipSourceY }) => {
528
+ const r = resolve(params);
529
+ const { gl, program, vao, texture, uniforms } = state;
530
+ gl.viewport(0, 0, width, height);
531
+ gl.clearColor(0, 0, 0, 0);
532
+ gl.clear(gl.COLOR_BUFFER_BIT);
533
+ gl.useProgram(program);
534
+ gl.bindVertexArray(vao);
535
+ gl.activeTexture(gl.TEXTURE0);
536
+ gl.bindTexture(gl.TEXTURE_2D, texture);
537
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipSourceY);
538
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
539
+ if (uniforms.uSource)
540
+ gl.uniform1i(uniforms.uSource, 0);
541
+ if (uniforms.uResolution)
542
+ gl.uniform2f(uniforms.uResolution, width, height);
543
+ if (uniforms.uScale)
544
+ gl.uniform1f(uniforms.uScale, r.scale);
545
+ if (uniforms.uCrop)
546
+ gl.uniform4f(uniforms.uCrop, r.cropLeft, r.cropTop, r.cropRight, r.cropBottom);
547
+ if (uniforms.uGap)
548
+ gl.uniform2f(uniforms.uGap, r.gapX, r.gapY);
549
+ if (uniforms.uOffset)
550
+ gl.uniform2f(uniforms.uOffset, r.offsetU, r.offsetV);
551
+ if (uniforms.uRowOffset)
552
+ gl.uniform2f(uniforms.uRowOffset, r.rowOffset, r.rowOffsetEvery);
553
+ if (uniforms.uColumnOffset)
554
+ gl.uniform2f(uniforms.uColumnOffset, r.columnOffset, r.columnOffsetEvery);
555
+ if (uniforms.uOrigin)
556
+ gl.uniform2f(uniforms.uOrigin, r.origin[0], r.origin[1]);
557
+ if (uniforms.uWrap)
558
+ gl.uniform1i(uniforms.uWrap, r.wrap ? 1 : 0);
559
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
560
+ gl.bindVertexArray(null);
561
+ gl.bindTexture(gl.TEXTURE_2D, null);
562
+ gl.useProgram(null);
563
+ },
564
+ cleanup: ({ gl, program, vao, vbo, texture }) => {
565
+ gl.deleteBuffer(vbo);
566
+ gl.deleteProgram(program);
567
+ gl.deleteVertexArray(vao);
568
+ gl.deleteTexture(texture);
569
+ },
570
+ schema: patternSchema,
571
+ validateParams: validatePatternParams
572
+ });
573
+
574
+ // src/rings.ts
575
+ import { Internals as Internals2 } from "remotion";
576
+
577
+ // src/uv-coordinate.ts
578
+ var publicUvToShaderUv = (uv) => {
579
+ return [uv[0], 1 - uv[1]];
580
+ };
581
+
582
+ // src/rings.ts
583
+ var { createEffect: createEffect2, createWebGL2ContextError: createWebGL2ContextError2 } = Internals2;
111
584
  var DEFAULT_COLORS = ["#dff4ff", "#7cc6ff"];
112
585
  var DEFAULT_CENTER = [0.5, 0.5];
113
586
  var DEFAULT_THICKNESS = 40;
114
- var DEFAULT_GAP = 0;
115
- var DEFAULT_OFFSET = 0;
587
+ var DEFAULT_GAP2 = 0;
588
+ var DEFAULT_OFFSET2 = 0;
116
589
  var DEFAULT_MASK_TO_SOURCE_ALPHA = false;
117
590
  var ringsSchema = {
591
+ colors: {
592
+ type: "array",
593
+ item: {
594
+ type: "color"
595
+ },
596
+ default: DEFAULT_COLORS,
597
+ minLength: 2,
598
+ newItemDefault: "#ff0000",
599
+ description: "Colors",
600
+ keyframable: false
601
+ },
118
602
  center: {
119
603
  type: "uv-coordinate",
120
604
  min: 0,
@@ -137,14 +621,14 @@ var ringsSchema = {
137
621
  min: 0,
138
622
  max: 400,
139
623
  step: 0.1,
140
- default: DEFAULT_GAP,
624
+ default: DEFAULT_GAP2,
141
625
  description: "Gap",
142
626
  hiddenFromList: false
143
627
  },
144
628
  offset: {
145
629
  type: "number",
146
630
  step: 0.1,
147
- default: DEFAULT_OFFSET,
631
+ default: DEFAULT_OFFSET2,
148
632
  description: "Offset",
149
633
  hiddenFromList: false
150
634
  },
@@ -154,24 +638,24 @@ var ringsSchema = {
154
638
  description: "Mask to source alpha"
155
639
  }
156
640
  };
157
- var resolve = (p) => {
641
+ var resolve2 = (p) => {
158
642
  const thickness = p.thickness ?? DEFAULT_THICKNESS;
159
- const gap = p.gap ?? DEFAULT_GAP;
643
+ const gap = p.gap ?? DEFAULT_GAP2;
160
644
  return {
161
645
  colors: p.colors ?? DEFAULT_COLORS,
162
646
  center: [...p.center ?? DEFAULT_CENTER],
163
647
  thickness,
164
648
  spacing: thickness + gap,
165
- offset: p.offset ?? DEFAULT_OFFSET,
649
+ offset: p.offset ?? DEFAULT_OFFSET2,
166
650
  maskToSourceAlpha: p.maskToSourceAlpha ?? DEFAULT_MASK_TO_SOURCE_ALPHA
167
651
  };
168
652
  };
169
- var validatePositive = (value, name) => {
653
+ var validatePositive2 = (value, name) => {
170
654
  if (value <= 0) {
171
655
  throw new TypeError(`"${name}" must be greater than 0, but got ${JSON.stringify(value)}`);
172
656
  }
173
657
  };
174
- var validateNonNegative2 = (value, name) => {
658
+ var validateNonNegative3 = (value, name) => {
175
659
  if (value < 0) {
176
660
  throw new TypeError(`"${name}" must be greater than or equal to 0, but got ${JSON.stringify(value)}`);
177
661
  }
@@ -206,9 +690,9 @@ var validateRingsParams = (params) => {
206
690
  assertOptionalFiniteNumber(params.offset, "offset");
207
691
  assertOptionalBoolean(params.maskToSourceAlpha, "maskToSourceAlpha");
208
692
  const thickness = params.thickness ?? DEFAULT_THICKNESS;
209
- const gap = params.gap ?? DEFAULT_GAP;
210
- validatePositive(thickness, "thickness");
211
- validateNonNegative2(gap, "gap");
693
+ const gap = params.gap ?? DEFAULT_GAP2;
694
+ validatePositive2(thickness, "thickness");
695
+ validateNonNegative3(gap, "gap");
212
696
  };
213
697
  var RINGS_VS = `#version 300 es
214
698
  in vec2 aPos;
@@ -275,7 +759,7 @@ void main() {
275
759
  );
276
760
  }
277
761
  `;
278
- var compileShader = (gl, type, source) => {
762
+ var compileShader2 = (gl, type, source) => {
279
763
  const shader = gl.createShader(type);
280
764
  if (!shader) {
281
765
  throw new Error("Failed to create WebGL shader");
@@ -289,7 +773,7 @@ var compileShader = (gl, type, source) => {
289
773
  }
290
774
  return shader;
291
775
  };
292
- var linkProgram = (gl, vs, fs) => {
776
+ var linkProgram2 = (gl, vs, fs) => {
293
777
  const program = gl.createProgram();
294
778
  if (!program) {
295
779
  throw new Error("Failed to create WebGL program");
@@ -305,9 +789,9 @@ var linkProgram = (gl, vs, fs) => {
305
789
  return program;
306
790
  };
307
791
  var createProgram = (gl, vertexSource, fragmentSource) => {
308
- const vs = compileShader(gl, gl.VERTEX_SHADER, vertexSource);
309
- const fs = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSource);
310
- const program = linkProgram(gl, vs, fs);
792
+ const vs = compileShader2(gl, gl.VERTEX_SHADER, vertexSource);
793
+ const fs = compileShader2(gl, gl.FRAGMENT_SHADER, fragmentSource);
794
+ const program = linkProgram2(gl, vs, fs);
311
795
  gl.deleteShader(vs);
312
796
  gl.deleteShader(fs);
313
797
  return program;
@@ -332,7 +816,7 @@ var setupRings = (target) => {
332
816
  preserveDrawingBuffer: true
333
817
  });
334
818
  if (!gl) {
335
- throw createWebGL2ContextError("rings effect");
819
+ throw createWebGL2ContextError2("rings effect");
336
820
  }
337
821
  gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
338
822
  const program = createProgram(gl, RINGS_VS, RINGS_FS);
@@ -423,19 +907,19 @@ var updatePalette = (state, colors) => {
423
907
  }
424
908
  return true;
425
909
  };
426
- var rings = createEffect({
910
+ var rings = createEffect2({
427
911
  type: "remotion/rings",
428
912
  label: "rings()",
429
913
  documentationLink: "https://www.remotion.dev/docs/effects/rings",
430
914
  backend: "webgl2",
431
915
  calculateKey: (params) => {
432
- const r = resolve(params);
916
+ const r = resolve2(params);
433
917
  const maskSuffix = r.maskToSourceAlpha ? "-mask-to-source-alpha" : "";
434
918
  return `rings-${r.colors.join("|")}-${r.center.join(":")}-${r.thickness}-${r.spacing}-${r.offset}${maskSuffix}`;
435
919
  },
436
920
  setup: (target) => setupRings(target),
437
921
  apply: ({ source, width, height, params, state, flipSourceY }) => {
438
- const r = resolve(params);
922
+ const r = resolve2(params);
439
923
  const paletteDirty = updatePalette(state, r.colors);
440
924
  const { gl, program, sourceTexture, paletteTexture, uniforms, vao } = state;
441
925
  gl.viewport(0, 0, width, height);
@@ -464,8 +948,10 @@ var rings = createEffect({
464
948
  gl.uniform2f(uniforms.uResolution, width, height);
465
949
  if (uniforms.uNumColors)
466
950
  gl.uniform1f(uniforms.uNumColors, r.colors.length);
467
- if (uniforms.uCenter)
468
- gl.uniform2f(uniforms.uCenter, r.center[0], r.center[1]);
951
+ if (uniforms.uCenter) {
952
+ const shaderCenter = publicUvToShaderUv(r.center);
953
+ gl.uniform2f(uniforms.uCenter, shaderCenter[0], shaderCenter[1]);
954
+ }
469
955
  if (uniforms.uThickness)
470
956
  gl.uniform1f(uniforms.uThickness, r.thickness);
471
957
  if (uniforms.uSpacing)
@@ -492,19 +978,30 @@ var rings = createEffect({
492
978
  });
493
979
 
494
980
  // src/zigzag.ts
495
- import { Internals as Internals2 } from "remotion";
496
- var { createEffect: createEffect2, createWebGL2ContextError: createWebGL2ContextError2 } = Internals2;
981
+ import { Internals as Internals3 } from "remotion";
982
+ var { createEffect: createEffect3, createWebGL2ContextError: createWebGL2ContextError3 } = Internals3;
497
983
  var ZIGZAG_DIRECTIONS = ["horizontal", "vertical"];
498
984
  var DEFAULT_COLORS2 = ["#dff4ff", "#7cc6ff"];
499
985
  var DEFAULT_DIRECTION = "horizontal";
500
986
  var DEFAULT_THICKNESS2 = 40;
501
- var DEFAULT_GAP2 = 0;
987
+ var DEFAULT_GAP3 = 0;
502
988
  var DEFAULT_ANGLE = 0;
503
- var DEFAULT_OFFSET2 = 0;
989
+ var DEFAULT_OFFSET3 = 0;
504
990
  var DEFAULT_AMPLITUDE = 40;
505
991
  var DEFAULT_WAVELENGTH = 160;
506
992
  var DEFAULT_MASK_TO_SOURCE_ALPHA2 = false;
507
993
  var zigzagSchema = {
994
+ colors: {
995
+ type: "array",
996
+ item: {
997
+ type: "color"
998
+ },
999
+ default: DEFAULT_COLORS2,
1000
+ minLength: 2,
1001
+ newItemDefault: "#ff0000",
1002
+ description: "Colors",
1003
+ keyframable: false
1004
+ },
508
1005
  direction: {
509
1006
  type: "enum",
510
1007
  variants: {
@@ -528,7 +1025,7 @@ var zigzagSchema = {
528
1025
  min: 0,
529
1026
  max: 400,
530
1027
  step: 0.1,
531
- default: DEFAULT_GAP2,
1028
+ default: DEFAULT_GAP3,
532
1029
  description: "Gap",
533
1030
  hiddenFromList: false
534
1031
  },
@@ -541,7 +1038,7 @@ var zigzagSchema = {
541
1038
  offset: {
542
1039
  type: "number",
543
1040
  step: 0.1,
544
- default: DEFAULT_OFFSET2,
1041
+ default: DEFAULT_OFFSET3,
545
1042
  description: "Offset",
546
1043
  hiddenFromList: false
547
1044
  },
@@ -569,16 +1066,16 @@ var zigzagSchema = {
569
1066
  description: "Mask to source alpha"
570
1067
  }
571
1068
  };
572
- var resolve2 = (p) => {
1069
+ var resolve3 = (p) => {
573
1070
  const thickness = p.thickness ?? DEFAULT_THICKNESS2;
574
- const gap = p.gap ?? DEFAULT_GAP2;
1071
+ const gap = p.gap ?? DEFAULT_GAP3;
575
1072
  return {
576
1073
  colors: p.colors ?? DEFAULT_COLORS2,
577
1074
  direction: p.direction ?? DEFAULT_DIRECTION,
578
1075
  thickness,
579
1076
  spacing: thickness + gap,
580
1077
  angle: p.angle ?? DEFAULT_ANGLE,
581
- offset: p.offset ?? DEFAULT_OFFSET2,
1078
+ offset: p.offset ?? DEFAULT_OFFSET3,
582
1079
  amplitude: p.amplitude ?? DEFAULT_AMPLITUDE,
583
1080
  wavelength: p.wavelength ?? DEFAULT_WAVELENGTH,
584
1081
  maskToSourceAlpha: p.maskToSourceAlpha ?? DEFAULT_MASK_TO_SOURCE_ALPHA2
@@ -590,12 +1087,12 @@ var formatEnum = (variants) => {
590
1087
  }
591
1088
  return `${variants.slice(0, -1).map((variant) => `"${variant}"`).join(", ")} or "${variants[variants.length - 1]}"`;
592
1089
  };
593
- var validatePositive2 = (value, name) => {
1090
+ var validatePositive3 = (value, name) => {
594
1091
  if (value <= 0) {
595
1092
  throw new TypeError(`"${name}" must be greater than 0, but got ${JSON.stringify(value)}`);
596
1093
  }
597
1094
  };
598
- var validateNonNegative3 = (value, name) => {
1095
+ var validateNonNegative4 = (value, name) => {
599
1096
  if (value < 0) {
600
1097
  throw new TypeError(`"${name}" must be greater than or equal to 0, but got ${JSON.stringify(value)}`);
601
1098
  }
@@ -631,13 +1128,13 @@ var validateZigzagParams = (params) => {
631
1128
  assertOptionalFiniteNumber(params.wavelength, "wavelength");
632
1129
  assertOptionalBoolean(params.maskToSourceAlpha, "maskToSourceAlpha");
633
1130
  const thickness = params.thickness ?? DEFAULT_THICKNESS2;
634
- const gap = params.gap ?? DEFAULT_GAP2;
1131
+ const gap = params.gap ?? DEFAULT_GAP3;
635
1132
  const amplitude = params.amplitude ?? DEFAULT_AMPLITUDE;
636
1133
  const wavelength = params.wavelength ?? DEFAULT_WAVELENGTH;
637
- validatePositive2(thickness, "thickness");
638
- validateNonNegative3(gap, "gap");
639
- validateNonNegative3(amplitude, "amplitude");
640
- validatePositive2(wavelength, "wavelength");
1134
+ validatePositive3(thickness, "thickness");
1135
+ validateNonNegative4(gap, "gap");
1136
+ validateNonNegative4(amplitude, "amplitude");
1137
+ validatePositive3(wavelength, "wavelength");
641
1138
  };
642
1139
  var ZIGZAG_VS = `#version 300 es
643
1140
  in vec2 aPos;
@@ -715,7 +1212,7 @@ void main() {
715
1212
  );
716
1213
  }
717
1214
  `;
718
- var compileShader2 = (gl, type, source) => {
1215
+ var compileShader3 = (gl, type, source) => {
719
1216
  const shader = gl.createShader(type);
720
1217
  if (!shader) {
721
1218
  throw new Error("Failed to create WebGL shader");
@@ -729,7 +1226,7 @@ var compileShader2 = (gl, type, source) => {
729
1226
  }
730
1227
  return shader;
731
1228
  };
732
- var linkProgram2 = (gl, vs, fs) => {
1229
+ var linkProgram3 = (gl, vs, fs) => {
733
1230
  const program = gl.createProgram();
734
1231
  if (!program) {
735
1232
  throw new Error("Failed to create WebGL program");
@@ -745,9 +1242,9 @@ var linkProgram2 = (gl, vs, fs) => {
745
1242
  return program;
746
1243
  };
747
1244
  var createProgram2 = (gl, vertexSource, fragmentSource) => {
748
- const vs = compileShader2(gl, gl.VERTEX_SHADER, vertexSource);
749
- const fs = compileShader2(gl, gl.FRAGMENT_SHADER, fragmentSource);
750
- const program = linkProgram2(gl, vs, fs);
1245
+ const vs = compileShader3(gl, gl.VERTEX_SHADER, vertexSource);
1246
+ const fs = compileShader3(gl, gl.FRAGMENT_SHADER, fragmentSource);
1247
+ const program = linkProgram3(gl, vs, fs);
751
1248
  gl.deleteShader(vs);
752
1249
  gl.deleteShader(fs);
753
1250
  return program;
@@ -772,7 +1269,7 @@ var setupZigzag = (target) => {
772
1269
  preserveDrawingBuffer: true
773
1270
  });
774
1271
  if (!gl) {
775
- throw createWebGL2ContextError2("zigzag effect");
1272
+ throw createWebGL2ContextError3("zigzag effect");
776
1273
  }
777
1274
  gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
778
1275
  const program = createProgram2(gl, ZIGZAG_VS, ZIGZAG_FS);
@@ -866,19 +1363,19 @@ var updatePalette2 = (state, colors) => {
866
1363
  }
867
1364
  return true;
868
1365
  };
869
- var zigzag = createEffect2({
1366
+ var zigzag = createEffect3({
870
1367
  type: "remotion/zigzag",
871
1368
  label: "zigzag()",
872
1369
  documentationLink: "https://www.remotion.dev/docs/effects/zigzag",
873
1370
  backend: "webgl2",
874
1371
  calculateKey: (params) => {
875
- const r = resolve2(params);
1372
+ const r = resolve3(params);
876
1373
  const maskSuffix = r.maskToSourceAlpha ? "-mask-to-source-alpha" : "";
877
1374
  return `zigzag-${r.colors.join("|")}-${r.direction}-${r.thickness}-${r.spacing}-${r.angle}-${r.offset}-${r.amplitude}-${r.wavelength}${maskSuffix}`;
878
1375
  },
879
1376
  setup: (target) => setupZigzag(target),
880
1377
  apply: ({ source, width, height, params, state, flipSourceY }) => {
881
- const r = resolve2(params);
1378
+ const r = resolve3(params);
882
1379
  const paletteDirty = updatePalette2(state, r.colors);
883
1380
  const { gl, program, sourceTexture, paletteTexture, uniforms, vao } = state;
884
1381
  gl.viewport(0, 0, width, height);
@@ -948,5 +1445,6 @@ var zigzag = createEffect2({
948
1445
  });
949
1446
  export {
950
1447
  zigzag,
951
- rings
1448
+ rings,
1449
+ pattern
952
1450
  };