imageHelpers: { toCanvaImageBlob, toCanvas, toImageElement },
const canva = window.canva.init();
canva.onReady(async (opts) => {
if (!opts.element.fixed) {
throw new Error("This example is only intended to work on fixed elements");
state.element = opts.element;
state.image = await toCanvaImageBlob(opts.element, { quality: "preview" });
state.canvas = await toCanvas(state.image);
document.body.appendChild(state.canvas);
canva.onLayoutChange((opts) => {
state.element.layout = opts.layout;
canva.onControlsEvent((event) => {
switch (event.message.controlId) {
canva.onImageUpdate(async (opts) => {
const img = await toImageElement(opts.image);
const context = state.canvas.getContext("2d");
context.drawImage(img, 0, 0, state.canvas.width, state.canvas.height);
canva.onSaveRequest(async () => {
return toCanvaImageBlob(state.element, {
imageType: state.image.imageType,
function renderControls() {
canva.create("button", { id: "enlarge", label: "Enlarge" }),
canva.create("button", { id: "shift_right", label: "Shift Right" }),
canva.create("button", { id: "shift_left", label: "Shift Left" }),
canva.updateControlPanel(controls);
// Create a copy of the layout
const layout = { ...state.element.layout };
layout.cropBox.left += 25;
layout.cropBox.top += 25;
layout.cropBox.width += 50;
layout.cropBox.height += 50;
canva.updateLayout({ layout });
function shift(direction) {
// Create a copy of the layout
const layout = { ...state.element.layout };
if (direction === "right") {
layout.cropBox.left -= 50;
if (direction === "left") {
layout.cropBox.left += 50;
canva.updateLayout({ layout });