Crop option cycle button (TODO: pollish)
This commit is contained in:
parent
3ed2448545
commit
9a4a89c9c7
2 changed files with 51 additions and 30 deletions
|
@ -190,8 +190,8 @@ class AnimationSlice:
|
||||||
"audio": self.getAudioDict() if self.audio else None,
|
"audio": self.getAudioDict() if self.audio else None,
|
||||||
}
|
}
|
||||||
if include_full_drawing:
|
if include_full_drawing:
|
||||||
print(type(self.drawing))
|
|
||||||
drawing["background"] = [s.get_as_d() for s in self.drawing.get_animation().strokes]
|
drawing["background"] = [s.get_as_d() for s in self.drawing.get_animation().strokes]
|
||||||
|
drawing["background_bounding_box"] = self.drawing.get_animation().get_bounding_box().__dict__
|
||||||
return drawing
|
return drawing
|
||||||
|
|
||||||
def getAudioDict(self):
|
def getAudioDict(self):
|
||||||
|
|
|
@ -125,6 +125,18 @@ class StrokeSlice {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CropOptions = {
|
||||||
|
Fit_Selection: 'selection',
|
||||||
|
Follow_Drawing: 'follow',
|
||||||
|
Whole_Drawing: 'whole',
|
||||||
|
};
|
||||||
|
|
||||||
|
const CropDescriptions = {
|
||||||
|
selection: 'Crop to annotation',
|
||||||
|
follow: 'Follow drawing canvas',
|
||||||
|
whole: 'Show whole drawing',
|
||||||
|
}
|
||||||
|
|
||||||
class Annotator extends EventTarget {
|
class Annotator extends EventTarget {
|
||||||
constructor(wrapperEl, tagFile, fileurl, config) {
|
constructor(wrapperEl, tagFile, fileurl, config) {
|
||||||
fileurl = fileurl.replace("&", "&"); // little hack: tornadoweb does this automatically for some reason
|
fileurl = fileurl.replace("&", "&"); // little hack: tornadoweb does this automatically for some reason
|
||||||
|
@ -132,7 +144,8 @@ class Annotator extends EventTarget {
|
||||||
|
|
||||||
this.config = {
|
this.config = {
|
||||||
is_player: config && config.hasOwnProperty('is_player') ? config.is_player : false, // in player mode annotations are not loaded, nor is the annotator shown
|
is_player: config && config.hasOwnProperty('is_player') ? config.is_player : false, // in player mode annotations are not loaded, nor is the annotator shown
|
||||||
crop_to_fit: config && config.hasOwnProperty('crop_to_fit') ? config.crop_to_fit : false, // don't animate viewport, but show the whole drawing
|
crop_to_fit: config && config.hasOwnProperty('crop_to_fit') ? config.crop_to_fit : false, // DEPRECATED don't animate viewport, but show the whole drawing
|
||||||
|
crop: config && config.hasOwnProperty('crop') && Object.values(CropOptions).indexOf(config.crop) !== -1 ? config.crop : CropOptions.Fit_Selection, // don't animate viewport, but show the whole drawing
|
||||||
autoplay: config && config.hasOwnProperty('autoplay') ? config.autoplay : false, // immediately start playback
|
autoplay: config && config.hasOwnProperty('autoplay') ? config.autoplay : false, // immediately start playback
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,7 +181,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.wrapperEl.classList.add("crop-" + this.config.crop);
|
||||||
|
|
||||||
|
|
||||||
this.controlsEl = document.createElement('div');
|
this.controlsEl = document.createElement('div');
|
||||||
|
@ -234,10 +247,10 @@ class Annotator extends EventTarget {
|
||||||
toggleFutureEl.addEventListener('click', () => this.wrapperEl.classList.toggle('hide-drawing-preview'));
|
toggleFutureEl.addEventListener('click', () => this.wrapperEl.classList.toggle('hide-drawing-preview'));
|
||||||
extraControlsEl.appendChild(toggleFutureEl);
|
extraControlsEl.appendChild(toggleFutureEl);
|
||||||
|
|
||||||
const toggleCropPlayerEl = document.createElement('li');
|
this.toggleCropPlayerEl = document.createElement('li');
|
||||||
toggleCropPlayerEl.innerText = "Crop to selection";
|
this.toggleCropPlayerEl.innerText = CropDescriptions[this.config.crop];
|
||||||
toggleCropPlayerEl.addEventListener('click', () => this.toggleCrop());
|
this.toggleCropPlayerEl.addEventListener('click', () => this.toggleCrop());
|
||||||
extraControlsEl.appendChild(toggleCropPlayerEl);
|
extraControlsEl.appendChild(this.toggleCropPlayerEl);
|
||||||
|
|
||||||
extraEl.appendChild(extraControlsEl);
|
extraEl.appendChild(extraControlsEl);
|
||||||
|
|
||||||
|
@ -754,6 +767,7 @@ class Annotator extends EventTarget {
|
||||||
this.filename = drawing.file;
|
this.filename = drawing.file;
|
||||||
this.strokes = drawing.shape.map(s => new Stroke(s['color'], s['points']));
|
this.strokes = drawing.shape.map(s => new Stroke(s['color'], s['points']));
|
||||||
this.backgroundStrokes = drawing.hasOwnProperty('background') ? drawing.background : [];
|
this.backgroundStrokes = drawing.hasOwnProperty('background') ? drawing.background : [];
|
||||||
|
this.backgroundBoundingBox = drawing.hasOwnProperty('background_bounding_box') ? drawing.background_bounding_box : null;
|
||||||
this.viewboxes = drawing.viewboxes;
|
this.viewboxes = drawing.viewboxes;
|
||||||
this.currentPathI = null;
|
this.currentPathI = null;
|
||||||
this.currentPointI = null;
|
this.currentPointI = null;
|
||||||
|
@ -1119,8 +1133,10 @@ class Annotator extends EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
updateViewbox() {
|
updateViewbox() {
|
||||||
if (this.config.crop_to_fit) {
|
if (this.config.crop == CropOptions.Fit_Selection) {
|
||||||
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 if (this.config.crop == CropOptions.Whole_Drawing && this.backgroundBoundingBox) {
|
||||||
|
this.svgEl.setAttribute('viewBox', `${this.backgroundBoundingBox.x} ${this.backgroundBoundingBox.y} ${this.backgroundBoundingBox.width} ${this.backgroundBoundingBox.height}`);
|
||||||
} else {
|
} else {
|
||||||
let x, y, w, h;
|
let x, y, w, h;
|
||||||
if (this.currentViewboxI !== null) {
|
if (this.currentViewboxI !== null) {
|
||||||
|
@ -1138,18 +1154,31 @@ class Annotator extends EventTarget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setCrop(crop_to_fit) {
|
setCrop(crop_option) {
|
||||||
this.config.crop_to_fit = Boolean(crop_to_fit);
|
if(Object.values(CropOptions).indexOf(crop_option) === -1) {
|
||||||
if (this.config.crop_to_fit) {
|
console.error('invalid crop option', crop_option);
|
||||||
this.wrapperEl.classList.add('cropped-to-selection');
|
crop_option = CropOptions.Fit_Selection;
|
||||||
} else {
|
|
||||||
this.wrapperEl.classList.remove('cropped-to-selection');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.config.crop = crop_option;
|
||||||
|
for(let option of Object.values(CropOptions)) {
|
||||||
|
if (this.config.crop == option) {
|
||||||
|
this.wrapperEl.classList.add('crop-' + option);
|
||||||
|
} else {
|
||||||
|
this.wrapperEl.classList.remove('crop-' + option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.toggleCropPlayerEl.innerText = CropDescriptions[this.config.crop];
|
||||||
this.updateViewbox();
|
this.updateViewbox();
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleCrop() {
|
toggleCrop() {
|
||||||
this.setCrop(!this.config.crop_to_fit);
|
console.log(this.config.crop, Object.values(CropOptions), Object.values(CropOptions).indexOf(this.config.crop))
|
||||||
|
const i = (Object.values(CropOptions).indexOf(this.config.crop) + 1) % Object.keys(CropOptions).length;
|
||||||
|
const newCrop = Object.values(CropOptions)[i];
|
||||||
|
console.log(i, newCrop);
|
||||||
|
this.setCrop(newCrop);
|
||||||
}
|
}
|
||||||
|
|
||||||
getNextPosition(path_i, point_i) {
|
getNextPosition(path_i, point_i) {
|
||||||
|
@ -1527,7 +1556,7 @@ class AnnotationPlayer extends HTMLElement {
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
is_player: true,
|
is_player: true,
|
||||||
crop_to_fit: this.hasAttribute('data-no-crop') ? false : true,
|
crop: this.hasAttribute('data-crop') ? this.getAttribute('data-crop') : null,
|
||||||
autoplay: true,
|
autoplay: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1689,7 +1718,7 @@ class AnnotationPlayer extends HTMLElement {
|
||||||
.background{
|
.background{
|
||||||
visibility: hidden
|
visibility: hidden
|
||||||
}
|
}
|
||||||
.play:not(.cropped-to-selection) .background{
|
.play:not(.crop-selection) .background{
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1729,7 +1758,7 @@ class AnnotationPlayer extends HTMLElement {
|
||||||
/*text-decoration: line-through;*/
|
/*text-decoration: line-through;*/
|
||||||
font-weight:bold;
|
font-weight:bold;
|
||||||
}
|
}
|
||||||
.play.cropped-to-selection details > ul li:nth-child(2){
|
.play.crop-selection details > ul li:nth-child(2){
|
||||||
/*text-decoration: line-through;*/
|
/*text-decoration: line-through;*/
|
||||||
font-weight:bold;
|
font-weight:bold;
|
||||||
}
|
}
|
||||||
|
@ -1747,26 +1776,18 @@ class AnnotationPlayer extends HTMLElement {
|
||||||
this.setAttribute('data-poster-url', `/annotation/${annotation.id}.svg`)
|
this.setAttribute('data-poster-url', `/annotation/${annotation.id}.svg`)
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleCrop() {
|
|
||||||
if (this.hasAttribute('data-no-crop')) {
|
|
||||||
this.removeAttribute('data-no-crop');
|
|
||||||
} else {
|
|
||||||
this.setAttribute('data-no-crop', true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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-crop') {
|
||||||
if (!this.annotator) {
|
if (!this.annotator) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.annotator.setCrop(!this.hasAttribute('data-no-crop'));
|
this.annotator.setCrop(this.hasAttribute('data-crop'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// required for attributeChangedCallback()
|
// required for attributeChangedCallback()
|
||||||
static get observedAttributes() { return ['data-no-crop']; }
|
static get observedAttributes() { return ['data-crop']; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue