remotion 4.0.474 → 4.0.475

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.
@@ -42,6 +42,32 @@ var lengthUnits = new Set([
42
42
  "vw"
43
43
  ]);
44
44
  var cssNumberRegex = /^([+-]?(?:\d+\.?\d*|\.\d+))([a-zA-Z%]+)?$/;
45
+ var transformOriginKeywords = new Set([
46
+ "left",
47
+ "center",
48
+ "right",
49
+ "top",
50
+ "bottom"
51
+ ]);
52
+ var transformOriginKeywordOptions = (keyword) => {
53
+ if (keyword === "left") {
54
+ return [{ axis: "x", value: { value: 0, unit: "%" } }];
55
+ }
56
+ if (keyword === "right") {
57
+ return [{ axis: "x", value: { value: 100, unit: "%" } }];
58
+ }
59
+ if (keyword === "top") {
60
+ return [{ axis: "y", value: { value: 0, unit: "%" } }];
61
+ }
62
+ if (keyword === "bottom") {
63
+ return [{ axis: "y", value: { value: 100, unit: "%" } }];
64
+ }
65
+ return [
66
+ { axis: "x", value: { value: 50, unit: "%" } },
67
+ { axis: "y", value: { value: 50, unit: "%" } }
68
+ ];
69
+ };
70
+ var transformOriginCenter = { value: 50, unit: "%" };
45
71
  var stringifyNumber = (value) => {
46
72
  return String(normalizeNumber(value));
47
73
  };
@@ -66,6 +92,110 @@ var parseStringInterpolationComponent = (component, value) => {
66
92
  }
67
93
  throw new TypeError(`Cannot interpolate "${value}" because "${unit}" is not a supported translate or rotate unit`);
68
94
  };
95
+ var parseTransformOriginLengthPercentage = ({
96
+ component,
97
+ value,
98
+ allowPercentage
99
+ }) => {
100
+ const match = cssNumberRegex.exec(component);
101
+ if (match === null) {
102
+ throw new TypeError(`Cannot interpolate "${value}" because "${component}" is not a supported transform-origin ${allowPercentage ? "length-percentage" : "z length"}`);
103
+ }
104
+ const unit = match[2] ?? null;
105
+ const numberValue = Number(match[1]);
106
+ if (!Number.isFinite(numberValue)) {
107
+ throw new TypeError(`Cannot interpolate "${value}" because "${component}" is not finite`);
108
+ }
109
+ if (unit === null || !lengthUnits.has(unit) || !allowPercentage && unit === "%") {
110
+ throw new TypeError(`Cannot interpolate "${value}" because "${component}" is not a supported transform-origin ${allowPercentage ? "length-percentage" : "z length"}`);
111
+ }
112
+ return { value: numberValue, unit };
113
+ };
114
+ var parseTransformOriginToken = (component, value) => {
115
+ const lower = component.toLowerCase();
116
+ if (transformOriginKeywords.has(lower)) {
117
+ return { type: "keyword", keyword: lower };
118
+ }
119
+ return {
120
+ type: "length-percentage",
121
+ parsed: parseTransformOriginLengthPercentage({
122
+ component,
123
+ value,
124
+ allowPercentage: true
125
+ })
126
+ };
127
+ };
128
+ var parseTwoTransformOriginKeywords = (first, second, value) => {
129
+ const candidates = [];
130
+ for (const firstOption of transformOriginKeywordOptions(first)) {
131
+ for (const secondOption of transformOriginKeywordOptions(second)) {
132
+ if (firstOption.axis === secondOption.axis) {
133
+ continue;
134
+ }
135
+ candidates.push(firstOption.axis === "x" ? [firstOption.value, secondOption.value] : [secondOption.value, firstOption.value]);
136
+ }
137
+ }
138
+ if (candidates.length === 0) {
139
+ throw new TypeError(`Cannot interpolate "${value}" because "${first} ${second}" is not a valid transform-origin keyword pair`);
140
+ }
141
+ return candidates[0];
142
+ };
143
+ var parseTransformOriginXY = (parts, value) => {
144
+ if (parts.length === 1) {
145
+ const token = parseTransformOriginToken(parts[0], value);
146
+ if (token.type === "length-percentage") {
147
+ return [token.parsed, transformOriginCenter];
148
+ }
149
+ if (token.keyword === "top" || token.keyword === "bottom") {
150
+ return [
151
+ transformOriginCenter,
152
+ transformOriginKeywordOptions(token.keyword)[0].value
153
+ ];
154
+ }
155
+ return [
156
+ transformOriginKeywordOptions(token.keyword)[0].value,
157
+ transformOriginCenter
158
+ ];
159
+ }
160
+ const first = parseTransformOriginToken(parts[0], value);
161
+ const second = parseTransformOriginToken(parts[1], value);
162
+ if (first.type === "length-percentage" && second.type === "length-percentage") {
163
+ return [first.parsed, second.parsed];
164
+ }
165
+ if (first.type === "keyword" && second.type === "keyword") {
166
+ return parseTwoTransformOriginKeywords(first.keyword, second.keyword, value);
167
+ }
168
+ const keyword = first.type === "keyword" ? first : second.type === "keyword" ? second : null;
169
+ const length = first.type === "length-percentage" ? first.parsed : second.type === "length-percentage" ? second.parsed : null;
170
+ if (keyword === null || length === null) {
171
+ throw new Error("Expected a keyword and a length-percentage value");
172
+ }
173
+ const keywordIsFirst = first.type === "keyword";
174
+ if (keyword.keyword === "left" || keyword.keyword === "right") {
175
+ if (!keywordIsFirst) {
176
+ throw new TypeError(`Cannot interpolate "${value}" because horizontal transform-origin keywords must come before a length-percentage value`);
177
+ }
178
+ return [transformOriginKeywordOptions(keyword.keyword)[0].value, length];
179
+ }
180
+ if (keyword.keyword === "top" || keyword.keyword === "bottom") {
181
+ return [length, transformOriginKeywordOptions(keyword.keyword)[0].value];
182
+ }
183
+ return keywordIsFirst ? [transformOriginCenter, length] : [length, transformOriginCenter];
184
+ };
185
+ var parseTransformOriginValue = (output, parts) => {
186
+ const [x, y] = parseTransformOriginXY(parts.slice(0, 2), output);
187
+ const z = parts[2] === undefined ? { value: 0, unit: null } : parseTransformOriginLengthPercentage({
188
+ component: parts[2],
189
+ value: output,
190
+ allowPercentage: false
191
+ });
192
+ return {
193
+ kind: "translate",
194
+ values: [x.value, y.value, z.value],
195
+ units: [x.unit, y.unit, z.unit],
196
+ dimensions: parts[2] === undefined ? 2 : 3
197
+ };
198
+ };
69
199
  var parseStringInterpolationValue = (output) => {
70
200
  if (typeof output === "number") {
71
201
  if (!Number.isFinite(output)) {
@@ -82,6 +212,9 @@ var parseStringInterpolationValue = (output) => {
82
212
  if (parts.length < 1 || parts.length > 3 || parts[0] === "") {
83
213
  throw new TypeError(`String outputRange values must contain 1 to 3 components, but got "${output}"`);
84
214
  }
215
+ if (parts.some((part) => transformOriginKeywords.has(part.toLowerCase()))) {
216
+ return parseTransformOriginValue(output, parts);
217
+ }
85
218
  const parsed = parts.map((part) => parseStringInterpolationComponent(part, output));
86
219
  const [{ kind }] = parsed;
87
220
  for (const part of parsed) {
@@ -1007,6 +1140,12 @@ var serializeScaleValue = ([x, y, z]) => {
1007
1140
 
1008
1141
  // src/sequence-field-schema.ts
1009
1142
  var sequenceVisualStyleSchema = {
1143
+ "style.transformOrigin": {
1144
+ type: "transform-origin",
1145
+ step: 1,
1146
+ default: "50% 50%",
1147
+ description: "Transform origin"
1148
+ },
1010
1149
  "style.translate": {
1011
1150
  type: "translate",
1012
1151
  step: 1,
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var VERSION = "4.0.474";
2
+ var VERSION = "4.0.475";
3
3
  export {
4
4
  VERSION
5
5
  };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/core"
4
4
  },
5
5
  "name": "remotion",
6
- "version": "4.0.474",
6
+ "version": "4.0.475",
7
7
  "description": "Make videos programmatically",
8
8
  "main": "dist/cjs/index.js",
9
9
  "types": "dist/cjs/index.d.ts",
@@ -35,7 +35,7 @@
35
35
  "react-dom": "19.2.3",
36
36
  "webpack": "5.105.0",
37
37
  "zod": "4.3.6",
38
- "@remotion/eslint-config-internal": "4.0.474",
38
+ "@remotion/eslint-config-internal": "4.0.475",
39
39
  "eslint": "9.19.0",
40
40
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
41
41
  },