diff options
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | pages/editor.tsx | 34 | ||||
-rw-r--r-- | yarn.lock | 5 |
3 files changed, 36 insertions, 4 deletions
diff --git a/package.json b/package.json index 9ece09e..ea90dc2 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "@material-ui/lab": "^4.0.0-alpha.58", "@mdi/js": "^5.9.55", "@mdi/react": "^1.5.0", + "@types/mousetrap": "^1.6.8", "@types/uuid": "^8.3.0", "ajv": "^8.3.0", "mousetrap": "^1.6.5", diff --git a/pages/editor.tsx b/pages/editor.tsx index 0da9a0d..a1960a8 100644 --- a/pages/editor.tsx +++ b/pages/editor.tsx @@ -1,7 +1,12 @@ +import mousetrap from 'mousetrap'; import { CSSProperties, ReactNode, useEffect, useRef, useState } from 'react'; import { animated, useSpring } from 'react-spring'; import { useDrag } from 'react-use-gesture'; import create from 'zustand'; + +import { PressureIcon, SlideKeyframe } from '../components/icons'; +import PlaySkipIconAni from '../components/play-skip'; +import Selection from '../components/selection'; import { anySlide, loopBeginSlide, loopSlide, slide, slideTypes, toolToSlide } from '../timeline'; import { TimedVideoPlayer } from './present'; @@ -21,9 +26,6 @@ import NavigateBeforeRoundedIcon from '@material-ui/icons/NavigateBeforeRounded' import NavigateNextRoundedIcon from '@material-ui/icons/NavigateNextRounded'; 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; }; } = {}; var slideAPIs: { [key: string]: any; }[] = []; @@ -34,7 +36,8 @@ var useWorkingTimeline = create((set, get) => ({ setTimeline: (newTimeline: anySlide[]) => set(() => ({ timeline: newTimeline })), refreshLiveTimeline: () => { player.timeline.slides = Array(...((get() as any).timeline)); - player.timeline.slides.sort((a: anySlide, b: anySlide) => a.frame - b.frame); + player.timeline.slides = player.timeline.slides.filter(slide => slide != null); + player.timeline.slides.sort((a, b) => a.frame - b.frame); player.timeline.slides[-1] = { // TODO: dry id: '00000000-0000-0000-0000-000000000000', frame: 0, @@ -497,6 +500,29 @@ function TimelineEditor(props: { } }, { domTarget: selectionAreaRef, eventOptions: { passive: false } }); + useEffect(() => { + var delkeys = ['del', 'backspace']; + mousetrap.bind(delkeys, () => { + if (!selectionPlaced) return; + + selection.forEach((slide: anySlide) => { + if (!slideTypes.includes(slide.type)) return; + var index = workingTimeline.findIndex((s: anySlide) => s?.id == slide.id); + if (index == -1) return; + delete workingTimeline[index]; + }); + refreshWorkingTimline(); + + setSelectionPlaced(false); + setSelectionHidden(true); + setSelection([]); + }); + + return () => { + mousetrap.unbind(delkeys); + }; + }, [selectionPlaced, workingTimeline]); + return <> <canvas className='timeScale posabs a0' @@ -292,6 +292,11 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== +"@types/mousetrap@^1.6.8": + version "1.6.8" + resolved "https://registry.yarnpkg.com/@types/mousetrap/-/mousetrap-1.6.8.tgz#448929e6dc21126392830465fdb9d4a2cfc16a88" + integrity sha512-zTqjvgCUT5EoXqbqmd8iJMb4NJqyV/V7pK7AIKq7qcaAsJIpGlTVJS1HQM6YkdHCdnkNSbhcQI7MXYxFfE3iCA== + "@types/node@*": version "15.6.0" resolved "https://registry.yarnpkg.com/@types/node/-/node-15.6.0.tgz#f0ddca5a61e52627c9dcb771a6039d44694597bc" |