diff --git a/src/taskpane/components/RoundImage.tsx b/src/taskpane/components/RoundImage.tsx index 6ad59592..04160f59 100644 --- a/src/taskpane/components/RoundImage.tsx +++ b/src/taskpane/components/RoundImage.tsx @@ -83,110 +83,46 @@ export const RoundImage: React.FC = () => { const shape = shapes.items[0]; // Load essential properties - shape.load(["width", "height", "left", "top", "zIndex"]); + shape.load(["type"]); await context.sync(); - - try { - // Get the current slide - const slide = context.presentation.getSelectedSlides().getItemAt(0); - - // Step 1: Create an elliptical mask with the same dimensions as the image - // @ts-ignore - Use type assertion to avoid TypeScript issues - const maskShape = slide.shapes.addGeometricShape("Ellipse" as any); - - // Position and size the mask to exactly match the image - maskShape.left = shape.left; - maskShape.top = shape.top; - maskShape.width = shape.width; - maskShape.height = shape.height; - - // Set mask appearance - white fill with no outline - maskShape.fill.setSolidColor("white"); - - // Try to set no outline if the API supports it - try { - // @ts-ignore - This property might not be in TypeScript definitions - maskShape.lineFormat.visible = false; - } catch (lineError) { - console.log("Could not set line format visibility", lineError); - } - - // Make sure the mask is on top of the image - // The z-index should be higher than the image - // @ts-ignore - zIndex might not be directly settable - if (maskShape.hasOwnProperty("zIndex")) { - // @ts-ignore - Using property that might not be in the type definition - maskShape.zIndex = shape.zIndex + 1; - } - - await context.sync(); - - // Step 2: Select both the mask and the image - // First, clear any current selection - // No direct "clearSelection" method in the API - // We'll try to select the image first, but need to use @ts-ignore for TypeScript - try { - // @ts-ignore - The select method may not be in the TypeScript definitions - shape.select(); - await context.sync(); - } catch (selectError) { - console.log("Could not select shape", selectError); - // If we can't select the shape, we'll just continue and instruct the user - } - - // Now try to add the mask to the selection - // @ts-ignore - This method might not exist or might have different name - try { - // Try different possible methods to select multiple shapes - // @ts-ignore - if (maskShape.hasOwnProperty("select")) { - // @ts-ignore - Method might exist but with different parameters - maskShape.select(false); // false = add to selection, not exclusive - } else { - // Alternative: try to create a multi-selection directly - // @ts-ignore - This might not be in the API - slide.shapes.select([shape, maskShape]); - } - await context.sync(); - } catch (selectError) { - console.error("Could not multi-select shapes", selectError); - // If multi-select fails, we need to guide the user to do it manually - setStatusMessage("Created mask shape. Please select both the image and the oval, then use the 'Merge Shapes > Intersect' command in PowerPoint."); - setStatusType("warning"); - return; - } - - // Step 3: Merge the shapes to create a masked image - // Unfortunately, the Office.js API doesn't directly expose shape merging functionality - // We would need to use PowerPoint's "Merge Shapes > Intersect" command - // Since we can't call this directly, we'll need to guide the user - - setStatusMessage("Created oval mask. Please use 'Merge Shapes > Intersect' command in PowerPoint to complete the conversion."); - setStatusType("success"); - } catch (error) { - console.error("Error creating mask:", error); - - // Simplified fallback approach if the main one fails - try { - // Just create an oval with the same dimensions - const slide = context.presentation.getSelectedSlides().getItemAt(0); - // @ts-ignore - Use type assertion to avoid TypeScript issues - const oval = slide.shapes.addGeometricShape("Ellipse" as any); - oval.left = shape.left; - oval.top = shape.top; - oval.width = shape.width; - oval.height = shape.height; - oval.fill.setSolidColor("white"); - - await context.sync(); - - setStatusMessage("Created a round mask. Select both shapes and use PowerPoint's 'Merge Shapes > Intersect' command."); - setStatusType("success"); - } catch (fallbackError) { - console.error("Fallback error:", fallbackError); - throw fallbackError; - } + + // Ensure the shape is a picture + if (shape.type !== PowerPoint.ShapeType.image) { + setStatusMessage("Please select an image."); + setStatusType("warning"); + return; } + + // Load current dimensions to maintain aspect ratio + shape.load(["width", "height", "left", "top", "id"]); + await context.sync(); + + // Store current dimensions + const width = shape.width; + const height = shape.height; + + const slide = context.presentation.getSelectedSlides().getItemAt(0); + const maskShape = slide.shapes.addGeometricShape("Ellipse" as any); + + maskShape.load(["width", "height", "left", "top", "id"]); + await context.sync(); + + maskShape.left = shape.left; + maskShape.top = shape.top + 1; // TODO: Why + 1 + maskShape.width = shape.width; + maskShape.height = shape.height; + maskShape.fill.setSolidColor("red"); + maskShape.lineFormat.visible = false; + + setStatusMessage("Created mask shape. Please select both the image and the oval, then use the 'Merge Shapes > Intersect' command in PowerPoint."); + setStatusType("warning"); + + slide.setSelectedShapes([shape.id, maskShape.id]); + // Ensure we maintain the same size + shape.width = width; + shape.height = height; + + await context.sync(); }); } catch (error) { setStatusMessage(`Error: ${error.message}`);