diff --git a/code/CHANGELOG.md b/code/CHANGELOG.md index 477b19e6a..8b7259cf7 100644 --- a/code/CHANGELOG.md +++ b/code/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - [#701](https://github.com/InditexTech/weavejs/issues/701) Fix Video node TS types issues and rotation +- [#705](https://github.com/InditexTech/weavejs/issues/705) When ctrl + alt and drag, original node is moved a delta, but when reload its OK ## [0.74.0] - 2025-10-09 diff --git a/code/packages/sdk/src/actions/image-tool/image-tool.ts b/code/packages/sdk/src/actions/image-tool/image-tool.ts index 054ff6fdc..be71026e5 100644 --- a/code/packages/sdk/src/actions/image-tool/image-tool.ts +++ b/code/packages/sdk/src/actions/image-tool/image-tool.ts @@ -6,7 +6,6 @@ import { v4 as uuidv4 } from 'uuid'; import { WeaveAction } from '@/actions/action'; import { type Vector2d } from 'konva/lib/types'; import { - type ImageOptions, type WeaveImageToolActionTriggerParams, type WeaveImageToolActionState, type WeaveImageToolActionTriggerReturn, @@ -20,6 +19,7 @@ import { WeaveNodesSelectionPlugin } from '@/plugins/nodes-selection/nodes-selec import Konva from 'konva'; import type { WeaveImageNode } from '@/nodes/image/image'; import { SELECTION_TOOL_ACTION_NAME } from '../selection-tool/constants'; +import { getPositionRelativeToContainerOnPosition } from '@/utils'; export class WeaveImageToolAction extends WeaveAction { protected initialized: boolean = false; @@ -69,7 +69,8 @@ export class WeaveImageToolAction extends WeaveAction { this.instance.addEventListener('onStageDrop', (e) => { if (window.weaveDragImageURL) { this.instance.getStage().setPointersPositions(e); - const position = this.instance.getStage().getRelativePointerPosition(); + const position: Vector2d | null | undefined = + getPositionRelativeToContainerOnPosition(this.instance); this.instance.triggerAction(IMAGE_TOOL_ACTION_NAME, { imageURL: window.weaveDragImageURL, @@ -164,11 +165,7 @@ export class WeaveImageToolAction extends WeaveAction { this.state = state; } - private loadImage( - imageURL: string, - options?: ImageOptions, - position?: Vector2d - ) { + private loadImage(imageURL: string, position?: Vector2d) { this.setCursor(); this.setFocusStage(); @@ -380,11 +377,7 @@ export class WeaveImageToolAction extends WeaveAction { } if (params?.imageURL) { - this.loadImage( - params.imageURL, - params?.options ?? undefined, - params?.position ?? undefined - ); + this.loadImage(params.imageURL, params?.position ?? undefined); return; } diff --git a/code/packages/sdk/src/actions/image-tool/types.ts b/code/packages/sdk/src/actions/image-tool/types.ts index 152d614b8..30cfa6c39 100644 --- a/code/packages/sdk/src/actions/image-tool/types.ts +++ b/code/packages/sdk/src/actions/image-tool/types.ts @@ -32,6 +32,9 @@ export type ImageOptions = { export type WeaveImageToolActionTriggerReturn = | { - finishUploadCallback: (imageURL: string, options?: ImageOptions) => void; + finishUploadCallback: ( + imageURL: string, + position?: Vector2d | undefined + ) => void; } | undefined; diff --git a/code/packages/sdk/src/actions/video-tool/video-tool.ts b/code/packages/sdk/src/actions/video-tool/video-tool.ts index 8454c0b0b..daacab1c7 100644 --- a/code/packages/sdk/src/actions/video-tool/video-tool.ts +++ b/code/packages/sdk/src/actions/video-tool/video-tool.ts @@ -18,6 +18,7 @@ import { WeaveNodesSelectionPlugin } from '@/plugins/nodes-selection/nodes-selec import Konva from 'konva'; import { SELECTION_TOOL_ACTION_NAME } from '../selection-tool/constants'; import type { WeaveVideoNode } from '@/nodes/video/video'; +import { getPositionRelativeToContainerOnPosition } from '@/utils'; export class WeaveVideoToolAction extends WeaveAction { protected initialized: boolean = false; @@ -73,7 +74,8 @@ export class WeaveVideoToolAction extends WeaveAction { this.instance.addEventListener('onStageDrop', (e) => { if (window.weaveDragVideoId && window.weaveDragVideoParams) { this.instance.getStage().setPointersPositions(e); - const position = this.instance.getStage().getRelativePointerPosition(); + const position: Vector2d | null | undefined = + getPositionRelativeToContainerOnPosition(this.instance); this.instance.triggerAction(VIDEO_TOOL_ACTION_NAME, { videoId: window.weaveDragVideoId, diff --git a/code/packages/sdk/src/nodes/node.ts b/code/packages/sdk/src/nodes/node.ts index e3f412ef5..b0673db06 100644 --- a/code/packages/sdk/src/nodes/node.ts +++ b/code/packages/sdk/src/nodes/node.ts @@ -283,7 +283,26 @@ export abstract class WeaveNode implements WeaveNodeBase { } }); - let clone: Konva.Node | undefined = undefined; + const stage = this.instance.getStage(); + + let originalPosition: Vector2d | null = null; + + this.instance.addEventListener('onSelectionState', (state) => { + const nodesSelectionPlugin = this.getSelectionPlugin(); + const selectedNodes = nodesSelectionPlugin?.getSelectedNodes() ?? []; + + if ( + !state && + selectedNodes?.some((n) => n.getAttrs().id === node.getAttrs().id) + ) { + originalPosition = node.getAbsolutePosition(); + } + }); + + node.on('mousedown', (e) => { + const nodeTarget = e.target; + originalPosition = nodeTarget.getAbsolutePosition(); + }); node.on('dragstart', (e) => { const nodeTarget = e.target; @@ -295,8 +314,6 @@ export abstract class WeaveNode implements WeaveNodeBase { return; } - const stage = this.instance.getStage(); - const isErasing = this.instance.getActiveAction() === 'eraseTool'; if (isErasing) { @@ -318,13 +335,18 @@ export abstract class WeaveNode implements WeaveNodeBase { } if (e.evt?.altKey) { + nodeTarget.setAttrs({ isCloneOrigin: true }); + nodeTarget.setAttrs({ isCloned: false }); nodeTarget.stopDrag(e.evt); e.cancelBubble = true; - clone = this.instance.getCloningManager().cloneNode(realNodeTarget); + const clone = this.instance + .getCloningManager() + .cloneNode(realNodeTarget); if (clone && !this.instance.getCloningManager().isClone(clone)) { + clone.setAttrs({ isCloneOrigin: false }); clone.setAttrs({ isCloned: true }); this.instance.getCloningManager().addClone(clone); } @@ -334,12 +356,12 @@ export abstract class WeaveNode implements WeaveNodeBase { const nodesSelectionPlugin = this.getNodesSelectionPlugin(); nodesSelectionPlugin?.setSelectedNodes([]); - setTimeout(() => { + requestAnimationFrame(() => { nodesSelectionPlugin?.setSelectedNodes( this.instance.getCloningManager().getClones() ); clone?.startDrag(e.evt); - }, 0); + }); } }); @@ -374,7 +396,6 @@ export abstract class WeaveNode implements WeaveNodeBase { if ( this.isSelecting() && - // this.isNodeSelected(node) && this.getSelectionPlugin()?.getSelectedNodes().length === 1 ) { clearContainerTargets(this.instance); @@ -402,8 +423,12 @@ export abstract class WeaveNode implements WeaveNodeBase { e.cancelBubble = true; - if (clone) { - clone = undefined; + if (nodeTarget.getAttrs().isCloneOrigin && originalPosition) { + nodeTarget.setAbsolutePosition(originalPosition); + nodeTarget.setAttrs({ isCloneOrigin: undefined }); + nodeTarget.setAttrs({ isCloned: undefined }); + originalPosition = null; + return; } if (!this.didMove) { @@ -452,11 +477,7 @@ export abstract class WeaveNode implements WeaveNodeBase { } let moved = false; - if ( - containerToMove && - !hasFrames(node) && - !realNodeTarget.getAttrs().isCloned - ) { + if (containerToMove && !hasFrames(node)) { moved = moveNodeToContainer( this.instance, realNodeTarget, @@ -466,10 +487,9 @@ export abstract class WeaveNode implements WeaveNodeBase { if (realNodeTarget.getAttrs().isCloned) { this.instance.getCloningManager().removeClone(realNodeTarget); + originalPosition = realNodeTarget.getAbsolutePosition(); } - realNodeTarget?.setAttrs({ isCloned: undefined }); - if (containerToMove) { containerToMove.fire(WEAVE_NODE_CUSTOM_EVENTS.onTargetLeave, { bubbles: true, @@ -482,6 +502,12 @@ export abstract class WeaveNode implements WeaveNodeBase { ); } } + + nodeTarget.setAttrs({ isCloned: undefined }); + nodeTarget.setAttrs({ isCloneOrigin: undefined }); + realNodeTarget.setAttrs({ isCloned: undefined }); + realNodeTarget.setAttrs({ isCloneOrigin: undefined }); + originalPosition = realNodeTarget.getAbsolutePosition(); }); node.handleMouseover = () => { diff --git a/code/packages/sdk/src/plugins/nodes-selection/nodes-selection.ts b/code/packages/sdk/src/plugins/nodes-selection/nodes-selection.ts index c4d73fa64..9f06538b7 100644 --- a/code/packages/sdk/src/plugins/nodes-selection/nodes-selection.ts +++ b/code/packages/sdk/src/plugins/nodes-selection/nodes-selection.ts @@ -309,18 +309,6 @@ export class WeaveNodesSelectionPlugin extends WeavePlugin { e.cancelBubble = true; - const selectedNodes = tr.nodes(); - for (let i = 0; i < selectedNodes.length; i++) { - const node = selectedNodes[i]; - node.updatePosition(node.getAbsolutePosition()); - } - - if (e.evt?.altKey) { - tr.stopDrag(e.evt); - - e.cancelBubble = true; - } - tr.forceUpdate(); }); @@ -390,7 +378,6 @@ export class WeaveNodesSelectionPlugin extends WeavePlugin { const node = selectedNodes[i]; selectionContainsFrames = selectionContainsFrames || hasFrames(node); node.updatePosition(node.getAbsolutePosition()); - node.setAttrs({ isCloned: undefined }); } if (this.isSelecting() && tr.nodes().length > 1) { @@ -464,6 +451,8 @@ export class WeaveNodesSelectionPlugin extends WeavePlugin { selectedNodes[i].getAttrs().nodeType ); + selectedNodes[i].setAttrs({ isCloned: undefined }); + if (nodeHandler) { this.instance.updateNode( nodeHandler.serialize(selectedNodes[i] as WeaveElementInstance) diff --git a/code/packages/sdk/src/utils.ts b/code/packages/sdk/src/utils.ts index c85fcde39..600bbf7a6 100644 --- a/code/packages/sdk/src/utils.ts +++ b/code/packages/sdk/src/utils.ts @@ -568,3 +568,24 @@ export function isIOS() { } export const isServer = () => typeof window === 'undefined'; + +export const getPositionRelativeToContainerOnPosition = ( + instance: Weave +): Vector2d | null | undefined => { + let position: Vector2d | null | undefined = instance + .getStage() + .getRelativePointerPosition(); + + if (!position) { + return position; + } + + const container = containerOverCursor(instance, [], position); + position = container?.getRelativePointerPosition(); + + if (!position) { + return position; + } + + return position; +}; diff --git a/docs/content/docs/main/changelog/prerelease/0.74.1.mdx b/docs/content/docs/main/changelog/prerelease/0.74.1.mdx index 824d1520a..5722e8f3a 100644 --- a/docs/content/docs/main/changelog/prerelease/0.74.1.mdx +++ b/docs/content/docs/main/changelog/prerelease/0.74.1.mdx @@ -1,12 +1,13 @@ --- title: v0.74.1 -description: Minor bugfixed +description: Minor bugfixes --- ## Metadata -- **Release date**: 2025-10-09 +- **Release date**: 2025-10-10 ### Fixed - [#701](https://github.com/InditexTech/weavejs/issues/701) Fix Video node TS types issues and rotation +- [#705](https://github.com/InditexTech/weavejs/issues/705) When ctrl + alt and drag, original node is moved a delta, but when reload its OK diff --git a/docs/content/docs/main/changelog/prerelease/meta.json b/docs/content/docs/main/changelog/prerelease/meta.json index bc64b9990..bd98d8ffb 100644 --- a/docs/content/docs/main/changelog/prerelease/meta.json +++ b/docs/content/docs/main/changelog/prerelease/meta.json @@ -2,6 +2,7 @@ "title": "Prerelease versions", "description": "Detailed changelog for Weave.js pre-release versions", "pages": [ + "0.74.1", "0.74.0", "0.73.1", "0.73.0",