More player controls
This commit is contained in:
parent
f7e9fd99fc
commit
8be08ce9d6
1 changed files with 92 additions and 26 deletions
|
@ -144,7 +144,7 @@ class Annotator extends EventTarget {
|
||||||
ms += v * factor;
|
ms += v * factor;
|
||||||
factor *= 60;
|
factor *= 60;
|
||||||
});
|
});
|
||||||
return `${ ms } `;
|
return `${ms} `;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -153,6 +153,7 @@ class Annotator extends EventTarget {
|
||||||
this.svgEl = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
this.svgEl = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||||
this.wrapperEl.appendChild(this.svgEl);
|
this.wrapperEl.appendChild(this.svgEl);
|
||||||
this.wrapperEl.classList.add(this.config.is_player ? "svganim_player" : "svganim_annotator");
|
this.wrapperEl.classList.add(this.config.is_player ? "svganim_player" : "svganim_annotator");
|
||||||
|
this.wrapperEl.classList.add(this.config.crop_to_fit ? "cropped-to-selection" : "follow-drawing");
|
||||||
|
|
||||||
|
|
||||||
this.controlsEl = document.createElement('div');
|
this.controlsEl = document.createElement('div');
|
||||||
|
@ -193,7 +194,7 @@ class Annotator extends EventTarget {
|
||||||
ev.preventDefault(); // we don't want to spacebar, as this is captured in the overall keydown event
|
ev.preventDefault(); // we don't want to spacebar, as this is captured in the overall keydown event
|
||||||
})
|
})
|
||||||
|
|
||||||
if(!this.config.is_player){
|
if (!this.config.is_player) {
|
||||||
this.scrubberEl = document.createElement('div');
|
this.scrubberEl = document.createElement('div');
|
||||||
this.scrubberEl.classList.add('scrubber')
|
this.scrubberEl.classList.add('scrubber')
|
||||||
this.controlsEl.appendChild(this.scrubberEl);
|
this.controlsEl.appendChild(this.scrubberEl);
|
||||||
|
@ -202,6 +203,31 @@ class Annotator extends EventTarget {
|
||||||
this.annotationsEl = document.createElement('div');
|
this.annotationsEl = document.createElement('div');
|
||||||
this.annotationsEl.classList.add('annotations')
|
this.annotationsEl.classList.add('annotations')
|
||||||
this.controlsEl.appendChild(this.annotationsEl);
|
this.controlsEl.appendChild(this.annotationsEl);
|
||||||
|
} else {
|
||||||
|
const extraEl = document.createElement('details');
|
||||||
|
extraEl.classList.add('controls--extra');
|
||||||
|
|
||||||
|
const summaryEl = document.createElement('summary');
|
||||||
|
summaryEl.innerHTML = "…";
|
||||||
|
extraEl.appendChild(summaryEl);
|
||||||
|
|
||||||
|
const extraControlsEl = document.createElement('ul');
|
||||||
|
|
||||||
|
// TODO: add handlers
|
||||||
|
const toggleFutureEl = document.createElement('li');
|
||||||
|
toggleFutureEl.innerText = "Show preview"
|
||||||
|
toggleFutureEl.addEventListener('click', () => this.wrapperEl.classList.toggle('hide-drawing-preview'));
|
||||||
|
extraControlsEl.appendChild(toggleFutureEl);
|
||||||
|
|
||||||
|
const toggleCropPlayerEl = document.createElement('li');
|
||||||
|
toggleCropPlayerEl.innerText = "Crop to selection";
|
||||||
|
toggleCropPlayerEl.addEventListener('click', () => this.toggleCrop());
|
||||||
|
extraControlsEl.appendChild(toggleCropPlayerEl);
|
||||||
|
|
||||||
|
extraEl.appendChild(extraControlsEl);
|
||||||
|
|
||||||
|
this.playbackControlsEl.appendChild(extraEl);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -340,7 +366,7 @@ class Annotator extends EventTarget {
|
||||||
if (this.selectedAnnotationI == annotation_i) {
|
if (this.selectedAnnotationI == annotation_i) {
|
||||||
this.annotationEl.classList.add('selected');
|
this.annotationEl.classList.add('selected');
|
||||||
}
|
}
|
||||||
this.annotationEl.title = `[${ annotation.tag }] ${ annotation.comment } `;
|
this.annotationEl.title = `[${annotation.tag}] ${annotation.comment} `;
|
||||||
|
|
||||||
this.annotationEl.addEventListener('mouseover', (e) => {
|
this.annotationEl.addEventListener('mouseover', (e) => {
|
||||||
|
|
||||||
|
@ -426,7 +452,7 @@ class Annotator extends EventTarget {
|
||||||
// draw full stroke of annotation
|
// draw full stroke of annotation
|
||||||
console.debug('setInOut');
|
console.debug('setInOut');
|
||||||
this.drawStrokePosition(this.inPointPosition, this.outPointPosition);
|
this.drawStrokePosition(this.inPointPosition, this.outPointPosition);
|
||||||
console.debug([`${ this.inPointTimeMs } `, `${ this.outPointTimeMs } `])
|
console.debug([`${this.inPointTimeMs} `, `${this.outPointTimeMs} `])
|
||||||
this.slider.set([this.inPointTimeMs, this.outPointTimeMs]);
|
this.slider.set([this.inPointTimeMs, this.outPointTimeMs]);
|
||||||
|
|
||||||
// console.debug(this.selectedAnnotation);
|
// console.debug(this.selectedAnnotation);
|
||||||
|
@ -461,7 +487,7 @@ class Annotator extends EventTarget {
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (!this.config.is_player) {
|
if (!this.config.is_player) {
|
||||||
|
|
||||||
const metadata_req = new Request(`/ annotations / ${ data.file } `, {
|
const metadata_req = new Request(`/ annotations / ${data.file} `, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
});
|
});
|
||||||
return fetch(metadata_req)
|
return fetch(metadata_req)
|
||||||
|
@ -479,7 +505,7 @@ class Annotator extends EventTarget {
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// play on click for player
|
// play on click for player
|
||||||
if(this.config.is_player) {
|
if (this.config.is_player) {
|
||||||
this.svgEl.addEventListener('click', (ev) => {
|
this.svgEl.addEventListener('click', (ev) => {
|
||||||
console.debug('clicked for play/pause');
|
console.debug('clicked for play/pause');
|
||||||
this.playPause();
|
this.playPause();
|
||||||
|
@ -487,9 +513,9 @@ class Annotator extends EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
// autoplay if necessary
|
// autoplay if necessary
|
||||||
if(this.config.autoplay){
|
if (this.config.autoplay) {
|
||||||
this.play(); // play should remove loading
|
this.play(); // play should remove loading
|
||||||
} else{
|
} else {
|
||||||
this.wrapperEl.classList.remove('loading');
|
this.wrapperEl.classList.remove('loading');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -846,7 +872,7 @@ class Annotator extends EventTarget {
|
||||||
titleEl.title = this.title ?? "[click to add title for this diagram]"
|
titleEl.title = this.title ?? "[click to add title for this diagram]"
|
||||||
titleEl.addEventListener('click', (ev) => {
|
titleEl.addEventListener('click', (ev) => {
|
||||||
const title = prompt("Change the title for the drawing", this.title ?? "");
|
const title = prompt("Change the title for the drawing", this.title ?? "");
|
||||||
if(title === null) return; //cancel
|
if (title === null) return; //cancel
|
||||||
titleEl.innerText = title.length ? title : "[add title]";
|
titleEl.innerText = title.length ? title : "[add title]";
|
||||||
this.title = title.length ? title : null;
|
this.title = title.length ? title : null;
|
||||||
this.updateState();
|
this.updateState();
|
||||||
|
@ -987,7 +1013,7 @@ class Annotator extends EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
getFinalFrameTime() {
|
getFinalFrameTime() {
|
||||||
if(this.strokes.length == 0) return null; // when no strokes are loaded (eg. for annotation)
|
if (this.strokes.length == 0) return null; // when no strokes are loaded (eg. for annotation)
|
||||||
const points = this.strokes[this.strokes.length - 1].points;
|
const points = this.strokes[this.strokes.length - 1].points;
|
||||||
return points[points.length - 1][3];
|
return points[points.length - 1][3];
|
||||||
}
|
}
|
||||||
|
@ -1073,10 +1099,10 @@ class Annotator extends EventTarget {
|
||||||
|
|
||||||
updateViewbox() {
|
updateViewbox() {
|
||||||
if (this.config.crop_to_fit) {
|
if (this.config.crop_to_fit) {
|
||||||
this.svgEl.setAttribute('viewBox', `${ this.bounding_box.x } ${ this.bounding_box.y } ${ this.bounding_box.width } ${ this.bounding_box.height } `);
|
this.svgEl.setAttribute('viewBox', `${this.bounding_box.x} ${this.bounding_box.y} ${this.bounding_box.width} ${this.bounding_box.height} `);
|
||||||
} else {
|
} else {
|
||||||
let x,y,w,h;
|
let x, y, w, h;
|
||||||
if(this.currentViewboxI !== null) {
|
if (this.currentViewboxI !== null) {
|
||||||
x = this.viewboxes[this.currentViewboxI].x,
|
x = this.viewboxes[this.currentViewboxI].x,
|
||||||
y = this.viewboxes[this.currentViewboxI].y,
|
y = this.viewboxes[this.currentViewboxI].y,
|
||||||
w = this.dimensions[0],
|
w = this.dimensions[0],
|
||||||
|
@ -1087,16 +1113,21 @@ class Annotator extends EventTarget {
|
||||||
w = this.dimensions[0],
|
w = this.dimensions[0],
|
||||||
h = this.dimensions[1];
|
h = this.dimensions[1];
|
||||||
}
|
}
|
||||||
this.svgEl.setAttribute('viewBox', `${ x } ${ y } ${ w } ${ h } `);
|
this.svgEl.setAttribute('viewBox', `${x} ${y} ${w} ${h} `);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setCrop(crop_to_fit) {
|
setCrop(crop_to_fit) {
|
||||||
this.config.crop_to_fit = Boolean(crop_to_fit);
|
this.config.crop_to_fit = Boolean(crop_to_fit);
|
||||||
|
if (this.config.crop_to_fit) {
|
||||||
|
this.wrapperEl.classList.add('cropped-to-selection');
|
||||||
|
} else {
|
||||||
|
this.wrapperEl.classList.remove('cropped-to-selection');
|
||||||
|
}
|
||||||
this.updateViewbox();
|
this.updateViewbox();
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleCrop(){
|
toggleCrop() {
|
||||||
this.setCrop(!this.config.crop_to_fit);
|
this.setCrop(!this.config.crop_to_fit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1630,11 +1661,46 @@ class AnnotationPlayer extends HTMLElement {
|
||||||
stroke: gray !important;
|
stroke: gray !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hide-drawing-preview g.after path, .hide-drawing-preview path.before_in{
|
||||||
|
opacity:0;
|
||||||
|
}
|
||||||
|
|
||||||
.gray {
|
.gray {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background: rgba(255, 255, 255, 0.7);
|
background: rgba(255, 255, 255, 0.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
summary{
|
||||||
|
list-style: none;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
details > ul{
|
||||||
|
position: absolute;
|
||||||
|
bottom: 30px;
|
||||||
|
background: rgba(0,0,0, .5);
|
||||||
|
border-radius: 3px;
|
||||||
|
right: 0;
|
||||||
|
padding: 5px;
|
||||||
|
margin: 0;
|
||||||
|
list-style: none;
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
details > ul li:hover{
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.play:not(.hide-drawing-preview) details > ul li:first-child{
|
||||||
|
/*text-decoration: line-through;*/
|
||||||
|
font-weight:bold;
|
||||||
|
}
|
||||||
|
.play.cropped-to-selection details > ul li:nth-child(2){
|
||||||
|
/*text-decoration: line-through;*/
|
||||||
|
font-weight:bold;
|
||||||
|
}
|
||||||
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -1660,8 +1726,8 @@ class AnnotationPlayer extends HTMLElement {
|
||||||
|
|
||||||
attributeChangedCallback(name, oldValue, newValue) {
|
attributeChangedCallback(name, oldValue, newValue) {
|
||||||
console.log(name, oldValue, newValue);
|
console.log(name, oldValue, newValue);
|
||||||
if(name == 'data-no-crop'){
|
if (name == 'data-no-crop') {
|
||||||
if(!this.annotator) {
|
if (!this.annotator) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.annotator.setCrop(!this.hasAttribute('data-no-crop'));
|
this.annotator.setCrop(!this.hasAttribute('data-no-crop'));
|
||||||
|
|
Loading…
Reference in a new issue