diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2020-10-14 16:49:07 +0200 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2020-10-14 16:49:07 +0200 |
| commit | 6373c1321cb680de9e354e1e03a11394e532254d (patch) | |
| tree | 657244b24b544c7d64f3d3a71e557ffcd11d9451 | |
| parent | 38fd1460b6de1a72b1345c5f23ea688c54f14689 (diff) | |
select a region
7 files changed, 90 insertions, 9 deletions
diff --git a/animism-align/frontend/app/utils/index.js b/animism-align/frontend/app/utils/index.js index ac4b83b..6777a5e 100644 --- a/animism-align/frontend/app/utils/index.js +++ b/animism-align/frontend/app/utils/index.js @@ -61,7 +61,7 @@ export const timestamp = (n = 0, fps = 1, ms = false, h_label = ':', m_label = ' let s = '' n /= fps if (ms) { - const mantissa = Math.round((n % 1) * 10) + const mantissa = Math.floor((n % 1) * 10) s = '.' + mantissa } n = Math.floor(n) diff --git a/animism-align/frontend/app/views/align/align.actions.js b/animism-align/frontend/app/views/align/align.actions.js index 524de07..0766460 100644 --- a/animism-align/frontend/app/views/align/align.actions.js +++ b/animism-align/frontend/app/views/align/align.actions.js @@ -25,6 +25,12 @@ export const throttledSetZoom = throttle(zoom => dispatch => { export const setCursor = cursor_ts => dispatch => ( dispatch({ type: types.align.set_display_setting, key: 'cursor_ts', value: cursor_ts }) ) +export const setCursorRegion = (a_ts, b_ts) => dispatch => ( + dispatch({ type: types.align.set_display_setting, key: 'cursor_region', value: { a_ts, b_ts } }) +) +export const clearCursorRegion = () => dispatch => ( + dispatch({ type: types.align.set_display_setting, key: 'cursor_region', value: null }) +) export const setSelectedAnnotation = annotation => dispatch => { debouncedUpdateAnnotation.flush() diff --git a/animism-align/frontend/app/views/align/align.css b/animism-align/frontend/app/views/align/align.css index 15ff840..acb65d2 100644 --- a/animism-align/frontend/app/views/align/align.css +++ b/animism-align/frontend/app/views/align/align.css @@ -74,6 +74,21 @@ canvas { margin-top: -7px; text-align: right; text-shadow: 0 0 2px #000, 0 0 2px #000, 0 0 2px #000; + user-select: none; +} +.timeline .cursor_region { + position: absolute; + left: 0; + width: 100%; + border-top: 1px solid #33f; + border-bottom: 1px solid #33f; + background: rgba(32,64,255,0.2); +} +.timeline .cursor_region .tickLabel { + position: absolute; + top: 2px; + left: 6px; + user-select: none; } /* Audio player */ diff --git a/animism-align/frontend/app/views/align/align.reducer.js b/animism-align/frontend/app/views/align/align.reducer.js index 50498c5..dec27a4 100644 --- a/animism-align/frontend/app/views/align/align.reducer.js +++ b/animism-align/frontend/app/views/align/align.reducer.js @@ -4,6 +4,7 @@ import { session, getDefault, getDefaultInt } from 'app/session' const initialState = { timeline: { cursor_ts: -1, + cursor_region: null, start_ts: 0, zoom: 1, duration: 0, diff --git a/animism-align/frontend/app/views/align/components/timeline/cursorRegion.component.js b/animism-align/frontend/app/views/align/components/timeline/cursorRegion.component.js new file mode 100644 index 0000000..cce2001 --- /dev/null +++ b/animism-align/frontend/app/views/align/components/timeline/cursorRegion.component.js @@ -0,0 +1,28 @@ +import React, { Component } from 'react' + +import { ZOOM_STEPS } from 'app/constants' +import { timestamp } from 'app/utils' + +const CursorRegion = ({ timeline }) => { + const { start_ts, zoom, cursor_region } = timeline + if (!cursor_region) return null + const secondsPerPixel = ZOOM_STEPS[zoom] * 0.1 + const duration = cursor_region.b_ts - cursor_region.a_ts + const y = (cursor_region.a_ts - start_ts) / secondsPerPixel + const height = (duration) / secondsPerPixel + return ( + <div + className='cursor_region' + style={{ + top: y, + height, + }} + > + <div className='tickLabel'> + {timestamp(duration, 1, true)} + </div> + </div> + ) +} + +export default CursorRegion
\ No newline at end of file diff --git a/animism-align/frontend/app/views/align/components/timeline/waveform.component.js b/animism-align/frontend/app/views/align/components/timeline/waveform.component.js index 023b877..59a2c13 100644 --- a/animism-align/frontend/app/views/align/components/timeline/waveform.component.js +++ b/animism-align/frontend/app/views/align/components/timeline/waveform.component.js @@ -84,7 +84,11 @@ class Waveform extends Component { } render() { return ( - <canvas ref={this.canvasRef} onClick={this.props.onClick} /> + <canvas + ref={this.canvasRef} + onMouseDown={this.props.onMouseDown} + onMouseUp={this.props.onMouseUp} + /> ) } } diff --git a/animism-align/frontend/app/views/align/containers/timeline.container.js b/animism-align/frontend/app/views/align/containers/timeline.container.js index 3db658c..0cf49f8 100644 --- a/animism-align/frontend/app/views/align/containers/timeline.container.js +++ b/animism-align/frontend/app/views/align/containers/timeline.container.js @@ -9,19 +9,25 @@ import Waveform from 'app/views/align/components/timeline/waveform.component' import Ticks from 'app/views/align/components/timeline/ticks.component' import Cursor from 'app/views/align/components/timeline/cursor.component' import PlayCursor from 'app/views/align/components/timeline/playCursor.component' +import CursorRegion from 'app/views/align/components/timeline/cursorRegion.component' import { WAVEFORM_SIZE, ZOOM_STEPS, INNER_HEIGHT } from 'app/constants' import { clamp } from 'app/utils' import { positionToTime } from 'app/utils/align.utils' class Timeline extends Component { + state = { + dragging: false, + a_ts: -1, + } constructor(props){ super(props) this.handleKeydown = this.handleKeydown.bind(this) this.handleMouseMove = this.handleMouseMove.bind(this) this.handleWheel = this.handleWheel.bind(this) this.handleContainerClick = this.handleContainerClick.bind(this) - this.handleTimelineClick = this.handleTimelineClick.bind(this) + this.handleTimelineMouseDown = this.handleTimelineMouseDown.bind(this) + this.handleTimelineMouseUp = this.handleTimelineMouseUp.bind(this) } componentDidMount() { this.bind() @@ -117,15 +123,32 @@ class Timeline extends Component { actions.align.setScrollPosition(start_ts) } } - handleMouseMove(e) { - const cursor_ts = positionToTime(e.pageY, this.props.timeline) - actions.align.setCursor(cursor_ts) - } handleContainerClick(e) { actions.align.clearSelectedAnnotation() actions.align.clearSelectedParagraph() } - handleTimelineClick(e) { + handleTimelineMouseDown(e) { + const cursor_ts = positionToTime(e.pageY, this.props.timeline) + actions.align.clearCursorRegion() + actions.align.setCursor(cursor_ts) + this.setState({ + dragging: true, + a_ts: cursor_ts, + }) + } + handleMouseMove(e) { + const cursor_ts = positionToTime(e.pageY, this.props.timeline) + if (this.state.dragging) { + actions.align.setCursorRegion( + Math.min(this.state.a_ts, cursor_ts), + Math.max(this.state.a_ts, cursor_ts), + ) + } else { + actions.align.setCursor(cursor_ts) + } + } + handleTimelineMouseUp(e) { + this.setState({ dragging: false }) const play_ts = positionToTime(e.pageY, this.props.timeline) if (e.metaKey) { actions.align.spliceTime(play_ts) @@ -144,9 +167,13 @@ class Timeline extends Component { onMouseMove={this.handleMouseMove} > <div className='timelineColumn'> - <Waveform onClick={this.handleTimelineClick} /> + <Waveform + onMouseDown={this.handleTimelineMouseDown} + onMouseUp={this.handleTimelineMouseUp} + /> <Ticks timeline={this.props.timeline} /> <Cursor timeline={this.props.timeline} annotation={this.props.annotation} /> + <CursorRegion timeline={this.props.timeline} /> </div> <Annotations timeline={this.props.timeline} /> <PlayCursor /> |
