Cropping stickers with a secondary Pintura instance
We can use the willRenderShapeControls
property to add a "crop" button above a sticker shape.
<!DOCTYPE html>
<head>
<link rel="stylesheet" href="./pintura.css" />
</head>
<style>
#editor {
height: 600px;
}
.pintura-sticker-editor {
--editor-modal-overlay-opacity: 0.65;
--editor-modal-border-radius: 1.5rem;
--editor-max-width: 40rem;
--editor-max-height: 50rem;
}
</style>
<div id="editor"></div>
<script type="module">
import {
appendDefaultEditor,
openDefaultEditor,
createNode,
} from './pintura.js';
const editor = appendDefaultEditor('#editor', {
src: 'image.jpeg',
// Available stickers
stickers: [
'./sticker-one.svg',
'./sticker-two.svg',
'./sticker-three.svg',
],
// Manipulate shape controls menu
willRenderShapeControls: (controls, selectedShapeId) => {
controls[0][3].push(
// Add an Edit button
createNode('Button', 'my-button', {
label: 'Edit',
onclick: () => {
// Find the currently selected shape
const annotations = editor.imageAnnotation;
const shape = annotations.find(
(shape) => shape.id === selectedShapeId
);
// Create our sticker editor and use the current backgroundImage as src
const stickerEditor = openDefaultEditor({
class: 'pintura-sticker-editor',
src: shape.backgroundImage,
});
// Update the shape when the sticker is edited
stickerEditor.on('process', ({ dest }) => {
// Update the backgroundImage of the active shape
shape.backgroundImage = URL.createObjectURL(dest);
// Refresh annotations
editor.imageAnnotation = annotations;
});
},
})
);
return controls;
},
});
</script>
import '@pqina/pintura/pintura.css';
import './App.css';
import { useRef } from 'react';
import { PinturaEditor } from '@pqina/react-pintura';
import {
getEditorDefaults,
openDefaultEditor,
createNode,
} from '@pqina/pintura';
const editorDefaults = getEditorDefaults();
function App() {
const editorRef = useRef(null);
const willRenderShapeControls = (controls, selectedShapeId) => {
controls[0][3].push(
// Add an Edit button
createNode('Button', 'my-button', {
label: 'Edit',
onclick: () => {
// Find the currently selected shape
const annotations =
editorRef.current.editor.imageAnnotation;
const shape = annotations.find(
(shape) => shape.id === selectedShapeId
);
// Create our sticker editor and use the current backgroundImage as src
const stickerEditor = openDefaultEditor({
class: 'pintura-sticker-editor',
src: shape.backgroundImage,
});
// Update the shape when the sticker is edited
stickerEditor.on('process', ({ dest }) => {
// Update the backgroundImage of the active shape
shape.backgroundImage = URL.createObjectURL(dest);
// Refresh annotations
editorRef.current.editor.imageAnnotation = annotations;
});
},
})
);
return controls;
};
return (
<div className="App">
<PinturaEditor
ref={editorRef}
{...editorDefaults}
src={'image.jpeg'}
// Available stickers
stickers={[
'./sticker-one.svg',
'./sticker-two.svg',
'./sticker-three.svg',
]}
// Manipulate shape controls menu
willRenderShapeControls={willRenderShapeControls}
/>
</div>
);
}
export default App;
#editor {
height: 600px;
}
.pintura-sticker-editor {
--editor-modal-overlay-opacity: 0.65;
--editor-modal-border-radius: 1.5rem;
--editor-max-width: 40rem;
--editor-max-height: 50rem;
}
<template>
<div>
<PinturaEditor
ref="editor"
v-bind="editorDefaults"
src="image.jpeg"
:stickers="stickers"
:willRenderShapeControls="willRenderShapeControls"
/>
</div>
</template>
<script>
import { PinturaEditor } from '@pqina/vue-pintura';
import {
getEditorDefaults,
openDefaultEditor,
createNode,
} from '@pqina/pintura';
export default {
name: 'App',
components: {
PinturaEditor,
},
data() {
return {
editorDefaults: getEditorDefaults(),
// Available stickers
stickers: [
'./sticker-one.svg',
'./sticker-two.svg',
'./sticker-three.svg',
],
// Manipulate shape controls menu
willRenderShapeControls: (controls, selectedShapeId) => {
controls[0][3].push(
// Add an Edit button
createNode('Button', 'my-button', {
label: 'Edit',
onclick: () => {
// Find the currently selected shape
const annotations =
this.$refs.editor.editor.imageAnnotation;
const shape = annotations.find(
(shape) => shape.id === selectedShapeId
);
// Create our sticker editor and use the current backgroundImage as src
const stickerEditor = openDefaultEditor({
class: 'pintura-sticker-editor',
src: shape.backgroundImage,
});
// Update the shape when the sticker is edited
stickerEditor.on('process', ({ dest }) => {
// Update the backgroundImage of the active shape
shape.backgroundImage =
URL.createObjectURL(dest);
// Refresh annotations
this.$refs.editor.editor.imageAnnotation =
annotations;
});
},
})
);
return controls;
},
};
},
methods: {},
};
</script>
<style>
@import '@pqina/pintura/pintura.css';
#editor {
height: 600px;
}
.pintura-sticker-editor {
--editor-modal-overlay-opacity: 0.65;
--editor-modal-border-radius: 1.5rem;
--editor-max-width: 40rem;
--editor-max-height: 50rem;
}
</style>
<script>
import { PinturaEditor } from '@pqina/svelte-pintura';
import {
getEditorDefaults,
openDefaultEditor,
createNode,
} from '@pqina/pintura';
import '@pqina/pintura/pintura.css';
let editorDefaults = getEditorDefaults();
let editor;
const willRenderShapeControls = (controls, selectedShapeId) => {
controls[0][3].push(
// Add an Edit button
createNode('Button', 'my-button', {
label: 'Edit',
onclick: () => {
// Find the currently selected shape
const annotations = editor.imageAnnotation;
const shape = annotations.find(
(shape) => shape.id === selectedShapeId
);
// Create our sticker editor and use the current backgroundImage as src
const stickerEditor = openDefaultEditor({
class: 'pintura-sticker-editor',
src: shape.backgroundImage,
});
// Update the shape when the sticker is edited
stickerEditor.on('process', ({ dest }) => {
// Update the backgroundImage of the active shape
shape.backgroundImage = URL.createObjectURL(dest);
// Refresh annotations
editor.imageAnnotation = annotations;
});
},
})
);
return controls;
};
</script>
<div>
<PinturaEditor
bind:this={editor}
{...editorDefaults}
src={'image.jpeg'}
stickers={/* Available stickers */
['./sticker-one.svg', './sticker-two.svg', './sticker-three.svg']}
{willRenderShapeControls}
/>
</div>
<style>
#editor {
height: 600px;
}
.pintura-sticker-editor {
--editor-modal-overlay-opacity: 0.65;
--editor-modal-border-radius: 1.5rem;
--editor-max-width: 40rem;
--editor-max-height: 50rem;
}
</style>
import { Component, ViewChild } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import {
getEditorDefaults,
openDefaultEditor,
createNode,
PinturaNode,
} from '@pqina/pintura';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
constructor(private domSanitizer: DomSanitizer) {}
@ViewChild('editor') editor?: any;
editorDefaults: any = getEditorDefaults();
// Available stickers
stickers: any = [
'./sticker-one.svg',
'./sticker-two.svg',
'./sticker-three.svg',
];
// Manipulate shape controls menu
willRenderShapeControls = (
controls: any,
selectedShapeId: any
): PinturaNode[] => {
controls[0][3].push(
// Add an Edit button
createNode('Button', 'my-button', {
label: 'Edit',
onclick: () => {
// Find the currently selected shape
const annotations = this.editor.editor.imageAnnotation;
const shape = annotations.find(
(shape) => shape.id === selectedShapeId
);
// Create our sticker editor and use the current backgroundImage as src
const stickerEditor = openDefaultEditor({
class: 'pintura-sticker-editor',
src: shape.backgroundImage,
});
// Update the shape when the sticker is edited
stickerEditor.on('process', ({ dest }) => {
// Update the backgroundImage of the active shape
shape.backgroundImage = <string>(
this.domSanitizer.bypassSecurityTrustResourceUrl(
URL.createObjectURL(dest)
)
);
// Refresh annotations
this.editor.editor.imageAnnotation = annotations;
});
},
})
);
return controls;
};
}
<pintura-editor
#editor
[options]="editorDefaults"
src="image.jpeg"
[stickers]="stickers"
[willRenderShapeControls]="willRenderShapeControls"
></pintura-editor>
#editor {
height: 600px;
}
.pintura-sticker-editor {
--editor-modal-overlay-opacity: 0.65;
--editor-modal-border-radius: 1.5rem;
--editor-max-width: 40rem;
--editor-max-height: 50rem;
}
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularPinturaModule } from '@pqina/angular-pintura';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, AngularPinturaModule],
exports: [AppComponent],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
<!DOCTYPE html>
<head>
<link rel="stylesheet" href="./pintura/pintura.css" />
</head>
<script src="./jquery.js"></script>
<script src="./jquery-pintura/useEditorWithJQuery-iife.js"></script>
<script src="./pintura/pintura-iife.js"></script>
<style>
#editor {
height: 600px;
}
.pintura-sticker-editor {
--editor-modal-overlay-opacity: 0.65;
--editor-modal-border-radius: 1.5rem;
--editor-max-width: 40rem;
--editor-max-height: 50rem;
}
</style>
<div id="editor"></div>
<script>
useEditorWithJQuery(jQuery, pintura);
$(function () {
var { openDefaultEditor, createNode } = $.fn.pintura;
var editor = $('#editor').pinturaDefault({
src: 'image.jpeg',
// Available stickers
stickers: [
'./sticker-one.svg',
'./sticker-two.svg',
'./sticker-three.svg',
],
// Manipulate shape controls menu
willRenderShapeControls: (controls, selectedShapeId) => {
controls[0][3].push(
// Add an Edit button
createNode('Button', 'my-button', {
label: 'Edit',
onclick: () => {
// Find the currently selected shape
const annotations =
$(editor).pintura('imageAnnotation');
const shape = annotations.find(
(shape) => shape.id === selectedShapeId
);
// Create our sticker editor and use the current backgroundImage as src
const stickerEditor = openDefaultEditor({
class: 'pintura-sticker-editor',
src: shape.backgroundImage,
});
// Update the shape when the sticker is edited
stickerEditor.on('process', ({ dest }) => {
// Update the backgroundImage of the active shape
shape.backgroundImage =
URL.createObjectURL(dest);
// Refresh annotations
$(editor).pintura(
'imageAnnotation',
annotations
);
});
},
})
);
return controls;
},
});
});
</script>