| 327 | |
| 328 | // Get position/dimensions accounting for rotation |
| 329 | const getPositionAndSize = (el, rect, rotation) => { |
| 330 | if (rotation === null) { |
| 331 | return { x: rect.left, y: rect.top, w: rect.width, h: rect.height }; |
| 332 | } |
| 333 | |
| 334 | // For 90° or 270° rotations, swap width and height |
| 335 | // because PowerPoint applies rotation to the original (unrotated) box |
| 336 | const isVertical = rotation === 90 || rotation === 270; |
| 337 | |
| 338 | if (isVertical) { |
| 339 | // The browser shows us the rotated dimensions (tall box for vertical text) |
| 340 | // But PowerPoint needs the pre-rotation dimensions (wide box that will be rotated) |
| 341 | // So we swap: browser's height becomes PPT's width, browser's width becomes PPT's height |
| 342 | const centerX = rect.left + rect.width / 2; |
| 343 | const centerY = rect.top + rect.height / 2; |
| 344 | |
| 345 | return { |
| 346 | x: centerX - rect.height / 2, |
| 347 | y: centerY - rect.width / 2, |
| 348 | w: rect.height, |
| 349 | h: rect.width |
| 350 | }; |
| 351 | } |
| 352 | |
| 353 | // For other rotations, use element's offset dimensions |
| 354 | const centerX = rect.left + rect.width / 2; |
| 355 | const centerY = rect.top + rect.height / 2; |
| 356 | return { |
| 357 | x: centerX - el.offsetWidth / 2, |
| 358 | y: centerY - el.offsetHeight / 2, |
| 359 | w: el.offsetWidth, |
| 360 | h: el.offsetHeight |
| 361 | }; |
| 362 | }; |
| 363 | |
| 364 | // Parse CSS box-shadow into PptxGenJS shadow properties |
| 365 | const parseBoxShadow = (boxShadow) => { |