@@ -4,6 +4,7 @@ import { ColorPicker } from "./ColorPicker";
44import { StrokeControl } from "./StrokeControl" ;
55import { toast } from "sonner" ;
66import { io } from "socket.io-client" ;
7+ import tinycolor from "tinycolor2" ;
78
89export const Canvas = ( ) => {
910 const canvasRef = useRef ( null ) ;
@@ -31,9 +32,7 @@ export const Canvas = () => {
3132 const [ socket , setSocket ] = useState ( null ) ;
3233 const [ isModalOpen , setIsModalOpen ] = useState ( false ) ;
3334
34- const [ isLoggedIn , setIsLoggedIn ] = useState (
35- ! ! localStorage . getItem ( "token" )
36- ) ;
35+ const [ isLoggedIn , setIsLoggedIn ] = useState ( ! ! localStorage . getItem ( "token" ) ) ;
3736
3837 const handleLogout = async ( ) => {
3938 // ... (existing logout logic - unchanged)
@@ -257,9 +256,15 @@ export const Canvas = () => {
257256 startPoint . current = { x, y } ;
258257 setIsDrawing ( true ) ;
259258
260- if ( activeTool === "pen" || activeTool === "eraser" ) {
259+ // Begin drawing for pen, eraser, or brush tools
260+ if (
261+ activeTool === "pen" ||
262+ activeTool === "eraser" ||
263+ activeTool . startsWith ( "brush-" )
264+ ) {
261265 ctx . beginPath ( ) ;
262266 ctx . moveTo ( x , y ) ;
267+
263268 if ( joined && socket )
264269 socket . emit ( "draw" , {
265270 roomId,
@@ -272,28 +277,28 @@ export const Canvas = () => {
272277 } ) ;
273278 }
274279
275- // Save snapshot for preview tools
280+ // Snapshot for line/rectangle previews
276281 if ( activeTool === "line" || activeTool === "rectangle" ) {
277- // Snapshot must be taken from the *un-transformed* context
278- ctx . restore ( ) ; // Restore *before* getImageData
282+ ctx . restore ( ) ; // restore before snapshot
279283 snapshot . current = ctx . getImageData ( 0 , 0 , canvas . width , canvas . height ) ;
280- // Re-save to apply transform again for next draw
281284 ctx . save ( ) ;
282285 ctx . setTransform ( 1 , 0 , 0 , 1 , 0 , 0 ) ;
283286 ctx . translate ( offset . x , offset . y ) ;
284287 ctx . scale ( scale , scale ) ;
285288 }
289+
286290 ctx . restore ( ) ; // Restore transform
287291 } ;
288292
289293 const draw = ( e ) => {
290- if ( ! isPointerDown ) return ;
294+ if ( ! isPointerDown || ! isDrawing ) return ;
291295
292296 const canvas = canvasRef . current ;
293297 const ctx = canvas ?. getContext ( "2d" ) ;
294298 if ( ! ctx ) return ;
295299
296300 // Apply transform
301+
297302 ctx . save ( ) ;
298303 ctx . setTransform ( 1 , 0 , 0 , 1 , 0 , 0 ) ;
299304 ctx . translate ( offset . x , offset . y ) ;
@@ -311,25 +316,121 @@ export const Canvas = () => {
311316 return ;
312317 }
313318
314- if ( ! isDrawing ) {
315- ctx . restore ( ) ;
316- return ;
317- }
319+ // --- Brush / Pen / Eraser Tools ---
320+ if (
321+ activeTool === "pen" ||
322+ activeTool === "eraser" ||
323+ activeTool . startsWith ( "brush-" )
324+ ) {
325+ ctx . lineCap = "round" ;
326+ ctx . lineJoin = "round" ;
327+ ctx . setLineDash ( [ ] ) ;
328+ ctx . shadowBlur = 0 ;
329+ ctx . globalAlpha = 1 ;
330+
331+ let color = activeColor ;
332+ let width = strokeWidth ;
333+
334+ if ( activeTool === "eraser" ) {
335+ color = "#ffffff" ;
336+ width = strokeWidth * 3 ;
337+ }
338+
339+ if ( activeTool . startsWith ( "brush-" ) ) {
340+ const brush = activeTool . split ( "-" ) [ 1 ] ;
341+ switch ( brush ) {
342+ case "dashed" : {
343+ const dashLength = strokeWidth * 4 ;
344+ const gapLength = strokeWidth * 2.5 ;
345+ ctx . setLineDash ( [ dashLength , gapLength ] ) ;
346+ ctx . lineCap = "round" ;
347+ ctx . lineJoin = "round" ;
348+
349+ ctx . strokeStyle = activeColor ;
350+ ctx . lineWidth = strokeWidth ;
351+
352+ const jitterX = x + ( Math . random ( ) - 0.5 ) * 0.5 ;
353+ const jitterY = y + ( Math . random ( ) - 0.5 ) * 0.5 ;
354+ ctx . lineTo ( jitterX , jitterY ) ;
355+ ctx . stroke ( ) ;
356+ break ;
357+ }
358+
359+ case "paint" :
360+ ctx . shadowColor = color ;
361+ ctx . shadowBlur = 12 ;
362+ ctx . globalAlpha = 0.5 + Math . random ( ) * 0.2 ;
363+ width = strokeWidth * 2 ;
364+ break ;
365+ case "crayon" :
366+ ctx . globalAlpha = 0.8 ;
367+ ctx . shadowBlur = 5 ;
368+ for ( let i = 0 ; i < 4 ; i ++ ) {
369+ const jitterX = x + ( Math . random ( ) - 0.5 ) * 1.5 ;
370+ const jitterY = y + ( Math . random ( ) - 0.5 ) * 1.5 ;
371+ ctx . lineTo ( jitterX , jitterY ) ;
372+ }
373+ break ;
374+ case "oil-pastel" : {
375+ console . log ( "this is oil" )
376+ ctx . setLineDash ( [ ] ) ;
377+ ctx . lineCap = "round" ;
378+ ctx . lineJoin = "round" ;
379+
380+ const steps = 10 ;
381+ for ( let i = 0 ; i < steps ; i ++ ) {
382+ const jitterX = x + ( Math . random ( ) - 0.5 ) * 5 ;
383+ const jitterY = y + ( Math . random ( ) - 0.5 ) * 5 ;
384+ const jitterWidth = strokeWidth * ( 0.8 + Math . random ( ) * 0.6 ) ;
385+ const opacity = 0.1 + Math . random ( ) * 0.15 ;
386+ const color = tinycolor ( activeColor )
387+ . brighten ( ( Math . random ( ) - 0.5 ) * 8 )
388+ . setAlpha ( opacity )
389+ . toRgbString ( ) ;
390+
391+ ctx . strokeStyle = color ;
392+ ctx . lineWidth = jitterWidth ;
393+
394+ ctx . beginPath ( ) ;
395+ ctx . moveTo (
396+ startPoint . current . x + ( Math . random ( ) - 0.5 ) * 3 ,
397+ startPoint . current . y + ( Math . random ( ) - 0.5 ) * 3
398+ ) ;
399+ ctx . lineTo ( jitterX , jitterY ) ;
400+ ctx . stroke ( ) ;
401+ }
402+ ctx . shadowColor = activeColor ;
403+ ctx . shadowBlur = 2 ;
404+ ctx . globalAlpha = 0.7 ;
405+ ctx . lineWidth = strokeWidth * 1.5 ;
406+ ctx . beginPath ( ) ;
407+ ctx . moveTo ( startPoint . current . x , startPoint . current . y ) ;
408+ ctx . lineTo ( x , y ) ;
409+ ctx . stroke ( ) ;
410+ ctx . shadowBlur = 0 ;
411+ ctx . globalAlpha = 1 ;
412+ break ;
413+ }
414+
415+ default :
416+ ctx . setLineDash ( [ ] ) ;
417+ }
418+ }
419+
420+ ctx . strokeStyle = color ;
421+ ctx . lineWidth = width ;
318422
319- // --- Handle Drawing ---
320- if ( activeTool === "pen" || activeTool === "eraser" ) {
321- ctx . strokeStyle = activeTool === "eraser" ? "#ffffff" : activeColor ;
322- ctx . lineWidth = activeTool === "eraser" ? strokeWidth * 3 : strokeWidth ;
323423 ctx . lineTo ( x , y ) ;
324424 ctx . stroke ( ) ;
425+
325426 if ( joined && socket )
326427 socket . emit ( "draw" , {
327428 roomId,
328- x, // Send WORLD coordinates
329- y, // Send WORLD coordinates
429+ x,
430+ y,
330431 type : "move" ,
331- color : activeColor ,
332- width : strokeWidth ,
432+ color,
433+ width,
333434 tool : activeTool ,
334435 } ) ;
335436 } else if ( activeTool === "line" || activeTool === "rectangle" ) {
@@ -583,4 +684,4 @@ export const Canvas = () => {
583684 </ div >
584685 </ div >
585686 ) ;
586- } ;
687+ } ;
0 commit comments