Improves scroll interaction for sequence editor
- Scroll paning (`shift + scroll`) is now synced for the keyframe viewport, easing viewport and scrollbar (Closes #22) - Scroll zooming out (`ctrl + scroll down`) is now bounded to avoid zooming out to infinity (Closes #19) There is still some quirky behaviour when using scroll to zoom inwards. It does not seem to respect the `pivotPointInUnitSpace` correctly. I've tried fixing it, but I've hit a dead end.
This commit is contained in:
parent
4d49a8bdd6
commit
bf0367bd0d
2 changed files with 42 additions and 1 deletions
|
@ -7,6 +7,7 @@
|
|||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
background: black;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
|
|
@ -11,6 +11,7 @@ import styled from 'styled-components'
|
|||
import {useReceiveVerticalWheelEvent} from '@theatre/studio/panels/SequenceEditorPanel/VerticalScrollContainer'
|
||||
import {pointerEventsAutoInNormalMode} from '@theatre/studio/css'
|
||||
import {useCursorLock} from '@theatre/studio/uiComponents/PointerEventsHandler'
|
||||
import type {IRange} from '@theatre/shared/utils/types'
|
||||
|
||||
const Container = styled.div`
|
||||
position: absolute;
|
||||
|
@ -192,7 +193,8 @@ function useHandlePanAndZoom(
|
|||
)
|
||||
|
||||
const oldRange = val(layoutP.clippedSpace.range)
|
||||
const scaleFactor = 1 + event.deltaY * 0.03
|
||||
const delta = normalize(event.deltaY, [-50, 50])
|
||||
const scaleFactor = 1 + delta * 0.03
|
||||
|
||||
const newRange = mapValues(oldRange, (originalPos) => {
|
||||
return (
|
||||
|
@ -201,6 +203,33 @@ function useHandlePanAndZoom(
|
|||
)
|
||||
})
|
||||
|
||||
// Set maximum scroll points based on the sequence length.
|
||||
// This is to avoid zooming out to infinity.
|
||||
const sequenceLength = val(layoutP.sheet).getSequence().length
|
||||
const maxEnd = sequenceLength + sequenceLength * 0.25
|
||||
|
||||
val(layoutP.clippedSpace.setRange)(
|
||||
normalizeRange(newRange, [0, maxEnd]),
|
||||
)
|
||||
}
|
||||
// paning
|
||||
else if (event.shiftKey) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
|
||||
const sequenceLength = val(layoutP.sheet).getSequence().length
|
||||
const oldRange = val(layoutP.clippedSpace.range)
|
||||
const windowSize = oldRange.end - oldRange.start
|
||||
const speed = windowSize / sequenceLength
|
||||
|
||||
const delta = normalize(event.deltaY, [-50, 50])
|
||||
const scaleFactor = delta * 0.05 * speed
|
||||
|
||||
const newRange = mapValues(
|
||||
oldRange,
|
||||
(originalPos) => originalPos + scaleFactor,
|
||||
)
|
||||
|
||||
val(layoutP.clippedSpace.setRange)(newRange)
|
||||
}
|
||||
}
|
||||
|
@ -217,6 +246,17 @@ function useHandlePanAndZoom(
|
|||
}, [node, layoutP])
|
||||
}
|
||||
|
||||
function normalize(value: number, [min, max]: [min: number, max: number]) {
|
||||
return Math.max(Math.min(value, max), min)
|
||||
}
|
||||
|
||||
function normalizeRange(
|
||||
range: IRange<number>,
|
||||
minMax: [min: number, max: number],
|
||||
) {
|
||||
return mapValues(range, (pos) => normalize(pos, minMax))
|
||||
}
|
||||
|
||||
function useUpdateScrollFromClippedSpaceRange(
|
||||
layoutP: Pointer<SequenceEditorPanelLayout>,
|
||||
node: HTMLDivElement | null,
|
||||
|
|
Loading…
Reference in a new issue