-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into text-new-line-style-fix
- Loading branch information
Showing
96 changed files
with
1,934 additions
and
854 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,69 +1,53 @@ | ||
import * as fabric from 'fabric'; | ||
import React, { useCallback, useEffect, useRef } from 'react'; | ||
import React, { useEffect, useRef } from 'react'; | ||
|
||
const DEV_MODE = process.env.NODE_ENV === 'development'; | ||
|
||
export function useCanvas( | ||
ref?: React.ForwardedRef<HTMLCanvasElement>, | ||
init?: (canvas: fabric.Canvas) => any, | ||
saveState = false, | ||
deps: any[] = [] | ||
) { | ||
const elementRef = useRef<HTMLCanvasElement>(null); | ||
const fc = useRef<fabric.Canvas | null>(null); | ||
const data = useRef<any>(null); | ||
declare global { | ||
var canvas: fabric.Canvas | undefined; | ||
} | ||
|
||
export const Canvas = React.forwardRef< | ||
fabric.Canvas, | ||
{ onLoad?(canvas: fabric.Canvas): void } | ||
>(({ onLoad }, ref) => { | ||
const canvasRef = useRef<HTMLCanvasElement>(null); | ||
|
||
const setRef = useCallback( | ||
(el: HTMLCanvasElement | null) => { | ||
//@ts-ignore | ||
elementRef.current = el; | ||
ref && (ref.current = elementRef.current); | ||
// save state | ||
if (DEV_MODE && saveState && fc.current) { | ||
data.current = fc.current.toJSON(); | ||
} | ||
// dispose canvas | ||
fc.current?.dispose(); | ||
// set/clear ref | ||
if (!el) { | ||
fc.current = null; | ||
return; | ||
} | ||
const canvas = new fabric.Canvas(el); | ||
window.canvas = fc.current = canvas; | ||
// invoke callback | ||
init && init(canvas); | ||
// restore state | ||
if (DEV_MODE && saveState && data.current) { | ||
canvas.loadFromJSON(data.current); | ||
} | ||
}, | ||
[saveState, ...deps] | ||
); | ||
useEffect(() => { | ||
// disposer | ||
if (!canvasRef.current) { | ||
return; | ||
} | ||
|
||
const canvas = new fabric.Canvas(canvasRef.current); | ||
|
||
DEV_MODE && (window.canvas = canvas); | ||
|
||
if (typeof ref === 'function') { | ||
ref(canvas); | ||
} else if (typeof ref === 'object' && ref) { | ||
ref.current = canvas; | ||
} | ||
|
||
// it is crucial `onLoad` is a dependency of this effect | ||
// to ensure the canvas is disposed and re-created if it changes | ||
onLoad?.(canvas); | ||
|
||
return () => { | ||
// save state | ||
if (DEV_MODE && saveState && fc.current) { | ||
data.current = fc.current.toJSON(); | ||
} | ||
// we avoid unwanted disposing by doing so only if element ref is unavailable | ||
if (!elementRef.current) { | ||
fc.current?.dispose(); | ||
fc.current = null; | ||
DEV_MODE && delete window.canvas; | ||
|
||
if (typeof ref === 'function') { | ||
ref(null); | ||
} else if (typeof ref === 'object' && ref) { | ||
ref.current = null; | ||
} | ||
|
||
// `dispose` is async | ||
// however it runs a sync DOM cleanup | ||
// its async part ensures rendering has completed | ||
// and should not affect react | ||
canvas.dispose(); | ||
}; | ||
}, [saveState]); | ||
return [fc, setRef] as [typeof fc, typeof setRef]; | ||
} | ||
}, [canvasRef, onLoad]); | ||
|
||
export const Canvas = React.forwardRef< | ||
HTMLCanvasElement, | ||
{ | ||
onLoad?: (canvas: fabric.Canvas) => any; | ||
saveState?: boolean; | ||
} | ||
>(({ onLoad, saveState }, ref) => { | ||
const [canvasRef, setCanvasElRef] = useCanvas(ref, onLoad, saveState); | ||
return <canvas ref={setCanvasElRef} />; | ||
return <canvas ref={canvasRef} />; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.