npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ks-ng2-canvas-whiteboard

v9.1.2

Published

A Canvas component for Angular which supports free drawing.

Downloads

144

Readme

ng2-canvas-whiteboard

Angular Canvas Whiteboard Component - A powerful drawing library for Angular applications with support for shapes, colors, undo/redo, and touch events.

Features

  • 🎨 Draw & Paint - Freehand drawing with customizable brush size and colors
  • 🔄 Undo/Redo - Full undo/redo support with history tracking
  • 🎭 Shapes - Built-in shapes (circle, rectangle, line, star, smiley) with custom shape support
  • 🌈 Color Picker - Separate stroke and fill color pickers
  • 📱 Touch Support - Works on touch devices (tablets, mobile)
  • 💾 Save Images - Export canvas as image (PNG, JPEG, etc.)
  • ⚙️ Highly Configurable - Extensive options for customization
  • 🔌 Service-based - Control canvas programmatically via service

Requirements

  • Node.js: >= 20.19.0 and < 23
  • npm: >= 10 and < 12
  • Angular: 17+

Installation

1. Install the package

npm install ng2-canvas-whiteboard --save

Release

This repository can publish the library to npm from CI.

  1. Ensure package.json and projects/ng2-canvas-whiteboard/package.json are updated to the release version.
  2. Create a Git tag in the format v<version>, for example v8.1.5.
  3. Push the tag to GitHub.
  4. The GitHub Actions workflow publishes dist/ng2-canvas-whiteboard to npm using the NPM_TOKEN repository secret.

Example:

git tag v8.1.5
git push origin v8.1.5

2. Import the module

import { CanvasWhiteboardModule } from 'ng2-canvas-whiteboard';

@NgModule({
  imports: [
    CanvasWhiteboardModule
  ]
})
export class AppModule { }

3. Add to your component

import { Component, ViewChild } from '@angular/core';
import { CanvasWhiteboardComponent } from 'ng2-canvas-whiteboard';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  @ViewChild('canvasWhiteboard') canvasWhiteboard: CanvasWhiteboardComponent;
}

4. Use in template

<canvas-whiteboard #canvasWhiteboard
                   [drawButtonText]="'Draw'"
                   [clearButtonText]="'Clear'"
                   [undoButtonText]="'Undo'"
                   [undoButtonEnabled]="true"
                   [redoButtonText]="'Redo'"
                   [redoButtonEnabled]="true"
                   [colorPickerEnabled]="true"
                   [saveDataButtonEnabled]="true"
                   [saveDataButtonText]="'Save'"
                   (onBatchUpdate)="onCanvasDraw($event)"
                   (onClear)="onCanvasClear()"
                   (onUndo)="onCanvasUndo($event)"
                   (onRedo)="onCanvasRedo($event)"
                   (onSave)="onCanvasSave($event)">
</canvas-whiteboard>

Quick Start with Options

For a simpler approach, use the options input object:

export class AppComponent {
  canvasOptions = {
    drawingEnabled: true,          // Enable drawing mode by default
    drawButtonEnabled: true,
    clearButtonEnabled: true,
    undoButtonEnabled: true,
    redoButtonEnabled: true,
    colorPickerEnabled: true,
    saveDataButtonEnabled: true,
    lineWidth: 5,
    strokeColor: 'rgb(0,0,0)',
    fillColor: 'rgba(0,0,0,0)',
    scaleFactor: 1
  };
}
<canvas-whiteboard [options]="canvasOptions"
                   (onBatchUpdate)="onCanvasDraw($event)"
                   (onClear)="onCanvasClear()"
                   (onUndo)="onCanvasUndo($event)"
                   (onRedo)="onCanvasRedo($event)"
                   (onSave)="onCanvasSave($event)">
</canvas-whiteboard>

Configuration Options

Drawing Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | drawingEnabled | boolean | false | Enable drawing mode automatically | | drawButtonEnabled | boolean | true | Show/hide draw button | | clearButtonEnabled | boolean | true | Show/hide clear button | | undoButtonEnabled | boolean | false | Show/hide undo button | | redoButtonEnabled | boolean | false | Show/hide redo button | | saveDataButtonEnabled | boolean | false | Show/hide save button |

Styling Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | lineWidth | number | 2 | Brush width in pixels | | strokeColor | string | "rgba(0, 0, 0, 1)" | Brush color | | fillColor | string | "rgba(0, 0, 0, 0)" | Shape fill color | | startingColor | string | "#fff" | Canvas background color | | lineJoin | string | "round" | Line join style (round, bevel, miter) | | lineCap | string | "round" | Line cap style (round, square, butt) |

Shape Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | shapeSelectorEnabled | boolean | true | Enable shape selector | | showShapeSelector | boolean | false | Show shape selector programmatically |

Advanced Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | scaleFactor | number | 0 | Manual coordinate scale factor (0 = auto) | | aspectRatio | number | - | Force canvas aspect ratio | | batchUpdateTimeoutDuration | number | 100 | Delay before sending batch updates (ms) | | downloadedFileName | string | - | Downloaded image filename | | shouldDownloadDrawing | boolean | true | Auto-download on save |

Events

@Output() onClear = new EventEmitter<any>();
@Output() onBatchUpdate = new EventEmitter<CanvasWhiteboardUpdate[]>();
@Output() onImageLoaded = new EventEmitter<any>();
@Output() onUndo = new EventEmitter<string>();
@Output() onRedo = new EventEmitter<string>();
@Output() onSave = new EventEmitter<string | Blob>();

Saving Canvas as Image

export class AppComponent {
  @ViewChild('canvasWhiteboard') canvasWhiteboard: CanvasWhiteboardComponent;

  // Get canvas as data URL
  generateCanvasDataUrl(type: string = 'image/jpeg', quality: number = 0.3) {
    return this.canvasWhiteboard.generateCanvasDataUrl(type, quality);
  }

  // Get canvas as Blob
  generateCanvasBlob(callback: Function, type: string = 'image/png') {
    this.canvasWhiteboard.generateCanvasBlob(callback, type);
  }

  // Download canvas as image
  downloadImage() {
    this.canvasWhiteboard.downloadCanvasImage('image/png', undefined, 'my-drawing');
  }

  // Handle save event
  onCanvasSave(data: string | Blob) {
    console.log('Canvas saved:', data);
  }
}

Programmatic Control

Use CanvasWhiteboardService to control the canvas from code:

import { CanvasWhiteboardService } from 'ng2-canvas-whiteboard';

export class AppComponent {
  constructor(private canvasService: CanvasWhiteboardService) {}

  // Draw updates programmatically
  drawUpdates(updates: CanvasWhiteboardUpdate[]) {
    this.canvasService.drawCanvas(updates);
  }

  // Clear canvas
  clear() {
    this.canvasService.clearCanvas();
  }

  // Undo
  undo() {
    this.canvasService.undoCanvas();
  }

  // Redo
  redo() {
    this.canvasService.redoCanvas();
  }

  // Get drawing history
  getHistory() {
    return this.canvasService.getDrawingHistory();
  }
}

Custom Shapes

Create custom shapes by extending CanvasWhiteboardShape:

import { CanvasWhiteboardShape } from 'ng2-canvas-whiteboard';

export class CustomShape extends CanvasWhiteboardShape {
  getShapeName(): string {
    return 'CustomShape';
  }

  draw(context: CanvasRenderingContext2D): void {
    // Your drawing code here
    context.beginPath();
    context.arc(this.getStartingPoint().x, this.getStartingPoint().y, 50, 0, 2 * Math.PI);
    context.stroke();
  }

  drawPreview(context: CanvasRenderingContext2D): void {
    this.draw(context);
  }

  onUpdateReceived(update: CanvasWhiteboardUpdate): void {
    // Handle updates
  }
}

Register custom shape in your component:

import { CanvasWhiteboardShapeService } from 'ng2-canvas-whiteboard';

export class AppComponent {
  constructor(private shapeService: CanvasWhiteboardShapeService) {
    this.shapeService.registerShape(CustomShape);
  }
}

Unregistering Default Shapes

Unregister built-in shapes if you don't need them:

import { CircleShape, StarShape, SmileyShape, CanvasWhiteboardShapeService } from 'ng2-canvas-whiteboard';

export class AppComponent {
  constructor(private shapeService: CanvasWhiteboardShapeService) {
    this.shapeService.unregisterShapes([CircleShape, StarShape, SmileyShape]);
  }
}

Troubleshooting

Drawing starts from wrong position

This is typically a coordinate mapping issue. Try setting scaleFactor:

canvasOptions = {
  scaleFactor: 1,  // or window.devicePixelRatio
  drawingEnabled: true
};

Canvas size is wrong after resize

Trigger a resize event:

window.dispatchEvent(new Event('resize'));

High DPI / Retina display issues

Set appropriate scale factor:

canvasOptions = {
  scaleFactor: window.devicePixelRatio || 1
};

Development

Install dependencies

npm install

Run example app

npm run serve:ng2-canvas-whiteboard-example

Open http://localhost:4200 in your browser.

Build library

npm run build:ng2-canvas-whiteboard:prod

Lint

npm run lint

Build all (library + example)

npm run build:all

Run tests

npm run test:ng2-canvas-whiteboard

Run tests in CI mode

npm run test:ci

Maintenance Notes

  • This fork uses ESLint for linting (ng lint via @angular-eslint).
  • Legacy TSLint/Codelyzer configuration has been removed.
  • Legacy Protractor e2e configuration has been removed.

Browser Support

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

Known Issues

  • Some older browsers may have coordinate mapping issues with transformed canvas elements
  • High DPI displays may require manual scaleFactor configuration
  • Touch events on certain devices may need calibration

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Support

For issues, questions, or feature requests, please open an issue on GitHub.