Skip to content

Commit

Permalink
add image accept, edit functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
deveshidwivedi committed Jun 28, 2024
1 parent c7757cb commit ea56502
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 155 deletions.
30 changes: 4 additions & 26 deletions modules/room/components/board/Canvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useSocketDraw } from "../../hooks/useSocketDraw";
import { socket } from "@/common/lib/socket";
import Minimap from "./Minimap";
import { useRoom } from "@/common/recoil/room";
import { drawAllMoves } from "../../helpers/Canvas.helpers";
import { useMovesHandlers } from "../../hooks/useMovesHandlers";
import { useBoardPosition } from "../../hooks/useBoardPosition";
import Background from "./Background";
import { useOptionsValue } from "@/common/recoil/options";
Expand All @@ -27,29 +27,15 @@ const Canvas = () => {
const { width, height } = useViewportSize();
const { x, y } = useBoardPosition();

const {handleUndo, drawAllMoves} = useMovesHandlers();

useKeyPressEvent("Control", (e) => {
if (e.ctrlKey && !dragging) {
setDragging(true);
}
});

const copyCanvasToSmall = useCallback(() => {
if (canvasRef.current && smallCanvasRef.current) {
const smallCtx = smallCanvasRef.current.getContext("2d");
if (smallCtx) {
smallCtx.clearRect(0, 0, CANVAS_SIZE.width, CANVAS_SIZE.height);
smallCtx.drawImage(
canvasRef.current,
0,
0,
CANVAS_SIZE.width,
CANVAS_SIZE.height
);
}
}
}, [canvasRef, smallCanvasRef]);

const { handleEndDrawing, handleDraw, handleStartDrawing, drawing, handleUndo } = useDraw(ctx, dragging);
const { handleEndDrawing, handleDraw, handleStartDrawing, drawing} = useDraw(dragging, drawAllMoves);

useSocketDraw(ctx, drawing);

Expand Down Expand Up @@ -77,13 +63,6 @@ const Canvas = () => {
if (ctx) socket.emit("joined_room");
}, [ctx]);

useEffect(() => {
if (ctx) {
drawAllMoves(ctx, room, options);
copyCanvasToSmall();
}
}, [ctx, room, options]);

return (
<div className="relative h-full w-full overflow-hidden">
<motion.canvas
Expand Down Expand Up @@ -133,7 +112,6 @@ const Canvas = () => {
/>
<Background bgRef={bgRef} />
<Minimap
ref={smallCanvasRef}
dragging={dragging}
setMovedMiniMap={setMovedMiniMap}
/>
Expand Down
15 changes: 7 additions & 8 deletions modules/room/components/board/Minimap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import { MotionValue, useMotionValue } from "framer-motion";
import {Dispatch, SetStateAction, forwardRef, useEffect, useRef} from "react";
import {motion} from "framer-motion";
import { useBoardPosition } from "../../hooks/useBoardPosition";
import { useRefs } from "../../hooks/useRefs";


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

Expand Down Expand Up @@ -40,7 +40,7 @@ return (
height: CANVAS_SIZE.height / 7,
}}>
<canvas
ref={ref}
ref={minimapRef}
width={CANVAS_SIZE.width}
height={CANVAS_SIZE.height}
className="h-full w-full"
Expand All @@ -64,7 +64,6 @@ return (
></motion.div>
</div>
)
});
};

Minimap.displayName = "Minimap";
export default Minimap;
72 changes: 0 additions & 72 deletions modules/room/helpers/Canvas.helpers.ts
Original file line number Diff line number Diff line change
@@ -1,76 +1,4 @@

export const handleMove = (
move: Move,
ctx: CanvasRenderingContext2D,
)=>{
const {options, path} = move;

ctx.lineWidth= options.lineWidth;
ctx.strokeStyle= options.lineColor;

if(move.eraser) ctx.globalCompositeOperation = "destination-out";

switch(options.shape){
case 'line':
ctx.beginPath();
path.forEach(([x,y])=> {
ctx.lineTo(x,y);
});
ctx.stroke();
ctx.closePath();
break;

case 'circle':
ctx.beginPath();
ctx.arc(path[0][0], path[0][1], move.radius, 0, 2* Math.PI);
ctx.stroke();
ctx.closePath();
break;

case 'rect':
ctx.beginPath();
ctx.rect(path[0][0], path[0][1], move.width, move.height);
ctx.stroke();
ctx.closePath();
break;

default:
break;
}

ctx.globalCompositeOperation= "source-over";

};



export const drawAllMoves = (
ctx: CanvasRenderingContext2D,
room: ClientRoom,
options: CtxOptions
) => {
const {usersMoves, movesWithoutUser, myMoves} = room;
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

const moves= [...movesWithoutUser, ...myMoves];


usersMoves.forEach((userMoves)=>{
moves.push(...userMoves);
});

moves.sort((a,b)=> a.timestamp - b.timestamp);

moves.forEach((move)=> {
handleMove(move, ctx);
});

ctx.lineJoin= "round";
ctx.lineCap= "round";
ctx.lineWidth= options.lineWidth;
ctx.strokeStyle= options.lineColor;
if(options.erase) ctx.globalCompositeOperation= "destination-out";
};

//helper function for circle
export const drawCircle= (
Expand Down
76 changes: 27 additions & 49 deletions modules/room/hooks/useDraw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,26 @@ import { useOptionsValue } from "@/common/recoil/options";
import { useState, useEffect, useCallback} from "react";
import { useBoardPosition } from "./useBoardPosition";
import { socket } from "@/common/lib/socket";
import { drawAllMoves, drawCircle, drawLine, drawRect } from "../helpers/Canvas.helpers";
import { drawCircle, drawLine, drawRect } from "../helpers/Canvas.helpers";

import { getPos } from "@/common/lib/getPos";
import { useMyMoves, useRoom } from "@/common/recoil/room";
import { useRefs } from "./useRefs";



let tempMoves: [number, number][] = [];

const setCtxOptions= (ctx: CanvasRenderingContext2D, options: CtxOptions)=> {
ctx.lineJoin = "round";
ctx.lineCap = "round";
ctx.lineWidth = options.lineWidth;
ctx.strokeStyle= options.lineColor;
if(options.erase) ctx.globalCompositeOperation = "destination-out";
};

let tempRadius=0;
let tempSize= {width:0, height:0};


export const useDraw = (
ctx: CanvasRenderingContext2D | undefined,
blocked: boolean,
drawAllMoves: ()=> void
) => {
const {canvasRef}= useRefs();
const room=useRoom();
const {handleRemoveMyMove, handleAddMyMove} = useMyMoves();

const [drawing, setDrawing] = useState(false);

Expand All @@ -37,46 +31,31 @@ export const useDraw = (

const options = useOptionsValue();

const [ctx,setCtx ]= useState<CanvasRenderingContext2D >();

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

},[canvasRef]);

const setCtxOptions= ()=> {
if(ctx){
ctx.lineJoin = "round";
ctx.lineCap = "round";
ctx.lineWidth = options.lineWidth;
ctx.strokeStyle= options.lineColor;
if(options.erase) ctx.globalCompositeOperation = "destination-out";
else ctx.globalCompositeOperation = "source-over";

}
});

useEffect(()=> {
socket.on("your_move", (move)=>{
handleAddMyMove(move);
});

return ()=> {
socket.off("your_move");
};
});

const handleUndo = useCallback(() => {
if (ctx) {
handleRemoveMyMove();
socket.emit("undo");

}
}, [ctx, handleRemoveMyMove]);

useEffect(() => {
const handleUndoKeyboard = (e: KeyboardEvent) => {
if (e.key === 'z' && e.ctrlKey) {
handleUndo();
}
};

};

document.addEventListener('keydown', handleUndoKeyboard);
return () => {
document.removeEventListener('keydown', handleUndoKeyboard);
};
}, [handleUndo]);
const drawAndSet = ()=> {
drawAllMoves();
setCtxOptions();
}

const handleStartDrawing = (x: number, y: number) => {
if (!ctx || blocked) return;
Expand All @@ -85,6 +64,7 @@ export const useDraw = (
const finalY= getPos(y, movedY);

setDrawing(true);
setCtxOptions();

ctx.beginPath();
ctx.lineTo(finalX, finalY);
Expand All @@ -103,17 +83,17 @@ export const useDraw = (
case 'line':
if(shift){
tempMoves= tempMoves.slice(0,1);
drawAllMoves(ctx, room, options);
drawAndSet();
}
drawLine(ctx, tempMoves[0], finalX, finalY, shift);
tempMoves.push([finalX, finalY]);
break;
case 'circle':
drawAllMoves(ctx, room, options);
drawAndSet();
tempRadius= drawCircle(ctx, tempMoves[0], finalX, finalY);
break;
case 'rect':
drawAllMoves(ctx, room, options);
drawAndSet();
tempSize= drawRect(ctx, tempMoves[0], finalX, finalY, shift);
break;
default:
Expand All @@ -131,16 +111,15 @@ export const useDraw = (

const move: Move = {
...tempSize,
shape:options.shape,
radius: tempRadius,
path: tempMoves,
options,
timestamp: 0,
eraser: options.erase,
base64: "",
};

tempMoves = [];
ctx.globalCompositeOperation= "source-over"

socket.emit("draw", move);

Expand All @@ -153,7 +132,6 @@ export const useDraw = (
handleEndDrawing,
handleDraw,
handleStartDrawing,
handleUndo,
drawing,
}
};
Loading

0 comments on commit ea56502

Please sign in to comment.