Image elements

What are image elements? How do I create them?

An image element is a type of element that renders a raster image, such as a PNG or JPEG file. Apps can use the Design Interaction capability to add image elements to a user's design.

User experience

When an app adds an image to a user's design, it's uploaded to the user's media library.

This makes it easy for the user to access the image at a later time, but it's important to know that:

  • Creating a large image element, or an app element that contains multiple image elements, can make an app feel slow, as the images are uploaded before they're added to the design.
  • If a user doesn't have a Canva Pro account, they may reach their storage limit, at which point they will start to encounter errors.

Creating image elements

There are two ways to add an image element to a design:

  • As a native element
  • As part of an app element

The following snippet demonstrates how to add an image element to a design as a native element:

import React from "react";
import { getDesignInteraction } from "@canva/design-interaction";
export const App = () => {
const designInteraction = getDesignInteraction();
const handleClick = () => {
const dataUrl = createGradient("#440496", "#3b0388");
designInteraction.addNativeElement({
type: "IMAGE",
dataUrl,
});
};
return (
<div>
<button onClick={handleClick}>Add image element</button>
</div>
);
};
function createGradient(color1: string, color2: string): string {
const canvas = document.createElement("canvas");
canvas.width = 640;
canvas.height = 360;
const ctx = canvas.getContext("2d");
if (!ctx) {
throw new Error("Can't get CanvasRenderingContext2D");
}
const gradient = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
gradient.addColorStop(0, color1);
gradient.addColorStop(1, color2);
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);
return canvas.toDataURL();
}

To learn more, see Creating native elements.

Creating data URLs

When creating image elements, the image data can be provided as a data URL. This section explains the available options for creating data URLs and when each option is most appropriate.

Importing local images

In the starter kit, the webpack configuration allows images to be imported directly into the app's source code:

import dog from "../assets/dog.jpg";
console.log(dog); // => data:image/jpeg;base64,/9j/4AA...

The imported images are immediately available as data URLs.

This is suitable for small image files that must be loaded for every user, such as static thumbnail images. The downside is that it increases the size of the JavaScript bundle, which increases the app's load time.

Fetching remote images

In the starter kit, we've included a getImageFromUrl function. This function fetches an image from a URL and returns it as an HTMLImageElement. This is more performant than bundling images, as:

  • The images don't increase the size of the app's JavaScript bundle
  • The app can determine at runtime if (or when) to load certain images

To use the getImageFromUrl function, import it:

import { getImageFromUrl, ImageType } from "../utils/get_image_from_url";

Then pass the URL of an image and the type of image into the function:

const image = await getImageFromUrl({
url: "https://picsum.photos/200/300",
type: ImageType.JPEG,
});

You can use the base64encode method to convert the HTMLImageElement into a data URL:

const dataUrl = image.base64Encode();
console.log(dataUrl); // => data:image/jpeg;base64,/9j/4AA...

Using the Canvas API

The native Canvas API is a good option for generating images programmatically or applying effects to an already loaded image. For example, the following code programmatically generates a pink square:

// Create an HTMLCanvasElement
const canvas = document.createElement("canvas");
canvas.width = 250;
canvas.height = 250;
// Fill the HTMLCanvasElement with a color
const context = canvas.getContext("2d");
if (!context) {
throw new Error("Can't get CanvasRenderingContext2D");
}
context.fillStyle = "#ff0099";
context.fillRect(0, 0, canvas.width, canvas.height);
// Get the data URL of the HTMLCanvasElement
const dataUrl = canvas.toDataURL();

Limitations

  • Only PNG and JPEG images are supported.
  • GIFs must be added to a design as videos or embeds, not images.
  • To add an SVG to a design, it must be added as a shape or first imported via the Content capability.