我正在创建一个白板应用程序,我正在用我的鼠标使用不同 colored颜色 的钢笔进行绘制. 我试图使用ctx.strokeStyle来更改钢笔的 colored颜色 ,但由于某种原因不起作用. 我试着改变钢笔的其他属性,但它们也不会像粗细一样变化

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;

Log的输出是#ff0000,因此它也具有值.

推荐答案

设置画布高度和宽度会 destruct 您先前在上下文中设置的样式.try 先设置宽度/高度,然后应用样式:

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>

请注意,在哪里调用setContext(ctx)实际上并不重要,尽管似乎最好的方式是在函数的末尾这样做,以传达这是next呈现的状态.

下面是一个最小的例子,它表明问题与RESPECT无关:

const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");

const draw = resize => {
  ctx.reset();
  ctx.strokeStyle = "red";
  ctx.lineWidth = 4;

  if (resize) {
    // destroys styles set above
    canvas.width = 300;
  }

  ctx.moveTo(0, 0);
  ctx.lineTo(150, 100);
  ctx.stroke();
};
canvas {
  border: 1px solid black;
}
<div>
  <button onclick="draw(true)">Draw with resize</button>
  <button onclick="draw()">Draw without resize</button>
</div>
<canvas height="150" width="300"></canvas>

Reactjs相关问答推荐

为什么这个'Suspense'子组件在挂起promise解决后会丢失它的状态,而不是呈现?<>

在带有和设计的表格中禁用和取消选中复选框

条件索引路由

为什么我的标签在Redux API中不能正常工作?

单击空白区域时,Reaction Multiple下拉组件不关闭

如何访问子集合中的文档?

在新屏幕上显示照片时出现问题-react

在Reaction中导入';图片&文件夹时出错

阻止组件更新的多分派Redux Thunk或setState是否有任何问题

React useEffect 问题...异步函数内的变量正在获取延迟的更新值

FabricJS反序列化问题

如何修改 react/jsx-no-useless-fragment 规则以允许 <>{children}

我应该如何将字符串作为props 传递给 React 组件?

Recharts 笛卡尔网格 - 垂直线和水平线的不同样式

使用 React.lazy 调试 webpack 代码拆分

如何将值从下拉列表传递到 select 上的输入?响应式JS

如何使图标适合 react-bootstrap 中的行元素

多次响应获取发送请求

下拉菜单在 AppBar 中未正确对齐

RTK 查询 POST 方法不会改变数据