In this quick start guide we will create a very simple application that enables us to annotate an image and then both display the annotation as overlay and download the image with the annotation rendered on top of it.
Note: this quick start aims to demonstrate the core concepts in marker.js 3 and purposely ignores best practices and other considerations that would add to the bulk of code without contributing to helping you understand the main parts and principles.
We will use Vite to scaffold the project and avoid covering the boilerplate code. To generate our initial project we will use the vanilla-ts
template.
To get started create a directory of your choice and run this command in the terminal to create our project:
npm create vite@latest mjsui-quickstart-ts -- --template vanilla-ts
Follow the instructions on the screen to install dependencies. In case you need help with Vite, check out their getting started guide.
Note that marker.js UI is a wrapper around marker.js 3. So, you need to install both marker.js 3 and marker.js UI to use the UI.
To add marker.js 3 and marker.js UI to the project run this command:
npm install @markerjs/markerjs3 @markerjs/markerjs-ui
We will need a sample image to annotate. You can use any image you want, but if you don't have one handy, just use this one:
Save it in the public
folder of the project. The rest of this tutorial assumes that you have a sample-image.png
in your public
directory.
We will try to make as few changes to the generated boilerplate as needed.
The core functionality will reside in the src/main.ts
file. Open it and remove everything that was generated there except for the CSS import line:
import "./style.css";
Let's start by creating a target image object. We will need to pass it to the editor and later viewer and renderer.
Import the image file and create an image element:
import sampleImage from "/sample-image.png";
const targetImg = document.createElement("img");
targetImg.src = sampleImage;
Let's store the reference to the app
div in the app
constant:
const app = document.querySelector<HTMLDivElement>("#app");
Now it's finally time to add the main annotation editor element - AnnotationEditor from the marker.js UI package.
First add an import for the AnnotationEditor
class:
import { AnnotationEditor } from "@markerjs/markerjs-ui";
And now we can create the editor
instance, assign our sample image to it, and add it to the page:
const editor = new AnnotationEditor();
editor.targetImage = targetImg;
app?.appendChild(editor);
Now if you start the dev server and navigate to the page you should see the sample image loaded into the editor and you should be able to draw markers on it.
npm run dev
Let's add the interactive viewer now. We will use it to overlay the annotations we created in the editor
on top of our original image.
Add an import for the AnnotationViewer class:
import { AnnotationViewer } from "@markerjs/markerjs-ui";
And now we can create the viewer
instance, assign our sample image to it, and add it to the page:
const viewer = new AnnotationViewer();
viewer.targetImage = targetImg;
app?.appendChild(viewer);
We are going to add an event listener to the "Save" button's click in the editor
(editorsave
event), get the state (annotation) from the editor, and show it in the viewer:
editor.addEventListener("editorsave", (event) => {
viewer.show(event.detail.state);
});
As the final touch, let's also add the code to download the annotated image with the annotations rendered on top of it. As part of the custom event argument in the editorsave
event we get the dataUrl
property that contains the base64 encoded image with the annotations rendered on top of it.
So, we will amend the editorsave
event handler to also initiate the download of the image:
editor.addEventListener("editorsave", (event) => {
// Show the annotation in the viewer
viewer.show(event.detail.state);
// Download the annotation as a PNG
const dataUrl = event.detail.dataUrl;
if (dataUrl) {
const link = document.createElement("a");
link.href = dataUrl;
link.download = "annotation.png";
link.click();
}
});
And that's it. This concludes our quick walkthrough. Now you have a basic fully functional image annotation and viewing experience in just a few lines of code.
Here's the complete content of our main.ts file:
import "./style.css";
import sampleImage from "/sample-image.png";
import { AnnotationEditor, AnnotationViewer } from "@markerjs/markerjs-ui";
// create an img element for the image to be annotated
const targetImg = document.createElement("img");
targetImg.src = sampleImage;
// app div reference
const app = document.querySelector<HTMLDivElement>("#app");
// create the annotation editor
const editor = new AnnotationEditor();
editor.targetImage = targetImg;
app?.appendChild(editor);
// create the annotation viewer
const viewer = new AnnotationViewer();
viewer.targetImage = targetImg;
app?.appendChild(viewer);
// handle the save button click
editor.addEventListener("editorsave", (event) => {
// Show the annotation in the viewer
viewer.show(event.detail.state);
// Download the annotation as a PNG
const dataUrl = event.detail.dataUrl;
if (dataUrl) {
const link = document.createElement("a");
link.href = dataUrl;
link.download = "annotation.png";
link.click();
}
});
And you can find this whole project on GitHub
Additional quick start samples (for React, vanilla JavaScript, etc.) can be found here.
If you prefer to follow this type of tutorial for specific frameworks, check out the quick starts for marker.js 3 and adapt them to marker.js UI based on this tutorial.