Fixes canvas re-renders
This commit is contained in:
parent
c0dcce7c82
commit
b87e05b1de
3 changed files with 59 additions and 10 deletions
|
@ -1 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10,20A10,10,0,1,1,20,10,10.011,10.011,0,0,1,10,20ZM10,1.474A8.526,8.526,0,1,0,18.526,10,8.536,8.536,0,0,0,10,1.474Z"/><circle cx="10" cy="10" r="2.513"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10,20A10,10,0,1,1,20,10,10.011,10.011,0,0,1,10,20ZM10,1.483A8.517,8.517,0,1,0,18.517,10,8.526,8.526,0,0,0,10,1.483Z"/><circle cx="10" cy="10" r="3.747"/></svg>
|
Before Width: | Height: | Size: 229 B After Width: | Height: | Size: 229 B |
|
@ -1 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10,20A10,10,0,1,1,20,10,10.011,10.011,0,0,1,10,20ZM10,1.483A8.517,8.517,0,1,0,18.517,10,8.526,8.526,0,0,0,10,1.483Z"/><circle cx="10" cy="10" r="3.747"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10,20A10,10,0,1,1,20,10,10.011,10.011,0,0,1,10,20ZM10,1.474A8.526,8.526,0,1,0,18.526,10,8.536,8.536,0,0,0,10,1.474Z"/><circle cx="10" cy="10" r="2.513"/></svg>
|
Before Width: | Height: | Size: 229 B After Width: | Height: | Size: 229 B |
|
@ -94,6 +94,12 @@ export const MediaEditor = ({
|
|||
|
||||
// Initial image load and Fabric canvas setup
|
||||
useEffect(() => {
|
||||
// This is important. We can't re-run this function if we've already setup
|
||||
// a canvas since Fabric doesn't like that.
|
||||
if (fabricCanvas) {
|
||||
return;
|
||||
}
|
||||
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
setImage(img);
|
||||
|
@ -117,7 +123,7 @@ export const MediaEditor = ({
|
|||
img.onload = noop;
|
||||
img.onerror = noop;
|
||||
};
|
||||
}, [canvasId, imageSrc, onClose]);
|
||||
}, [canvasId, fabricCanvas, imageSrc, onClose]);
|
||||
|
||||
const history = useFabricHistory(fabricCanvas);
|
||||
|
||||
|
@ -142,7 +148,22 @@ export const MediaEditor = ({
|
|||
ev => isCmdOrCtrl(ev) && ev.key === 't',
|
||||
() => setEditMode(EditMode.Text),
|
||||
],
|
||||
[ev => isCmdOrCtrl(ev) && ev.key === 'z', () => history?.undo()],
|
||||
[
|
||||
ev => isCmdOrCtrl(ev) && ev.key === 'z',
|
||||
() => {
|
||||
if (history?.canUndo()) {
|
||||
history?.undo();
|
||||
}
|
||||
},
|
||||
],
|
||||
[
|
||||
ev => isCmdOrCtrl(ev) && ev.shiftKey && ev.key === 'z',
|
||||
() => {
|
||||
if (history?.canRedo()) {
|
||||
history?.redo();
|
||||
}
|
||||
},
|
||||
],
|
||||
[
|
||||
ev => ev.key === 'Escape',
|
||||
() => {
|
||||
|
@ -519,6 +540,7 @@ export const MediaEditor = ({
|
|||
return;
|
||||
}
|
||||
|
||||
obj.exitEditing();
|
||||
obj.set(getTextStyleAttributes(textStyle, sliderValue));
|
||||
fabricCanvas.requestRenderAll();
|
||||
}, [editMode, fabricCanvas, sliderValue, textStyle]);
|
||||
|
@ -610,6 +632,8 @@ export const MediaEditor = ({
|
|||
textStyle,
|
||||
]);
|
||||
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
|
||||
// In an ideal world we'd use <ModalHost /> to get the nice animation benefits
|
||||
// but because of the way IText is implemented -- with a hidden textarea -- to
|
||||
// capture keyboard events, we can't use ModalHost since that traps focus, and
|
||||
|
@ -963,12 +987,12 @@ export const MediaEditor = ({
|
|||
'MediaEditor__control--selected': editMode === EditMode.Text,
|
||||
})}
|
||||
onClick={() => {
|
||||
if (!fabricCanvas) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (editMode === EditMode.Text) {
|
||||
setEditMode(undefined);
|
||||
const obj = fabricCanvas?.getActiveObject();
|
||||
if (obj instanceof MediaEditorFabricIText) {
|
||||
obj.exitEditing();
|
||||
}
|
||||
} else {
|
||||
setEditMode(EditMode.Text);
|
||||
}
|
||||
|
@ -1069,12 +1093,37 @@ export const MediaEditor = ({
|
|||
/>
|
||||
</div>
|
||||
<Button
|
||||
disabled={!image || isSaving}
|
||||
onClick={async () => {
|
||||
if (!fabricCanvas) {
|
||||
return;
|
||||
}
|
||||
const renderedCanvas = fabricCanvas.toCanvasElement();
|
||||
const data = await canvasToBytes(renderedCanvas);
|
||||
|
||||
setEditMode(undefined);
|
||||
setIsSaving(true);
|
||||
|
||||
let data: Uint8Array;
|
||||
try {
|
||||
fabricCanvas.discardActiveObject();
|
||||
fabricCanvas.setDimensions({
|
||||
width: image.width,
|
||||
height: image.height,
|
||||
});
|
||||
fabricCanvas.setZoom(1);
|
||||
const renderedCanvas = fabricCanvas.toCanvasElement();
|
||||
fabricCanvas.setDimensions({
|
||||
width: imageState.width * zoom,
|
||||
height: imageState.height * zoom,
|
||||
});
|
||||
fabricCanvas.setZoom(zoom);
|
||||
data = await canvasToBytes(renderedCanvas);
|
||||
} catch (err) {
|
||||
onClose();
|
||||
throw err;
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
}
|
||||
|
||||
onDone(data);
|
||||
}}
|
||||
theme={Theme.Dark}
|
||||
|
|
Loading…
Add table
Reference in a new issue