vue2 + fabric.js 实现撤销、恢复效果

示例

原生js参考版本

全部代码

<template>
  <div>
    <canvas id="canvas" width="400" height="400" style="border: 1px"></canvas>
    <button :disabled="!canUndo" @click="historyState(stateIndex - 1)">
      撤销
    </button>
    <button :disabled="!canRedo" @click="historyState(stateIndex + 1)">
      恢复
    </button>
  </div>
</template>

<script>
import { fabric } from "fabric";
export default {
  data() {
    return {
      canvas: null,
      isLoadCanvas: false,
      canvasState: [],
      stateIndex: -1,
    };
  },
  mounted() {
    this.canvas = new fabric.Canvas("canvas", {
      backgroundColor: "#f5deb3",
    });
    this.canvas.on("object:modified", this.updateCanvasState);
    this.canvas.on("object:added", this.updateCanvasState);
    this.addObject();
  },
  computed: {
    canUndo() {
      return this.stateIndex > 0;
    },
    canRedo() {
      return this.stateIndex < this.canvasState.length - 1;
    },
  },
  methods: {
    addObject() {
      const rect = new fabric.Rect({
        left: 100,
        top: 100,
        fill: "red",
        width: 200,
        height: 200,
      });
      this.canvas.add(rect);
      this.canvas.renderAll();
    },

    updateCanvasState() {
      if (!this.isLoadCanvas) {
        const canvasAsJson = JSON.stringify(this.canvas.toJSON());
        this.canvasState.splice(this.stateIndex + 1);
        this.canvasState.push(canvasAsJson);
        this.stateIndex = this.canvasState.length - 1;
      } else {
        this.isLoadCanvas = false;
      }
    },

    historyState(index) {
      if (this.canUndo || this.canRedo) {
        this.isLoadCanvas = true;
        this.canvas.loadFromJSON(this.canvasState[index], () => {
          this.canvas.renderAll();
          this.stateIndex = index;
        });
      }
    },
  },
};
</script>
posted @ 2023-05-16 17:48  lwlcode  阅读(1394)  评论(0编辑  收藏  举报