Commit 9a0b7b6a by Jonathan Thomas

Improving clip selection, allowing clip selection dragging, improving style of Add Clip button

parent 83573e2f
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
<!-- Timeline w/ Clip Trimming --> <!-- Timeline w/ Clip Trimming -->
<div class="col-sm-10 d-flex flex-column p-1"> <div class="col-sm-10 d-flex flex-column p-1">
<div class="timeline" ref="timeline" @mousedown="seekToCursor($event)" @mousemove="drag($event)" @touchmove="drag($event)" @mouseup="endDrag" @touchend="endDrag" @mouseleave="endDrag"> <div class="timeline" ref="timeline" @mousedown="seekToCursor($event)" @mousemove="drag($event)" @touchmove="drag($event)" @mouseup="endDrag" @touchend="endDrag">
<div title="Drag Playback Position" ref="playhead" class="playhead" @mousedown="startDrag($event, 'playhead')" @touchstart="startDrag($event, 'playhead')" :style="{left: preview.position * 100.0 + '%'}"></div> <div title="Drag Playback Position" ref="playhead" class="playhead" @mousedown="startDrag($event, 'playhead')" @touchstart="startDrag($event, 'playhead')" :style="{left: preview.position * 100.0 + '%'}"></div>
<div title="Drag to Trim Start" ref="start" class="marker marker_left" @click="seekToMarker('start')" @mousedown="startDrag($event, 'start')" @touchstart="startDrag($event, 'start')" :style="{left: preview.start * 100.0 + '%'}"> <div title="Drag to Trim Start" ref="start" class="marker marker_left" @click="seekToMarker('start')" @mousedown="startDrag($event, 'start')" @touchstart="startDrag($event, 'start')" :style="{left: preview.start * 100.0 + '%'}">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="48" fill="currentColor" class="bi bi-grip-vertical" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="48" fill="currentColor" class="bi bi-grip-vertical" viewBox="0 0 16 16">
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
<path d="M7 2a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0zM7 5a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0zM7 8a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm-3 3a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm-3 3a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/> <path d="M7 2a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0zM7 5a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0zM7 8a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm-3 3a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm-3 3a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/>
</svg> </svg>
</div> </div>
<div ref="clip" class="clip" :class="clipSizeClass" :style="{left: preview.start * 100.0 + '%', width: `calc(${(preview.end - preview.start) * 100.0}%)`}"> <div ref="clip" class="clip" :class="clipSizeClass" :style="{left: preview.start * 100.0 + '%', width: `calc(${(preview.end - preview.start) * 100.0}%)`}" @mousedown="startDrag($event, 'clip')" @touchstart="startDrag($event, 'clip')">
{{ preview.length.toFixed(1) }} Seconds {{ preview.length.toFixed(1) }} Seconds
</div> </div>
</div> </div>
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
<!-- Add Clip button --> <!-- Add Clip button -->
<div class="col-sm-1 d-flex flex-column p-1"> <div class="col-sm-1 d-flex flex-column p-1">
<button title="Add Clip" type="button" class="btn btn-secondary timeline-btn" @click="createClipBtn"> <button title="Add Clip" type="button" class="btn btn-primary timeline-btn" @click="createClipBtn">
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-plus" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-plus" viewBox="0 0 16 16">
<path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"/> <path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"/>
</svg> </svg>
...@@ -95,6 +95,9 @@ export default { ...@@ -95,6 +95,9 @@ export default {
data() { data() {
return { return {
dragging_marker: null, dragging_marker: null,
clipDragOffset: 0,
windowDragHandler: null,
windowEndHandler: null,
is_paused: true, is_paused: true,
marker_width: 12, marker_width: 12,
marker_width_percent: 0.0, marker_width_percent: 0.0,
...@@ -206,10 +209,23 @@ export default { ...@@ -206,10 +209,23 @@ export default {
if (this.$refs.video) { if (this.$refs.video) {
this.$refs.video.pause() this.$refs.video.pause()
} }
if (marker == 'clip') {
let percent_x = this.getCursorPosition(e)
let clip_length = this.preview.end - this.preview.start
this.clipDragOffset = percent_x - this.preview.start
if (!isFinite(this.clipDragOffset)) {
this.clipDragOffset = 0
} else {
this.clipDragOffset = Math.max(0, Math.min(clip_length, this.clipDragOffset))
}
}
this.dragging_marker = marker this.dragging_marker = marker
this.attachGlobalDragListeners()
}, },
endDrag() { endDrag() {
this.dragging_marker = null this.dragging_marker = null
this.clipDragOffset = 0
this.detachGlobalDragListeners()
}, },
seekToCursor(e) { seekToCursor(e) {
if (!this.dragging_marker) { if (!this.dragging_marker) {
...@@ -249,6 +265,19 @@ export default { ...@@ -249,6 +265,19 @@ export default {
if (this.$refs.video && isFinite(this.preview.start * this.$refs.video.duration)) { if (this.$refs.video && isFinite(this.preview.start * this.$refs.video.duration)) {
this.$refs.video.currentTime = percent_x * this.$refs.video.duration this.$refs.video.currentTime = percent_x * this.$refs.video.duration
} }
} else if (this.dragging_marker == 'clip') {
let percent_x = this.getCursorPosition(e)
let clip_length = this.preview.end - this.preview.start
let new_start = percent_x - this.clipDragOffset
if (!isFinite(new_start)) {
new_start = 0
}
new_start = Math.max(0, Math.min(1 - clip_length, new_start))
let new_end = new_start + clip_length
this.setPreview({start: new_start, end: new_end})
if (this.$refs.video && isFinite(new_start * this.$refs.video.duration)) {
this.$refs.video.currentTime = new_start * this.$refs.video.duration
}
} }
}, },
getMarkerWidth() { getMarkerWidth() {
...@@ -282,6 +311,30 @@ export default { ...@@ -282,6 +311,30 @@ export default {
let percent_x = (relative_x / timeline_bounds.width) let percent_x = (relative_x / timeline_bounds.width)
return percent_x return percent_x
}, },
attachGlobalDragListeners() {
if (!this.windowDragHandler) {
this.windowDragHandler = (event) => this.drag(event)
}
if (!this.windowEndHandler) {
this.windowEndHandler = () => this.endDrag()
}
window.addEventListener('mousemove', this.windowDragHandler)
window.addEventListener('touchmove', this.windowDragHandler)
window.addEventListener('mouseup', this.windowEndHandler)
window.addEventListener('touchend', this.windowEndHandler)
window.addEventListener('touchcancel', this.windowEndHandler)
},
detachGlobalDragListeners() {
if (this.windowDragHandler) {
window.removeEventListener('mousemove', this.windowDragHandler)
window.removeEventListener('touchmove', this.windowDragHandler)
}
if (this.windowEndHandler) {
window.removeEventListener('mouseup', this.windowEndHandler)
window.removeEventListener('touchend', this.windowEndHandler)
window.removeEventListener('touchcancel', this.windowEndHandler)
}
},
...mapActions(['createClip', 'editClip', 'moveClip']), ...mapActions(['createClip', 'editClip', 'moveClip']),
...mapMutations(['setPreview', 'setPreviewPosition', 'setPreviewFile']) ...mapMutations(['setPreview', 'setPreviewPosition', 'setPreviewFile'])
}, },
...@@ -327,6 +380,9 @@ export default { ...@@ -327,6 +380,9 @@ export default {
}, },
updated() { updated() {
this.marker_width_percent = this.getMarkerWidth() this.marker_width_percent = this.getMarkerWidth()
},
beforeUnmount() {
this.detachGlobalDragListeners()
} }
} }
</script> </script>
...@@ -362,6 +418,11 @@ video { ...@@ -362,6 +418,11 @@ video {
font-size: 0.7em; font-size: 0.7em;
text-align: center; text-align: center;
padding-top: 15px; padding-top: 15px;
cursor: grab;
user-select: none;
}
.clip:active {
cursor: grabbing;
} }
.clip-too-small { .clip-too-small {
color: #0d6efd!important; color: #0d6efd!important;
...@@ -398,4 +459,4 @@ video { ...@@ -398,4 +459,4 @@ video {
.spinner-container { .spinner-container {
min-height: 300px; min-height: 300px;
} }
</style> </style>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment