MCPcopy Create free account
hub / github.com/heygen-com/hyperframes / parseObjectPosition

Function parseObjectPosition

packages/sdk/src/adapters/iframe.ts:195–249  ·  view source on GitHub ↗

* Parse a CSS object-position value into x/y offsets (top-left of the * rendered content relative to the CSS box top-left). * * Supports the common subset: keyword pairs, percentage pairs, pixel pairs, * and single-value shorthand. Mixed units (e.g. "50% 10px") are supported. * * Pure — no DOM

(
  objectPosition: string,
  box: { width: number; height: number },
  content: { width: number; height: number },
)

Source from the content-addressed store, hash-verified

193 * Pure — no DOM access.
194 */
195function parseObjectPosition(
196 objectPosition: string,
197 box: { width: number; height: number },
198 content: { width: number; height: number },
199): { x: number; y: number } {
200 const raw = (objectPosition || "50% 50%").trim();
201 const parts = raw.split(/\s+/);
202
203 // Resolve a single token into a pixel offset along the given axis.
204 // `available` is the "slack" (box dimension - content dimension).
205 // fallow-ignore-next-line complexity
206 function resolveToken(token: string, available: number): number {
207 if (token === "left" || token === "top") return 0;
208 if (token === "right" || token === "bottom") return available;
209 if (token === "center") return available / 2;
210 if (token.endsWith("%")) {
211 const pct = parseFloat(token) / 100;
212 return isNaN(pct) ? available / 2 : pct * available;
213 }
214 if (token.endsWith("px")) {
215 const px = parseFloat(token);
216 return isNaN(px) ? available / 2 : px;
217 }
218 // Bare number — treat as px
219 const n = parseFloat(token);
220 return isNaN(n) ? available / 2 : n;
221 }
222
223 const availX = box.width - content.width;
224 const availY = box.height - content.height;
225
226 const isVert = (t: string) => t === "top" || t === "bottom";
227 const isHoriz = (t: string) => t === "left" || t === "right";
228
229 if (parts.length === 1) {
230 const tokenX = parts[0] ?? "50%";
231 // Single value: if it's a vertical keyword the x defaults to center
232 if (isVert(tokenX)) {
233 return { x: availX / 2, y: resolveToken(tokenX, availY) };
234 }
235 return { x: resolveToken(tokenX, availX), y: availY / 2 };
236 }
237
238 // Keyword pairs may be given vertical-first ("bottom left"); normalize so the
239 // first token addresses the x-axis and the second the y-axis.
240 let xToken = parts[0] ?? "50%";
241 let yToken = parts[1] ?? "50%";
242 if (isVert(xToken) || isHoriz(yToken)) {
243 [xToken, yToken] = [yToken, xToken];
244 }
245 return {
246 x: resolveToken(xToken, availX),
247 y: resolveToken(yToken, availY),
248 };
249}
250
251function clamp(v: number, min: number, max: number): number {
252 return v < min ? min : v > max ? max : v;

Callers 1

mapPointToImagePixelFunction · 0.70

Calls 3

isVertFunction · 0.85
resolveTokenFunction · 0.85
isHorizFunction · 0.85

Tested by

no test coverage detected