Cleaner API for useFrameStampPosition()

This commit is contained in:
Aria Minaei 2021-08-01 18:09:07 +02:00
parent 0a3c699180
commit 74b6f93872
5 changed files with 56 additions and 38 deletions

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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()