我正在尝试在React Konva中动态制作和移动Rectangles。问题是,有时我的代码运行得很好,有时会引发错误,有时矩形无法正确更新和移动。

我没有遇到任何问题,直到我实现了每当矩形移动时更新状态的功能。为此,我正在调用handleDragStart和handleDragEnd。在handleDragStart中,我选择矩形并将其放入selectedrectangle变量中,然后在handleDragEnd中,从状态中删除该矩形并添加更新的矩形。

问题1-错误显示selectedRectangle仍然为空。应该在handleDragStart函数中未对其进行更新。

问题2-当我移动矩形时,它们会在舞台上任意移动。当我绘制新矩形时,将移回到其原始绘制位置。

请帮助我找到问题并解决。

var index;
var selectedRectangle = null;

export default class MyRectangle extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
          shapes : [],
          isDrawing : false,
          isDrawingMode : true,
          image : null,
        }

        this.handleDragStart = this.handleDragStart.bind (this);
        this.handleDragEnd = this.handleDragEnd.bind (this);
      }

      componentDidMount() {
        const image = new window.Image();
        image.src = this.props.image;

        image.onload = () => {
          this.setState ({
            image: image
          });
        };
      }

      handleClick = (e) => {
        if (!this.state.isDrawingMode) {
          return;
        }

        if (this.state.isDrawing) {
          this.setState ({
            isDrawing: !this.state.isDrawing,
          })

          return;
        }

        const newShapes = this.state.shapes.slice();
        newShapes.push ({
          x: e.evt.layerX,
          y: e.evt.layerY,
          width: 0,
          height: 0,
        });

        this.setState ({
          isDrawing: true,
          shapes: newShapes,
        });
      }

      handleMouseMove = (e) => {
        if (!this.state.isDrawingMode) return;

        const mouseX = e.evt.layerX;
        const mouseY = e.evt.layerY;

        if (this.state.isDrawing) {

          const currShapeIndex = this.state.shapes.length - 1;
          const currShape = this.state.shapes[currShapeIndex];
          const newWidth = mouseX - currShape.x;
          const newHeight = mouseY - currShape.y;

          const newShapesList = this.state.shapes.slice();
          newShapesList[currShapeIndex] = {
            x: currShape.x,
            y: currShape.y,
            width: newWidth,
            height: newHeight
          }

          this.setState ({
            shapes: newShapesList,
          });
        }
      }

      handleCheckboxChange = () => {
        this.setState ({
          isDrawingMode: !this.state.isDrawingMode,
        })
      }

      handleDragStart(e) {
        this.state.shapes.map ((sh) => {
          if ((sh.x < e.evt.layerX) && (sh.y < e.evt.layerY) && ((sh.x + sh.width) > e.evt.layerX) && ((sh.y + sh.height) > e.evt.layerY)) {
            selectedRectangle = sh;
          }
        });

        console.log(selectedRectangle)
      }

      handleDragEnd (e) {

        console.log(selectedRectangle)
        index = this.state.shapes.indexOf (selectedRectangle);
        this.state.shapes.splice(index, 1);
        console.log(index);

        selectedRectangle.x = e.target._lastPos.x;
        selectedRectangle.y = e.target._lastPos.y;

        this.setState({shapes : [...this.state.shapes, selectedRectangle]});
        console.log(this.state.shapes)
      }

      render() {
       return (
          <div>
            <input type = "checkbox" checked = {this.state.isDrawingMode} onChange = {this.handleCheckboxChange} />
            <label>Drawing Mode</label>

            <Stage
                ref = 'stage'
                width = {window.innerWidth}
                height = {window.innerHeight}
                onContentClick = {this.handleClick}
                onContentMouseMove = {this.handleMouseMove}
            >
              <Layer ref = 'layer'>
                <Image image = {this.state.image}   />

                {this.state.shapes.map((shape) => {
                  return (
                    <Group>
                      <Rect
                        x = {shape.x}
                        y = {shape.y}
                        width = {shape.width}
                        height = {shape.height}
                        isDrawingMode = {this.state.isDrawingMode}
                        strokeWidth = {2}
                        draggable = "true"
                        stroke="yellow"
                        fill="green"
                        opacity={0.4}
                        onDragStart = {(e) => this.handleDragStart(e)}
                        onDragEnd = {(e) => this.handleDragEnd(e)}
                      />
                    </Group >
                  );
                })}

              </Layer>
            </Stage>
            <button onClick={this.sendData}>Submit</button>
          </div>
        );
      }
}

最佳答案

我看不到selectedRectangle的定义位置,因此我假设您未明确定义它。结果,这里

  handleDragStart(e) {
    this.state.shapes.map ((sh) => {
      if ((sh.x < e.evt.layerX) && (sh.y < e.evt.layerY) && ((sh.x + sh.width) > e.evt.layerX) && ((sh.y + sh.height) > e.evt.layerY)) {
        selectedRectangle = sh;
      }
    });

    console.log(selectedRectangle)
  }


selectedRectangle成为箭头函数内的局部变量,当您尝试对其进行console.log时,您不在其范围内。您将需要正确定义此变量。

10-06 08:28