Fill with a pattern or picture
Set a preset pattern or a picture on shapes and slide backgrounds, as one undo step.
Use the setShapePattern and setShapePicture commands to fill the selected shapes with a preset pattern or a picture. Use setSlideBackground for the slide background. Each command is one undo step.
Fill shapes with a pattern
This helper accepts an open PptxEditorInstance and fills the selected shapes:
import type { PptxEditorInstance } from '@pptx-editor.dev/core/editor';
export function hatchSelection(editor: PptxEditorInstance) {
const result = editor.exec({
type: 'setShapePattern',
pattern: {
preset: 'dkDnDiag', // one of the 54 ECMA-376 preset patterns
foreground: '#C00000',
background: '#FFFFFF',
},
});
if (!result.ok) throw new Error(result.reason);
}preset is a PatternPreset, such as pct25, smGrid, or horzBrick. Colors are #RRGGBB.
Fill shapes with a picture
This browser-only helper reads a file from an <input type="file"> and fills the selected shapes. The picture stretches over each shape. Set tile: true to repeat it at its own size instead:
import type { PptxEditorInstance } from '@pptx-editor.dev/core/editor';
export async function fillWithPicture(editor: PptxEditorInstance, file: File) {
const bytes = new Uint8Array(await file.arrayBuffer());
const result = editor.exec({ type: 'setShapePicture', bytes, tile: false });
if (!result.ok) throw new Error(result.reason);
}The editor accepts PNG, JPEG, and GIF. It reads the type from the bytes, so mime is optional. All selected shapes share one media part.
Set a pattern or a tiled picture as the background
setSlideBackground takes the same pattern, or a picture with tile:
editor.exec({
type: 'setSlideBackground',
background: {
kind: 'pattern',
pattern: { preset: 'smGrid', foreground: '#D9D9D9', background: '#FFFFFF' },
},
allSlides: true,
});Limits
- Only shapes take a fill. With no shape selected, the commands are refused with
disabled.noShapeFill. - An unknown preset, a color that is not
#RRGGBB, or bytes that are no PNG, JPEG, or GIF with a readable size are refused witherrors.unsupported. - A picture fill does not set a crop, offset, scale, or transparency.
- The selection state reports
geometry.fillaspatternorpicture, andgeometry.patternfor a pattern.slideBackground.kindispatternorpicture, andslideBackground.tileistruefor a tiled picture.
Let users pick a fill
In the default editor, the fill color menu has Pattern… and Picture…. Pattern… opens a dialog with the 54 patterns, the foreground and background colors, and a preview. The Format Background dialog has a Pattern section and a Tile the picture option.
To open the pattern dialog from your own control, render PatternDialog inside the editor root, such as in the children of <PptxEditor>. The dialog starts from initial, or from a 50% pattern in base when initial is null:
import { useState } from 'react';
import { PatternDialog, usePptxEditor, type PatternFill } from '@pptx-editor.dev/react';
export function PatternButton() {
const editor = usePptxEditor();
// The pattern the dialog starts from, read once when it opens; false while it is closed.
const [start, setStart] = useState<PatternFill | null | false>(false);
return (
<>
<button type="button" onClick={() => setStart(editor?.snapshot().geometry?.pattern ?? null)}>
Pattern
</button>
<PatternDialog
open={start !== false}
initial={start || null}
base="#4472C4"
onClose={() => setStart(false)}
onApply={(pattern) => {
editor?.exec({ type: 'setShapePattern', pattern });
setStart(false);
}}
/>
</>
);
}<script setup lang="ts">
import { shallowRef } from 'vue';
import { PatternDialog, usePptxEditor } from '@pptx-editor.dev/vue';
import type { PatternFill } from '@pptx-editor.dev/vue';
const editor = usePptxEditor();
// The pattern the dialog starts from, read once when it opens; false while it is closed.
const start = shallowRef<PatternFill | null | false>(false);
function openDialog() {
start.value = editor.value?.snapshot().geometry?.pattern ?? null;
}
function apply(pattern: PatternFill) {
editor.value?.exec({ type: 'setShapePattern', pattern });
start.value = false;
}
</script>
<template>
<button type="button" @click="openDialog">Pattern</button>
<PatternDialog
:open="start !== false"
:initial="start || null"
base="#4472C4"
@close="start = false"
@apply="apply"
/>
</template>onClose runs on Cancel, Escape, and a click on the backdrop. onApply receives the chosen PatternFill. Read the start pattern once when the dialog opens: a new initial object while the dialog is open starts the dialog again.