Skip to content

Commit

Permalink
#101 stageRef promoted to Provider, export working
Browse files Browse the repository at this point in the history
  • Loading branch information
oleojake committed Aug 6, 2024
1 parent 4031b40 commit 4ccbf76
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 12 deletions.
1 change: 1 addition & 0 deletions src/core/providers/canvas/canvas.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@ export interface CanvasContextModel {
addNewShape: (type: ShapeType, x: number, y: number) => string;
updateShapeSizeAndPosition: (id: string, position: Coord, size: Size) => void;
updateShapePosition: (id: string, position: Coord) => void;
stageRef: React.RefObject<Konva.Stage>;
selectionInfo: SelectionInfo;
}
3 changes: 3 additions & 0 deletions src/core/providers/canvas/canvas.provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { CanvasContext } from './canvas.context';
import { useSelection } from './use-selection.hook';
import { createShape } from '@/pods/canvas/canvas.model';
import { v4 as uuidv4 } from 'uuid';
import Konva from 'konva';

interface Props {
children: React.ReactNode;
Expand All @@ -13,6 +14,7 @@ export const CanvasProvider: React.FC<Props> = props => {
const { children } = props;
const [shapes, setShapes] = React.useState<ShapeModel[]>([]);
const [scale, setScale] = React.useState(1);
const stageRef = React.useRef<Konva.Stage>(null);

const selectionInfo = useSelection(shapes, setShapes);

Expand Down Expand Up @@ -62,6 +64,7 @@ export const CanvasProvider: React.FC<Props> = props => {
pasteShape,
updateShapeSizeAndPosition,
updateShapePosition,
stageRef,
}}
>
{children}
Expand Down
5 changes: 3 additions & 2 deletions src/pods/canvas/canvas.pod.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const CanvasPod = () => {
addNewShape,
updateShapeSizeAndPosition,
updateShapePosition,
stageRef,
} = useCanvasContext();

const {
Expand All @@ -45,7 +46,7 @@ export const CanvasPod = () => {
};

const { isDraggedOver, dropRef } = useDropShape();
const { stageRef } = useMonitorShape(dropRef, addNewShapeAndSetSelected);
useMonitorShape(dropRef, addNewShapeAndSetSelected);

const getSelectedShapeKonvaId = (): string => {
let result = '';
Expand All @@ -68,7 +69,7 @@ export const CanvasPod = () => {
showSnapInVerticalLine,
yCoordHorizontalLine,
xCoordVerticalLine,
} = useSnapIn(stageRef, transformerRef, selectedShapeKonvaId);
} = useSnapIn(transformerRef, selectedShapeKonvaId);

const { handleTransform, handleTransformerBoundBoxFunc } = useTransform(
updateShapeSizeAndPosition,
Expand Down
8 changes: 3 additions & 5 deletions src/pods/canvas/use-monitor-shape.hook.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { useEffect, useRef } from 'react';
import { useEffect } from 'react';
import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
import invariant from 'tiny-invariant';
import {
extractScreenCoordinatesFromPragmaticLocation,
portScreenPositionToDivCoordinates,
convertFromDivElementCoordsToKonvaCoords,
} from './canvas.util';
import Konva from 'konva';
import { ShapeType } from '@/core/model';
import { useCanvasContext } from '@/core/providers';

export const useMonitorShape = (
dropRef: React.MutableRefObject<null>,
addNewShape: (type: ShapeType, x: number, y: number) => void
) => {
const stageRef = useRef<Konva.Stage>(null);
const { stageRef } = useCanvasContext();

useEffect(() => {
return monitorForElements({
Expand Down Expand Up @@ -54,6 +54,4 @@ export const useMonitorShape = (
},
});
}, []);

return { stageRef };
};
4 changes: 2 additions & 2 deletions src/pods/canvas/use-snapin.hook.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import Konva from 'konva';
import { KonvaEventObject } from 'konva/lib/Node';
import { Stage } from 'konva/lib/Stage';
import invariant from 'tiny-invariant';
import { ClosestSnapLines, SnapEdges, SnapLines } from './canvas.model';
import { getClosestSnapLines } from './snap.utils';
import { useState } from 'react';
import { useCanvasContext } from '@/core/providers';

export const useSnapIn = (
stageRef: React.RefObject<Stage>,
transformRef: React.RefObject<Konva.Transformer>,
excludedShapeId: string
) => {
Expand All @@ -16,6 +15,7 @@ export const useSnapIn = (
const [showSnapInVerticalLine, setShowSnapInVerticalLine] = useState(false);
const [yCoordHorizontalLine, setYCoordHorizontalLine] = useState(0);
const [xCoordVerticalLine, setXCoordVerticalLine] = useState(0);
const { stageRef } = useCanvasContext();

const handleTransformerDragMove = (e: KonvaEventObject<DragEvent>) => {
if (!excludedShapeId) return;
Expand Down
36 changes: 33 additions & 3 deletions src/pods/toolbar/components/export-button/export-button.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,44 @@
import { ExportIcon } from '@/common/components/icons/export-icon.component';
import { useCanvasContext } from '@/core/providers';
import ToolbarButton from '@/pods/toolbar/components/toolbar-button/toolbar-button';
import classes from '@/pods/toolbar/toolbar.pod.module.css';

export const ExportButton = () => {
const handleClick = () => {
console.log('Export');
const { stageRef, selectionInfo } = useCanvasContext();
const { transformerRef } = selectionInfo;

const hideTransformer = () => {
if (transformerRef.current) {
transformerRef.current.hide();
}
};

const showTransformer = () => {
if (transformerRef.current) {
transformerRef.current.show();
}
};

const createDownloadLink = (dataURL: string) => {
const link = document.createElement('a');
link.href = dataURL;
link.download = 'canvas.png';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};

const handleExport = () => {
if (!stageRef.current) return;

hideTransformer();
const dataURL = stageRef.current.toDataURL({ mimeType: 'image/png' });
createDownloadLink(dataURL);
showTransformer();
};

return (
<ToolbarButton onClick={handleClick} className={classes.button}>
<ToolbarButton onClick={handleExport} className={classes.button}>
<ExportIcon />
<span>Export</span>
</ToolbarButton>
Expand Down

0 comments on commit 4ccbf76

Please sign in to comment.