🧐 What is fabric.js
Fabric.js is a powerful and simple
Javascript HTML5 canvas library. It provides an interactive object model on top of the canvas element.
Fabric also has SVG-to-canvas (and canvas-to-SVG) parser.
What we build in this blog
The demo above is taken from this medium blog, in which there's some slight modification or fix need to be done.
Install fabric.js
npm
npm i fabric
npm i -D @types/fabric # typescript
yarn
yarn add fabric
yarn add -D @types/fabric # typescript
pnpm
pnpm add fabric
pnpm add -D @types/fabric # typescript
Setup for next.config.js
Below is the code for next.config.js. The reason is to configure the webpack for canvas runtime error that will crash the application and utf-8-validate & bufferutil warning. View more at the relevant references.
/** @type {import('next').NextConfig} */
const nextConfig = {
// reactStrictMode: false,
webpack: (config) => {
config.externals.push({
"utf-8-validate": "commonjs utf-8-validate",
bufferutil: "commonjs bufferutil",
canvas: "commonjs canvas",
});
// config.infrastructureLogging = { debug: /PackFileCache/ };
return config;
},
};
module.exports = nextConfig;
See also relevant references
Boilerplate for Next.js with Fabric.js
Below is the next.js
.tsx
code. If you are using Next.js 13.4 and above and opt-in to the app router, add "use client"
on top of the file to use the Next.js client component, or else ignore the line.
"use client"; // next.js app router
import React, { useState, useEffect } from "react";
import { fabric } from "fabric";
const App = () => {
const [canvas, setCanvas] = useState<fabric.Canvas>();
useEffect(() => {
const c = new fabric.Canvas("canvas", {
// ...
});
// settings for all canvas in the app
// ...
setCanvas(c);
return () => {
// ...
};
}, []);
const addRect = (canvi?: fabric.Canvas) => {
// ...
};
return (
<div>
<button onClick={() => addRect(canvas)}>Rectangle</button>
<canvas id="canvas" />
</div>
);
};
export default App;
Ensure that <canvas>
tag has an ID the same as new fabric.Canvas(id, {...})
useEffect & addRect function
useEffect(() => {
const c = new fabric.Canvas("canvas", {
height: 400,
width: 800,
backgroundColor: "black",
});
// settings for all canvas in the app
fabric.Object.prototype.transparentCorners = false;
fabric.Object.prototype.cornerColor = "#2BEBC8";
fabric.Object.prototype.cornerStyle = "rect";
fabric.Object.prototype.cornerStrokeColor = "#2BEBC8";
fabric.Object.prototype.cornerSize = 6;
setCanvas(c);
return () => {
c.dispose();
};
}, []);
const addRect = (canvas?: fabric.Canvas) => {
const rect = new fabric.Rect({
height: 280,
width: 200,
stroke: "#2BEBC8",
});
canvas?.add(rect);
canvas?.requestRenderAll();
};
Note
c.dispose()
is required to clean up the instantiated canvas element. See why you should clean up so that your rectangle can move and resize properly -> StackOverflow Question.
If you refuse to add the return () => {c.dispose();};
statement, you can disable the reactStrictMode
in next.config.js
. See the concept of reactStrictMode in this StackOverflow Question.
❤️ Leave a like if you like this post
❤️ It will be a massive motivation for me
Top comments (7)
TypeError: Cannot read properties of undefined (reading 'Canvas')
Fabric V6 has a new import
import * as fabric from 'fabric';
did you find the solution?????? If yes....can you please contact me at luckysolanki902@gmail.com... Please... I'm tired of this error, and fixing since morning
Fabric V6 has a new import
import * as fabric from 'fabric';
thank you bro.. you saved me from a bad headache !!
Thanks mate!
May you provide demo, github?