From 5e779010d06c0e867cfd13d5019bd5615a0ecb09 Mon Sep 17 00:00:00 2001 From: Taye Adeyemi Date: Mon, 26 Dec 2022 00:38:42 +0100 Subject: [PATCH] fix(modifiers): allow toggling aspectRatio modifier during interaction Close #984 #879 --- .../@interactjs/modifiers/Modification.ts | 24 ++++++++++++----- packages/@interactjs/modifiers/aspectRatio.ts | 26 +++++++++++-------- packages/@interactjs/modifiers/base.ts | 23 +++++++++++++--- 3 files changed, 52 insertions(+), 21 deletions(-) diff --git a/packages/@interactjs/modifiers/Modification.ts b/packages/@interactjs/modifiers/Modification.ts index acf914a1e..d19e773e1 100644 --- a/packages/@interactjs/modifiers/Modification.ts +++ b/packages/@interactjs/modifiers/Modification.ts @@ -31,12 +31,19 @@ export default class Modification { startDelta!: Point result!: ModificationResult endResult!: Point - edges!: EdgeOptions + startEdges!: EdgeOptions + edges: EdgeOptions readonly interaction: Readonly constructor (interaction: Interaction) { this.interaction = interaction this.result = createResult() + this.edges = { + left: false, + right: false, + top: false, + bottom: false, + } } start ({ phase }: { phase: EventPhase }, pageCoords: Point) { @@ -44,7 +51,8 @@ export default class Modification { const modifierList = getModifierList(interaction) this.prepareStates(modifierList) - this.edges = extend({}, interaction.edges) + this.startEdges = extend({}, interaction.edges) + this.edges = extend({}, this.startEdges) this.startOffset = getRectOffset(interaction.rect, pageCoords) this.startDelta = { x: 0, y: 0 } @@ -68,8 +76,8 @@ export default class Modification { arg.interaction = interaction arg.interactable = interaction.interactable arg.element = interaction.element - arg.rect = arg.rect || interaction.rect - arg.edges = this.edges + arg.rect ||= interaction.rect + arg.edges ||= this.startEdges arg.startOffset = this.startOffset return arg as ModifierArg @@ -85,10 +93,11 @@ export default class Modification { } setAll (arg: MethodArg & Partial): ModificationResult { - const { phase, preEnd, skipModifiers, rect: unmodifiedRect } = arg + const { phase, preEnd, skipModifiers, rect: unmodifiedRect, edges: unmodifiedEdges } = arg arg.coords = extend({}, arg.pageCoords) arg.rect = extend({}, unmodifiedRect) + arg.edges = extend({}, unmodifiedEdges) const states = skipModifiers ? this.states.slice(skipModifiers) : this.states @@ -103,7 +112,7 @@ export default class Modification { arg.state = state returnValue = state.methods.set(arg as ModifierArg) - rectUtils.addEdges(this.interaction.edges, arg.rect, { + rectUtils.addEdges(arg.edges, arg.rect, { x: arg.coords.x - lastModifierCoords.x, y: arg.coords.y - lastModifierCoords.y, }) @@ -112,6 +121,8 @@ export default class Modification { newResult.eventProps.push(returnValue) } + extend(this.edges, arg.edges) + newResult.delta.x = arg.coords.x - arg.pageCoords.x newResult.delta.y = arg.coords.y - arg.pageCoords.y @@ -341,6 +352,7 @@ export default class Modification { copyFrom (other: Modification) { this.startOffset = other.startOffset this.startDelta = other.startDelta + this.startEdges = other.startEdges this.edges = other.edges this.states = other.states.map((s) => clone(s) as ModifierState) this.result = createResult(extend({}, other.result.coords), extend({}, other.result.rect)) diff --git a/packages/@interactjs/modifiers/aspectRatio.ts b/packages/@interactjs/modifiers/aspectRatio.ts index 1c18336e3..4f61936d1 100644 --- a/packages/@interactjs/modifiers/aspectRatio.ts +++ b/packages/@interactjs/modifiers/aspectRatio.ts @@ -50,8 +50,8 @@ AspectRatioOptions, const aspectRatio: ModifierModule = { start (arg) { - const { state, rect, edges: originalEdges, pageCoords: coords } = arg - let { ratio } = state.options + const { state, rect, edges, pageCoords: coords } = arg + let { ratio, enabled } = state.options const { equalDelta, modifiers } = state.options if (ratio === 'preserve') { @@ -64,13 +64,13 @@ const aspectRatio: ModifierModule = { state.equalDelta = equalDelta const linkedEdges = (state.linkedEdges = { - top: originalEdges.top || (originalEdges.left && !originalEdges.bottom), - left: originalEdges.left || (originalEdges.top && !originalEdges.right), - bottom: originalEdges.bottom || (originalEdges.right && !originalEdges.top), - right: originalEdges.right || (originalEdges.bottom && !originalEdges.left), + top: edges.top || (edges.left && !edges.bottom), + left: edges.left || (edges.top && !edges.right), + bottom: edges.bottom || (edges.right && !edges.top), + right: edges.right || (edges.bottom && !edges.left), }) - state.xIsPrimaryAxis = !!(originalEdges.left || originalEdges.right) + state.xIsPrimaryAxis = !!(edges.left || edges.right) if (state.equalDelta) { const sign = (linkedEdges.left ? 1 : -1) * (linkedEdges.top ? 1 : -1) @@ -85,9 +85,11 @@ const aspectRatio: ModifierModule = { } } - extend(arg.edges, linkedEdges) + if (enabled !== false) { + extend(edges, linkedEdges) + } - if (!modifiers || !modifiers.length) return + if (!modifiers?.length) return const subModification = new Modification(arg.interaction) @@ -100,9 +102,11 @@ const aspectRatio: ModifierModule = { set (arg) { const { state, rect, coords } = arg + const { linkedEdges } = state const initialCoords = extend({}, coords) const aspectMethod = state.equalDelta ? setEqualDelta : setRatio + extend(arg.edges, linkedEdges) aspectMethod(state, state.xIsPrimaryAxis, coords, rect) if (!state.subModification) { @@ -111,7 +115,7 @@ const aspectRatio: ModifierModule = { const correctedRect = extend({}, rect) - addEdges(state.linkedEdges, correctedRect, { + addEdges(linkedEdges, correctedRect, { x: coords.x - initialCoords.x, y: coords.y - initialCoords.y, }) @@ -119,7 +123,7 @@ const aspectRatio: ModifierModule = { const result = state.subModification.setAll({ ...arg, rect: correctedRect, - edges: state.linkedEdges, + edges: linkedEdges, pageCoords: coords, prevCoords: coords, prevRect: correctedRect, diff --git a/packages/@interactjs/modifiers/base.ts b/packages/@interactjs/modifiers/base.ts index ab1c16703..25fb36c58 100644 --- a/packages/@interactjs/modifiers/base.ts +++ b/packages/@interactjs/modifiers/base.ts @@ -104,16 +104,31 @@ const modifiersBase: Plugin = { }, 'interactions:before-action-start': (arg) => { + const { interaction } = arg const modification = arg.interaction.modification! - modification.start(arg, arg.interaction.coords.start.page) - arg.interaction.edges = modification.edges + modification.start(arg, interaction.coords.start.page) + interaction.edges = modification.edges modification.applyToInteraction(arg) }, - 'interactions:before-action-move': (arg) => arg.interaction.modification.setAndApply(arg), + 'interactions:before-action-move': (arg) => { + const { interaction } = arg + const { modification } = interaction + const ret = modification.setAndApply(arg) + interaction.edges = modification.edges - 'interactions:before-action-end': (arg) => arg.interaction.modification.beforeEnd(arg), + return ret + }, + + 'interactions:before-action-end': (arg) => { + const { interaction } = arg + const { modification } = interaction + const ret = modification.beforeEnd(arg) + interaction.edges = modification.startEdges + + return ret + }, 'interactions:action-start': addEventModifiers, 'interactions:action-move': addEventModifiers,