Skip to content

Commit

Permalink
fix(modifiers): allow toggling aspectRatio modifier during interaction
Browse files Browse the repository at this point in the history
Close #984 #879
  • Loading branch information
taye authored and interactjs-ci committed Jul 30, 2023
1 parent 9c280e4 commit 5e77901
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 21 deletions.
24 changes: 18 additions & 6 deletions packages/@interactjs/modifiers/Modification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,28 @@ export default class Modification {
startDelta!: Point
result!: ModificationResult
endResult!: Point
edges!: EdgeOptions
startEdges!: EdgeOptions
edges: EdgeOptions
readonly interaction: Readonly<Interaction>

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) {
const { interaction } = this
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 }

Expand All @@ -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
Expand All @@ -85,10 +93,11 @@ export default class Modification {
}

setAll (arg: MethodArg & Partial<ModifierArg>): 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

Expand All @@ -103,7 +112,7 @@ export default class Modification {
arg.state = state
returnValue = state.methods.set(arg as ModifierArg<never>)

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,
})
Expand All @@ -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

Expand Down Expand Up @@ -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))
Expand Down
26 changes: 15 additions & 11 deletions packages/@interactjs/modifiers/aspectRatio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ AspectRatioOptions,

const aspectRatio: ModifierModule<AspectRatioOptions, AspectRatioState> = {
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') {
Expand All @@ -64,13 +64,13 @@ const aspectRatio: ModifierModule<AspectRatioOptions, AspectRatioState> = {
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)
Expand All @@ -85,9 +85,11 @@ const aspectRatio: ModifierModule<AspectRatioOptions, AspectRatioState> = {
}
}

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)

Expand All @@ -100,9 +102,11 @@ const aspectRatio: ModifierModule<AspectRatioOptions, AspectRatioState> = {

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) {
Expand All @@ -111,15 +115,15 @@ const aspectRatio: ModifierModule<AspectRatioOptions, AspectRatioState> = {

const correctedRect = extend({}, rect)

addEdges(state.linkedEdges, correctedRect, {
addEdges(linkedEdges, correctedRect, {
x: coords.x - initialCoords.x,
y: coords.y - initialCoords.y,
})

const result = state.subModification.setAll({
...arg,
rect: correctedRect,
edges: state.linkedEdges,
edges: linkedEdges,
pageCoords: coords,
prevCoords: coords,
prevRect: correctedRect,
Expand Down
23 changes: 19 additions & 4 deletions packages/@interactjs/modifiers/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 5e77901

Please sign in to comment.