I have an application using heavily HTML5 canvas via Fabric.js. The app is written on top of Angular 1.x, and I am planning to migrate it to React. My app allows writing tex
I don't see any answers here using React's functional components, and I couldn't get the hook from @jantimon to work. Here's my approach. I have the canvas itself take its dimensions from the layout of the page, then have a "backgroundObject" at (0,0) that acts as the drawable area for the user.
import React, { useState, useRef, useEffect } from 'react';
const { fabric } = window;
// this component takes one prop, data, which is an object with data.sizePixels, an array that represents the width,height of the "backgroundObject"
const CanvasComponent = ({ data }) => {
const canvasContainer = useRef();
const canvasRef = useRef();
const fabricRef = useRef();
const [error, setError] = useState();
const initCanvas = ({ canvas, size }) => {
console.log('*** canvas init');
console.log(canvas);
let rect = new fabric.Rect({
width: size[0],
height: size[1],
fill: 'white',
left: 0,
top: 0,
selectable: false,
excludeFromExport: true,
});
canvas.add(rect);
rect = new fabric.Rect({
width: 100,
height: 100,
fill: 'red',
left: 100,
top: 100,
});
canvas.add(rect);
};
// INIT
useEffect(() => {
if (!canvasRef.current) return;
if (fabricRef.current) return;
const canvas = new fabric.Canvas('canvas', {
width: canvasContainer.current.clientWidth,
height: canvasContainer.current.clientHeight,
selection: false, // disables drag-to-select
backgroundColor: 'lightGrey',
});
fabricRef.current = canvas;
initCanvas({ canvas, size: data.sizePixels });
});
// INPUT CHECKING
if (!data || !Array.isArray(data.sizePixels)) setError('Sorry, we could not open this item.');
if (error) {
return (
{error}
);
}
return (
<>
Controls
>
);
};
export default CanvasComponent;