fix: rotated transform box, video texture crash, paste duplication, and loading UX
- TransformBox rotates with single-item selection (Figma-style), with handles and resize math projected into rotated coordinate space - Fix VideoSprite alphaMode crash by swapping texture to EMPTY before destroying, preventing PixiJS render loop from reading null source - Fix Ctrl+V double-paste: internal clipboard now always takes priority over system clipboard PNG, with wasRecentInternalPaste() guard - Add asset loading progress bar and suppress "Drop images here" flash during initial scene load
This commit is contained in:
@@ -22,12 +22,19 @@ import { onArrangeAnimationDone } from './operations';
|
||||
// Tracks when the last internal copy happened so paste can decide
|
||||
// whether to use internal clipboard (just copied) vs system clipboard (external app).
|
||||
let _lastInternalCopyTime = 0;
|
||||
// Tracks when the last internal paste happened so setupPaste can skip the native event.
|
||||
let _lastInternalPasteTime = 0;
|
||||
|
||||
/** Mark that an internal copy just happened. Called by copy/cut handlers. */
|
||||
export function markInternalCopy(): void {
|
||||
_lastInternalCopyTime = Date.now();
|
||||
}
|
||||
|
||||
/** Check if an internal paste just happened (within last 500ms). Used by setupPaste to skip. */
|
||||
export function wasRecentInternalPaste(): boolean {
|
||||
return Date.now() - _lastInternalPasteTime < 500;
|
||||
}
|
||||
|
||||
/** Collect selected items + their group children (for deep clone). */
|
||||
function _collectGroupChildren(items: SceneItem[], scene: SceneManager): SceneItem[] {
|
||||
const all: SceneItem[] = [];
|
||||
@@ -494,19 +501,18 @@ export const shortcuts: ShortcutDef[] = [
|
||||
category: 'editing', description: 'Paste',
|
||||
preventDefault: false,
|
||||
handler: async (ctx) => {
|
||||
// Only handle recent internal copies here.
|
||||
// For external clipboard content (images, text, HTML), do NOT call
|
||||
// e.preventDefault() — let the native paste event fire through to setupPaste
|
||||
// in image-drop.ts, which is the single path for all external clipboard content.
|
||||
const timeSinceInternalCopy = Date.now() - _lastInternalCopyTime;
|
||||
// If we have items in the internal clipboard, always prefer internal paste
|
||||
// (duplicates the scene items with offset). This avoids re-uploading the
|
||||
// PNG screenshot that Ctrl+C also wrote to the system clipboard.
|
||||
const hasInternalItems = ctx.clipboardRef.current.length > 0;
|
||||
const recentInternalCopy = hasInternalItems && timeSinceInternalCopy < 500;
|
||||
|
||||
if (recentInternalCopy) {
|
||||
if (hasInternalItems) {
|
||||
_lastInternalPasteTime = Date.now();
|
||||
await _pasteInternal(ctx);
|
||||
return;
|
||||
}
|
||||
// For external clipboard content: do nothing, let native paste event fire through to setupPaste
|
||||
// No internal items — let native paste event fire through to setupPaste
|
||||
// in image-drop.ts for external clipboard content (images, text, HTML).
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user