Cleaner API for useFrameStampPosition()
This commit is contained in:
parent
0a3c699180
commit
74b6f93872
5 changed files with 56 additions and 38 deletions
|
@ -9,14 +9,11 @@ import useDrag from '@theatre/studio/uiComponents/useDrag'
|
|||
import useRefAndState from '@theatre/studio/utils/useRefAndState'
|
||||
import {val} from '@theatre/dataverse'
|
||||
import {lighten} from 'polished'
|
||||
import React, {useMemo, useRef} from 'react'
|
||||
import React, {useMemo, useRef, useState} from 'react'
|
||||
import styled from 'styled-components'
|
||||
import type KeyframeEditor from './KeyframeEditor'
|
||||
import type {FrameStampPositionLock} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
||||
import {
|
||||
attributeNameThatLocksFramestamp,
|
||||
useFrameStampPosition,
|
||||
} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
||||
import {useLockFrameStampPosition} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
||||
import {attributeNameThatLocksFramestamp} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
||||
|
||||
export const dotSize = 6
|
||||
const hitZoneSize = 12
|
||||
|
@ -112,7 +109,8 @@ function useKeyframeContextMenu(node: HTMLDivElement | null, props: IProps) {
|
|||
}
|
||||
|
||||
function useDragKeyframe(node: HTMLDivElement | null, props: IProps) {
|
||||
const {getLock} = useFrameStampPosition()
|
||||
const [isDragging, setIsDragging] = useState(false)
|
||||
useLockFrameStampPosition(isDragging, props.keyframe.position)
|
||||
|
||||
const propsRef = useRef(props)
|
||||
propsRef.current = props
|
||||
|
@ -121,7 +119,6 @@ function useDragKeyframe(node: HTMLDivElement | null, props: IProps) {
|
|||
let toUnitSpace: SequenceEditorPanelLayout['scaledSpace']['toUnitSpace']
|
||||
let tempTransaction: CommitOrDiscard | undefined
|
||||
let propsAtStartOfDrag: IProps
|
||||
let frameStampPositionLock: FrameStampPositionLock
|
||||
|
||||
let selectionDragHandlers:
|
||||
| ReturnType<DopeSheetSelection['getDragHandlers']>
|
||||
|
@ -130,6 +127,7 @@ function useDragKeyframe(node: HTMLDivElement | null, props: IProps) {
|
|||
return {
|
||||
lockCursorTo: 'ew-resize',
|
||||
onDragStart(event) {
|
||||
setIsDragging(true)
|
||||
if (propsRef.current.selection) {
|
||||
const {selection, leaf} = propsRef.current
|
||||
const {sheetObject} = leaf
|
||||
|
@ -145,9 +143,6 @@ function useDragKeyframe(node: HTMLDivElement | null, props: IProps) {
|
|||
|
||||
propsAtStartOfDrag = propsRef.current
|
||||
toUnitSpace = val(propsAtStartOfDrag.layoutP.scaledSpace.toUnitSpace)
|
||||
|
||||
frameStampPositionLock = getLock()
|
||||
frameStampPositionLock.set(propsAtStartOfDrag.keyframe.position)
|
||||
},
|
||||
onDrag(dx, dy, event) {
|
||||
if (selectionDragHandlers) {
|
||||
|
@ -155,9 +150,6 @@ function useDragKeyframe(node: HTMLDivElement | null, props: IProps) {
|
|||
return
|
||||
}
|
||||
const delta = toUnitSpace(dx)
|
||||
const original =
|
||||
propsAtStartOfDrag.trackData.keyframes[propsAtStartOfDrag.index]
|
||||
frameStampPositionLock.set(original.position + delta)
|
||||
|
||||
if (tempTransaction) {
|
||||
tempTransaction.discard()
|
||||
|
@ -177,7 +169,7 @@ function useDragKeyframe(node: HTMLDivElement | null, props: IProps) {
|
|||
})
|
||||
},
|
||||
onDragEnd(dragHappened) {
|
||||
frameStampPositionLock.unlock()
|
||||
setIsDragging(false)
|
||||
|
||||
if (selectionDragHandlers) {
|
||||
selectionDragHandlers.onDragEnd?.(dragHappened)
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import {usePrism} from '@theatre/dataverse-react'
|
||||
import type {Pointer} from '@theatre/dataverse'
|
||||
import {Box} from '@theatre/dataverse'
|
||||
import {val} from '@theatre/dataverse'
|
||||
import React, {useMemo, useRef} from 'react'
|
||||
import React, {useMemo, useRef, useState} from 'react'
|
||||
import styled from 'styled-components'
|
||||
import type {SequenceEditorPanelLayout} from '@theatre/studio/panels/SequenceEditorPanel/layout/layout'
|
||||
import {zIndexes} from '@theatre/studio/panels/SequenceEditorPanel/SequenceEditorPanel'
|
||||
|
@ -13,7 +12,10 @@ import useDrag from '@theatre/studio/uiComponents/useDrag'
|
|||
import getStudio from '@theatre/studio/getStudio'
|
||||
import type Sheet from '@theatre/core/sheets/Sheet'
|
||||
import usePopover from '@theatre/studio/uiComponents/Popover/usePopover'
|
||||
import {attributeNameThatLocksFramestamp} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
||||
import {
|
||||
attributeNameThatLocksFramestamp,
|
||||
useLockFrameStampPosition,
|
||||
} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
||||
|
||||
const coverWidth = 1000
|
||||
|
||||
|
@ -159,7 +161,9 @@ const LengthIndicator: React.FC<IProps> = ({layoutP}) => {
|
|||
function useDragBulge(node: HTMLDivElement | null, props: IProps) {
|
||||
const propsRef = useRef(props)
|
||||
propsRef.current = props
|
||||
const isDragging = useMemo(() => new Box(false), [])
|
||||
const [isDragging, setIsDragging] = useState(false)
|
||||
|
||||
useLockFrameStampPosition(isDragging, -1)
|
||||
|
||||
const gestureHandlers = useMemo<Parameters<typeof useDrag>[1]>(() => {
|
||||
let toUnitSpace: SequenceEditorPanelLayout['scaledSpace']['toUnitSpace']
|
||||
|
@ -171,12 +175,12 @@ function useDragBulge(node: HTMLDivElement | null, props: IProps) {
|
|||
return {
|
||||
lockCursorTo: 'ew-resize',
|
||||
onDragStart(event) {
|
||||
setIsDragging(true)
|
||||
propsAtStartOfDrag = propsRef.current
|
||||
sheet = val(propsRef.current.layoutP.sheet)
|
||||
initialLength = sheet.getSequence().length
|
||||
|
||||
toUnitSpace = val(propsAtStartOfDrag.layoutP.scaledSpace.toUnitSpace)
|
||||
isDragging.set(true)
|
||||
},
|
||||
onDrag(dx, dy, event) {
|
||||
const delta = toUnitSpace(dx)
|
||||
|
@ -192,7 +196,7 @@ function useDragBulge(node: HTMLDivElement | null, props: IProps) {
|
|||
})
|
||||
},
|
||||
onDragEnd(dragHappened) {
|
||||
isDragging.set(false)
|
||||
setIsDragging(false)
|
||||
if (dragHappened) {
|
||||
if (tempTransaction) {
|
||||
tempTransaction.commit()
|
||||
|
@ -209,7 +213,7 @@ function useDragBulge(node: HTMLDivElement | null, props: IProps) {
|
|||
|
||||
useDrag(node, gestureHandlers)
|
||||
|
||||
return [isDragging.derivation]
|
||||
return [isDragging]
|
||||
}
|
||||
|
||||
export default LengthIndicator
|
||||
|
|
|
@ -3,10 +3,17 @@ import {Atom, prism, val} from '@theatre/dataverse'
|
|||
import mousePositionD from '@theatre/studio/utils/mousePositionD'
|
||||
import type {$IntentionalAny} from '@theatre/shared/utils/types'
|
||||
import {inRange, last} from 'lodash-es'
|
||||
import React, {createContext, useCallback, useContext, useMemo} from 'react'
|
||||
import React, {
|
||||
createContext,
|
||||
useCallback,
|
||||
useContext,
|
||||
useLayoutEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
} from 'react'
|
||||
import type {SequenceEditorPanelLayout} from './layout/layout'
|
||||
|
||||
export type FrameStampPositionLock = {
|
||||
type FrameStampPositionLock = {
|
||||
unlock: () => void
|
||||
set: (pointerPositonInUnitSpace: number) => void
|
||||
}
|
||||
|
@ -93,7 +100,27 @@ const FrameStampPositionProvider: React.FC<{
|
|||
return <context.Provider value={value}>{children}</context.Provider>
|
||||
}
|
||||
|
||||
export const useFrameStampPosition = () => useContext(context)
|
||||
export const useFrameStampPositionD = () => useContext(context).currentD
|
||||
|
||||
export const useLockFrameStampPosition = (shouldLock: boolean, val: number) => {
|
||||
const {getLock} = useContext(context)
|
||||
const lockRef = useRef<undefined | ReturnType<typeof getLock>>()
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (!shouldLock) return
|
||||
lockRef.current = getLock()
|
||||
|
||||
return () => {
|
||||
lockRef.current!.unlock()
|
||||
}
|
||||
}, [shouldLock])
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (shouldLock) {
|
||||
lockRef.current!.set(val)
|
||||
}
|
||||
}, [val])
|
||||
}
|
||||
|
||||
/**
|
||||
* This attribute is used so that when the cursor hovers over a keyframe,
|
||||
|
@ -129,8 +156,6 @@ const pointerPositionInUnitSpace = (
|
|||
}
|
||||
}
|
||||
|
||||
// if (mousePos.composedPath())
|
||||
|
||||
const {clientX, clientY} = mousePos
|
||||
|
||||
const {screenX: x, screenY: y, width: rightWidth, height} = rightDims
|
||||
|
|
|
@ -6,13 +6,12 @@ import useDrag from '@theatre/studio/uiComponents/useDrag'
|
|||
import useRefAndState from '@theatre/studio/utils/useRefAndState'
|
||||
import type {VoidFn} from '@theatre/shared/utils/types'
|
||||
import {val} from '@theatre/dataverse'
|
||||
import React, {useMemo, useRef} from 'react'
|
||||
import React, {useMemo, useRef, useState} from 'react'
|
||||
import styled from 'styled-components'
|
||||
import type KeyframeEditor from './KeyframeEditor'
|
||||
import type {Keyframe} from '@theatre/core/projects/store/types/SheetState_Historic'
|
||||
import type {FrameStampPositionLock} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
||||
import {useLockFrameStampPosition} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
||||
import {attributeNameThatLocksFramestamp} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
||||
import {useFrameStampPosition} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
||||
|
||||
export const dotSize = 6
|
||||
|
||||
|
@ -80,7 +79,8 @@ const Dot: React.FC<IProps> = (props) => {
|
|||
export default Dot
|
||||
|
||||
function useDragKeyframe(node: SVGCircleElement | null, _props: IProps): void {
|
||||
const {getLock} = useFrameStampPosition()
|
||||
const [isDragging, setIsDragging] = useState(false)
|
||||
useLockFrameStampPosition(isDragging, _props.keyframe.position)
|
||||
const propsRef = useRef(_props)
|
||||
propsRef.current = _props
|
||||
|
||||
|
@ -92,11 +92,11 @@ function useDragKeyframe(node: SVGCircleElement | null, _props: IProps): void {
|
|||
let verticalToExtremumSpace: SequenceEditorPanelLayout['graphEditorVerticalSpace']['toExtremumSpace']
|
||||
let unlockExtremums: VoidFn | undefined
|
||||
let keepSpeeds = false
|
||||
let frameStampPositionLock: FrameStampPositionLock
|
||||
|
||||
return {
|
||||
lockCursorTo: 'move',
|
||||
onDragStart(event) {
|
||||
setIsDragging(true)
|
||||
keepSpeeds = !!event.altKey
|
||||
|
||||
propsAtStartOfDrag = propsRef.current
|
||||
|
@ -106,8 +106,6 @@ function useDragKeyframe(node: SVGCircleElement | null, _props: IProps): void {
|
|||
propsAtStartOfDrag.layoutP.graphEditorVerticalSpace.toExtremumSpace,
|
||||
)
|
||||
unlockExtremums = propsAtStartOfDrag.extremumSpace.lock()
|
||||
frameStampPositionLock = getLock()
|
||||
frameStampPositionLock.set(propsAtStartOfDrag.keyframe.position)
|
||||
},
|
||||
onDrag(dx, dy) {
|
||||
const original =
|
||||
|
@ -128,7 +126,6 @@ function useDragKeyframe(node: SVGCircleElement | null, _props: IProps): void {
|
|||
value: original.value + dYInValueSpace,
|
||||
handles: [...original.handles],
|
||||
}
|
||||
frameStampPositionLock.set(cur.position)
|
||||
updatedKeyframes.push(cur)
|
||||
|
||||
if (keepSpeeds) {
|
||||
|
@ -189,7 +186,7 @@ function useDragKeyframe(node: SVGCircleElement | null, _props: IProps): void {
|
|||
})
|
||||
},
|
||||
onDragEnd(dragHappened) {
|
||||
frameStampPositionLock.unlock()
|
||||
setIsDragging(false)
|
||||
if (unlockExtremums) {
|
||||
const unlock = unlockExtremums
|
||||
unlockExtremums = undefined
|
||||
|
|
|
@ -7,7 +7,7 @@ import styled from 'styled-components'
|
|||
import {stampsGridTheme} from '@theatre/studio/panels/SequenceEditorPanel/FrameGrid/StampsGrid'
|
||||
import {zIndexes} from '@theatre/studio/panels/SequenceEditorPanel/SequenceEditorPanel'
|
||||
import {topStripTheme} from './TopStrip'
|
||||
import {useFrameStampPosition} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
||||
import {useFrameStampPositionD} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
||||
|
||||
const Label = styled.div`
|
||||
position: absolute;
|
||||
|
@ -36,7 +36,7 @@ const Line = styled.div`
|
|||
const FrameStamp: React.FC<{
|
||||
layoutP: Pointer<SequenceEditorPanelLayout>
|
||||
}> = React.memo(({layoutP}) => {
|
||||
const posInUnitSpace = useVal(useFrameStampPosition().currentD)
|
||||
const posInUnitSpace = useVal(useFrameStampPositionD())
|
||||
const unitSpaceToClippedSpace = useVal(layoutP.clippedSpace.fromUnitSpace)
|
||||
const {sequence, formatter, clippedSpaceWidth} = usePrism(() => {
|
||||
const sequence = val(layoutP.sheet).getSequence()
|
||||
|
|
Loading…
Reference in a new issue