working on fabric js
This commit is contained in:
@@ -5,7 +5,7 @@ import { LayoutFilled, ProductFilled, CloudUploadOutlined } from "@ant-design/ic
|
||||
import Sidebar from './sidebar/sidebar'
|
||||
import WidgetsContainer from './sidebar/widgetsContainer'
|
||||
import UploadsContainer from './sidebar/uploadsContainer'
|
||||
import Canvas from './canvas/main'
|
||||
import Canvas from './canvas/mainClass'
|
||||
|
||||
function App() {
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import * as fabric from 'fabric'
|
||||
|
||||
|
||||
/**
|
||||
* NOTE: Not in use
|
||||
*/
|
||||
function FabricJSCanvas({ canvasOptions, className = '', onCanvasContextUpdate }) {
|
||||
|
||||
const canvasRef = useRef(null)
|
||||
@@ -22,8 +24,9 @@ function FabricJSCanvas({ canvasOptions, className = '', onCanvasContextUpdate }
|
||||
canvasRef.current.parentNode.style.width = "100%"
|
||||
canvasRef.current.parentNode.style.height = "100%"
|
||||
|
||||
console.log("Parent: ", canvasRef.current.parentNode)
|
||||
|
||||
console.log("Parent: ", canvasRef.current.parentNode.parentNode)
|
||||
|
||||
canvasRef.current.parentNode.parentNode.addEventListener("resize", updateCanvasDimensions)
|
||||
window.addEventListener("resize", updateCanvasDimensions)
|
||||
|
||||
// make the fabric.Canvas instance available to your app
|
||||
@@ -33,6 +36,7 @@ function FabricJSCanvas({ canvasOptions, className = '', onCanvasContextUpdate }
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("resize", updateCanvasDimensions)
|
||||
canvasRef.current.parentNode.parentNode.removeEventListener("resize", updateCanvasDimensions)
|
||||
|
||||
if (onCanvasContextUpdate)
|
||||
onCanvasContextUpdate(null)
|
||||
@@ -45,17 +49,19 @@ function FabricJSCanvas({ canvasOptions, className = '', onCanvasContextUpdate }
|
||||
const updateCanvasDimensions = useCallback(() => {
|
||||
if (!canvasRef.current || !fabricCanvasRef.current)
|
||||
return
|
||||
|
||||
// console.log("Updating canvas")
|
||||
const parent = canvasRef.current.parentNode.parentNode
|
||||
|
||||
fabricCanvasRef.current.setDimensions({ width: parent.clientWidth, height: parent.clientHeight })
|
||||
fabricCanvasRef.current.calcOffset()
|
||||
|
||||
fabricCanvasRef.current.renderAll()
|
||||
|
||||
}, [fabricCanvasRef, canvasRef])
|
||||
|
||||
|
||||
|
||||
return <canvas className={className} ref={canvasRef} id='we'/>
|
||||
return <canvas className={className} ref={canvasRef}/>
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,30 +1,64 @@
|
||||
import { useCallback, useRef, useState } from "react"
|
||||
import FabricJSCanvas from "./fabricCanvas"
|
||||
import { useCallback, useRef, useEffect, useMemo } from "react"
|
||||
import * as fabric from 'fabric'
|
||||
|
||||
|
||||
|
||||
function Canvas(){
|
||||
|
||||
const fabricCanvasRef = useRef()
|
||||
const canvasRef = useRef(null)
|
||||
|
||||
const updateCanvasDimensions = useCallback((event) => {
|
||||
console.log("Updating: ", fabricCanvasRef)
|
||||
if (!fabricCanvasRef.current)
|
||||
const canvas = useMemo(() => {
|
||||
const options = {}
|
||||
|
||||
if (canvasRef.current)
|
||||
return new fabric.Canvas(canvasRef.current, options)
|
||||
else
|
||||
return null
|
||||
|
||||
}, [canvasRef.current])
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
return () => {
|
||||
canvas?.dispose() // if already exist, dispose before re-initializing
|
||||
}
|
||||
|
||||
}, [])
|
||||
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (canvasRef.current && canvas) {
|
||||
window.addEventListener("resize", updateCanvasDimensions)
|
||||
updateCanvasDimensions()
|
||||
}
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("resize", updateCanvasDimensions)
|
||||
}
|
||||
}, [canvasRef, canvas])
|
||||
|
||||
|
||||
const updateCanvasDimensions = useCallback(() => {
|
||||
if (!canvasRef.current || !canvas)
|
||||
return
|
||||
// console.log("Updating canvas")
|
||||
const parent = canvasRef.current.parentNode.parentNode // this is the canvas outer container
|
||||
|
||||
const parent = event.target
|
||||
|
||||
fabricCanvasRef.current.setDimensions({ width: parent.clientWidth, height: parent.clientHeight })
|
||||
fabricCanvasRef.current.renderAll()
|
||||
canvas.setDimensions({ width: parent.clientWidth, height: parent.clientHeight })
|
||||
canvas.calcOffset()
|
||||
|
||||
canvas.renderAll()
|
||||
|
||||
}, [canvas, canvasRef])
|
||||
|
||||
}, [fabricCanvasRef])
|
||||
|
||||
|
||||
return (
|
||||
<div className="tw-flex tw-w-full tw-h-full tw-max-h-[100vh] tw-overflow-auto"
|
||||
|
||||
>
|
||||
<FabricJSCanvas className="tw-bg-red-200"
|
||||
onCanvasContextUpdate={(canvas) => fabricCanvasRef.current = canvas}/>
|
||||
<div className="tw-relative tw-flex tw-w-full tw-h-full tw-max-h-[100vh] tw-overflow-auto"
|
||||
onResize={updateCanvasDimensions}>
|
||||
<canvas className="tw-bg-red-200 tw-w-full tw-h-full" ref={canvasRef}/>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
138
src/canvas/mainClass.js
Normal file
138
src/canvas/mainClass.js
Normal file
@@ -0,0 +1,138 @@
|
||||
import React from "react"
|
||||
import * as fabric from 'fabric'
|
||||
|
||||
|
||||
class Canvas extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this.fabricCanvas = null
|
||||
this.canvasRef = React.createRef()
|
||||
|
||||
this.mousePressed = false
|
||||
this.mousePos = {
|
||||
startX: 0,
|
||||
startY: 0
|
||||
}
|
||||
|
||||
this.modes = {
|
||||
PAN: 'pan',
|
||||
}
|
||||
this.currentMode = 'pan'
|
||||
|
||||
this.updateCanvasDimensions = this.updateCanvasDimensions.bind(this)
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.fabricCanvas = new fabric.Canvas(this.canvasRef.current, {
|
||||
selection: false,
|
||||
})
|
||||
const rect = new fabric.Rect({
|
||||
left: 100,
|
||||
top: 100,
|
||||
fill: 'red',
|
||||
width: 200,
|
||||
height: 100,
|
||||
angle: 0
|
||||
})
|
||||
this.fabricCanvas.add(rect)
|
||||
console.log("Mounted: ", rect)
|
||||
fabric.FabricImage.fromURL("https://images.unsplash.com/photo-1722898614949-c9a315e35209?q=80&w=1974&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
|
||||
(oImg) => {
|
||||
console.log("added image", oImg)
|
||||
|
||||
const canvasWidth = this.fabricCanvas.getWidth()
|
||||
const canvasHeight = this.fabricCanvas.getHeight()
|
||||
|
||||
// Get the image's original dimensions
|
||||
const imgWidth = oImg.getScaledWidth()
|
||||
const imgHeight = oImg.getScaledHeight()
|
||||
|
||||
// Set the position to the center
|
||||
oImg.set({
|
||||
left: (canvasWidth - imgWidth) / 2,
|
||||
top: (canvasHeight - imgHeight) / 2
|
||||
})
|
||||
|
||||
oImg.scaleX(2)
|
||||
oImg.scaleY(2)
|
||||
|
||||
// this.fabricCanvas.backgroundImage = oImg
|
||||
this.fabricCanvas.add(oImg)
|
||||
this.fabricCanvas.renderAll()
|
||||
})
|
||||
|
||||
this.initPan()
|
||||
|
||||
window.addEventListener("resize", this.updateCanvasDimensions)
|
||||
this.updateCanvasDimensions()
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.fabricCanvas.dispose()
|
||||
window.removeEventListener("resize", this.updateCanvasDimensions)
|
||||
}
|
||||
|
||||
updateCanvasDimensions() {
|
||||
if (!this.canvasRef.current || !this.fabricCanvas) return
|
||||
|
||||
const parent = this.canvasRef.current.parentNode.parentNode // Get the outer container
|
||||
|
||||
this.fabricCanvas.setDimensions({
|
||||
width: parent.clientWidth,
|
||||
height: parent.clientHeight
|
||||
})
|
||||
|
||||
this.fabricCanvas.calcOffset()
|
||||
this.fabricCanvas.renderAll()
|
||||
}
|
||||
|
||||
initPan(){
|
||||
|
||||
this.fabricCanvas.on("mouse:down", (event) => {
|
||||
this.mousePressed = true
|
||||
|
||||
this.startX = event.e.clientX
|
||||
this.startY = event.e.clientY
|
||||
|
||||
this.fabricCanvas.setCursor("grab")
|
||||
|
||||
})
|
||||
|
||||
this.fabricCanvas.on("mouse:up", () => {
|
||||
this.mousePressed = false
|
||||
this.fabricCanvas.setCursor("default")
|
||||
|
||||
})
|
||||
|
||||
this.fabricCanvas.on("mouse:move", (event) => {
|
||||
|
||||
if (this.mousePressed && this.currentMode === this.modes.PAN){
|
||||
|
||||
this.fabricCanvas.setCursor("grab")
|
||||
|
||||
const deltaX = event.e.clientX - this.mousePos.startX
|
||||
const deltaY = event.e.clientY - this.mousePos.startY
|
||||
|
||||
this.fabricCanvas.relativePan({ x: deltaX, y: deltaY })
|
||||
|
||||
this.mousePos.startX = event.e.clientX
|
||||
this.mousePos.startY = event.e.clientY
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="tw-relative tw-flex tw-w-full tw-h-full tw-max-h-[100vh] tw-overflow-auto">
|
||||
<canvas className="tw-w-full tw-h-full" ref={this.canvasRef}/> {/* Don't add any bg color here */}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Canvas
|
||||
@@ -43,9 +43,9 @@ function Sidebar({tabs}){
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`tw-relative tw-min-w-[80px] tw-duration-[0.3s] tw-transition-all
|
||||
<div className={`tw-relative tw-duration-[0.3s] tw-transition-all
|
||||
tw-max-w-[400px] tw-flex tw-h-full tw-z-10
|
||||
${sidebarOpen ? "tw-bg-white tw-min-w-[400px] tw-w-[400px] tw-shadow-lg": "tw-bg-primaryBg tw-w-[80px]"}
|
||||
${sidebarOpen ? "tw-bg-white tw-min-w-[400px] tw-w-[400px] tw-shadow-lg": "tw-bg-primaryBg tw-min-w-[80px] tw-w-[80px]"}
|
||||
`} ref={sideBarRef}
|
||||
onMouseLeave={hideOnMouseLeave}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user