Designing Custom Textboxes in Fabric.js: Creating Stroked, Rounded, and Padded Elements

Dinesh Rawat
4 min readMay 30, 2023

Fabric.js is an incredible JavaScript library that simplifies the usage of HTML5 canvas elements, empowering developers to effortlessly create engaging web applications. With a wide range of features and tools, Fabric.js allows users to design interactive and visually stunning interfaces.

One notable advantage of Fabric.js is its ability to generate custom classes, enabling developers to enhance its capabilities and tailor it to their specific requirements.

In this article, we will explore the process of designing and utilizing a personalized class in Fabric.js. Our focus will be on creating a stroked textbox with rounded corners and padding. Additionally, we will demonstrate how this class can be adapted to different scenarios. By the end of this article, you will have a comprehensive understanding of crafting custom classes in Fabric.js and leveraging 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 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: This function oversees the rendering process of the textbox’s background, encompassing padding, rounded corners, and the stroke.

Here’s the revised code snippet:

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: GitHub Repository

Demo: Try it out

Benefits of Using the Stroked Textbox Class

By utilizing the Stroked Textbox class, we gain the ability to create personalized textboxes with distinctive visual attributes that go beyond the capabilities of the default Textbox class. This empowers us to craft canvas applications that possess enhanced visual appeal, captivating the audience with their uniqueness and setting them apart from others in the field.

Using the Stroked Textbox Class

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

const textbox = new fabric.TextboxWithPadding('Input 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 example, 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. Feel free to experiment with different values to achieve the desired results.

Conclusion

Customizing classes in Fabric.js provides immense flexibility and empowers developers to create canvas applications that align with their unique visions.

By extending the capabilities of the default classes, such as the Textbox class, we can introduce new features and enhance the visual appeal of our designs. The Stroked Textbox class presented in this article demonstrates the possibilities of personalized classes in Fabric.js, showcasing how rounded corners, padding, and strokes can be incorporated into textboxes to create stunning interfaces.

Fabric.js opens up a world of possibilities for developers, enabling the creation of captivating and interactive web applications. So go ahead, dive into the realm of custom classes in Fabric.js, and unlock the true potential of your canvas designs.

Remember, the code used in this article is available on the GitHub repository, and you can explore a live demo here.

Happy coding and designing!

For more topics related to Fabric.js, you can refer to https://prodeasy.com/the-product-mindset for many other topics related to fabric js.

--

--

Dinesh Rawat

Seasoned software engineer, Content creator, Helping teams achieve their goals. https://www.linkedin.com/in/dinesh-rawat/