@remotion/effects 4.0.511 → 4.0.513

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.
@@ -970,8 +970,159 @@ var pattern = createEffect2({
970
970
  validateParams: validatePatternParams
971
971
  });
972
972
 
973
- // src/rings.ts
973
+ // src/tile.ts
974
974
  import { Internals as Internals3 } from "remotion";
975
+ var { createEffect: createEffect3 } = Internals3;
976
+ var DEFAULT_HORIZONTAL = true;
977
+ var DEFAULT_VERTICAL = true;
978
+ var tileSchema = {
979
+ horizontal: {
980
+ type: "boolean",
981
+ default: DEFAULT_HORIZONTAL,
982
+ description: "Horizontal"
983
+ },
984
+ vertical: {
985
+ type: "boolean",
986
+ default: DEFAULT_VERTICAL,
987
+ description: "Vertical"
988
+ }
989
+ };
990
+ var resolve3 = (params) => ({
991
+ horizontal: params.horizontal ?? DEFAULT_HORIZONTAL,
992
+ vertical: params.vertical ?? DEFAULT_VERTICAL
993
+ });
994
+ var validateTileParams = (params) => {
995
+ assertEffectParamsObject(params, "Tile");
996
+ assertOptionalBoolean(params.horizontal, "horizontal");
997
+ assertOptionalBoolean(params.vertical, "vertical");
998
+ };
999
+ var tile = createEffect3({
1000
+ type: "dev.remotion.effects.tile",
1001
+ label: "tile()",
1002
+ documentationLink: "https://www.remotion.dev/docs/effects/tile",
1003
+ backend: "2d",
1004
+ calculateKey: (params) => {
1005
+ const r = resolve3(params);
1006
+ return `tile-${r.horizontal}-${r.vertical}`;
1007
+ },
1008
+ setup: (target) => {
1009
+ const boundsCanvas = target.ownerDocument.createElement("canvas");
1010
+ const boundsContext = boundsCanvas.getContext("2d", {
1011
+ colorSpace: "srgb",
1012
+ willReadFrequently: true
1013
+ });
1014
+ if (!boundsContext) {
1015
+ throw new Error("Failed to acquire 2D context for tile effect.");
1016
+ }
1017
+ const tileCanvas = target.ownerDocument.createElement("canvas");
1018
+ const tileContext = tileCanvas.getContext("2d");
1019
+ if (!tileContext) {
1020
+ throw new Error("Failed to acquire 2D context for tile effect.");
1021
+ }
1022
+ return { boundsCanvas, boundsContext, tileCanvas, tileContext };
1023
+ },
1024
+ apply: ({ source, target, width, height, params, state }) => {
1025
+ const context = target.getContext("2d");
1026
+ if (!context) {
1027
+ throw new Error("Failed to acquire 2D context for tile effect. The canvas may have been assigned a different context type.");
1028
+ }
1029
+ const r = resolve3(params);
1030
+ context.clearRect(0, 0, width, height);
1031
+ if (!r.horizontal && !r.vertical) {
1032
+ context.drawImage(source, 0, 0, width, height);
1033
+ return;
1034
+ }
1035
+ if (state.boundsCanvas.width !== width || state.boundsCanvas.height !== height) {
1036
+ state.boundsCanvas.width = width;
1037
+ state.boundsCanvas.height = height;
1038
+ }
1039
+ state.boundsContext.clearRect(0, 0, width, height);
1040
+ state.boundsContext.drawImage(source, 0, 0, width, height);
1041
+ const pixels = state.boundsContext.getImageData(0, 0, width, height).data;
1042
+ const rowMaximumAlpha = (y) => {
1043
+ let maximumAlpha = 0;
1044
+ for (let x = 0;x < width; x++) {
1045
+ maximumAlpha = Math.max(maximumAlpha, pixels[(y * width + x) * 4 + 3]);
1046
+ }
1047
+ return maximumAlpha;
1048
+ };
1049
+ const columnMaximumAlpha = (x, visibleTop, visibleBottom) => {
1050
+ let maximumAlpha = 0;
1051
+ for (let y = visibleTop;y <= visibleBottom; y++) {
1052
+ maximumAlpha = Math.max(maximumAlpha, pixels[(y * width + x) * 4 + 3]);
1053
+ }
1054
+ return maximumAlpha;
1055
+ };
1056
+ let top = 0;
1057
+ while (top < height && rowMaximumAlpha(top) === 0) {
1058
+ top++;
1059
+ }
1060
+ if (top === height) {
1061
+ context.clearRect(0, 0, width, height);
1062
+ return;
1063
+ }
1064
+ let bottom = height - 1;
1065
+ while (bottom > top && rowMaximumAlpha(bottom) === 0) {
1066
+ bottom--;
1067
+ }
1068
+ let left = 0;
1069
+ while (left < width && columnMaximumAlpha(left, top, bottom) === 0) {
1070
+ left++;
1071
+ }
1072
+ let right = width - 1;
1073
+ while (right > left && columnMaximumAlpha(right, top, bottom) === 0) {
1074
+ right--;
1075
+ }
1076
+ if (r.vertical && top < bottom) {
1077
+ if (rowMaximumAlpha(top) < rowMaximumAlpha(top + 1)) {
1078
+ top++;
1079
+ }
1080
+ if (rowMaximumAlpha(bottom) < rowMaximumAlpha(bottom - 1)) {
1081
+ bottom--;
1082
+ }
1083
+ }
1084
+ if (r.horizontal && left < right) {
1085
+ if (columnMaximumAlpha(left, top, bottom) < columnMaximumAlpha(left + 1, top, bottom)) {
1086
+ left++;
1087
+ }
1088
+ if (columnMaximumAlpha(right, top, bottom) < columnMaximumAlpha(right - 1, top, bottom)) {
1089
+ right--;
1090
+ }
1091
+ }
1092
+ const tileWidth = right - left + 1;
1093
+ const tileHeight = bottom - top + 1;
1094
+ state.tileCanvas.width = tileWidth;
1095
+ state.tileCanvas.height = tileHeight;
1096
+ state.tileContext.clearRect(0, 0, tileWidth, tileHeight);
1097
+ state.tileContext.drawImage(source, left, top, tileWidth, tileHeight, 0, 0, tileWidth, tileHeight);
1098
+ context.clearRect(0, 0, width, height);
1099
+ const startX = r.horizontal ? left - Math.ceil(left / tileWidth) * tileWidth : left;
1100
+ const startY = r.vertical ? top - Math.ceil(top / tileHeight) * tileHeight : top;
1101
+ const endX = r.horizontal ? width : left + tileWidth;
1102
+ const endY = r.vertical ? height : top + tileHeight;
1103
+ for (let y = startY;y < endY; y += tileHeight) {
1104
+ const tileY = Math.round((y - top) / tileHeight);
1105
+ const mirrorY = r.vertical && Math.abs(tileY) % 2 === 1;
1106
+ for (let x = startX;x < endX; x += tileWidth) {
1107
+ const tileX = Math.round((x - left) / tileWidth);
1108
+ const mirrorX = r.horizontal && Math.abs(tileX) % 2 === 1;
1109
+ context.save();
1110
+ context.translate(mirrorX ? x + tileWidth : x, mirrorY ? y + tileHeight : y);
1111
+ context.scale(mirrorX ? -1 : 1, mirrorY ? -1 : 1);
1112
+ context.drawImage(state.tileCanvas, 0, 0);
1113
+ context.restore();
1114
+ }
1115
+ }
1116
+ },
1117
+ cleanup: () => {
1118
+ return;
1119
+ },
1120
+ schema: tileSchema,
1121
+ validateParams: validateTileParams
1122
+ });
1123
+
1124
+ // src/rings.ts
1125
+ import { Internals as Internals4 } from "remotion";
975
1126
 
976
1127
  // src/uv-coordinate.ts
977
1128
  var publicUvToShaderUv = (uv) => {
@@ -979,7 +1130,7 @@ var publicUvToShaderUv = (uv) => {
979
1130
  };
980
1131
 
981
1132
  // src/rings.ts
982
- var { createEffect: createEffect3, createWebGL2ContextError: createWebGL2ContextError3 } = Internals3;
1133
+ var { createEffect: createEffect4, createWebGL2ContextError: createWebGL2ContextError3 } = Internals4;
983
1134
  var DEFAULT_COLORS2 = ["#dff4ff", "#7cc6ff"];
984
1135
  var DEFAULT_CENTER = [0.5, 0.5];
985
1136
  var DEFAULT_THICKNESS = 40;
@@ -1037,7 +1188,7 @@ var ringsSchema = {
1037
1188
  description: "Mask to source alpha"
1038
1189
  }
1039
1190
  };
1040
- var resolve3 = (p) => {
1191
+ var resolve4 = (p) => {
1041
1192
  const thickness = p.thickness ?? DEFAULT_THICKNESS;
1042
1193
  const gap = p.gap ?? DEFAULT_GAP3;
1043
1194
  return {
@@ -1306,19 +1457,19 @@ var updatePalette2 = (state, colors) => {
1306
1457
  }
1307
1458
  return true;
1308
1459
  };
1309
- var rings = createEffect3({
1460
+ var rings = createEffect4({
1310
1461
  type: "dev.remotion.effects.rings",
1311
1462
  label: "rings()",
1312
1463
  documentationLink: "https://www.remotion.dev/docs/effects/rings",
1313
1464
  backend: "webgl2",
1314
1465
  calculateKey: (params) => {
1315
- const r = resolve3(params);
1466
+ const r = resolve4(params);
1316
1467
  const maskSuffix = r.maskToSourceAlpha ? "-mask-to-source-alpha" : "";
1317
1468
  return `rings-${r.colors.join("|")}-${r.center.join(":")}-${r.thickness}-${r.spacing}-${r.offset}${maskSuffix}`;
1318
1469
  },
1319
1470
  setup: (target) => setupRings(target),
1320
1471
  apply: ({ source, width, height, params, state, flipSourceY }) => {
1321
- const r = resolve3(params);
1472
+ const r = resolve4(params);
1322
1473
  const paletteDirty = updatePalette2(state, r.colors);
1323
1474
  const { gl, program, sourceTexture, paletteTexture, uniforms, vao } = state;
1324
1475
  gl.viewport(0, 0, width, height);
@@ -1377,9 +1528,9 @@ var rings = createEffect3({
1377
1528
  });
1378
1529
 
1379
1530
  // src/starburst.ts
1380
- import { Internals as Internals4 } from "remotion";
1531
+ import { Internals as Internals5 } from "remotion";
1381
1532
  import { NoReactInternals } from "remotion/no-react";
1382
- var { createEffect: createEffect4, createWebGL2ContextError: createWebGL2ContextError4 } = Internals4;
1533
+ var { createEffect: createEffect5, createWebGL2ContextError: createWebGL2ContextError4 } = Internals5;
1383
1534
  var colorToRgb = (color) => {
1384
1535
  const packed = NoReactInternals.processColor(color);
1385
1536
  return [packed >>> 16 & 255, packed >>> 8 & 255, packed & 255];
@@ -1433,7 +1584,7 @@ var starburstEffectSchema = {
1433
1584
  description: "Origin"
1434
1585
  }
1435
1586
  };
1436
- var resolve4 = (p) => ({
1587
+ var resolve5 = (p) => ({
1437
1588
  rays: p.rays,
1438
1589
  colors: p.colors,
1439
1590
  rotation: p.rotation ?? 0,
@@ -1454,7 +1605,7 @@ var validateStarburstEffectParams = (params) => {
1454
1605
  if (!Array.isArray(colors) || colors.length < 2) {
1455
1606
  throw new TypeError(`"colors" must be an array with at least 2 colors, but got ${JSON.stringify(colors)}`);
1456
1607
  }
1457
- const r = resolve4(params);
1608
+ const r = resolve5(params);
1458
1609
  if (typeof r.rotation !== "number" || !Number.isFinite(r.rotation)) {
1459
1610
  throw new TypeError(`"rotation" must be a finite number, but got ${JSON.stringify(params.rotation)}`);
1460
1611
  }
@@ -1561,13 +1712,13 @@ var linkProgram4 = (gl, vs, fs) => {
1561
1712
  }
1562
1713
  return program;
1563
1714
  };
1564
- var starburst = createEffect4({
1715
+ var starburst = createEffect5({
1565
1716
  type: "remotion/starburst",
1566
1717
  label: "starburst()",
1567
1718
  documentationLink: "https://www.remotion.dev/docs/effects/starburst",
1568
1719
  backend: "webgl2",
1569
1720
  calculateKey: (params) => {
1570
- const r = resolve4(params);
1721
+ const r = resolve5(params);
1571
1722
  return `starburst-${r.rays}-${r.colors.join("|")}-${r.rotation}-${r.smoothness}-${r.origin.join(":")}`;
1572
1723
  },
1573
1724
  setup: (target) => {
@@ -1649,7 +1800,7 @@ var starburst = createEffect4({
1649
1800
  };
1650
1801
  },
1651
1802
  apply: ({ width, height, params, state }) => {
1652
- const r = resolve4(params);
1803
+ const r = resolve5(params);
1653
1804
  const {
1654
1805
  gl,
1655
1806
  program,
@@ -1721,8 +1872,8 @@ var starburst = createEffect4({
1721
1872
  });
1722
1873
 
1723
1874
  // src/light-leak.ts
1724
- import { Internals as Internals5 } from "remotion";
1725
- var { createEffect: createEffect5, createWebGL2ContextError: createWebGL2ContextError5 } = Internals5;
1875
+ import { Internals as Internals6 } from "remotion";
1876
+ var { createEffect: createEffect6, createWebGL2ContextError: createWebGL2ContextError5 } = Internals6;
1726
1877
  var DEFAULT_SEED = 0;
1727
1878
  var DEFAULT_HUE_SHIFT = 0;
1728
1879
  var DEFAULT_PROGRESS = 0.5;
@@ -1751,7 +1902,7 @@ var lightLeakEffectSchema = {
1751
1902
  hiddenFromList: false
1752
1903
  }
1753
1904
  };
1754
- var resolve5 = (p) => ({
1905
+ var resolve6 = (p) => ({
1755
1906
  seed: p.seed ?? DEFAULT_SEED,
1756
1907
  hueShift: p.hueShift ?? DEFAULT_HUE_SHIFT,
1757
1908
  progress: p.progress ?? DEFAULT_PROGRESS
@@ -1761,7 +1912,7 @@ var validateLightLeakParams = (params) => {
1761
1912
  assertOptionalFiniteNumber(params.seed, "seed");
1762
1913
  assertOptionalFiniteNumber(params.hueShift, "hueShift");
1763
1914
  assertOptionalFiniteNumber(params.progress, "progress");
1764
- const { hueShift, progress } = resolve5(params);
1915
+ const { hueShift, progress } = resolve6(params);
1765
1916
  if (hueShift < 0) {
1766
1917
  throw new TypeError(`"hueShift" must be >= 0, but got ${hueShift}`);
1767
1918
  }
@@ -1888,13 +2039,13 @@ var linkProgram5 = (gl, vs, fs) => {
1888
2039
  }
1889
2040
  return program;
1890
2041
  };
1891
- var lightLeak = createEffect5({
2042
+ var lightLeak = createEffect6({
1892
2043
  type: "remotion/light-leak",
1893
2044
  label: "lightLeak()",
1894
2045
  documentationLink: "https://www.remotion.dev/docs/effects/light-leak",
1895
2046
  backend: "webgl2",
1896
2047
  calculateKey: (params) => {
1897
- const r = resolve5(params);
2048
+ const r = resolve6(params);
1898
2049
  return `light-leak-${r.seed}-${r.hueShift}-${r.progress}`;
1899
2050
  },
1900
2051
  setup: (target) => {
@@ -1972,7 +2123,7 @@ var lightLeak = createEffect5({
1972
2123
  };
1973
2124
  },
1974
2125
  apply: ({ source, width, height, params, state, flipSourceY }) => {
1975
- const r = resolve5(params);
2126
+ const r = resolve6(params);
1976
2127
  const evolveProgress = Math.min(1, r.progress * 2);
1977
2128
  const retractProgress = Math.max(0, r.progress * 2 - 1);
1978
2129
  const {
@@ -2029,8 +2180,8 @@ var lightLeak = createEffect5({
2029
2180
  });
2030
2181
 
2031
2182
  // src/gridlines.ts
2032
- import { Internals as Internals6 } from "remotion";
2033
- var { createEffect: createEffect6, createWebGL2ContextError: createWebGL2ContextError6 } = Internals6;
2183
+ import { Internals as Internals7 } from "remotion";
2184
+ var { createEffect: createEffect7, createWebGL2ContextError: createWebGL2ContextError6 } = Internals7;
2034
2185
  var DEFAULT_GRID_SIZE = 64;
2035
2186
  var DEFAULT_LINE_WIDTH = 2;
2036
2187
  var DEFAULT_LINE_COLOR = "#ffffff";
@@ -2128,7 +2279,7 @@ var gridlinesSchema = {
2128
2279
  description: "Mask to source alpha"
2129
2280
  }
2130
2281
  };
2131
- var resolve6 = (p) => ({
2282
+ var resolve7 = (p) => ({
2132
2283
  gridSize: p.gridSize ?? DEFAULT_GRID_SIZE,
2133
2284
  lineWidth: p.lineWidth ?? DEFAULT_LINE_WIDTH,
2134
2285
  lineColor: p.lineColor ?? DEFAULT_LINE_COLOR,
@@ -2328,13 +2479,13 @@ var rgbaToUniform = (rgba) => {
2328
2479
  const alpha = a / 255;
2329
2480
  return [r / 255 * alpha, g / 255 * alpha, b / 255 * alpha, alpha];
2330
2481
  };
2331
- var gridlines = createEffect6({
2482
+ var gridlines = createEffect7({
2332
2483
  type: "remotion/gridlines",
2333
2484
  label: "gridlines()",
2334
2485
  documentationLink: "https://www.remotion.dev/docs/effects/gridlines",
2335
2486
  backend: "webgl2",
2336
2487
  calculateKey: (params) => {
2337
- const r = resolve6(params);
2488
+ const r = resolve7(params);
2338
2489
  const maskSuffix = r.maskToSourceAlpha ? "-mask-to-source-alpha" : "";
2339
2490
  return `gridlines-${r.gridSize}-${r.lineWidth}-${r.lineColor}-${r.backgroundColor}-${r.rotation}-${r.rotationX}-${r.rotationY}-${r.perspective}-${r.offsetX}-${r.offsetY}${maskSuffix}`;
2340
2491
  },
@@ -2434,7 +2585,7 @@ var gridlines = createEffect6({
2434
2585
  };
2435
2586
  },
2436
2587
  apply: ({ source, width, height, params, state, flipSourceY }) => {
2437
- const r = resolve6(params);
2588
+ const r = resolve7(params);
2438
2589
  const { gl, program, vao, texture, uniforms } = state;
2439
2590
  if (state.cachedLineColorStr !== r.lineColor) {
2440
2591
  state.cachedLineColorStr = r.lineColor;
@@ -2496,8 +2647,8 @@ var gridlines = createEffect6({
2496
2647
  });
2497
2648
 
2498
2649
  // src/zigzag.ts
2499
- import { Internals as Internals7 } from "remotion";
2500
- var { createEffect: createEffect7, createWebGL2ContextError: createWebGL2ContextError7 } = Internals7;
2650
+ import { Internals as Internals8 } from "remotion";
2651
+ var { createEffect: createEffect8, createWebGL2ContextError: createWebGL2ContextError7 } = Internals8;
2501
2652
  var ZIGZAG_DIRECTIONS = ["horizontal", "vertical"];
2502
2653
  var DEFAULT_COLORS3 = ["#dff4ff", "#7cc6ff"];
2503
2654
  var DEFAULT_DIRECTION = "horizontal";
@@ -2584,7 +2735,7 @@ var zigzagSchema = {
2584
2735
  description: "Mask to source alpha"
2585
2736
  }
2586
2737
  };
2587
- var resolve7 = (p) => {
2738
+ var resolve8 = (p) => {
2588
2739
  const thickness = p.thickness ?? DEFAULT_THICKNESS2;
2589
2740
  const gap = p.gap ?? DEFAULT_GAP4;
2590
2741
  return {
@@ -2881,19 +3032,19 @@ var updatePalette3 = (state, colors) => {
2881
3032
  }
2882
3033
  return true;
2883
3034
  };
2884
- var zigzag = createEffect7({
3035
+ var zigzag = createEffect8({
2885
3036
  type: "dev.remotion.effects.zigzag",
2886
3037
  label: "zigzag()",
2887
3038
  documentationLink: "https://www.remotion.dev/docs/effects/zigzag",
2888
3039
  backend: "webgl2",
2889
3040
  calculateKey: (params) => {
2890
- const r = resolve7(params);
3041
+ const r = resolve8(params);
2891
3042
  const maskSuffix = r.maskToSourceAlpha ? "-mask-to-source-alpha" : "";
2892
3043
  return `zigzag-${r.colors.join("|")}-${r.direction}-${r.thickness}-${r.spacing}-${r.angle}-${r.offset}-${r.amplitude}-${r.wavelength}${maskSuffix}`;
2893
3044
  },
2894
3045
  setup: (target) => setupZigzag(target),
2895
3046
  apply: ({ source, width, height, params, state, flipSourceY }) => {
2896
- const r = resolve7(params);
3047
+ const r = resolve8(params);
2897
3048
  const paletteDirty = updatePalette3(state, r.colors);
2898
3049
  const { gl, program, sourceTexture, paletteTexture, uniforms, vao } = state;
2899
3050
  gl.viewport(0, 0, width, height);
@@ -2963,8 +3114,8 @@ var zigzag = createEffect7({
2963
3114
  });
2964
3115
 
2965
3116
  // src/linear-gradient.ts
2966
- import { Internals as Internals8 } from "remotion";
2967
- var { createEffect: createEffect8, createWebGL2ContextError: createWebGL2ContextError8 } = Internals8;
3117
+ import { Internals as Internals9 } from "remotion";
3118
+ var { createEffect: createEffect9, createWebGL2ContextError: createWebGL2ContextError8 } = Internals9;
2968
3119
  var DEFAULT_START = [0, 0.5];
2969
3120
  var DEFAULT_END = [1, 0.5];
2970
3121
  var DEFAULT_START_COLOR = "#000000";
@@ -3001,7 +3152,7 @@ var linearGradientSchema = {
3001
3152
  description: "End color"
3002
3153
  }
3003
3154
  };
3004
- var resolve8 = (p) => ({
3155
+ var resolve9 = (p) => ({
3005
3156
  start: [...p.start ?? DEFAULT_START],
3006
3157
  end: [...p.end ?? DEFAULT_END],
3007
3158
  startColor: p.startColor ?? DEFAULT_START_COLOR,
@@ -3180,18 +3331,18 @@ var getParsedColors = (state, resolved) => {
3180
3331
  end: state.cachedEndColorRgba
3181
3332
  };
3182
3333
  };
3183
- var linearGradient = createEffect8({
3334
+ var linearGradient = createEffect9({
3184
3335
  type: "dev.remotion.effects.linearGradient",
3185
3336
  label: "linearGradient()",
3186
3337
  documentationLink: "https://www.remotion.dev/docs/effects/linear-gradient",
3187
3338
  backend: "webgl2",
3188
3339
  calculateKey: (params) => {
3189
- const r = resolve8(params);
3340
+ const r = resolve9(params);
3190
3341
  return `linear-gradient-${r.start.join(":")}-${r.end.join(":")}-${r.startColor}-${r.endColor}`;
3191
3342
  },
3192
3343
  setup: (target) => setupLinearGradient(target),
3193
3344
  apply: ({ width, height, params, state }) => {
3194
- const r = resolve8(params);
3345
+ const r = resolve9(params);
3195
3346
  const { start, end } = getParsedColors(state, r);
3196
3347
  const [sr, sg, sb, sa] = normalizedRgba(start);
3197
3348
  const [er, eg, eb, ea] = normalizedRgba(end);
@@ -3226,8 +3377,8 @@ var linearGradient = createEffect8({
3226
3377
  });
3227
3378
 
3228
3379
  // src/linear-gradient-tint.ts
3229
- import { Internals as Internals9 } from "remotion";
3230
- var { createEffect: createEffect9, createWebGL2ContextError: createWebGL2ContextError9 } = Internals9;
3380
+ import { Internals as Internals10 } from "remotion";
3381
+ var { createEffect: createEffect10, createWebGL2ContextError: createWebGL2ContextError9 } = Internals10;
3231
3382
  var DEFAULT_START2 = [0, 0.5];
3232
3383
  var DEFAULT_END2 = [1, 0.5];
3233
3384
  var DEFAULT_START_COLOR2 = "#000000";
@@ -3274,7 +3425,7 @@ var linearGradientTintSchema = {
3274
3425
  hiddenFromList: false
3275
3426
  }
3276
3427
  };
3277
- var resolve9 = (p) => ({
3428
+ var resolve10 = (p) => ({
3278
3429
  start: [...p.start ?? DEFAULT_START2],
3279
3430
  end: [...p.end ?? DEFAULT_END2],
3280
3431
  startColor: p.startColor ?? DEFAULT_START_COLOR2,
@@ -3296,7 +3447,7 @@ var validateLinearGradientTintParams = (params) => {
3296
3447
  assertOptionalColor(params.startColor, "startColor");
3297
3448
  assertOptionalColor(params.endColor, "endColor");
3298
3449
  assertOptionalFiniteNumber(params.amount, "amount");
3299
- validateUnitInterval(resolve9(params).amount, "amount");
3450
+ validateUnitInterval(resolve10(params).amount, "amount");
3300
3451
  };
3301
3452
  var VERTEX_SHADER2 = `#version 300 es
3302
3453
  in vec2 aPos;
@@ -3487,18 +3638,18 @@ var getParsedColors2 = (state, resolved) => {
3487
3638
  end: state.cachedEndColorRgba
3488
3639
  };
3489
3640
  };
3490
- var linearGradientTint = createEffect9({
3641
+ var linearGradientTint = createEffect10({
3491
3642
  type: "dev.remotion.effects.linearGradientTint",
3492
3643
  label: "linearGradientTint()",
3493
3644
  documentationLink: "https://www.remotion.dev/docs/effects/linear-gradient-tint",
3494
3645
  backend: "webgl2",
3495
3646
  calculateKey: (params) => {
3496
- const r = resolve9(params);
3647
+ const r = resolve10(params);
3497
3648
  return `linear-gradient-tint-${r.start.join(":")}-${r.end.join(":")}-${r.startColor}-${r.endColor}-${r.amount}`;
3498
3649
  },
3499
3650
  setup: (target) => setupLinearGradientTint(target),
3500
3651
  apply: ({ source, width, height, params, state, flipSourceY }) => {
3501
- const r = resolve9(params);
3652
+ const r = resolve10(params);
3502
3653
  const { start, end } = getParsedColors2(state, r);
3503
3654
  const [sr, sg, sb, sa] = normalizedRgba2(start);
3504
3655
  const [er, eg, eb, ea] = normalizedRgba2(end);
@@ -3542,10 +3693,10 @@ var linearGradientTint = createEffect9({
3542
3693
  validateParams: validateLinearGradientTintParams
3543
3694
  });
3544
3695
  // src/corner-pin/index.ts
3545
- import { Internals as Internals11 } from "remotion";
3696
+ import { Internals as Internals12 } from "remotion";
3546
3697
 
3547
3698
  // src/corner-pin/corner-pin-runtime.ts
3548
- import { Internals as Internals10 } from "remotion";
3699
+ import { Internals as Internals11 } from "remotion";
3549
3700
 
3550
3701
  // src/corner-pin/corner-pin-shaders.ts
3551
3702
  var CORNER_PIN_VS = `#version 300 es
@@ -3643,7 +3794,7 @@ void main() {
3643
3794
  `;
3644
3795
 
3645
3796
  // src/corner-pin/corner-pin-runtime.ts
3646
- var { createWebGL2ContextError: createWebGL2ContextError10 } = Internals10;
3797
+ var { createWebGL2ContextError: createWebGL2ContextError10 } = Internals11;
3647
3798
  var compileShader10 = (gl, type, source) => {
3648
3799
  const shader = gl.createShader(type);
3649
3800
  if (!shader) {
@@ -3810,7 +3961,7 @@ var applyCornerPin = ({
3810
3961
  };
3811
3962
 
3812
3963
  // src/corner-pin/index.ts
3813
- var { createEffect: createEffect10 } = Internals11;
3964
+ var { createEffect: createEffect11 } = Internals12;
3814
3965
  var DEFAULT_TOP_LEFT = [0, 0];
3815
3966
  var DEFAULT_TOP_RIGHT = [1, 0];
3816
3967
  var DEFAULT_BOTTOM_RIGHT = [1, 1];
@@ -3841,7 +3992,7 @@ var cornerPinSchema = {
3841
3992
  description: "Bottom left"
3842
3993
  }
3843
3994
  };
3844
- var resolve10 = (p) => ({
3995
+ var resolve11 = (p) => ({
3845
3996
  topLeft: [...p.topLeft ?? DEFAULT_TOP_LEFT],
3846
3997
  topRight: [...p.topRight ?? DEFAULT_TOP_RIGHT],
3847
3998
  bottomRight: [
@@ -3866,18 +4017,18 @@ var validateCornerPinParams = (params) => {
3866
4017
  assertOptionalUvCoordinate4(params.bottomRight, "bottomRight");
3867
4018
  assertOptionalUvCoordinate4(params.bottomLeft, "bottomLeft");
3868
4019
  };
3869
- var cornerPin = createEffect10({
4020
+ var cornerPin = createEffect11({
3870
4021
  type: "dev.remotion.effects.cornerPin",
3871
4022
  label: "cornerPin()",
3872
4023
  documentationLink: "https://www.remotion.dev/docs/effects/corner-pin",
3873
4024
  backend: "webgl2",
3874
4025
  calculateKey: (params) => {
3875
- const r = resolve10(params);
4026
+ const r = resolve11(params);
3876
4027
  return `corner-pin-${r.topLeft.join(":")}-${r.topRight.join(":")}-${r.bottomRight.join(":")}-${r.bottomLeft.join(":")}`;
3877
4028
  },
3878
4029
  setup: (target) => setupCornerPin(target),
3879
4030
  apply: ({ source, width, height, params, state, flipSourceY }) => {
3880
- const r = resolve10(params);
4031
+ const r = resolve11(params);
3881
4032
  applyCornerPin({
3882
4033
  state,
3883
4034
  source,
@@ -3896,6 +4047,7 @@ var cornerPin = createEffect10({
3896
4047
  });
3897
4048
  export {
3898
4049
  zigzag,
4050
+ tile,
3899
4051
  starburstEffectSchema,
3900
4052
  starburst,
3901
4053
  rings,
@@ -0,0 +1,186 @@
1
+ // src/tile.ts
2
+ import { Internals } from "remotion";
3
+
4
+ // src/validate-effect-param.ts
5
+ var assertEffectParamsObject = (params, effectLabel) => {
6
+ if (params === null || typeof params !== "object") {
7
+ throw new TypeError(`${effectLabel} effect requires a parameters object, but got ${JSON.stringify(params)}`);
8
+ }
9
+ };
10
+ var assertRequiredFiniteNumber = (value, name) => {
11
+ if (typeof value !== "number" || !Number.isFinite(value)) {
12
+ throw new TypeError(`"${name}" must be a finite number, but got ${JSON.stringify(value)}`);
13
+ }
14
+ };
15
+ var assertRequiredColor = (value, name) => {
16
+ if (typeof value !== "string" || value.length === 0) {
17
+ throw new TypeError(`"${name}" must be a non-empty string, but got ${JSON.stringify(value)}`);
18
+ }
19
+ };
20
+ var assertOptionalColor = (value, name) => {
21
+ if (value === undefined) {
22
+ return;
23
+ }
24
+ assertRequiredColor(value, name);
25
+ };
26
+ var assertOptionalBoolean = (value, name) => {
27
+ if (value === undefined) {
28
+ return;
29
+ }
30
+ if (typeof value !== "boolean") {
31
+ throw new TypeError(`"${name}" must be a boolean, but got ${JSON.stringify(value)}`);
32
+ }
33
+ };
34
+
35
+ // src/tile.ts
36
+ var { createEffect } = Internals;
37
+ var DEFAULT_HORIZONTAL = true;
38
+ var DEFAULT_VERTICAL = true;
39
+ var tileSchema = {
40
+ horizontal: {
41
+ type: "boolean",
42
+ default: DEFAULT_HORIZONTAL,
43
+ description: "Horizontal"
44
+ },
45
+ vertical: {
46
+ type: "boolean",
47
+ default: DEFAULT_VERTICAL,
48
+ description: "Vertical"
49
+ }
50
+ };
51
+ var resolve = (params) => ({
52
+ horizontal: params.horizontal ?? DEFAULT_HORIZONTAL,
53
+ vertical: params.vertical ?? DEFAULT_VERTICAL
54
+ });
55
+ var validateTileParams = (params) => {
56
+ assertEffectParamsObject(params, "Tile");
57
+ assertOptionalBoolean(params.horizontal, "horizontal");
58
+ assertOptionalBoolean(params.vertical, "vertical");
59
+ };
60
+ var tile = createEffect({
61
+ type: "dev.remotion.effects.tile",
62
+ label: "tile()",
63
+ documentationLink: "https://www.remotion.dev/docs/effects/tile",
64
+ backend: "2d",
65
+ calculateKey: (params) => {
66
+ const r = resolve(params);
67
+ return `tile-${r.horizontal}-${r.vertical}`;
68
+ },
69
+ setup: (target) => {
70
+ const boundsCanvas = target.ownerDocument.createElement("canvas");
71
+ const boundsContext = boundsCanvas.getContext("2d", {
72
+ colorSpace: "srgb",
73
+ willReadFrequently: true
74
+ });
75
+ if (!boundsContext) {
76
+ throw new Error("Failed to acquire 2D context for tile effect.");
77
+ }
78
+ const tileCanvas = target.ownerDocument.createElement("canvas");
79
+ const tileContext = tileCanvas.getContext("2d");
80
+ if (!tileContext) {
81
+ throw new Error("Failed to acquire 2D context for tile effect.");
82
+ }
83
+ return { boundsCanvas, boundsContext, tileCanvas, tileContext };
84
+ },
85
+ apply: ({ source, target, width, height, params, state }) => {
86
+ const context = target.getContext("2d");
87
+ if (!context) {
88
+ throw new Error("Failed to acquire 2D context for tile effect. The canvas may have been assigned a different context type.");
89
+ }
90
+ const r = resolve(params);
91
+ context.clearRect(0, 0, width, height);
92
+ if (!r.horizontal && !r.vertical) {
93
+ context.drawImage(source, 0, 0, width, height);
94
+ return;
95
+ }
96
+ if (state.boundsCanvas.width !== width || state.boundsCanvas.height !== height) {
97
+ state.boundsCanvas.width = width;
98
+ state.boundsCanvas.height = height;
99
+ }
100
+ state.boundsContext.clearRect(0, 0, width, height);
101
+ state.boundsContext.drawImage(source, 0, 0, width, height);
102
+ const pixels = state.boundsContext.getImageData(0, 0, width, height).data;
103
+ const rowMaximumAlpha = (y) => {
104
+ let maximumAlpha = 0;
105
+ for (let x = 0;x < width; x++) {
106
+ maximumAlpha = Math.max(maximumAlpha, pixels[(y * width + x) * 4 + 3]);
107
+ }
108
+ return maximumAlpha;
109
+ };
110
+ const columnMaximumAlpha = (x, visibleTop, visibleBottom) => {
111
+ let maximumAlpha = 0;
112
+ for (let y = visibleTop;y <= visibleBottom; y++) {
113
+ maximumAlpha = Math.max(maximumAlpha, pixels[(y * width + x) * 4 + 3]);
114
+ }
115
+ return maximumAlpha;
116
+ };
117
+ let top = 0;
118
+ while (top < height && rowMaximumAlpha(top) === 0) {
119
+ top++;
120
+ }
121
+ if (top === height) {
122
+ context.clearRect(0, 0, width, height);
123
+ return;
124
+ }
125
+ let bottom = height - 1;
126
+ while (bottom > top && rowMaximumAlpha(bottom) === 0) {
127
+ bottom--;
128
+ }
129
+ let left = 0;
130
+ while (left < width && columnMaximumAlpha(left, top, bottom) === 0) {
131
+ left++;
132
+ }
133
+ let right = width - 1;
134
+ while (right > left && columnMaximumAlpha(right, top, bottom) === 0) {
135
+ right--;
136
+ }
137
+ if (r.vertical && top < bottom) {
138
+ if (rowMaximumAlpha(top) < rowMaximumAlpha(top + 1)) {
139
+ top++;
140
+ }
141
+ if (rowMaximumAlpha(bottom) < rowMaximumAlpha(bottom - 1)) {
142
+ bottom--;
143
+ }
144
+ }
145
+ if (r.horizontal && left < right) {
146
+ if (columnMaximumAlpha(left, top, bottom) < columnMaximumAlpha(left + 1, top, bottom)) {
147
+ left++;
148
+ }
149
+ if (columnMaximumAlpha(right, top, bottom) < columnMaximumAlpha(right - 1, top, bottom)) {
150
+ right--;
151
+ }
152
+ }
153
+ const tileWidth = right - left + 1;
154
+ const tileHeight = bottom - top + 1;
155
+ state.tileCanvas.width = tileWidth;
156
+ state.tileCanvas.height = tileHeight;
157
+ state.tileContext.clearRect(0, 0, tileWidth, tileHeight);
158
+ state.tileContext.drawImage(source, left, top, tileWidth, tileHeight, 0, 0, tileWidth, tileHeight);
159
+ context.clearRect(0, 0, width, height);
160
+ const startX = r.horizontal ? left - Math.ceil(left / tileWidth) * tileWidth : left;
161
+ const startY = r.vertical ? top - Math.ceil(top / tileHeight) * tileHeight : top;
162
+ const endX = r.horizontal ? width : left + tileWidth;
163
+ const endY = r.vertical ? height : top + tileHeight;
164
+ for (let y = startY;y < endY; y += tileHeight) {
165
+ const tileY = Math.round((y - top) / tileHeight);
166
+ const mirrorY = r.vertical && Math.abs(tileY) % 2 === 1;
167
+ for (let x = startX;x < endX; x += tileWidth) {
168
+ const tileX = Math.round((x - left) / tileWidth);
169
+ const mirrorX = r.horizontal && Math.abs(tileX) % 2 === 1;
170
+ context.save();
171
+ context.translate(mirrorX ? x + tileWidth : x, mirrorY ? y + tileHeight : y);
172
+ context.scale(mirrorX ? -1 : 1, mirrorY ? -1 : 1);
173
+ context.drawImage(state.tileCanvas, 0, 0);
174
+ context.restore();
175
+ }
176
+ }
177
+ },
178
+ cleanup: () => {
179
+ return;
180
+ },
181
+ schema: tileSchema,
182
+ validateParams: validateTileParams
183
+ });
184
+ export {
185
+ tile
186
+ };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { checkerboard, type CheckerboardParams } from './checkerboard.js';
2
2
  export { pattern, type PatternOrigin, type PatternParams } from './pattern.js';
3
+ export { tile, type TileParams } from './tile.js';
3
4
  export { rings, type RingsCenter, type RingsParams } from './rings.js';
4
5
  export { starburst, starburstEffectSchema, type StarburstEffectParams, type StarburstOrigin, } from './starburst.js';
5
6
  export { lightLeak, lightLeakEffectSchema, type LightLeakEffectParams, } from './light-leak.js';
package/dist/tile.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ export type TileParams = {
2
+ /** Whether to repeat the source horizontally. Defaults to `true`. */
3
+ readonly horizontal?: boolean;
4
+ /** Whether to repeat the source vertically. Defaults to `true`. */
5
+ readonly vertical?: boolean;
6
+ };
7
+ export declare const tile: (params?: (TileParams & {
8
+ readonly disabled?: boolean | undefined;
9
+ }) | undefined) => import("remotion").EffectDescriptor<unknown>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/effects",
3
- "version": "4.0.511",
3
+ "version": "4.0.513",
4
4
  "description": "Effects that can be applied to Remotion-based canvas components",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -26,7 +26,7 @@
26
26
  "url": "https://github.com/remotion-dev/remotion/issues"
27
27
  },
28
28
  "dependencies": {
29
- "remotion": "4.0.511"
29
+ "remotion": "4.0.513"
30
30
  },
31
31
  "exports": {
32
32
  ".": {
@@ -319,6 +319,11 @@
319
319
  "module": "./dist/esm/thermal-vision.mjs",
320
320
  "import": "./dist/esm/thermal-vision.mjs"
321
321
  },
322
+ "./tile": {
323
+ "types": "./dist/tile.d.ts",
324
+ "module": "./dist/esm/tile.mjs",
325
+ "import": "./dist/esm/tile.mjs"
326
+ },
322
327
  "./tint": {
323
328
  "types": "./dist/tint.d.ts",
324
329
  "module": "./dist/esm/tint.mjs",
@@ -554,6 +559,9 @@
554
559
  "thermal-vision": [
555
560
  "dist/thermal-vision.d.ts"
556
561
  ],
562
+ "tile": [
563
+ "dist/tile.d.ts"
564
+ ],
557
565
  "tint": [
558
566
  "dist/tint.d.ts"
559
567
  ],
@@ -594,7 +602,7 @@
594
602
  },
595
603
  "homepage": "https://www.remotion.dev/docs/effects/api",
596
604
  "devDependencies": {
597
- "@remotion/eslint-config-internal": "4.0.511",
605
+ "@remotion/eslint-config-internal": "4.0.513",
598
606
  "@vitest/browser-playwright": "4.0.9",
599
607
  "eslint": "9.19.0",
600
608
  "vitest": "4.0.9",