引擎的核心代码里没有任何框架相关的代码,所以 Fabric.js 原生 JavaScript 用起来和任何框架一样顺手。你创建画布、创建引擎,再根据它的状态更新工具栏。
页面
<div role="toolbar">
<button id="undo">Undo</button>
<button id="redo">Redo</button>
<button id="save">Save</button>
<span id="status" aria-live="polite"></span>
</div>
<canvas id="editor"></canvas>脚本
import { Canvas } from "fabric";
import {
bindKeyboardShortcuts,
createDocumentEngine,
createDocumentStateStore,
} from "fabricjs-document-engine";
import { createLocalStorage } from "fabricjs-document-engine/storage";
const canvas = new Canvas("editor", { width: 800, height: 500 });
const engine = createDocumentEngine({
canvas,
storage: createLocalStorage(),
autosave: true,
});
bindKeyboardShortcuts(engine);
const undo = document.querySelector<HTMLButtonElement>("#undo")!;
const redo = document.querySelector<HTMLButtonElement>("#redo")!;
const save = document.querySelector<HTMLButtonElement>("#save")!;
const status = document.querySelector("#status")!;
undo.addEventListener("click", () => engine.undo());
redo.addEventListener("click", () => engine.redo());
save.addEventListener("click", () => engine.save());
const store = createDocumentStateStore(engine);
function render() {
const state = store.getSnapshot();
undo.disabled = !state.canUndo;
redo.disabled = !state.canRedo;
save.disabled = !state.isDirty;
status.textContent = state.saveStatus;
}
store.subscribe(render);
render();createDocumentStateStore 提供一个快照,里面有工具栏需要的全部状态。它只在有订阅者时才监听引擎。
用事件代替 store
如果你只要一个值,监听单个事件就行:
engine.on("history:change", ({ canUndo, canRedo }) => {
undo.disabled = !canUndo;
redo.disabled = !canRedo;
});on 会返回一个取消订阅的函数。完整列表见事件。
不用打包工具
Fabric.js 原生 JavaScript 也可以借助 import map 直接从 CDN 加载。这个包以 ES 模块发布,不用框架也不用打包:
<script type="importmap">
{
"imports": {
"fabric": "https://cdn.jsdelivr.net/npm/fabric@7/+esm",
"fabricjs-document-engine": "https://cdn.jsdelivr.net/npm/fabricjs-document-engine@1/+esm"
}
}
</script>想一步步不用框架做出编辑器,请跟着编辑器教程。