Skip to content

Commit 5a56c3b

Browse files
committed
refactor: export CanvasContextProvider to follow established context pattern
As noted [in the review]( #148 (comment) ), I disagree with this pattern. However, I will follow it to get these features added.
1 parent 471d2eb commit 5a56c3b

File tree

6 files changed

+188
-171
lines changed

6 files changed

+188
-171
lines changed

src/components/EditorCanvas/Area.jsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useContext, useRef, useState } from "react";
1+
import { useRef, useState } from "react";
22
import { Button, Popover, Input } from "@douyinfe/semi-ui";
33
import { IconEdit, IconDeleteStroked } from "@douyinfe/semi-icons";
44
import {
@@ -9,6 +9,7 @@ import {
99
State,
1010
} from "../../data/constants";
1111
import {
12+
useCanvas,
1213
useLayout,
1314
useSettings,
1415
useUndoRedo,
@@ -19,7 +20,6 @@ import {
1920
import ColorPalette from "../ColorPicker";
2021
import { useTranslation } from "react-i18next";
2122
import { useHover } from "usehooks-ts";
22-
import { CanvasContext } from "../../context/CanvasContext";
2323

2424
export default function Area({
2525
data,
@@ -33,7 +33,7 @@ export default function Area({
3333
pointer: {
3434
spaces: { diagram: pointer },
3535
},
36-
} = useContext(CanvasContext);
36+
} = useCanvas();
3737
const { layout } = useLayout();
3838
const { settings } = useSettings();
3939
const { setSaveState } = useSaveState();

src/components/EditorCanvas/Canvas.jsx

Lines changed: 159 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import Area from "./Area";
1111
import Relationship from "./Relationship";
1212
import Note from "./Note";
1313
import {
14+
useCanvas,
1415
useSettings,
1516
useTransform,
1617
useDiagram,
@@ -22,14 +23,13 @@ import {
2223
} from "../../hooks";
2324
import { useTranslation } from "react-i18next";
2425
import { diagram } from "../../data/heroDiagram";
25-
import { CanvasContext, useCanvasContextProviderValue } from "../../context/CanvasContext";
2626
import { useEventListener } from "usehooks-ts";
2727

2828
export default function Canvas() {
2929
const { t } = useTranslation();
3030

3131
const canvasRef = useRef(null);
32-
const canvasContextValue = useCanvasContextProviderValue(canvasRef);
32+
const canvasContextValue = useCanvas();
3333
const {
3434
canvas: { viewBox },
3535
pointer,
@@ -481,169 +481,167 @@ export default function Canvas() {
481481
const theme = localStorage.getItem("theme");
482482

483483
return (
484-
<CanvasContext.Provider value={canvasContextValue}>
485-
<div className="flex-grow h-full touch-none" id="canvas">
486-
<div
487-
className="w-full h-full"
488-
style={{
489-
cursor: pointer.style,
490-
backgroundColor: theme === "dark" ? "rgba(22, 22, 26, 1)" : "white",
491-
}}
492-
>
493-
{settings.showGrid && (
494-
<svg className="absolute w-full h-full">
495-
<defs>
496-
<pattern
497-
id="pattern-circles"
498-
x="0"
499-
y="0"
500-
width="24"
501-
height="24"
502-
patternUnits="userSpaceOnUse"
503-
patternContentUnits="userSpaceOnUse"
504-
>
505-
<circle
506-
id="pattern-circle"
507-
cx="4"
508-
cy="4"
509-
r="0.85"
510-
fill="rgb(99, 152, 191)"
511-
></circle>
512-
</pattern>
513-
</defs>
514-
<rect
484+
<div className="flex-grow h-full touch-none" id="canvas">
485+
<div
486+
className="w-full h-full"
487+
style={{
488+
cursor: pointer.style,
489+
backgroundColor: theme === "dark" ? "rgba(22, 22, 26, 1)" : "white",
490+
}}
491+
>
492+
{settings.showGrid && (
493+
<svg className="absolute w-full h-full">
494+
<defs>
495+
<pattern
496+
id="pattern-circles"
515497
x="0"
516498
y="0"
517-
width="100%"
518-
height="100%"
519-
fill="url(#pattern-circles)"
520-
></rect>
521-
</svg>
522-
)}
523-
<svg
524-
ref={canvasRef}
525-
onPointerMove={handlePointerMove}
526-
onPointerDown={handlePointerDown}
527-
onPointerUp={handlePointerUp}
528-
className="absolute w-full h-full touch-none"
529-
viewBox={`${viewBox.left} ${viewBox.top} ${viewBox.width} ${viewBox.height}`}
530-
>
531-
{areas.map((a) => (
532-
<Area
533-
key={a.id}
534-
data={a}
535-
onPointerDown={(e) =>
536-
handlePointerDownOnElement(e, a.id, ObjectType.AREA)
537-
}
538-
setResize={setAreaResize}
539-
setInitCoords={setInitCoords}
540-
/>
541-
))}
542-
{relationships.map((e, i) => (
543-
<Relationship key={i} data={e} />
544-
))}
545-
{tables.map((table) => (
546-
<Table
547-
key={table.id}
548-
tableData={table}
549-
setHoveredTable={setHoveredTable}
550-
handleGripField={handleGripField}
551-
setLinkingLine={setLinkingLine}
552-
onPointerDown={(e) =>
553-
handlePointerDownOnElement(e, table.id, ObjectType.TABLE)
554-
}
555-
/>
556-
))}
557-
{linking && (
558-
<path
559-
d={`M ${linkingLine.startX} ${linkingLine.startY} L ${linkingLine.endX} ${linkingLine.endY}`}
560-
stroke="red"
561-
strokeDasharray="8,8"
562-
className="pointer-events-none touch-none"
563-
/>
564-
)}
565-
{notes.map((n) => (
566-
<Note
567-
key={n.id}
568-
data={n}
569-
onPointerDown={(e) =>
570-
handlePointerDownOnElement(e, n.id, ObjectType.NOTE)
571-
}
572-
/>
573-
))}
499+
width="24"
500+
height="24"
501+
patternUnits="userSpaceOnUse"
502+
patternContentUnits="userSpaceOnUse"
503+
>
504+
<circle
505+
id="pattern-circle"
506+
cx="4"
507+
cy="4"
508+
r="0.85"
509+
fill="rgb(99, 152, 191)"
510+
></circle>
511+
</pattern>
512+
</defs>
513+
<rect
514+
x="0"
515+
y="0"
516+
width="100%"
517+
height="100%"
518+
fill="url(#pattern-circles)"
519+
></rect>
574520
</svg>
575-
</div>
576-
{settings.showDebugCoordinates && (
577-
<div className="fixed flex flex-col flex-wrap gap-6 bg-[rgba(var(--semi-grey-1),var(--tw-bg-opacity))]/40 border border-color bottom-4 right-4 p-4 rounded-xl backdrop-blur-sm pointer-events-none select-none">
578-
<table className="table-auto grow">
579-
<thead>
580-
<tr>
581-
<th className="text-left" colSpan={3}>
582-
{t("transform")}
583-
</th>
584-
</tr>
585-
<tr className="italic [&_th]:font-normal [&_th]:text-right">
586-
<th>pan x</th>
587-
<th>pan y</th>
588-
<th>scale</th>
589-
</tr>
590-
</thead>
591-
<tbody className="[&_td]:text-right [&_td]:min-w-[8ch]">
592-
<tr>
593-
<td>{transform.pan.x.toFixed(2)}</td>
594-
<td>{transform.pan.y.toFixed(2)}</td>
595-
<td>{transform.zoom.toFixed(4)}</td>
596-
</tr>
597-
</tbody>
598-
</table>
599-
<table className="table-auto grow [&_th]:text-left [&_th:not(:first-of-type)]:text-right [&_td:not(:first-of-type)]:text-right [&_td]:min-w-[8ch]">
600-
<thead>
601-
<tr>
602-
<th colSpan={4}>{t("viewbox")}</th>
603-
</tr>
604-
<tr className="italic [&_th]:font-normal">
605-
<th>left</th>
606-
<th>top</th>
607-
<th>width</th>
608-
<th>height</th>
609-
</tr>
610-
</thead>
611-
<tbody>
612-
<tr>
613-
<td>{viewBox.left.toFixed(2)}</td>
614-
<td>{viewBox.top.toFixed(2)}</td>
615-
<td>{viewBox.width.toFixed(2)}</td>
616-
<td>{viewBox.height.toFixed(2)}</td>
617-
</tr>
618-
</tbody>
619-
</table>
620-
<table className="table-auto grow [&_th]:text-left [&_th:not(:first-of-type)]:text-right [&_td:not(:first-of-type)]:text-right [&_td]:min-w-[8ch]">
621-
<thead>
622-
<tr>
623-
<th colSpan={3}>{t("cursor_coordinates")}</th>
624-
</tr>
625-
<tr className="italic [&_th]:font-normal">
626-
<th>{t("coordinate_space")}</th>
627-
<th>x</th>
628-
<th>y</th>
629-
</tr>
630-
</thead>
631-
<tbody>
632-
<tr>
633-
<td>{t("coordinate_space_screen")}</td>
634-
<td>{pointer.spaces.screen.x.toFixed(2)}</td>
635-
<td>{pointer.spaces.screen.y.toFixed(2)}</td>
636-
</tr>
637-
<tr>
638-
<td>{t("coordinate_space_diagram")}</td>
639-
<td>{pointer.spaces.diagram.x.toFixed(2)}</td>
640-
<td>{pointer.spaces.diagram.y.toFixed(2)}</td>
641-
</tr>
642-
</tbody>
643-
</table>
644-
</div>
645521
)}
522+
<svg
523+
ref={canvasRef}
524+
onPointerMove={handlePointerMove}
525+
onPointerDown={handlePointerDown}
526+
onPointerUp={handlePointerUp}
527+
className="absolute w-full h-full touch-none"
528+
viewBox={`${viewBox.left} ${viewBox.top} ${viewBox.width} ${viewBox.height}`}
529+
>
530+
{areas.map((a) => (
531+
<Area
532+
key={a.id}
533+
data={a}
534+
onPointerDown={(e) =>
535+
handlePointerDownOnElement(e, a.id, ObjectType.AREA)
536+
}
537+
setResize={setAreaResize}
538+
setInitCoords={setInitCoords}
539+
/>
540+
))}
541+
{relationships.map((e, i) => (
542+
<Relationship key={i} data={e} />
543+
))}
544+
{tables.map((table) => (
545+
<Table
546+
key={table.id}
547+
tableData={table}
548+
setHoveredTable={setHoveredTable}
549+
handleGripField={handleGripField}
550+
setLinkingLine={setLinkingLine}
551+
onPointerDown={(e) =>
552+
handlePointerDownOnElement(e, table.id, ObjectType.TABLE)
553+
}
554+
/>
555+
))}
556+
{linking && (
557+
<path
558+
d={`M ${linkingLine.startX} ${linkingLine.startY} L ${linkingLine.endX} ${linkingLine.endY}`}
559+
stroke="red"
560+
strokeDasharray="8,8"
561+
className="pointer-events-none touch-none"
562+
/>
563+
)}
564+
{notes.map((n) => (
565+
<Note
566+
key={n.id}
567+
data={n}
568+
onPointerDown={(e) =>
569+
handlePointerDownOnElement(e, n.id, ObjectType.NOTE)
570+
}
571+
/>
572+
))}
573+
</svg>
646574
</div>
647-
</CanvasContext.Provider>
575+
{settings.showDebugCoordinates && (
576+
<div className="fixed flex flex-col flex-wrap gap-6 bg-[rgba(var(--semi-grey-1),var(--tw-bg-opacity))]/40 border border-color bottom-4 right-4 p-4 rounded-xl backdrop-blur-sm pointer-events-none select-none">
577+
<table className="table-auto grow">
578+
<thead>
579+
<tr>
580+
<th className="text-left" colSpan={3}>
581+
{t("transform")}
582+
</th>
583+
</tr>
584+
<tr className="italic [&_th]:font-normal [&_th]:text-right">
585+
<th>pan x</th>
586+
<th>pan y</th>
587+
<th>scale</th>
588+
</tr>
589+
</thead>
590+
<tbody className="[&_td]:text-right [&_td]:min-w-[8ch]">
591+
<tr>
592+
<td>{transform.pan.x.toFixed(2)}</td>
593+
<td>{transform.pan.y.toFixed(2)}</td>
594+
<td>{transform.zoom.toFixed(4)}</td>
595+
</tr>
596+
</tbody>
597+
</table>
598+
<table className="table-auto grow [&_th]:text-left [&_th:not(:first-of-type)]:text-right [&_td:not(:first-of-type)]:text-right [&_td]:min-w-[8ch]">
599+
<thead>
600+
<tr>
601+
<th colSpan={4}>{t("viewbox")}</th>
602+
</tr>
603+
<tr className="italic [&_th]:font-normal">
604+
<th>left</th>
605+
<th>top</th>
606+
<th>width</th>
607+
<th>height</th>
608+
</tr>
609+
</thead>
610+
<tbody>
611+
<tr>
612+
<td>{viewBox.left.toFixed(2)}</td>
613+
<td>{viewBox.top.toFixed(2)}</td>
614+
<td>{viewBox.width.toFixed(2)}</td>
615+
<td>{viewBox.height.toFixed(2)}</td>
616+
</tr>
617+
</tbody>
618+
</table>
619+
<table className="table-auto grow [&_th]:text-left [&_th:not(:first-of-type)]:text-right [&_td:not(:first-of-type)]:text-right [&_td]:min-w-[8ch]">
620+
<thead>
621+
<tr>
622+
<th colSpan={3}>{t("cursor_coordinates")}</th>
623+
</tr>
624+
<tr className="italic [&_th]:font-normal">
625+
<th>{t("coordinate_space")}</th>
626+
<th>x</th>
627+
<th>y</th>
628+
</tr>
629+
</thead>
630+
<tbody>
631+
<tr>
632+
<td>{t("coordinate_space_screen")}</td>
633+
<td>{pointer.spaces.screen.x.toFixed(2)}</td>
634+
<td>{pointer.spaces.screen.y.toFixed(2)}</td>
635+
</tr>
636+
<tr>
637+
<td>{t("coordinate_space_diagram")}</td>
638+
<td>{pointer.spaces.diagram.x.toFixed(2)}</td>
639+
<td>{pointer.spaces.diagram.y.toFixed(2)}</td>
640+
</tr>
641+
</tbody>
642+
</table>
643+
</div>
644+
)}
645+
</div>
648646
);
649647
}

0 commit comments

Comments
 (0)