Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

历史记录插件感觉有点问题 #466

Closed
z910130233 opened this issue Jul 9, 2024 · 1 comment
Closed

历史记录插件感觉有点问题 #466

z910130233 opened this issue Jul 9, 2024 · 1 comment

Comments

@z910130233
Copy link

使用历史记录插件回退操作时,回退到最后一步时,形状left和top都为0,所以形状都跑到左上角去了,不知道对不对,我查看了记录时的json,我觉得可能是形状还没加载完成的时候,没有记录完整的形状属性数据,我根据这个code改动了下

`

import {Canvas} from 'fabric';
import Editor from '../Editor';
type IEditor = Editor;

type HistoryEventCallback = () => void;
class HistoryPlugin {
  private canvas: Canvas;
  private editor: IEditor;
  private historyUndo: string[];
  private historyRedo: string[];
  private extraProps: string[];
  private historyNextState: string;
  private historyProcessing: boolean;

  static pluginName = 'HistoryPlugin';
  static apis = ['undo', 'redo', 'clearHistory'];
  static events = ['historyUpdate'];
  public hotkeys: string[] = ['ctrl+z', 'ctrl+shift+z', '⌘+z', '⌘+shift+z'];
  
  constructor(canvas: Canvas, editor: IEditor) {
      this.canvas = canvas;
      this.editor = editor;
      this.historyUndo = [];
      this.historyRedo = [];
      this.extraProps = ['selectable', 'hasControls', 'left', 'top', 'id'];
      this.historyNextState = this._historyNext();
      this.historyProcessing = false;

      this._historyInit();
  }

  private _historyNext(): string {
      return JSON.stringify(this.canvas.toDatalessJSON(this.extraProps));
      // return JSON.stringify(this.canvas.toDatalessJSON());
      // return JSON.stringify(this.canvas.toJSON());
  }

  private _historyEvents() {
      return {
          'object:added': this._historySaveAction.bind(this),
          'object:removed': this._historySaveAction.bind(this),
          'object:modified': this._historySaveAction.bind(this),
          'object:skewing': this._historySaveAction.bind(this),
      };
  }

  private _historyInit() {
      this.canvas.on(this._historyEvents());

      window.addEventListener('beforeunload', (e) => {
          if (this.historyUndo.length > 0 || this.historyRedo.length > 0) {
              (e || window.event).returnValue = '确认离开';
          }
      });
  }

  private _historyDispose() {
      this.canvas.off(this._historyEvents());
  }

  private _historySaveAction() {
      if (this.historyProcessing) return;

      this.canvas.once('after:render', () => {
          const json = this.historyNextState;
          console.log('save', json)
          this.historyUndo.push(json);
          this.historyNextState = this._historyNext();
          this.canvas.fire('history:append', {json: json});

          this.historyUpdate();
      })
  }

  historyUpdate() {
      this.editor.emit('historyUpdate', this.historyUndo.length, this.historyRedo.length);
  }

  undo(callback?: HistoryEventCallback) {
      this.historyProcessing = true;

      const history = this.historyUndo.pop();
      if (history) {
          this.historyRedo.push(this._historyNext());
          this.historyNextState = history;
          this._loadHistory(history, 'history:undo', callback);
      } else {
          this.historyProcessing = false;
      }
      this.historyUpdate();
  }

  redo(callback?: HistoryEventCallback) {
      this.historyProcessing = true;

      const history = this.historyRedo.pop();
      if (history) {
          this.historyUndo.push(this._historyNext());
          this.historyNextState = history;
          this._loadHistory(history, 'history:redo', callback);
      } else {
          this.historyProcessing = false;
      }
      this.historyUpdate();
  }

  private _loadHistory(history: string, event: string, callback?: HistoryEventCallback) {
      const that = this;
      this.canvas.loadFromJSON(history, () => {
          that.canvas.renderAll();
          that.canvas.fire(event);
          that.historyProcessing = false;

          if (callback) callback();
      });
  }

  clearHistory() {
      this.historyUndo = [];
      this.historyRedo = [];
      this.canvas.fire('history:clear');
  }

  onHistory() {
      this.historyProcessing = false;
      this._historySaveAction();
  }

  canUndo(): boolean {
      return this.historyUndo.length > 0;
  }

  canRedo(): boolean {
      return this.historyRedo.length > 0;
  }

  offHistory() {
      this.historyProcessing = true;
  }

  // 快捷键扩展回调
  hotkeyEvent(eventName: string, e: any) {
      if (e.type === 'keydown') {
          switch (eventName) {
              case 'ctrl+z':
              case '⌘+z':
                  this.undo();
                  break;
              case 'ctrl+shift+z':
              case '⌘+shift+z':
                  this.redo();
                  break;
          }
      }
  }
  }
  export default HistoryPlugin;

`

@nihaojob
Copy link
Member

nihaojob commented Jul 9, 2024

这个问题下午已经修复了,这是相关代码哈 64e3fb6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants