Skip to main content

Command Palette

Search for a command to run...

Building a Zero-Dependency Image Editor with Web Components

Published
31 min read

Canvas Drawing Editor Complete Guide

A powerful, zero-dependency Canvas drawing editor Web Component

npm version

GitHub

GitHub: https://github.com/typsusan-zzz/canvas-drawing-editor

NPM: https://www.npmjs.com/package/canvas-drawing-editor

Live Demo: https://typsusan-zzz.github.io/canvas-drawing-editor/


Table of Contents

  1. Introduction

  2. Why Choose Canvas Drawing Editor

  3. Features

  4. Quick Start

  5. Installation

  6. Framework Integration

  7. Configuration Options

  8. Tool Configuration

  9. Drawing Tools

  10. Advanced Features

  11. Hotzone Feature

  12. Tween Animation System

  13. Event Handling

  14. Data Format

  15. API Reference

  16. Mobile Support

  17. Keyboard Shortcuts

  18. Best Practices

  19. FAQ


Introduction

Canvas Drawing Editor is a modern canvas editor built on HTML5 Canvas, packaged as a Web Component for seamless integration into any frontend framework or vanilla HTML project.

Image description

Core Advantages

  • Zero Dependencies: Pure JavaScript implementation, no React, Vue, or other frameworks required

  • Lightweight: Only ~33KB gzipped

  • Cross-Framework: Supports Vue 2/3, React, Angular, and vanilla HTML

  • Feature-Rich: Complete workflow for drawing, editing, and exporting

  • Mobile-Friendly: Full touch gesture support


Why Choose Canvas Drawing Editor

Among the many canvas editor libraries available, Canvas Drawing Editor stands out with its unique advantages:

1. True Zero Dependencies

Unlike most canvas libraries that require specific frameworks, Canvas Drawing Editor is completely standalone. This means:

  • No framework lock-in

  • Smaller bundle size

  • Faster loading times

  • Simpler integration

2. Web Component Standard

Built on the Web Component standard, enjoying native browser support:

<!-- As simple as using native HTML tags -->
<canvas-drawing-editor title="My Canvas"></canvas-drawing-editor>

3. Enterprise-Grade Features

Lightweight yet fully featured:

  • 20+ drawing tools

  • Complete undo/redo history

  • Layer management system

  • Hotzone template functionality

  • Tween animation engine

  • Multiple export formats

FeatureCanvas Drawing EditorFabric.jsKonva.jsExcalidrawtldraw
Basic Info
Bundle Size (gzip)~33KB~90KB~60KB~500KB+~300KB+
Zero Dependencies❌ (React)❌ (React)
Web Component
TypeScript Support
Framework Compatibility
Vanilla HTML✅ Out of box
Vue 2/3✅ Out of box⚠️ Wrapper needed⚠️ Wrapper needed
React✅ Out of box⚠️ Wrapper needed✅ react-konva✅ Native✅ Native
Angular✅ Out of box⚠️ Wrapper needed⚠️ Wrapper needed
Drawing Tools
Pencil/Freehand
Rectangle/Circle
Line/Arrow
Polygon
Star/Heart✅ Star only
Bezier Curve
Text Input
Rich Text⚠️ Limited
Image Import
Editing Features
Undo/Redo✅ Built-in❌ DIY❌ DIY✅ Built-in✅ Built-in
Layer Management✅ Built-in UI❌ DIY❌ DIY
Group/Ungroup
Align/Distribute✅ Built-in UI❌ DIY❌ DIY
Lock/Hide
Rotate/Scale
Advanced Features
Built-in Toolbar UI
Image Filters
Hotzone/Template Variables
Tween Animation✅ Built-in❌ DIY✅ Built-in
Multiple Line Styles
Import/Export
JSON Save/Load
PNG Export
SVG Export
Mobile Support
Touch Gestures⚠️ Limited
Pinch to Zoom⚠️ DIY
Responsive Layout❌ DIY❌ DIY
Developer Experience
Learning Curve⭐ Low⭐⭐⭐ Medium-High⭐⭐ Medium⭐ Low⭐ Low
Out-of-Box Ready⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
API Flexibility⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Documentation⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐

Legend:

  • ✅ Fully supported / Built-in feature

  • ⚠️ Partial support / Requires implementation

  • ❌ Not supported

  • DIY = Do It Yourself (requires custom implementation)


Features

🎨 Drawing Tools

ToolShortcutDescription
SelectVSelect, move, scale objects
PencilPFree-form path drawing
RectangleRDraw rectangles
CircleCDraw circles/ellipses
LineLDraw straight lines
ArrowADraw arrows (single/double)
Polygon-Draw polygons (any number of sides)
TextTAdd text
Rich Text-Text with mixed styles

Image description

🔷 More Shapes

  • Star: Customizable points and inner/outer radius

  • Heart: Perfect heart curve

  • Triangle: Equilateral triangle

  • Diamond: Standard diamond shape

  • Bezier Curve: Precise curve control

✏️ Line Styles

Three line styles supported for all shapes:

  • Solid

  • Dashed

  • Dotted

Image description

📚 Layer Management

  • Move layer up/down

  • Bring to front/Send to back

  • Visibility control

  • Lock/Unlock

Image description

🔄 Editing Features

  • Undo/Redo: Complete history support (Ctrl+Z / Ctrl+Y)

  • Copy/Paste: Quick object duplication (Ctrl+C / Ctrl+V)

  • Delete: Remove selected objects (Delete / Backspace)

  • Rotate: Free rotation to any angle

  • Proportional Scaling: Shift + drag corner handles

💾 Import/Export

FeatureDescription
JSON SaveSave complete project data for later editing
JSON LoadLoad previously saved projects
PNG ExportExport as high-quality PNG image
Clear CanvasOne-click clear all content

Quick Start

Minimal Example

Just three steps to add a fully functional canvas editor to your page:

Step 1: Include the library

<script src="https://unpkg.com/canvas-drawing-editor/dist/canvas-drawing-editor.umd.js"></script>

Step 2: Add the editor tag

<canvas-drawing-editor title="My Canvas"></canvas-drawing-editor>

Step 3: Set styles

canvas-drawing-editor {
  width: 100%;
  height: 600px;
  display: block;
}

Complete Example

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Canvas Drawing Editor Example</title>
  <style>
    canvas-drawing-editor {
      width: 100%;
      height: 100vh;
      display: block;
    }
  </style>
</head>
<body>
  <canvas-drawing-editor
    title="My Canvas"
    lang="en"
    theme-color="#5450dc"
  ></canvas-drawing-editor>

  <script src="https://unpkg.com/canvas-drawing-editor/dist/canvas-drawing-editor.umd.js"></script>

  <script>
    // Listen for canvas change events
    document.addEventListener('editor-change', (e) => {
      console.log('Canvas content changed:', e.detail.objects);
    });
  </script>
</body>
</html>

Installation

npm install canvas-drawing-editor

Or using yarn:

yarn add canvas-drawing-editor

Or using pnpm:

pnpm add canvas-drawing-editor

CDN Import

If not using a package manager, import directly via CDN:

<!-- unpkg -->
<script src="https://unpkg.com/canvas-drawing-editor/dist/canvas-drawing-editor.umd.js"></script>

<!-- Or specify version -->
<script src="https://unpkg.com/canvas-drawing-editor@latest/dist/canvas-drawing-editor.umd.js"></script>

ES Module Import

// Import in your project
import 'canvas-drawing-editor';

// Or import specific types (TypeScript)
import { CanvasDrawingEditor, ToolType, CanvasObject } from 'canvas-drawing-editor';

Framework Integration

Vanilla HTML

Vanilla HTML is the simplest integration method, requiring no build tools:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Canvas Drawing Editor</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    canvas-drawing-editor {
      width: 100vw;
      height: 100vh;
      display: block;
    }
  </style>
</head>
<body>
  <canvas-drawing-editor
    title="My Canvas"
    lang="en"
    theme-color="#5450dc"
  ></canvas-drawing-editor>

  <script src="https://unpkg.com/canvas-drawing-editor/dist/canvas-drawing-editor.umd.js"></script>

  <script>
    // Get editor instance
    const editor = document.querySelector('canvas-drawing-editor');

    // Listen for editor events
    document.addEventListener('editor-change', (e) => {
      console.log('Canvas content changed:', e.detail.objects);
      // Save data to server or localStorage here
    });

    document.addEventListener('editor-close', () => {
      console.log('Editor closed');
    });
  </script>
</body>
</html>

Image description

Vue 3

Using Canvas Drawing Editor in Vue 3 projects:

1. Installation

npm install canvas-drawing-editor

2. Basic Usage

<template>
  <canvas-drawing-editor
    title="Vue Canvas"
    style="width: 100%; height: 600px;"
  ></canvas-drawing-editor>
</template>

<script setup>
import 'canvas-drawing-editor';
</script>

3. Complete Example (with configuration and event handling)

<template>
  <canvas-drawing-editor
    :title="editorTitle"
    :lang="lang"
    :theme-color="themeColor"
    :tool-config="toolConfigStr"
    class="editor"
  ></canvas-drawing-editor>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue';
import 'canvas-drawing-editor';

// Configuration
const editorTitle = ref('Vue3 Canvas');
const lang = ref('en');
const themeColor = ref('#5450dc');

// Tool configuration
const toolConfig = ref({
  pencil: true,
  rectangle: true,
  circle: true,
  line: true,
  arrow: true,
  polygon: true,
  text: true,
  image: true,
  undo: true,
  redo: true,
  zoom: true,
  download: true,
  exportJson: true,
  importJson: true,
  clear: true,
  color: true,
  layers: true,
  group: true,
  align: true
});

// Convert to JSON string
const toolConfigStr = computed(() => JSON.stringify(toolConfig.value));

// Event handling
const handleEditorChange = (e: CustomEvent) => {
  console.log('Canvas content changed:', e.detail.objects);
  // Save to localStorage
  localStorage.setItem('canvas-data', JSON.stringify({ objects: e.detail.objects }));
};

onMounted(() => {
  document.addEventListener('editor-change', handleEditorChange as EventListener);
});

onUnmounted(() => {
  document.removeEventListener('editor-change', handleEditorChange as EventListener);
});
</script>

<style scoped>
.editor {
  width: 100%;
  height: 100vh;
  display: block;
}
</style>

4. Suppress Console Warnings (Optional)

If you see Failed to resolve component: canvas-drawing-editor warning, add this to vite.config.ts:

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [
    vue({
      template: {
        compilerOptions: {
          // Mark canvas-drawing-editor as custom element
          isCustomElement: (tag) => tag === 'canvas-drawing-editor'
        }
      }
    })
  ]
});

Vue 2

Vue 2 integration is similar to Vue 3:

1. main.js Configuration

import Vue from 'vue';
import App from './App.vue';

// Import Canvas Drawing Editor
import 'canvas-drawing-editor';

// Optional: Suppress console warnings
Vue.config.ignoredElements = ['canvas-drawing-editor'];

new Vue({
  render: h => h(App)
}).$mount('#app');

2. Component Usage

<template>
  <canvas-drawing-editor
    title="Vue2 Canvas"
    lang="en"
    :theme-color="themeColor"
    style="width: 100%; height: 600px;"
  ></canvas-drawing-editor>
</template>

<script>
export default {
  data() {
    return {
      themeColor: '#5450dc'
    };
  },
  mounted() {
    document.addEventListener('editor-change', this.handleChange);
  },
  beforeDestroy() {
    document.removeEventListener('editor-change', this.handleChange);
  },
  methods: {
    handleChange(e) {
      console.log('Canvas content changed:', e.detail.objects);
    }
  }
};
</script>

React

Using Canvas Drawing Editor in React projects:

1. Installation

npm install canvas-drawing-editor

2. TypeScript Type Declaration

For better type support, add type declarations:

// types/canvas-drawing-editor.d.ts
declare global {
  namespace JSX {
    interface IntrinsicElements {
      'canvas-drawing-editor': React.DetailedHTMLProps<
        React.HTMLAttributes<HTMLElement> & {
          title?: string;
          lang?: string;
          'theme-color'?: string;
          'tool-config'?: string;
          'initial-data'?: string;
          'enable-hotzone'?: string;
          'hotzone-data'?: string;
        },
        HTMLElement
      >;
    }
  }
}

3. Complete Usage Example

import { useEffect, useRef } from 'react';
import 'canvas-drawing-editor';

function App() {
  const editorRef = useRef<HTMLElement>(null);

  // Tool configuration
  const toolConfig = {
    pencil: true,
    rectangle: true,
    circle: true,
    line: true,
    arrow: true,
    polygon: true,
    text: true,
    image: true,
    undo: true,
    redo: true,
    zoom: true,
    download: true,
    exportJson: true,
    importJson: true,
    clear: true,
    color: true,
    layers: true,
    group: true,
    align: true
  };

  useEffect(() => {
    // Listen for editor events
    const handleEditorChange = (e: Event) => {
      const customEvent = e as CustomEvent;
      console.log('Canvas content changed:', customEvent.detail.objects);
    };

    const handleEditorClose = () => {
      console.log('Editor closed');
    };

    document.addEventListener('editor-change', handleEditorChange);
    document.addEventListener('editor-close', handleEditorClose);

    return () => {
      document.removeEventListener('editor-change', handleEditorChange);
      document.removeEventListener('editor-close', handleEditorClose);
    };
  }, []);

  return (
    <div className="app">
      <canvas-drawing-editor
        ref={editorRef}
        title="React Canvas"
        lang="en"
        theme-color="#5450dc"
        tool-config={JSON.stringify(toolConfig)}
        style={{ width: '100%', height: '100vh', display: 'block' }}
      />
    </div>
  );
}

export default App;

Angular

Using Canvas Drawing Editor in Angular projects:

1. Installation

npm install canvas-drawing-editor

2. Configure CUSTOM_ELEMENTS_SCHEMA

Angular requires CUSTOM_ELEMENTS_SCHEMA to support Web Components:

// app.module.ts
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';

// Import Canvas Drawing Editor
import 'canvas-drawing-editor';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],  // Add this line
  bootstrap: [AppComponent]
})
export class AppModule { }

3. Component Usage

// app.component.ts
import { Component, OnInit, OnDestroy, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import 'canvas-drawing-editor';

@Component({
  selector: 'app-root',
  standalone: true,
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  template: `
    <canvas-drawing-editor
      [attr.title]="editorTitle"
      [attr.lang]="lang"
      [attr.theme-color]="themeColor"
      [attr.tool-config]="toolConfigStr"
      style="width: 100%; height: 100vh; display: block;"
    ></canvas-drawing-editor>
  `
})
export class AppComponent implements OnInit, OnDestroy {
  editorTitle = 'Angular Canvas';
  lang = 'en';
  themeColor = '#5450dc';

  toolConfig = {
    pencil: true,
    rectangle: true,
    circle: true,
    line: true,
    arrow: true,
    polygon: true,
    text: true,
    image: true,
    undo: true,
    redo: true,
    zoom: true,
    download: true,
    exportJson: true,
    importJson: true,
    clear: true,
    color: true,
    layers: true,
    group: true,
    align: true
  };

  get toolConfigStr(): string {
    return JSON.stringify(this.toolConfig);
  }

  private handleEditorChange = (e: Event) => {
    const customEvent = e as CustomEvent;
    console.log('Canvas content changed:', customEvent.detail.objects);
  };

  ngOnInit(): void {
    document.addEventListener('editor-change', this.handleEditorChange);
  }

  ngOnDestroy(): void {
    document.removeEventListener('editor-change', this.handleEditorChange);
  }
}

Configuration Options

Canvas Drawing Editor provides rich configuration options for complete customization of editor behavior and appearance.

Basic Attributes

AttributeTypeDefaultDescription
titlestring"Canvas Editor"Editor title, displayed at the top
langstring"zh"Interface language, supports "zh" (Chinese) and "en" (English)
theme-colorstring"#5450dc"Theme color, affects buttons, hover states, selection states
initial-datastring-Initial JSON data for loading existing content
enable-hotzonebooleanfalseEnable hotzone feature (admin mode)
hotzone-datastring-Hotzone variable data (JSON format)
tool-configstring-Tool configuration object (JSON format)

Attribute Usage Example

<canvas-drawing-editor
  title="My Canvas"
  lang="en"
  theme-color="#3b82f6"
  enable-hotzone="true"
  tool-config='{"pencil":true,"rectangle":true,"circle":true}'
  initial-data='{"objects":[{"id":"1","type":"RECTANGLE","x":100,"y":100,"width":200,"height":150,"color":"#3b82f6","lineWidth":2}]}'
></canvas-drawing-editor>

Dynamic Attribute Updates

You can dynamically update editor attributes via JavaScript:

const editor = document.querySelector('canvas-drawing-editor');

// Update title
editor.setAttribute('title', 'New Title');

// Switch language
editor.setAttribute('lang', 'zh');

// Change theme color
editor.setAttribute('theme-color', '#10b981');

// Load new data
editor.setAttribute('initial-data', JSON.stringify({
  objects: [
    { id: 'rect1', type: 'RECTANGLE', x: 50, y: 50, width: 100, height: 80, color: '#ef4444', lineWidth: 2 }
  ]
}));

Tool Configuration

Use the tool-config attribute to precisely control which tools appear in the toolbar.

Complete tool-config Options

const toolConfig = {
  // Drawing tools
  pencil: true,      // Pencil tool
  rectangle: true,   // Rectangle tool
  circle: true,      // Circle tool
  line: true,        // Line tool
  arrow: true,       // Arrow tool
  polygon: true,     // Polygon tool
  text: true,        // Text tool
  image: true,       // Image import

  // Operation tools
  undo: true,        // Undo button
  redo: true,        // Redo button
  zoom: true,        // Zoom controls

  // File operations
  download: true,    // PNG export
  exportJson: true,  // JSON save
  importJson: true,  // JSON load
  clear: true,       // Clear canvas

  // Style tools
  color: true,       // Color picker

  // Advanced features
  layers: true,      // Layer management
  group: true,       // Group/Ungroup
  align: true        // Alignment/Distribution
};

// Usage
<canvas-drawing-editor
  tool-config={JSON.stringify(toolConfig)}
></canvas-drawing-editor>

Image description

Legacy Attributes (Backward Compatible)

In addition to tool-config, individual show-* attributes are supported, but tool-config is recommended:

AttributeTypeDefaultDescription
show-pencilbooleantrueShow pencil tool
show-rectanglebooleantrueShow rectangle tool
show-circlebooleantrueShow circle tool
show-linebooleantrueShow line tool
show-arrowbooleantrueShow arrow tool
show-polygonbooleantrueShow polygon tool
show-textbooleantrueShow text tool
show-imagebooleantrueShow image import
show-undobooleantrueShow undo button
show-redobooleantrueShow redo button
show-zoombooleantrueShow zoom controls
show-downloadbooleantrueShow PNG export
show-exportbooleantrueShow JSON save
show-importbooleantrueShow JSON load
show-colorbooleantrueShow color picker
show-clearbooleantrueShow clear canvas button
show-layersbooleantrueShow layer management
show-groupbooleantrueShow group/ungroup
show-alignbooleantrueShow alignment/distribution

Drawing Tools

Selection Tool (V)

The selection tool is the most basic tool for selecting, moving, and transforming objects.

Operations:

  • Single Click: Select single object

  • Shift + Click: Multi-select objects

  • Marquee Selection: Drag to create selection box, select all objects within

  • Drag: Move selected objects

  • Drag Corner Handles: Scale objects

  • Shift + Drag Corner: Proportional scaling

  • Drag Rotation Handle: Rotate objects

Image description

Pencil Tool (P)

Free-form path drawing, suitable for signatures, sketches, etc.

Operations:

  1. Select pencil tool

  2. Hold left mouse button and draw on canvas

  3. Release mouse to complete drawing

Properties:

  • Color: Set via color picker

  • Line Width: Default 3px

Image description

Rectangle Tool (R)

Draw rectangles or squares.

Operations:

  1. Select rectangle tool

  2. Hold left mouse button and drag on canvas

  3. Release mouse to complete drawing

  4. Hold Shift: Draw perfect square

Circle Tool (C)

Draw ellipses or circles.

Operations:

  1. Select circle tool

  2. Hold left mouse button and drag on canvas

  3. Release mouse to complete drawing

  4. Hold Shift: Draw perfect circle

Line Tool (L)

Draw straight lines with three line styles.

Operations:

  1. Select line tool

  2. Hold left mouse button and drag on canvas

  3. Release mouse to complete drawing

Line Styles:

  • Solid

  • Dashed

  • Dotted

Arrow Tool (A)

Draw arrows with single or double heads.

Operations:

  1. Select arrow tool

  2. Hold left mouse button and drag on canvas

  3. Release mouse to complete drawing

Arrow Types:

  • Single Arrow: Arrow head at end point

  • Double Arrow: Arrow heads at both ends

Polygon Tool

Draw regular polygons with any number of sides.

Operations:

  1. Select polygon tool

  2. Hold left mouse button and drag on canvas

  3. Adjust polygon sides (3 sides = triangle, 6 sides = hexagon, etc.)

Text Tool (T)

Add text content.

Operations:

  1. Select text tool

  2. Click position on canvas

  3. Enter text content

  4. Press Enter to confirm, Esc to cancel

Text Properties:

  • Font size

  • Color

  • Bold/Italic

Rich Text

Support different styles within the same text object.

Features:

  • Partial bold text

  • Partial color change

  • Partial italic text

  • Mixed styles

Image Import

Import local images to canvas.

Operations:

  1. Click image import button

  2. Select local image file

  3. Image will be added to canvas center

Supported Formats:

  • PNG

  • JPG/JPEG

  • GIF

  • WebP

  • SVG

Image Operations:

  • Scale

  • Rotate

  • Apply filters (brightness/contrast)


Advanced Features

Layer Management

Canvas Drawing Editor provides complete layer management functionality.

Feature List:

FeatureDescription
Move UpMove selected object up one layer
Move DownMove selected object down one layer
Bring to FrontMove selected object to top layer
Send to BackMove selected object to bottom layer
Show/HideControl layer visibility
Lock/UnlockLock layer to prevent accidental changes

Alignment & Distribution

When multiple objects are selected, alignment and distribution features become available.

Alignment Options:

FeatureDescription
Align LeftAlign all objects to left edge
Align Center (H)Align all objects to horizontal center
Align RightAlign all objects to right edge
Align TopAlign all objects to top edge
Align Center (V)Align all objects to vertical center
Align BottomAlign all objects to bottom edge

Distribution Options:

FeatureDescription
Distribute HorizontallyEqual horizontal spacing between objects
Distribute VerticallyEqual vertical spacing between objects

Group & Ungroup

Combine multiple objects into a single unit for unified operations.

Operations:

  • Group: Select multiple objects, press Ctrl+G or click group button

  • Ungroup: Select grouped object, press Ctrl+Shift+G or click ungroup button

Group Features:

  • Grouped objects move, scale, and rotate as a unit

  • Nested grouping supported (groups within groups)

  • Ungrouping restores independent objects

Image Filters

Apply filter effects to imported images.

Supported Filters:

FilterRangeDescription
Brightness-100 ~ 100Adjust image brightness
Contrast-100 ~ 100Adjust image contrast
Blur0 ~ 20Gaussian blur effect
Grayscale0 ~ 100Convert to grayscale
Saturation0 ~ 200Adjust color saturation

Hotzone Feature

Hotzone is a powerful feature of Canvas Drawing Editor that allows dynamic variables in text, enabling template-based content display.

What is Hotzone?

The hotzone feature allows you to define variable placeholders in text, then dynamically replace these variable values at runtime. This is useful for:

  • Certificate Generation: Dynamic content like names, dates, serial numbers

  • Poster Templates: Event names, times, locations

  • Data Visualization: Real-time data display

  • Personalized Content: User information, order details

Hotzone Workflow

The hotzone feature has two modes:

  1. Admin Mode: Design templates, define variables

  2. User Mode: View rendered content

Admin Mode (Design Templates)

<canvas-drawing-editor
  title="Template Designer"
  enable-hotzone="true"
></canvas-drawing-editor>

In admin mode:

  1. Add text objects

  2. Use {{variableName}} syntax to define variables in text

  3. Example: Dear {{userName}}, your order {{orderId}} has been confirmed

  4. Save template JSON

User Mode (Display Content)

<canvas-drawing-editor
  title="Certificate Display"
  enable-hotzone="false"
  :initial-data="templateData"
  :hotzone-data="hotzoneVariables"
></canvas-drawing-editor>
// Hotzone variable data
const hotzoneVariables = JSON.stringify({
  userName: 'John Smith',
  orderId: 'ORD-2024-001',
  date: 'January 15, 2024'
});

Hotzone Variable Syntax

SyntaxDescriptionExample
{{variableName}}Basic variable{{userName}}
{{date}}Simple variable{{createdAt}}
{{data.name}}Nested variable{{user.email}}

Complete Hotzone Example

Admin Side (Design Template):

<!DOCTYPE html>
<html>
<head>
  <title>Hotzone Template Design</title>
  <style>
    canvas-drawing-editor { width: 100%; height: 600px; display: block; }
  </style>
</head>
<body>
  <canvas-drawing-editor
    title="Certificate Template Design"
    lang="en"
    enable-hotzone="true"
  ></canvas-drawing-editor>

  <script src="https://unpkg.com/canvas-drawing-editor/dist/canvas-drawing-editor.umd.js"></script>

  <script>
    document.addEventListener('editor-change', (e) => {
      // Save template data
      const templateData = JSON.stringify({ objects: e.detail.objects });
      localStorage.setItem('certificate-template', templateData);
      console.log('Template saved');
    });
  </script>
</body>
</html>

User Side (Display Certificate):

<!DOCTYPE html>
<html>
<head>
  <title>My Certificate</title>
  <style>
    canvas-drawing-editor { width: 100%; height: 600px; display: block; }
  </style>
</head>
<body>
  <canvas-drawing-editor
    id="certificate"
    title="My Certificate"
    lang="en"
    enable-hotzone="false"
  ></canvas-drawing-editor>

  <script src="https://unpkg.com/canvas-drawing-editor/dist/canvas-drawing-editor.umd.js"></script>

  <script>
    // Load template
    const templateData = localStorage.getItem('certificate-template');

    // Define variable values
    const hotzoneData = {
      userName: 'John Smith',
      courseName: 'Web Frontend Development',
      completionDate: 'January 20, 2024',
      certificateNo: 'CERT-2024-00123'
    };

    const editor = document.getElementById('certificate');
    editor.setAttribute('initial-data', templateData);
    editor.setAttribute('hotzone-data', JSON.stringify(hotzoneData));
  </script>
</body>
</html>

Tween Animation System

Canvas Drawing Editor includes a powerful Tween animation system for adding smooth animation effects to canvas objects.

Animation Basics

Tween animations smoothly change object property values like position, size, rotation angle, opacity, etc.

Animatable Properties

PropertyDescriptionExample Values
xX coordinate100, 200, 300
yY coordinate50, 150, 250
widthWidth100, 200
heightHeight80, 160
rotationRotation angle (degrees)0, 90, 180, 360
opacityOpacity0 ~ 1
scaleXX-axis scale0.5, 1, 2
scaleYY-axis scale0.5, 1, 2

Easing Functions

Canvas Drawing Editor provides rich easing functions for more dynamic animations:

Easing FunctionDescription
linearLinear, constant speed
easeInQuadQuadratic ease-in
easeOutQuadQuadratic ease-out
easeInOutQuadQuadratic ease-in-out
easeInCubicCubic ease-in
easeOutCubicCubic ease-out
easeInOutCubicCubic ease-in-out
easeInQuartQuartic ease-in
easeOutQuartQuartic ease-out
easeInOutQuartQuartic ease-in-out
easeInElasticElastic ease-in
easeOutElasticElastic ease-out
easeInOutElasticElastic ease-in-out
easeOutBounceBounce ease-out

Using tweenAnimate API

// Get editor instance
const editor = document.querySelector('canvas-drawing-editor');

// Basic animation
editor.tweenAnimate({
  objectId: 'rect-001',           // Target object ID
  property: 'x',                   // Animation property
  from: 100,                       // Start value
  to: 500,                         // End value
  duration: 1000,                  // Duration (milliseconds)
  easing: 'easeOutQuad'           // Easing function
});

// Rotation animation
editor.tweenAnimate({
  objectId: 'star-001',
  property: 'rotation',
  from: 0,
  to: 360,
  duration: 2000,
  easing: 'linear',
  loop: true                       // Loop playback
});

// Opacity animation (fade in/out)
editor.tweenAnimate({
  objectId: 'text-001',
  property: 'opacity',
  from: 0,
  to: 1,
  duration: 500,
  easing: 'easeInOutQuad'
});

Animation Configuration Options

interface TweenConfig {
  objectId: string;        // Target object ID
  property: string;        // Animation property
  from: number;            // Start value
  to: number;              // End value
  duration: number;        // Duration (milliseconds)
  easing?: string;         // Easing function, default 'linear'
  delay?: number;          // Delay start (milliseconds)
  loop?: boolean;          // Whether to loop
  yoyo?: boolean;          // Whether to reverse (use with loop)
  onStart?: () => void;    // Animation start callback
  onUpdate?: (value: number) => void;  // Per-frame update callback
  onComplete?: () => void; // Animation complete callback
}

Stopping Animations

// Stop all animations
editor.stopAllAnimations();

// Stop specific object's animation
editor.stopAnimation('rect-001');

Animation Events

// Animation start event
document.addEventListener('animation-start', (e) => {
  console.log('Animation started:', e.detail.objectId, e.detail.property);
});

// Animation update event
document.addEventListener('animation-update', (e) => {
  console.log('Animation progress:', e.detail.progress);
});

// Animation complete event
document.addEventListener('animation-complete', (e) => {
  console.log('Animation completed:', e.detail.objectId);
});

Complex Animation Example

// Combined animation: move + rotate + scale
const editor = document.querySelector('canvas-drawing-editor');

// Execute multiple animations simultaneously
editor.tweenAnimate({
  objectId: 'star-001',
  property: 'x',
  from: 100,
  to: 400,
  duration: 2000,
  easing: 'easeInOutQuad'
});

editor.tweenAnimate({
  objectId: 'star-001',
  property: 'rotation',
  from: 0,
  to: 720,
  duration: 2000,
  easing: 'linear'
});

editor.tweenAnimate({
  objectId: 'star-001',
  property: 'scaleX',
  from: 1,
  to: 1.5,
  duration: 1000,
  easing: 'easeOutElastic',
  yoyo: true,
  loop: true
});

Event Handling

Canvas Drawing Editor communicates with external code through custom events.

Available Events

Event NameTriggerEvent Data
editor-changeWhen canvas content changes{ objects: CanvasObject[] }
editor-closeWhen editor closesNone
animation-startWhen animation starts{ objectId, property }
animation-updateOn each animation frame{ objectId, property, progress, value }
animation-completeWhen animation completes{ objectId, property }

Event Listening Examples

// Listen for canvas changes
document.addEventListener('editor-change', (e) => {
  const { objects } = e.detail;
  console.log('Canvas object count:', objects.length);

  // Auto-save to localStorage
  localStorage.setItem('canvas-backup', JSON.stringify({ objects }));
});

// Listen for editor close
document.addEventListener('editor-close', () => {
  console.log('Editor closed');
  // Perform cleanup operations here
});

// Listen for animation events
document.addEventListener('animation-complete', (e) => {
  const { objectId, property } = e.detail;
  console.log(`Object ${objectId}'s ${property} animation completed`);
});

Listening in Vue 3

<script setup>
import { onMounted, onUnmounted } from 'vue';

const handleEditorChange = (e) => {
  console.log('Canvas changed:', e.detail.objects);
};

onMounted(() => {
  document.addEventListener('editor-change', handleEditorChange);
});

onUnmounted(() => {
  document.removeEventListener('editor-change', handleEditorChange);
});
</script>

Listening in React

import { useEffect } from 'react';

function App() {
  useEffect(() => {
    const handleEditorChange = (e: CustomEvent) => {
      console.log('Canvas changed:', e.detail.objects);
    };

    document.addEventListener('editor-change', handleEditorChange as EventListener);

    return () => {
      document.removeEventListener('editor-change', handleEditorChange as EventListener);
    };
  }, []);

  return <canvas-drawing-editor />;
}

Data Format

JSON Data Structure

Canvas Drawing Editor uses JSON format to save and load canvas data.

interface CanvasData {
  objects: CanvasObject[];
}

interface CanvasObject {
  id: string;           // Unique identifier
  type: ToolType;       // Object type
  x: number;            // X coordinate
  y: number;            // Y coordinate
  color: string;        // Color
  lineWidth: number;    // Line width
  rotation?: number;    // Rotation angle
  opacity?: number;     // Opacity
  locked?: boolean;     // Whether locked
  visible?: boolean;    // Whether visible
  // ... other properties vary by type
}

Object Types (ToolType)

TypeDescriptionUnique Properties
PENCILPencil pathpoints: Point[]
RECTANGLERectanglewidth, height, fillColor, lineStyle
CIRCLECircleradiusX, radiusY, fillColor
LINELineendX, endY, lineStyle
ARROWArrowendX, endY, arrowType
POLYGONPolygonsides, radius
TEXTTexttext, fontSize, fontFamily, bold, italic
RICH_TEXTRich textsegments: TextSegment[]
IMAGEImagesrc, width, height, filters
TRIANGLETrianglewidth, height
STARStarpoints, innerRadius, outerRadius
HEARTHeartsize
DIAMONDDiamondwidth, height
BEZIERBezier curvecontrolPoints: Point[]
GROUPGroupchildren: CanvasObject[]

Rectangle Object Example

{
  "id": "rect-001",
  "type": "RECTANGLE",
  "x": 100,
  "y": 100,
  "width": 200,
  "height": 150,
  "color": "#3b82f6",
  "fillColor": "#93c5fd",
  "lineWidth": 2,
  "lineStyle": "solid",
  "rotation": 0,
  "opacity": 1,
  "locked": false,
  "visible": true
}

Text Object Example

{
  "id": "text-001",
  "type": "TEXT",
  "x": 200,
  "y": 200,
  "text": "Hello World",
  "fontSize": 24,
  "fontFamily": "Arial",
  "color": "#1f2937",
  "bold": false,
  "italic": false,
  "rotation": 0
}

Image Object Example

{
  "id": "image-001",
  "type": "IMAGE",
  "x": 50,
  "y": 50,
  "width": 300,
  "height": 200,
  "src": "data:image/png;base64,...",
  "rotation": 0,
  "filters": {
    "brightness": 0,
    "contrast": 0,
    "blur": 0,
    "grayscale": 0,
    "saturation": 100
  }
}

Group Object Example

{
  "id": "group-001",
  "type": "GROUP",
  "x": 100,
  "y": 100,
  "children": [
    {
      "id": "rect-002",
      "type": "RECTANGLE",
      "x": 0,
      "y": 0,
      "width": 100,
      "height": 80
    },
    {
      "id": "text-002",
      "type": "TEXT",
      "x": 10,
      "y": 30,
      "text": "Label"
    }
  ]
}

API Reference

Editor Instance Methods

After getting the editor instance, you can call the following methods:

const editor = document.querySelector('canvas-drawing-editor');

exportJSON()

Export canvas data as JSON format.

const jsonData = editor.exportJSON();
console.log(jsonData);
// Output: { objects: [...] }

// Save to file
const blob = new Blob([JSON.stringify(jsonData)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'canvas-data.json';
a.click();

exportPNG(options?)

Export canvas as PNG image.

// Basic export
const pngDataUrl = editor.exportPNG();

// Export with options
const pngDataUrl = editor.exportPNG({
  scale: 2,              // Scale factor for high-resolution export
  backgroundColor: '#ffffff'  // Background color
});

// Download image
const a = document.createElement('a');
a.href = pngDataUrl;
a.download = 'canvas-image.png';
a.click();

tweenAnimate(config)

Execute Tween animation.

editor.tweenAnimate({
  objectId: 'rect-001',
  property: 'x',
  from: 100,
  to: 500,
  duration: 1000,
  easing: 'easeOutQuad'
});

stopAllAnimations()

Stop all running animations.

editor.stopAllAnimations();

stopAnimation(objectId)

Stop specific object's animation.

editor.stopAnimation('rect-001');

Complete API List

MethodParametersReturnDescription
exportJSON()NoneCanvasDataExport JSON data
exportPNG(options?)ExportOptionsstringExport PNG DataURL
tweenAnimate(config)TweenConfigTweenInstanceExecute animation
stopAllAnimations()NonevoidStop all animations
stopAnimation(id)stringvoidStop specific animation

Mobile Support

Canvas Drawing Editor fully supports mobile touch operations.

Touch Gestures

GestureOperation
Single-finger tapSelect object
Single-finger dragMove object/Draw
Two-finger pinchZoom canvas
Two-finger rotateRotate canvas
Long pressShow context menu

Mobile Optimizations

The editor includes the following mobile optimizations:

  1. Enlarged Touch Areas: Larger control handles for easier touch operation

  2. Gesture Recognition: Smart single/two-finger operation detection

  3. Inertial Scrolling: Smooth canvas scrolling experience

  4. Responsive Layout: Toolbar adapts to screen width

Mobile Example

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  <title>Mobile Canvas</title>
  <style>
    * { margin: 0; padding: 0; }
    html, body {
      width: 100%;
      height: 100%;
      overflow: hidden;
      touch-action: none;
    }
    canvas-drawing-editor {
      width: 100%;
      height: 100%;
      display: block;
    }
  </style>
</head>
<body>
  <canvas-drawing-editor
    title="Mobile Canvas"
    lang="en"
  ></canvas-drawing-editor>

  <script src="https://unpkg.com/canvas-drawing-editor/dist/canvas-drawing-editor.umd.js"></script>
</body>
</html>

Keyboard Shortcuts

Canvas Drawing Editor supports rich keyboard shortcuts for improved efficiency.

Tool Shortcuts

ShortcutFunction
VSelection tool
PPencil tool
RRectangle tool
CCircle tool
LLine tool
AArrow tool
TText tool

Edit Shortcuts

ShortcutFunction
Ctrl + ZUndo
Ctrl + YRedo
Ctrl + Shift + ZRedo (alternative)
Ctrl + CCopy
Ctrl + VPaste
Ctrl + XCut
Ctrl + ASelect all
Delete / BackspaceDelete selected objects
EscapeDeselect/Cancel operation

Group Shortcuts

ShortcutFunction
Ctrl + GGroup selected objects
Ctrl + Shift + GUngroup

View Shortcuts

ShortcutFunction
Ctrl + +Zoom in
Ctrl + -Zoom out
Ctrl + 0Reset zoom
Space + DragPan canvas

Modifier Shortcuts

ShortcutFunction
Shift + DragProportional scaling
Alt + DragScale from center
Shift + DrawDraw perfect square/circle

Best Practices

1. Performance Optimization

Control Object Count

// Periodically clean up unnecessary objects
document.addEventListener('editor-change', (e) => {
  const { objects } = e.detail;
  if (objects.length > 500) {
    console.warn('Too many canvas objects, may affect performance');
  }
});

Use Appropriate Image Sizes

// Compress images before import
function compressImage(file, maxWidth = 1920) {
  return new Promise((resolve) => {
    const reader = new FileReader();
    reader.onload = (e) => {
      const img = new Image();
      img.onload = () => {
        const canvas = document.createElement('canvas');
        const ratio = Math.min(maxWidth / img.width, 1);
        canvas.width = img.width * ratio;
        canvas.height = img.height * ratio;
        const ctx = canvas.getContext('2d');
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
        resolve(canvas.toDataURL('image/jpeg', 0.8));
      };
      img.src = e.target.result;
    };
    reader.readAsDataURL(file);
  });
}

2. Data Persistence

Auto-Save

let saveTimeout;

document.addEventListener('editor-change', (e) => {
  // Debounce: Multiple changes within 500ms only save once
  clearTimeout(saveTimeout);
  saveTimeout = setTimeout(() => {
    const data = JSON.stringify({ objects: e.detail.objects });
    localStorage.setItem('canvas-autosave', data);
    console.log('Auto-save successful');
  }, 500);
});

Load Saved Data

window.addEventListener('load', () => {
  const savedData = localStorage.getItem('canvas-autosave');
  if (savedData) {
    const editor = document.querySelector('canvas-drawing-editor');
    editor.setAttribute('initial-data', savedData);
  }
});

3. Error Handling

// Handle loading errors
try {
  const editor = document.querySelector('canvas-drawing-editor');
  const data = JSON.parse(localStorage.getItem('canvas-data'));
  if (data && data.objects) {
    editor.setAttribute('initial-data', JSON.stringify(data));
  }
} catch (error) {
  console.error('Failed to load canvas data:', error);
  // Clear corrupted data
  localStorage.removeItem('canvas-data');
}

4. Responsive Design

/* Desktop */
canvas-drawing-editor {
  width: 100%;
  height: calc(100vh - 60px);
}

/* Tablet */
@media (max-width: 1024px) {
  canvas-drawing-editor {
    height: calc(100vh - 50px);
  }
}

/* Mobile */
@media (max-width: 768px) {
  canvas-drawing-editor {
    height: calc(100vh - 40px);
  }
}

5. Backend Integration

// Save to server
async function saveToServer(objects) {
  try {
    const response = await fetch('/api/canvas/save', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ objects })
    });

    if (!response.ok) {
      throw new Error('Save failed');
    }

    const result = await response.json();
    console.log('Save successful:', result.id);
    return result;
  } catch (error) {
    console.error('Failed to save to server:', error);
    throw error;
  }
}

// Load from server
async function loadFromServer(canvasId) {
  try {
    const response = await fetch(`/api/canvas/${canvasId}`);
    if (!response.ok) {
      throw new Error('Load failed');
    }

    const data = await response.json();
    const editor = document.querySelector('canvas-drawing-editor');
    editor.setAttribute('initial-data', JSON.stringify(data));
  } catch (error) {
    console.error('Failed to load from server:', error);
  }
}

FAQ

Q1: Editor Not Displaying or Shows Blank

Possible Causes:

  1. Library not properly imported

  2. Editor size not set

Solution:

<!-- Ensure proper import -->
<script src="https://unpkg.com/canvas-drawing-editor/dist/canvas-drawing-editor.umd.js"></script>

<!-- Ensure size is set -->
<style>
  canvas-drawing-editor {
    width: 100%;
    height: 600px;
    display: block;  /* Important! */
  }
</style>

Q2: Vue/React Console Warnings

Vue Warning: Failed to resolve component: canvas-drawing-editor

Solution (Vue 3 + Vite):

// vite.config.ts
export default defineConfig({
  plugins: [
    vue({
      template: {
        compilerOptions: {
          isCustomElement: (tag) => tag === 'canvas-drawing-editor'
        }
      }
    })
  ]
});

Solution (Vue 2):

// main.js
Vue.config.ignoredElements = ['canvas-drawing-editor'];

Q3: Event Listeners Not Working

Possible Cause: Events are dispatched on document, not the editor element.

Correct Approach:

// ✅ Correct
document.addEventListener('editor-change', handler);

// ❌ Wrong
editor.addEventListener('editor-change', handler);

Q4: Initial Data Not Loading

Possible Causes:

  1. Invalid JSON format

  2. Incorrect data structure

Solution:

// Ensure correct data format
const validData = {
  objects: [
    {
      id: 'unique-id',  // Must have unique ID
      type: 'RECTANGLE', // Must be valid type
      x: 100,
      y: 100,
      width: 200,
      height: 150,
      color: '#3b82f6',
      lineWidth: 2
    }
  ]
};

editor.setAttribute('initial-data', JSON.stringify(validData));

Q5: Exported PNG Image is Blurry

Solution:

// Use scale parameter for high-resolution export
const pngDataUrl = editor.exportPNG({
  scale: 2  // 2x resolution
});

Q6: Mobile Touch Not Responsive

Solution:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

<style>
  html, body {
    touch-action: none;
    overflow: hidden;
  }
</style>

Q7: How to Get Specific Objects

document.addEventListener('editor-change', (e) => {
  const { objects } = e.detail;

  // Find by ID
  const targetObject = objects.find(obj => obj.id === 'my-object-id');

  // Filter by type
  const rectangles = objects.filter(obj => obj.type === 'RECTANGLE');

  // Filter by property
  const redObjects = objects.filter(obj => obj.color === '#ff0000');
});

Q8: How to Implement Collaborative Editing

Canvas Drawing Editor doesn't provide built-in collaborative editing, but you can implement it:

// Use WebSocket to sync data
const ws = new WebSocket('wss://your-server.com/canvas');

// Send local changes
document.addEventListener('editor-change', (e) => {
  ws.send(JSON.stringify({
    type: 'canvas-update',
    objects: e.detail.objects
  }));
});

// Receive remote changes
ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  if (data.type === 'canvas-update') {
    const editor = document.querySelector('canvas-drawing-editor');
    editor.setAttribute('initial-data', JSON.stringify({ objects: data.objects }));
  }
};

Summary

Canvas Drawing Editor is a powerful, easy-to-use Canvas editor. Its main advantages include:

  • Zero Dependencies: Pure JavaScript implementation, no frameworks required

  • Cross-Framework: Supports Vue, React, Angular, and vanilla HTML

  • Feature-Rich: 20+ drawing tools, complete editing functionality

  • Highly Customizable: Flexible configuration options and API

  • Mobile-Friendly: Full touch gesture support

  • Animation System: Built-in Tween animation engine

  • Hotzone Feature: Dynamic variable template support

Whether for simple drawing applications or complex graphic editors, Canvas Drawing Editor can meet your needs.



License

MIT License

Copyright (c) 2025 typsusan


Thank you for using Canvas Drawing Editor! If this project helps you, please give us a ⭐ Star!