Drawing with FabricJS and TypeScript Part 3: Basic Shapes

Drawing with FabricJS and TypeScript Part 3: Basic Shapes

Let's add basic shapes like rectangles, ovals, and triangles, and create a toolbar so the user can select whichever they want!

Now that we have a canvas and can draw straight lines, let's find out how to draw other basic shapes, as well as create a "toolbar" for the user so they can pick what kinds of shapes to draw.

Stars, fish, hearts, and buttons not included. Photo by Soraya Irving / Unsplash

The Sample Project

The sample project for this series is over on GitHub, and contains the complete codebase for the finished drawing canvas.

Initializing the Display Components

Before we can build more shape drawers, we first need a way to display the existing drawers in a "toolbar" so the user can select which one they want. We need a lot of pieces to make this work, so let's get started building them.

The first thing we need is a class that represents each displayed option. We are calling these classes "display components" and we need a base one from which all specific components can inherit. This class will need some properties that allow us to set up things like the CSS classes and icon displayed, as well as set the Drawing Mode.

Here's the annotated code for this base class, called DisplayComponent:

class DisplayComponent {
    drawingMode: DrawingMode; //Line, Rectangle, Oval, etc.
    target: string; //The selector for the HTML element 
                    //this Component will be rendered in
    hoverText: string; //The tooltip text
    svg: string; //The SVG for the component's icon
    cssClass: string; //CSS class for the FontAwesome 
                      //icon used by this display component
    childName: string; //Selector for the child element; 
                       //only used by text components.
    canvasDrawer: DrawingEditor;

    constructor(mode: DrawingMode, selector: string, parent: DrawingEditor, options: DisplayComponentOptions) {
        this.drawingMode = mode;
        this.target = selector; 
        this.cssClass = options.classNames;
        this.hoverText = options.altText;
        this.svg = options.svg;
        this.childName = options.childName;
        this.canvasDrawer = parent; 
        this.render();
        this.attachEvents();
    }

    //This method replaces the target HTML with the component's HTML.
    //The radio button is included to have Bootstrap use the correct styles.
    render() {
        const html = `<label id="${this.target.replace('#', '')}" class="btn btn-primary text-light " title="${this.hoverText}">
                        <input type="radio" name="options" autocomplete="off">
                        ${this.iconStr()}
                     </label>`;

        $(this.target).replaceWith(html);
    }

    private iconStr(): string {
        if (this.cssClass != null) {
            return `<i class="${this.cssClass}"></i>`;
        }
        else {
            return this.svg;
        }
    }

    //This method attaches the componentSelected event in DrawingEditor
    attachEvents() {
        const data = {
            mode: this.drawingMode,
            container: this.canvasDrawer,
            target: this.target
        };

        //When clicking the <label>, fire this event.
        $(this.target).click(data, function () {
            data.container.drawingMode = data.mode;
            data.container.componentSelected(data.target);
        });
    }

    selectedChanged(componentName: string) { }
}

class DisplayComponentOptions {
    altText: string;
    svg?: string;
    classNames?: string;
    childName?: string;
}

fabricjs

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Drawing with FabricJS and TypeScript : Cut/Copy/Paste and Hotkeys

Drawing with FabricJS and TypeScript : Cut/Copy/Paste and Hotkeys - Let's add cut/copy/paste functionality to our FabricJS drawing canvas, as well as hotkeys for the same!

Drawing with FabricJS and TypeScript Part 7: Undo/Redo

Let's add a StateManager so we can implement undo and redo functionality in our FabricJS canvas!

Drawing with FabricJS and TypeScript Part 1: Intro, Goals and Setup

Let's see how to start building a drawing canvas with FabricJS and TypeScript!

Drawing with FabricJS and TypeScript Part 4: Text and Freeform Lines

Let's implement drawers and components to display text and "freeform" lines in our FabricJS canvas!

Drawing with FabricJS and TypeScript: Deleting Objects

Let's add a deletion feature to our drawing canvas!