feat: RefBoard v0.5.0 — PureRef-style shortcuts, clipboard fix, zoom normalization

- Add 40+ keyboard shortcuts via declarative registry system (shortcut-definitions.ts)
- Fix canvas tainting: patch crossOrigin before loadFromJSON in all paths (init, sync, undo/redo)
- Fix clipboard copy-to-system with proper async blob handling and error toasts
- Fix zoom wheel: normalize deltaY across mice/trackpads with consistent 8% step
- Add operations module: alignment, distribution, normalization, arrangement, flip, grayscale, lock, overlay compare
- Add breakSelection() to fix ActiveSelection relative coordinate bugs
- Add shortcuts help overlay (? / F1) auto-generated from registry
- Add grid overlay toggle (G key)
- Fix 10 shortcut bugs: Ctrl+Y/P conflicts, ? key matching, arrow conflicts, Ctrl+S intercept, context menu stale objects
This commit is contained in:
Hiren
2026-03-09 18:29:35 +05:30
parent 9e5c4ecdd0
commit cdeafce7ad
10 changed files with 1389 additions and 338 deletions
+14 -2
View File
@@ -20,7 +20,7 @@ export class UndoManager {
saveState(): void {
if (this.locked) return;
const json = JSON.stringify((this.canvas as any).toJSON(['id']));
const json = JSON.stringify((this.canvas as any).toJSON(['id', 'crossOrigin']));
// If we're not at the end, discard forward history
if (this.pointer < this.stack.length - 1) {
@@ -69,7 +69,19 @@ export class UndoManager {
if (!state) return;
this.locked = true;
this.canvas.loadFromJSON(JSON.parse(state)).then(() => {
const parsed = JSON.parse(state);
// Ensure images have crossOrigin to prevent canvas tainting
if (parsed?.objects) {
for (const obj of parsed.objects) {
if (obj.type === 'image') obj.crossOrigin = 'anonymous';
if (obj.type === 'group' && obj.objects) {
for (const child of obj.objects) {
if (child.type === 'image') child.crossOrigin = 'anonymous';
}
}
}
}
this.canvas.loadFromJSON(parsed).then(() => {
this.canvas.requestRenderAll();
this.locked = false;
});