Replace sticker background image

We can use the willRenderShapeControls property to add a "select image" button above a sticker shape.

We'll use a custom browse() function to select a new image from the file sytem.

<script type="module">
    import { openDefaultEditor, createNode } from './pintura.js';

    // Open the default image editor in a modal
    const editor = openDefaultEditor({
        src: './my-image.jpeg',

        // A shape for demo purposes
        imageAnnotation: [
            {
                x: 128,
                y: 128,
                width: 512,
                height: 384,
                backgroundSize: 'contain',
                backgroundImage: './my-placeholder.jpeg',
            },
        ],

        // Manipulate shape controls menu
        willRenderShapeControls: (controls, selectedShapeId) => {
            controls[0][3].push(
                // Add an "Select image" button
                createNode('Button', 'my-button', {
                    label: 'Select image',
                    onclick: async () => {
                        // Find the currently selected shape
                        const shape = editor.imageAnnotation.find(
                            (shape) => shape.id === selectedShapeId
                        );

                        // browse for an image
                        const file = await browse({
                            accept: 'image/*',
                        });

                        // no file selected
                        if (!file) return;

                        // update background image
                        shape.backgroundImage = URL.createObjectURL(file);

                        // redraw annotations
                        editor.imageAnnotation = editor.imageAnnotation;
                    },
                })
            );
            return controls;
        },
    });

    // Show resulting image preview
    editor.on('process', ({ dest }) => {
        const preview = new Image();
        preview.src = URL.createObjectURL(dest);
        document.body.appendChild(preview);
    });

    // Browse file system and return file
    const browse = (options) =>
        new Promise((resolve) => {
            const element = document.createElement('input');
            element.type = 'file';
            element.accept = options.accept;
            element.onchange = () => {
                const [file] = element.files;
                if (!file) return resolve();
                resolve(file);
            };
            element.click();
        });
</script>