annotator/static/main.js

144 lines
4.1 KiB
JavaScript

function findGetParameter(parameterName) {
var result = null, tmp = [];
location.search
.substr(1)
.split("&")
.forEach(function(item) {
tmp = item.split("=");
if (tmp[0] === parameterName) result = decodeURIComponent(tmp[1]);
});
return result;
}
const Events = [
'Transition -> slide',
'Transition -> demo',
'Transition -> new viewpoint',
'Build Up',
'Animation',
'Pointer',
'Live annotation',
];
class Annotator {
constructor(root, annotations, img1Id, img2Id, annotationId) {
this.root = root;
this.annotations = annotations;
this.maxIndex = Object.keys(this.annotations).length - 1;
this.img1Element = document.getElementById(img1Id);
this.img1IndexElement = document.getElementById(img1Id + '-index');
this.img2Element = document.getElementById(img2Id);
this.img2IndexElement = document.getElementById(img2Id + '-index');
this.annotationElement = document.getElementById(annotationId);
this.setIndex(0);
this.addShortcuts();
}
formatIndex(index) {
index += '';
return index.padStart(4, '0');
}
getUrl(index) {
return this.root + '/' + this.formatIndex(index) + '.jpg';
}
setIndex(index) {
// If index is undefined, we only want a refresh
if (index !== undefined) {
this.index = index;
this.index = Math.max(0, this.index);
this.index = Math.min(this.index, this.maxIndex);
// Refrsh images
this.img1Element.src = this.getUrl(this.index);
this.img2Element.src = this.getUrl(this.index + 1);
// Refresh headers
this.img1IndexElement.innerHTML = this.index + '/' + this.maxIndex;
this.img2IndexElement.innerHTML = this.index + 1 + '/' + this.maxIndex;
}
// Refresh annotations list
let currentAnnotations = this.annotations[this.formatIndex(this.index + 1)];
if (currentAnnotations.length === 0) {
this.annotationElement.innerHTML = "There is no annotation for this frame";
} else {
this.annotationElement.innerHTML = '<ul>';
for (let annotation of currentAnnotations) {
this.annotationElement.innerHTML += '<li>' + annotation + '</li>';
}
this.annotationElement.innerHTML += '</ul>';
}
}
increment(by = 1) {
this.setIndex(this.index + by);
}
decrement(by = 1) {
this.setIndex(this.index - by);
}
addShortcuts() {
document.addEventListener('keyup', (e) => {
switch (e.code) {
case 'ArrowRight': this.increment(e.ctrlKey ? 10 : 1); break;
case 'ArrowLeft': this.decrement(e.ctrlKey ? 10 : 1); break;
}
if (e.code.startsWith('Numpad') || e.code.startsWith('Digit')) {
let key = parseInt(e.code[e.code.length - 1], 10);
this.toggle(key);
}
});
}
toggle(key) {
let event = Events[key];
if (event === undefined) {
return;
}
let events = this.annotations[this.formatIndex(this.index + 1)];
let search = events.indexOf(event);
if (search === -1) {
events.push(event);
} else {
events.splice(search, 1);
}
this.setIndex();
this.sync();
}
sync() {
fetch('/data', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
root: this.root,
annotations: this.annotations,
}),
});
}
}
async function main() {
const root = findGetParameter('root');
let annotations = await fetch(root + '/annotations.json');
annotations = await annotations.json();
const annotator = new Annotator(root, annotations, 'img-1', 'img-2', 'annotations');
}
main();