paint-brush
How to Build Custom Textboxes in Fabric.js: Stroked, Rounded, and Paddedby@dineshrawat
2,705 reads
2,705 reads

How to Build Custom Textboxes in Fabric.js: Stroked, Rounded, and Padded

by Dinesh RawatMay 25th, 2023
Read on Terminal Reader
Read this story w/o Javascript

Too Long; Didn't Read

Discover how to create customized stroked textboxes with rounded corners and padding in Fabric.js. This comprehensive guide empowers developers to enhance their canvas applications with visually appealing and unique interfaces.
featured image - How to Build Custom Textboxes in Fabric.js: Stroked, Rounded, and Padded
Dinesh Rawat HackerNoon profile picture

Fabric.js is a remarkable JavaScript library that streamlines the usage of HTML5 canvas elements, empowering developers to effortlessly craft engaging web applications. Packed with a multitude of features and tools, it empowers users to design interactive and visually stunning interfaces.


A notable advantage of Fabric.js lies in its capacity to generate custom classes, enabling developers to amplify its capabilities and customize it to meet their unique requirements.


This blog will delve into the process of designing and utilizing a personalized class in Fabric.js. Our focus will be on developing a stroked textbox with rounded corners and padding. Additionally, we will explore the adaptability of this class to cater to various scenarios. Upon completing this blog, you will possess a comprehensive grasp of crafting custom classes in Fabric.js and utilizing them to elevate your canvas applications.

Creating the Stroked Textbox Class

The Stroked Textbox class is an extension of the default Textbox class in Fabric.js, introducing various additional features such as stroke width, stroke color, padding, and rounded corners.


Let's analyze each line of code within this class:

  • type: "textbox": This line specifies the object type being created.

  • strokeWidth: 5: This line sets the stroke width to 5 pixels.

  • strokeColor: "#ffb64f": This line determines the stroke color as #ffb64f.

  • splitByGrapheme: true: This line indicates that the textbox should be split based on graphemes.

  • rx: 0: This line assigns a value of 0 to rx, controlling the degree of rounding on the x-axis.

  • ry: 0: This line assigns a value of 0 to ry, governing the degree of rounding on the y-axis.

  • toObject: This function returns an object containing all properties of the Textbox class, along with the new properties introduced by the Stroked Textbox class.

  • _renderBackground: _renderBackground: This function oversees the rendering process of the textbox's background, encompassing padding, rounded corners, and the stroke.


fabric.TextboxWithPadding = fabric.util.createClass(fabric.Textbox, {
    type: "textbox",
    strokeWidth: 5, // Specifies the width of the stroke
    strokeColor: "#ffb64f", // Sets the color of the stroke
    splitByGrapheme: true,
    rx: 0, // Determines the rx value for rounded corners on the x-axis
    ry: 0, // Determines the ry value for rounded corners on the y-axis
    toObject: function() {
        return fabric.util.object.extend(this.callSuper("toObject"), {
            backgroundColor: this.get("backgroundColor"),
            padding: this.get("padding"),
            splitByGrapheme: this.get("splitByGrapheme"),
            rx: this.get("rx"),
            ry: this.get("ry")
        });
    },

    _renderBackground: function(ctx) {
        if (!this.backgroundColor) {
            return;
        }
        var dim = this._getNonTransformedDimensions();
        ctx.fillStyle = this.backgroundColor;
        ctx.fillRect(
            -dim.x / 2 - this.padding,
            -dim.y / 2 - this.padding,
            dim.x + this.padding * 2,
            dim.y + this.padding * 2
        );
        // Stroke only at the top
        ctx.strokeStyle = this.strokeColor;
        ctx.lineWidth = this.strokeWidth;
        ctx.beginPath();
        ctx.moveTo(-dim.x / 2 - this.padding, -dim.y / 2 - this.padding);
        ctx.lineTo(-dim.x / 2 - this.padding, dim.y / 2 + this.padding);
        ctx.stroke();

        ctx.beginPath();
        ctx.strokeStyle = this.strokeColor;
        ctx.lineWidth = 0.2; // Set line width to 1
        ctx.lineTo(dim.x / 2 + this.padding, -dim.y / 2 - this.padding + 1);
        ctx.lineTo(dim.x / 2 + this.padding, dim.y / 2 + this.padding - 1);
        ctx.strokeStyle = "#9181fc";

        ctx.lineWidth = 0.2; // Set line width to 1
        ctx.lineTo(dim.x / 2 + this.padding - 1, dim.y / 2 + this.padding);
        ctx.lineTo(-dim.x / 2 - this.padding + 1, dim.y / 2 + this.padding);
        ctx.strokeStyle = "#9181fc";

        ctx.lineWidth = 0.2; // Set line width to 1
        ctx.lineTo(-dim.x / 2 - this.padding, dim.y / 2 + this.padding - 1);
        ctx.lineTo(-dim.x / 2 - this.padding, -dim.y / 2 - this.padding + 1);
        ctx.closePath();

        ctx.stroke();

        // If there is a background color, no other shadows should be casted
        this._removeShadow(ctx);
    }
});

Codebase

https://github.com/dinesh-rawat-dev/Prodeasy-section-component

Demo

https://y5k9l8.csb.app/

Benefits of using the class

With the utilization of the Stroked Textbox class, we gain the ability to generate personalized textboxes endowed with distinctive visual attributes that surpass the capabilities of the default Textbox class. This empowers us to craft canvas applications that possess enhanced visual appeal and captivate the audience with their uniqueness, setting them apart from others in the field.

Using the Stroked Textbox Class

To utilize the Stroked Textbox class, we can easily generate a new instance of the class and provide the necessary parameters. Below is an example demonstrating the usage of the class, showcasing the creation of a textbox with padding, rounded corners, and various stroke colors and widths:


const textbox = new fabric.TextboxWithPadding('Inpur field', {
    fontFamily: "Roboto",
    // fontSize: 20,
    padding: 5,
    width: 100,
    textAlign: 'left',
    //@ts-ignore
    // left: rect.left + 20,
    //@ts-ignore
    // top: rect.top + 10,  
    selectable: true,
    evented: true,
    editable: true,
    //@ts-ignore
    placeholder: "",
    splitByGrapheme: true,
    // lockScalingX: true,
    // lockScalingY: true,
    lockMovementX: true,
    lockMovementY: true,
    fill: '#000000',
    fontSize: 10,
    // stroke: OBJECT_BORDER_COLOR,
    strokeWidth: 1,
    backgroundColor: "#d5d1eb",
    //@ts-ignore
    left: 30,
    //@ts-ignore
    top: 30,
    className: "text_box_with_padding",
    includeDefaultValues: true,
    intersectsWithFrame: true,
    hasControls: false,
    hasBorders: true,
});


In this particular instance, we have customized the textbox's appearance and behavior by configuring properties such as fontFamily, padding, width, textAlign, selectable, evented, editable, splitByGrapheme, fill, fontSize, strokeWidth, backgroundColor, hasControls, and hasBorders.

Customizing the Stroked Textbox Class

To further customize the Stroked Textbox class, there are two approaches you can take. Firstly, you possess the capability to modify the parameter values directly within the class itself.

Alternatively, you can create a new subclass that extends the Stroked Textbox class and introduces additional functionality. Here are some suggestions on how to tailor the class to suit specific requirements:


  1. Adjust the stroke width: To alter the thickness of the stroke, modify the strokeWidth parameter. By adjusting the parameter, you can define the stroke thickness: increasing the value will yield a bolder stroke, while decreasing it will create a finer stroke.

    For instance, setting strokeWidth to 10 will create a textbox with a thicker stroke compared to the default value of 5.


  2. Change the stroke color:

    This parameter empowers you to alter the hue of the stroke, granting you greater flexibility in design choices.

    You can utilize a hexadecimal code or a named color. For example, setting strokeColor to "#ff0000" will generate a red stroke.


  3. Modify the padding: To change the color of the stroke, you can adjust the value of strokeColor. This determines the space between the text and the textbox's edges. For instance, setting padding to 10 will increase the spacing around the text.


  4. Adjust the rounding of the corners: To change the degree of rounding on the textbox's corners, modify the values of rx and ry. These parameters govern the level of rounding on the x and y axes, respectively. For example, setting both rx and ry to 10 will create a textbox with more pronounced rounded corners.


Furthermore, you have the option to create a new subclass that extends the Stroked Textbox class and incorporates additional functionality. This approach grants you even greater customization possibilities, allowing you to introduce new features to the textbox. For instance, you could create a subclass that adds a drop shadow to the textbox or dynamically changes the font based on user input. The potential for customization is vast, and the Stroked Textbox class serves as an excellent foundation to build upon.