skip to Main Content

I am creating an White-board application and I am tying to draw with my mouse using different color pen.
I was trying to use ctx.strokeStyle to change the color of pen but for some reason it is not working.
I try changing other properties of pen and they are also not changing like thickness

import React, { useEffect, useRef, useState } from "react";

const WhiteBoard = () => {
  const canvasRef = useRef(null);
  const [isDrawing, setIsDrawing] = useState(false);
  const [context, setContext] = useState(null);
  const [prevX, setPrevX] = useState(0);
  const [prevY, setPrevY] = useState(0);

  const divRef = useRef(null);

  useEffect(() => {
    const canvas = canvasRef.current;
    const ctx = canvas.getContext("2d");
    setContext(ctx);
    
    ctx.strokeStyle = "red";
    console.log(ctx.strokeStyle,'here I am ');
    console.log("Stroke style set to:", );
    ctx.lineWidth = 2;

    const canvasdiv = divRef.current;

    // const canvasheight=canvasdiv.offsetHeight;
    // const canvaswidth=canvasdiv.offsetWidth;
    //Will get the height and width including border and margin

    //Excludes border and margin
    const canvasheight = canvasdiv.clientHeight;
    const canvaswidth = canvasdiv.clientWidth;

    canvas.width = canvaswidth;
    canvas.height = canvasheight;
  }, []);

  const startDrawing = (e) => {
    setIsDrawing(true);
    setPrevX(e.nativeEvent.offsetX);
    setPrevY(e.nativeEvent.offsetY);
  };

  const draw = (e) => {
    if (!isDrawing) return;

    context.beginPath();
    context.moveTo(prevX, prevY);
    context.lineTo(e.nativeEvent.offsetX, e.nativeEvent.offsetY);
    context.stroke();

    setPrevX(e.nativeEvent.offsetX);
    setPrevY(e.nativeEvent.offsetY);
  };

  const stopDrawing = () => {
    setIsDrawing(false);
  };

  return (
    <div ref={divRef} className="w-100">
      <canvas
        ref={canvasRef}
        className="w-100"
        onMouseDown={startDrawing}
        onMouseMove={draw}
        onMouseUp={stopDrawing}
        onMouseOut={stopDrawing}
        style={{ border: "1px solid black" }}
      ></canvas>
    </div>
  );
};

export default WhiteBoard;

The output of the console.log is #ff0000 so altest it has the value.

2

Answers


  1. Setting the canvas height and width destroys style settings. Try setting the width/height first, then setting the style:

    const {useEffect, useRef, useState} = React;
    
    const WhiteBoard = () => {
      const canvasRef = useRef(null);
      const [isDrawing, setIsDrawing] = useState(false);
      const [context, setContext] = useState(null);
      const [prevX, setPrevX] = useState(0);
      const [prevY, setPrevY] = useState(0);
      const divRef = useRef(null);
    
      useEffect(() => {
        const canvas = canvasRef.current;
        const canvasdiv = divRef.current;
        const canvasheight = canvasdiv.clientHeight;
        const canvaswidth = canvasdiv.clientWidth;
        canvas.width = canvaswidth;
        canvas.height = canvasheight;
        const ctx = canvas.getContext("2d");
        ctx.strokeStyle = "red";
        setContext(ctx);
      }, []);
    
      const startDrawing = (e) => {
        setIsDrawing(true);
        setPrevX(e.nativeEvent.offsetX);
        setPrevY(e.nativeEvent.offsetY);
      };
    
      const draw = (e) => {
        if (!isDrawing) return;
    
        context.beginPath();
        context.moveTo(prevX, prevY);
        context.lineTo(e.nativeEvent.offsetX, e.nativeEvent.offsetY);
        context.stroke();
    
        setPrevX(e.nativeEvent.offsetX);
        setPrevY(e.nativeEvent.offsetY);
      };
    
      const stopDrawing = () => {
        setIsDrawing(false);
      };
    
      return (
        <div ref={divRef} className="w-100">
          <canvas
            ref={canvasRef}
            className="w-100"
            onMouseDown={startDrawing}
            onMouseMove={draw}
            onMouseUp={stopDrawing}
            onMouseOut={stopDrawing}
            style={{ border: "1px solid black" }}
          ></canvas>
        </div>
      );
    };
    
    ReactDOM.createRoot(document.querySelector("#app"))
      .render(<WhiteBoard />);
    <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
    <div id="app"></div>
    Login or Signup to reply.
  2. Change your useEffect function to this code:

      useEffect(() => {
        const canvas = canvasRef.current;
        const ctx = canvas.getContext("2d");
        const canvasdiv = divRef.current;
    
        // const canvasheight=canvasdiv.offsetHeight;
        // const canvaswidth=canvasdiv.offsetWidth;
        //Will get the height and width including border and margin
    
        //Excludes border and margin
        const canvasheight = canvasdiv.clientHeight;
        const canvaswidth = canvasdiv.clientWidth;
    
        canvas.width = canvaswidth;
        canvas.height = canvasheight;
        
        ctx.strokeStyle = "#FF0000";
        console.log(ctx.strokeStyle,'here I am ');
        console.log("Stroke style set to:", ctx);
        ctx.lineWidth = 2;
    
        
        setContext(ctx);
      }, []);
    

    Basically, I just reverse the order of your code. So you change your ctx at the end of useEffect

    Hope it helps you

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search