v8.90.3

Adding An Emoji Picker

We can use the willRenderShapePresetToolbar hook to add custom shape preset tools to the sticker and preset toolbars.

In the example below we use emoji-picker-element to add an Emoji picker to the preset tab of the annotation util. We can see an example of this control on Edit • Photo

<!DOCTYPE html>

<head>
    <link rel="stylesheet" href="./pintura.css" />
</head>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

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

    const addSmiley = (editor, addPreset, smiley) => {
        // update the recent smileys
        const recent = new Set([smiley, ...editor.annotatePresets]);
        const recentArr = Array.from(recent);

        // max of five
        if (recentArr.length > 5) recentArr.length = 5;
        editor.annotatePresets = recentArr;

        // add the smiley to the canvas
        addPreset(smiley);
    };

    let picker = undefined;

    let imported = false;

    const editor = appendDefaultEditor('#editor', {
        src: 'image.jpeg',
        util: 'annotate',
        willRenderShapePresetToolbar: (toolbar, addPreset, env, redraw) => {
            // import from unpkg
            if (!imported) {
                import('https://unpkg.com/emoji-picker-element')
                    .then(() => {
                        imported = true;
                        redraw();
                    })
                    // silently error out
                    .catch(console.log);
                return toolbar;
            }

            // create root
            if (!picker) {
                // create the picker
                const emojiPicker = document.createElement('emoji-picker');

                // enable touch scroll of Pintura child element on iOS
                emojiPicker.dataset.touchScroll = 'true';

                // exit if no shadow root
                if (!emojiPicker.shadowRoot) return toolbar;

                // set custom styles to make it fit better
                const style = document.createElement('style');
                style.textContent = `
                                .favorites { display: none }
                                .emoji { border-radius: 0 }
                                button.emoji { border-radius: 0 }
                                .tabpanel {
                                    scrollbar-color:#ddd transparent;
                                    scrollbar-width: thin;
                                }
                                .tabpanel::-webkit-scrollbar {
                                    width: 1rem;
                                    cursor: pointer;
                                }
                                .tabpanel::-webkit-scrollbar-track {
                                    background: none;
                                }
                                .tabpanel::-webkit-scrollbar-thumb {
                                    cursor: pointer;
                                    background-clip: padding-box;
                                    background-color: #ddd;
                                    border-radius: 9999rem;
                                    border: 0.3125rem solid rgba(0, 0, 0, 0);
                                }
                            `;
                emojiPicker.shadowRoot.appendChild(style);

                // set theme, light or dark
                emojiPicker.className = 'light';

                // handle picking an emoji
                emojiPicker.addEventListener('emoji-click', (e) =>
                    addSmiley(editor, addPreset, e.detail.unicode)
                );
                picker = emojiPicker;
            }

            // append the picker Panel
            appendNode(
                createNode('Panel', 'emoji', {
                    buttonLabel: 'Emoji',
                    root: picker,
                }),
                toolbar
            );

            return toolbar;
        },
    });
</script>