0

我找到了一个使用 React-Konva 和 Free Drawing 的好例子,但我可以使用 React-Hooks。该示例非常好且简单。可以在这里找到:

React-Konva 示例

import React, { Component } from "react";
import Konva from "konva";
import { render } from "react-dom";
import { Stage, Layer, Line, Text } from "react-konva";

class App extends Component {
  state = {
    lines: []
  };

  handleMouseDown = () => {
    this._drawing = true;
    // add line
    this.setState({
      lines: [...this.state.lines, []]
    });
  };

  handleMouseMove = e => {
    // no drawing - skipping
    if (!this._drawing) {
      return;
    }
    const stage = this.stageRef.getStage();
    const point = stage.getPointerPosition();
    const { lines } = this.state;

    let lastLine = lines[lines.length - 1];
    // add point
    lastLine = lastLine.concat([point.x, point.y]);

    // replace last
    lines.splice(lines.length - 1, 1, lastLine);
    this.setState({
      lines: lines.concat()
    });
  };

  handleMouseUp = () => {
    this._drawing = false;
  };

  render() {
    return (
      <Stage
        width={window.innerWidth}
        height={window.innerHeight}
        onContentMousedown={this.handleMouseDown}
        onContentMousemove={this.handleMouseMove}
        onContentMouseup={this.handleMouseUp}
        ref={node => {
          this.stageRef = node;
        }}
      >
        <Layer>
          <Text text="Just start drawing" />
          {this.state.lines.map((line, i) => (
            <Line key={i} points={line} stroke="red" />
          ))}
        </Layer>
      </Stage>
    );
  }
}

render(<App />, document.getElementById("root"));

我试图用 React Hooks 重现它,但我没有用,也许我错过了一些东西。实际上,我真的不明白它是如何工作的。

  export default function RenderMap(tokens) {
    
    const [lines, setLines] = useState([])
    
          
    function handleMouseDown({ evt }) {
    setIsDrawing(true)

    setLines([...lines, []])
  }
    
     function handleMouseUp() {
    if (isDrawing) {
      setIsDrawing(false)
    }
  }
    
     function handleMouseMove({ evt }) {
    if (!isDrawing) {
      return
    }
    const { offsetX, offsetY } = evt

    if (isDrawing) {
      let lastLine = lines[lines.length - 1]
      lastLine = lastLine.concat([offsetX.x, offsetY.y])
      lines.splice(lines.length - 1, 1, lastLine)
      setLines(lines.concat())
    }
  }
    
    
      return (
        <Stage
          x={stagePos.x}
          y={stagePos.y}
          width={3840}
          height={2160}
          // draggable
          onDragEnd={e => {
            setStagePos(e.currentTarget.position())
          }}
          onMouseDown={handleMouseDown}
          onMouseUp={handleMouseUp}
          onMouseMove={handleMouseMove}
        >
    
    
         {lines.map((line, i) => (
          <Line key={i} points={line} stroke="red" />
        ))}
          </Layer>
        </Stage>
      )
    }

我做错了什么?我只是不确定!

4

1 回答 1

1

我找到了解决方案!!!!

export default function RenderMap() {
  const [stagePos, setStagePos] = useState({ x: 0, y: 0 })
  const [lines, setLines] = useState([])
  const [isDrawing, setIsDrawing] = useState(false)
 
  function handleMouseDown() {
    setIsDrawing(true)
    setLines([...lines, []])
  }

  function handleMouseUp() {
    if (isDrawing) {
      setIsDrawing(false)
    }
  }

  function handleMouseMove({ evt }) {
    if (!isDrawing) {
      return
    }
    const { offsetX, offsetY } = evt

    if (isDrawing) {
      let lastLine = lines[lines.length - 1]
      lastLine = lastLine.concat([offsetX, offsetY])
      lines.splice(lines.length - 1, 1, lastLine)
      setLines(lines.concat())
    }
  }  

  return (
    <Stage
      x={stagePos.x}
      y={stagePos.y}
      width={3840}
      height={2160}
      // draggable
      onDragEnd={e => {
        setStagePos(e.currentTarget.position())
      }}
      onMouseDown={handleMouseDown}
      onMouseUp={handleMouseUp}
      onMouseMove={handleMouseMove}
    >
      <Layer>       
       
        {lines.map((line, i) => (
          <Line key={i} points={line} stroke="red" />
        ))}
      </Layer>
    </Stage>
  )
}
于 2020-07-04T16:31:39.177 回答