【问题标题】:How to implement undo/redo functionality for KovaJS in react?如何在反应中为 KovaJS 实现撤消/重做功能?
【发布时间】:2018-05-18 08:07:03
【问题描述】:

在 react 中为 KovaJS 实现撤消/重做功能的最佳方式是什么?

我看到每个节点都有 toObject() 方法用于每个画布节点的序列化。一个简单的实现是在每次修改时序列化对象并将其推送到更改数组中。一旦用户点击撤消/重做,尝试从该数组重建画布。

有什么想法吗?

【问题讨论】:

  • 听起来可能可行。您将在撤消 - 重做时丢失画布形状的任何 js 句柄,因此如果您需要使用事件或任何类型的 js 操作形状,您将有重新连接它们的开销。也就是说,无论您如何处理撤消/重做,您都需要这样做,因此如果舞台没有过多的形状,序列化可能很有意义。有兴趣了解您的进展情况。
  • 感谢您的回复 :) 事件将是必需的,所以我需要想出一个解决方案来重新连接它们,需要考虑一下????

标签: konvajs


【解决方案1】:

如果您使用 React,则无需使用 toObject()

保存状态历史记录会简单得多(react 组件状态、redux 状态或您正在使用的任何状态)。并用它实现撤消/重做。

最简单的撤销演示:

let history = [{
  x: 20,
  y: 20
}];
let historyStep = 0;

class App extends Component {
  state = {
    position: history[0]
  };

  handleUndo = () => {
    if (historyStep === 0) {
      return;
    }
    historyStep -= 1;
    this.setState({
      position: history[historyStep]
    });
  };
  handleDragEnd = e => {
    history.slice(0, historyStep);
    history = history.concat({
      x: e.target.x(),
      y: e.target.y()
    });
    historyStep += 1;
    console.log(history[history.length - 1]);
    this.setState({
      position: history[history.length - 1]
    });
  };
  render() {
    return (
      <Stage width={window.innerWidth} height={window.innerHeight}>
        <Layer>
          <Text text="undo" onClick={this.handleUndo} />
          <Rect
            x={this.state.position.x}
            y={this.state.position.y}
            width={50}
            height={50}
            fill="black"
            draggable
            onDragEnd={this.handleDragEnd}
          />
        </Layer>
      </Stage>
    );
  }
}

https://codesandbox.io/s/3x3rwnlykp

【讨论】:

  • 感谢您的回复?? 我实际上计划为更广泛的操作(过滤器、转换、添加/删除组件)实施撤消重做。对于初始实现,我将序列化每个操作的整个阶段,并在应用撤消/重做时重建它。
猜你喜欢
  • 2012-12-16
  • 1970-01-01
  • 2020-05-12
  • 1970-01-01
  • 2012-02-08
  • 1970-01-01
  • 2011-05-01
  • 2010-10-10
  • 1970-01-01
相关资源
最近更新 更多