Skip to content

Commit

Permalink
update canvas component to render canvas element
Browse files Browse the repository at this point in the history
  • Loading branch information
deveshidwivedi committed Jun 18, 2024
1 parent 21828e1 commit 7148160
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 6 deletions.
143 changes: 143 additions & 0 deletions modules/canvas/components/Canvas.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import { CANVAS_SIZE } from "@/common/constants/canvasSize";
import { useViewportSize } from "@/common/hooks/useViewportSize";
import { useMotionValue, motion } from "framer-motion";
import { useRef, useState, useEffect } from "react";
import { useKeyPressEvent } from "react-use";
import { useDraw } from "../hooks/Canvas.hooks";
import { socket } from "@/common/lib/socket";
import { drawFromSocket } from "../helpers/Canvas.helpers";
import Minimap from "./Minimap";

const Canvas = () => {
const canvasRef = useRef<HTMLCanvasElement>(null);
const smallCanvasRef = useRef<HTMLCanvasElement>(null);

const [ctx, setCtx] = useState<CanvasRenderingContext2D | undefined>();
const [dragging, setDragging] = useState(false);
const [, setMovedMiniMap] = useState(false);

const { width, height } = useViewportSize();

useKeyPressEvent("Control", () => setDragging(true), () => setDragging(false));

const x = useMotionValue(0);
const y = useMotionValue(0);

const copyCanvasToSmall = () => {
if (canvasRef.current) {
smallCanvasRef.current
?.getContext("2d")
?.drawImage(
canvasRef.current,
0,
0,
CANVAS_SIZE.width,
CANVAS_SIZE.height
);
}
};

const { handleDraw, handleEndDrawing, handleStartDrawing, drawing } = useDraw(
ctx,
dragging,
-x.get(),
-y.get(),
copyCanvasToSmall
);

useEffect(() => {
const newCtx = canvasRef.current?.getContext("2d");
if (newCtx) setCtx(newCtx);

const handleKeyUp = (e: KeyboardEvent) => {
if (!e.ctrlKey && dragging) {
setDragging(false);
}
}
window.addEventListener("keyup", handleKeyUp);
return () => {
window.removeEventListener("keyup", handleKeyUp);
}
}, [dragging]);

useEffect(() => {
let movesToDrawLater: [number, number][] = [];
let optionsToUseLater: CtxOptions = {
lineColor: "",
lineWidth: 0,
};
socket.on("socket_draw", (movesToDraw, socketOptions) => {
if (ctx && !drawing) {
drawFromSocket(movesToDraw, socketOptions, ctx, copyCanvasToSmall);
} else {
movesToDrawLater = movesToDraw;
optionsToUseLater = socketOptions;
}
});

return () => {
socket.off("socket_draw");
if (movesToDrawLater.length && ctx) {
drawFromSocket(movesToDrawLater, optionsToUseLater, ctx, copyCanvasToSmall);
}
};
}, [drawing, ctx]);

return (
<div className="h-full w-full overflow-hidden">
<motion.canvas
ref={canvasRef}
width={CANVAS_SIZE.width}
height={CANVAS_SIZE.height}
className={`bg-zinc-300 ${dragging && 'cursor-move'}`}
style={{ x, y }}
drag={dragging}
dragConstraints={{
left: -(CANVAS_SIZE.width - width),
right: 0,
top: -(CANVAS_SIZE.height - height),
bottom: 0,
}}
dragElastic={0}
dragTransition={{ power: 0, timeConstant: 0 }}

onMouseDown={(e) => {
handleStartDrawing(
e.clientX,
e.clientY
)
}}
onMouseUp={handleEndDrawing}
onMouseMove={(e) => {
handleDraw(
e.clientX,
e.clientY
);
}}

onTouchStart={(e) => {
handleStartDrawing(
e.changedTouches[0].clientX,
e.changedTouches[0].clientY
);
}}
onTouchEnd={handleEndDrawing}
onTouchMove={(e) => {
handleDraw(
e.changedTouches[0].clientX,
e.changedTouches[0].clientY
);
}}
/>
<Minimap
ref={smallCanvasRef}
x={x}
y={y}
dragging={dragging}
setMovedMiniMap={setMovedMiniMap}
/>
</div>
)
};

export default Canvas;
14 changes: 9 additions & 5 deletions modules/canvas/components/Minimap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ import { useViewportSize } from "@/common/hooks/useViewportSize";
import { MotionValue, useMotionValue } from "framer-motion";
import {Dispatch, SetStateAction, forwardRef, useEffect, useRef} from "react";
import {motion} from "framer-motion";
const Minimap = forwardRef<{


const Minimap = forwardRef<
HTMLCanvasElement,{
x: MotionValue<number>;
y: MotionValue<number>;
dragging: boolean;
setMovedMinimap: Dispatch<SetStateAction<boolean>>;
}>(({x, y, dragging, setMovedMinimap}, ref)=>{
setMovedMiniMap: Dispatch<SetStateAction<boolean>>;
}
>(({x, y, dragging, setMovedMiniMap}, ref)=>{
const containerRef = useRef<HTMLDivElement>(null);
const {width, height} = useViewportSize();

Expand Down Expand Up @@ -36,7 +40,7 @@ return (
height: CANVAS_SIZE.height / 10,
}}>
<canvas
ref={ref as any}
ref={ref}
width={CANVAS_SIZE.width}
height={CANVAS_SIZE.height}
className="h-full w-full"
Expand All @@ -46,7 +50,7 @@ return (
dragConstraints={containerRef}
dragElastic={0}
dragTransition= {{power:0, timeConstant:0}}
onDragEnd={()=> setMovedMinimap((prev:boolean)=> !prev)}
onDragEnd={()=> setMovedMiniMap((prev:boolean)=> !prev)}
className="absolute top-0 left-0 cursor-grab border-2 border-red-500"
style={{
width: width / 10,
Expand Down
2 changes: 1 addition & 1 deletion modules/canvas/helpers/Canvas.helpers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const drawFromSocket = (
export const drawFromSocket = (
socketMoves: [number, number][],
socketOptions: CtxOptions,
ctx: CanvasRenderingContext2D,
Expand Down

0 comments on commit 7148160

Please sign in to comment.