fix: remove entrance animation so dropped items are instantly draggable
Items were fading in from alpha 0 via spring animation, preventing immediate interaction. Removed the entrance animation entirely — items now appear at full opacity and are movable on first frame.
This commit is contained in:
@@ -357,7 +357,7 @@ const PixiCanvas = forwardRef<PixiCanvasHandle, PixiCanvasProps>(
|
|||||||
// Re-load scene data so textures get re-uploaded to GPU
|
// Re-load scene data so textures get re-uploaded to GPU
|
||||||
if (sceneRef.current && initialLoadDone.current) {
|
if (sceneRef.current && initialLoadDone.current) {
|
||||||
const data = sceneRef.current.serialize();
|
const data = sceneRef.current.serialize();
|
||||||
sceneRef.current.loadScene(data, false);
|
sceneRef.current.loadScene(data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
canvas.addEventListener('webglcontextlost', onContextLost);
|
canvas.addEventListener('webglcontextlost', onContextLost);
|
||||||
@@ -441,7 +441,7 @@ const PixiCanvas = forwardRef<PixiCanvasHandle, PixiCanvasProps>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
initialLoadDone.current = true;
|
initialLoadDone.current = true;
|
||||||
sceneRef.current.loadScene(sceneData, false);
|
sceneRef.current.loadScene(sceneData);
|
||||||
}, [canvasState, pixiReady]);
|
}, [canvasState, pixiReady]);
|
||||||
|
|
||||||
// ── Space key for pan mode ────────────────────────────────────────
|
// ── Space key for pan mode ────────────────────────────────────────
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ export class SceneManager {
|
|||||||
* 3. Create new items
|
* 3. Create new items
|
||||||
* 4. Apply z-ordering
|
* 4. Apply z-ordering
|
||||||
*/
|
*/
|
||||||
async loadScene(scene: SceneData, animate = false): Promise<void> {
|
async loadScene(scene: SceneData, _animate?: boolean): Promise<void> {
|
||||||
const incomingById = new Map<string, AnySceneObject>();
|
const incomingById = new Map<string, AnySceneObject>();
|
||||||
for (const obj of scene.objects) {
|
for (const obj of scene.objects) {
|
||||||
incomingById.set(obj.id, obj);
|
incomingById.set(obj.id, obj);
|
||||||
@@ -258,7 +258,7 @@ export class SceneManager {
|
|||||||
if (existing) {
|
if (existing) {
|
||||||
this._updateItem(existing, data);
|
this._updateItem(existing, data);
|
||||||
} else {
|
} else {
|
||||||
loadPromises.push(this._createItem(data, animate));
|
loadPromises.push(this._createItem(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track highest z for nextZ()
|
// Track highest z for nextZ()
|
||||||
@@ -282,7 +282,7 @@ export class SceneManager {
|
|||||||
// -- Item Creation -------------------------------------------------------
|
// -- Item Creation -------------------------------------------------------
|
||||||
|
|
||||||
/** Create a PixiJS display object from scene data and add it to the viewport. */
|
/** Create a PixiJS display object from scene data and add it to the viewport. */
|
||||||
async _createItem(data: AnySceneObject, animate: boolean): Promise<void> {
|
async _createItem(data: AnySceneObject, _animate?: boolean): Promise<void> {
|
||||||
let displayObject: Container;
|
let displayObject: Container;
|
||||||
|
|
||||||
switch (data.type) {
|
switch (data.type) {
|
||||||
@@ -380,18 +380,7 @@ export class SceneManager {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Animate entrance: quick fade-in (no bounce — items are immediately interactive)
|
// No entrance animation — items must be visible and draggable immediately.
|
||||||
if (animate) {
|
|
||||||
displayObject.alpha = 0;
|
|
||||||
|
|
||||||
const alphaSpring = new Spring(0, data.opacity, PRESETS.snappy);
|
|
||||||
alphaSpring.onUpdate = (v) => {
|
|
||||||
if (!displayObject.destroyed) {
|
|
||||||
displayObject.alpha = v;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.springs.add(alphaSpring);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- Item Update ---------------------------------------------------------
|
// -- Item Update ---------------------------------------------------------
|
||||||
@@ -596,7 +585,7 @@ export class SceneManager {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Fire-and-forget the async creation (animation handles visual feedback)
|
// Fire-and-forget the async creation (animation handles visual feedback)
|
||||||
this._createItem(data, true);
|
this._createItem(data);
|
||||||
|
|
||||||
this._applyZOrder();
|
this._applyZOrder();
|
||||||
this._onChange?.();
|
this._onChange?.();
|
||||||
@@ -638,7 +627,7 @@ export class SceneManager {
|
|||||||
duration,
|
duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
this._createItem(data, true);
|
this._createItem(data);
|
||||||
this._applyZOrder();
|
this._applyZOrder();
|
||||||
this._onChange?.();
|
this._onChange?.();
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ export class UndoManager {
|
|||||||
|
|
||||||
this.locked = true;
|
this.locked = true;
|
||||||
const parsed = JSON.parse(state);
|
const parsed = JSON.parse(state);
|
||||||
this.sceneManager.loadScene(parsed, false).then(() => {
|
this.sceneManager.loadScene(parsed).then(() => {
|
||||||
this.locked = false;
|
this.locked = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user