diff --git a/acorn.svg b/acorn.svg new file mode 100644 index 000000000..705ed3ada --- /dev/null +++ b/acorn.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/add_image_with_rounding.js b/add_image_with_rounding.js new file mode 100644 index 000000000..47f692f23 --- /dev/null +++ b/add_image_with_rounding.js @@ -0,0 +1,150 @@ + +import pptxgen from "pptxgenjs"; + +const pptx = new pptxgen(); + +const slide = pptx.addSlide(); + + +slide.addImage({ + path: "https://files.chroniclehq.com/card-background-v2/thumbnail/v2-gradient-01-light.jpg", + x: 0.528, + y: 1.051, + w: 2.479, + h: 1.76, + rounding: true, + rectRadius: 0.2 +}); + +slide.addImage({ + path: "https://files.chroniclehq.com/card-background-v2/thumbnail/v2-gradient-13-light.jpg", + x: 3.87, + y: 1.051, + w: 2.479, + h: 1.76, + rounding: true, + rectRadius: 0.2 +}); + +slide.addImage({ + path: "atom.svg", + x: 0.628, + y: 1.295, + w: 0.15, + h: 0.15 +}); + +slide.addText("Card 1", { + x: 0.528, + y: 1.555, + w: 0.751, + h: 0.208, + fontSize: 14, + color: "050505", + align: "left" +}); + +slide.addText("Lorem ipsum dolor sit amet", { + x: 0.528, + y: 1.759, + w: 2.114, + h: 0.208, + fontSize: 12, + color: "050505", + align: "left" +}); + +slide.addText("Ut enim ad minim", { + x: 0.528, + y: 2.295, + w: 1.48, + h: 0.188, + fontSize: 12, + color: "050505", + align: "left" +}); + +slide.addText("Lorem ipsum dolor sit amet, consectetur adipiscing elit.", { + x: 4.051, + y: 1.862, + w: 2.114, + h: 0.188, + fontSize: 12, + color: "050505", + align: "left" +}); + +slide.addImage({ + path: "https://files.chroniclehq.com/card-background-v2/thumbnail/v2-image-architecture-01.jpg", + x: 6.893, + y: 1.169, + w: 1.992, + h: 2.755, + sizing: { + type: "crop", + w: 1.992, + h: 2.755 + }, + rounding: true, + rectRadius: 0.2 +}); + +slide.addShape(pptx.ShapeType.roundRect, { + x: 0.528, // Horizontal position in inches + y: 3.212, // Vertical position in inches + w: 2.5, // Width in inches + h: 2.0, // Height in inches + fill: { color: "000000", transparency: 92 }, + rectRadius: 0.2 + }); + + slide.addImage({ + path: "acorn.svg", + x: 0.628, + y: 3.3, + w: 0.15, + h: 0.15 +}); + +slide.addText("Card 3", { + x: 0.528, + y: 3.669, + w: 0.751, + h: 0.208, + fontSize: 14, + color: "050505", + align: "left" +}); + +slide.addText("Lorem ipsum dolor sit amet", { + x: 0.528, + y: 3.925, + w: 2.114, + h: 0.208, + fontSize: 12, + color: "050505", + align: "left" +}); + +slide.addText("Ut enim ad minim", { + x: 0.528, + y: 4.751, + w: 1.48, + h: 0.188, + fontSize: 12, + color: "050505", + align: "left" +}); + + + + +const exportName = "Image_With_Rounding"; +pptx.writeFile({ fileName: exportName }) + .then((fileName) => { + console.log(`Presentation exported: ${fileName}`); + }) + .catch((err) => { + console.error(`ERROR: ${err}`); + }); + diff --git a/atom.svg b/atom.svg new file mode 100644 index 000000000..a73826218 --- /dev/null +++ b/atom.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/core-interfaces.ts b/src/core-interfaces.ts index 52cb967d9..f7bd01e3f 100644 --- a/src/core-interfaces.ts +++ b/src/core-interfaces.ts @@ -513,6 +513,14 @@ export interface ImageProps extends PositionProps, DataOrPathProps, ObjectNamePr * @default false */ rounding?: boolean + /** + * Rounded rectangle corner radius (only when rounding is true) + * - values: 0.0 to 1.0 (0.0 = no rounding, 1.0 = maximum rounding) + * @default undefined (uses default PowerPoint rounding) + * @example 0.2 // 20% corner radius + * @example 0.5 // 50% corner radius + */ + rectRadius?: number /** * Shadow Props * - MS-PPT > Format Picture > Shadow diff --git a/src/gen-objects.ts b/src/gen-objects.ts index 6543cc052..a6a3356f9 100644 --- a/src/gen-objects.ts +++ b/src/gen-objects.ts @@ -451,6 +451,7 @@ export function addImageDefinition(target: PresSlide, opt: ImageProps): void { h: intHeight || 1, altText: opt.altText || '', rounding: typeof opt.rounding === 'boolean' ? opt.rounding : false, + rectRadius: opt.rectRadius, sizing, placeholder: opt.placeholder, rotate: opt.rotate || 0, diff --git a/src/gen-xml.ts b/src/gen-xml.ts index f1e3ecd9f..0d3307e43 100644 --- a/src/gen-xml.ts +++ b/src/gen-xml.ts @@ -608,7 +608,18 @@ function slideObjectToXml (slide: PresSlide | SlideLayout): string { strSlideXml += ` ` strSlideXml += ` ` strSlideXml += ' ' - strSlideXml += ` ` + if (rounding) { + strSlideXml += ` ` + if (slideItemObj.options.rectRadius !== undefined) { + // Calculate adjustment value: rectRadius is 0.0-1.0 (ratio), convert to Office Open XML adjustment value + // (rectRadius * EMU * 100000) / min(width, height) + const adjValue = Math.round((slideItemObj.options.rectRadius * EMU * 100000) / Math.min(imgWidth, imgHeight)) + strSlideXml += `` + } + strSlideXml += `` + } else { + strSlideXml += ` ` + } // EFFECTS > SHADOW: REF: @see http://officeopenxml.com/drwSp-effects.php if (slideItemObj.options.shadow && slideItemObj.options.shadow.type !== 'none') {