diff options
-rw-r--r-- | components/selection.tsx | 2 | ||||
-rw-r--r-- | pages/editor.tsx | 38 | ||||
-rw-r--r-- | styles/editor.css | 4 |
3 files changed, 41 insertions, 3 deletions
diff --git a/components/selection.tsx b/components/selection.tsx index 4a0812f..d1753f0 100644 --- a/components/selection.tsx +++ b/components/selection.tsx @@ -68,7 +68,7 @@ export default function Selection(props: { left?: slideTypes; right?: slideTypes; }) { - var small = props.width < 24 || props.height < 24; + var small = props.width < 24 || props.height < 24 || !props.left || !props.right; return <div className='selection' style={{ diff --git a/pages/editor.tsx b/pages/editor.tsx index 89d3887..8b9fef3 100644 --- a/pages/editor.tsx +++ b/pages/editor.tsx @@ -23,6 +23,7 @@ import SkipPreviousRoundedIcon from '@material-ui/icons/SkipPreviousRounded'; import { mdiCursorDefault } from '@mdi/js'; import { PressureIcon, SlideKeyframe } from '../components/icons'; import PlaySkipIconAni from '../components/play-skip'; +import Selection from '../components/selection'; var keyframeInAnimations: { [key: string]: { x: number; y: number; }; } = {}; @@ -334,6 +335,31 @@ function TimelineEditor(props: { }); }, []); + var [selectionPosX, setSelectionPosX] = useState(0); + var [selectionPosY, setSelectionPosY] = useState(0); + var [selectionWidth, setSelectionWidth] = useState(0); + var [selectionHeight, setSelectionHeight] = useState(0); + + var selectionRef = useRef(null); + useDrag(({ xy: [x, y], initial: [bx, by] }) => { + if (props.selectedTool != 'cursor') return; + // var frame = Math.max(0, Math.round(getFrameAtOffset(x - 240, timelineZoom)) - 1); + var timelineInner = document.querySelector('.timeline .timelineInner'); + var timelineRects = timelineInner.getBoundingClientRect(); + var tx = x - timelineRects.x + timelineInner.scrollLeft; + var ty = y - timelineRects.y; + var ix = bx - timelineRects.x + timelineInner.scrollLeft; + var iy = by - timelineRects.y; + + var sx = tx - ix; + var sy = ty - iy; + + setSelectionPosX(ix + Math.min(0, sx)); + setSelectionPosY(iy + Math.min(0, sy)); + setSelectionWidth(Math.abs(sx)); + setSelectionHeight(Math.abs(sy)); + }, { domTarget: selectionRef, eventOptions: { passive: false } }); + return <> <canvas className='timeScale posabs a0' @@ -376,8 +402,16 @@ function TimelineEditor(props: { <div className='keyframes' style={{ '--total-frames': props.player?.timeline?.framecount.toString() } as CSSProperties} - children={workingTimeline.map((slide: anySlide) => <TimelineKeyframe slide={slide} />)} - /> + > + <div className='selectionarea posabs v0' ref={selectionRef} /> + {workingTimeline.map((slide: anySlide) => <TimelineKeyframe slide={slide} />)} + <div + id='selection' + className='posabs dispinbl' + style={{ left: selectionPosX - 6, top: selectionPosY - 6 }} + children={<Selection width={selectionWidth + 12} height={selectionHeight + 12} />} + /> + </div> </div> <div className={'ghostArea posabs a0' + (props.selectedTool != 'cursor' ? ' active' : '')}> <animated.div diff --git a/styles/editor.css b/styles/editor.css index a333a56..fc56488 100644 --- a/styles/editor.css +++ b/styles/editor.css @@ -169,6 +169,10 @@ width: calc(var(--zoom) * var(--total-frames) * 1px); } +.appGrid .timeline .keyframes .selectionarea { + width: calc(var(--zoom) * var(--total-frames) * 1px); +} + .appGrid .timeline .ghostArea { pointer-events: none; line-height: 0; |