slitscan/src/components/Sidebar.vue

210 lines
5.4 KiB
Vue

<template>
<div id="sidebar-container">
<div>
<input type="file" id="file" @change="loadImage($event)">
</div>
<div>
<label>Image size: {{imageSize[0]}} x {{imageSize[1]}}</label>
</div>
<hr>
<div>
<label for="slice_x">Slice X: </label>
<input class="spinBox" id="slice_x" v-model.number="guideSizeX" type="number" min="2" :max="imageSize[0]/2"
step="1" value="64">
</div>
<div>
<label for="slice_x">No X remainder: {{noXremainder}}</label>
</div>
<div>
<label for="slice_y">Slice Y: </label>
<input class="spinBox" id="slice_y" v-model.number="guideSizeY" type="number" min="2" :max="imageSize[1]/2"
step="1" value="64">
</div>
<div>
<label for="slice_x">No Y remainder: {{noYremainder}}</label>
</div>
<div>
<label for="lockSize">Maintain square ratio: </label>
<input type="checkbox" id="lockSize" v-model="lockSize">
</div>
<div>
<label for="cleanSize">Allow only clean sizes: </label>
<input type="checkbox" id="cleanSize" v-model="cleanSize">
</div>
<hr>
<div>
<label>Offset: x={{offset[0]}}, y={{offset[1]}}</label>
<button @click="$emit('params', {type: 'offset', x: 0, y: 0})">RESET</button>
</div>
<hr>
<div>
<label>Total amount of slices: {{slices}}</label>
</div>
<div>
<label for="fps">FPS: </label>
<input class="spinBox" id="fps" v-model="fps" type="number" min="1" max="60" step="1" value="60" disabled>
</div>
<div>
<label>Est. length: {{length}}</label>
</div>
<hr>
<player :width="guideSizeX" :height="guideSizeY" :offset="offset" @frames="(n)=>{slices=n}"/>
</div>
</template>
<!--suppress JSSuspiciousNameCombination -->
<script>
import Player from "@/components/Player";
export default {
name: "Sidebar",
components: {
player: Player,
},
props: ["slice", "offset"],
data: function () {
return {
imageSize: [-1, -1],
guideSizeX: 64,
guideSizeY: 64,
lastGuideSizeX: 64,
lastGuideSizeY: 64,
lockSize: true,
cleanSize: false,
slices: 0,
fps: 60,
};
},
watch: {
guideSizeX (size) {
if (this.lockSize) this.guideSizeY = size;
if (this.cleanSize) {
let tmpSize = parseInt(size);
while (this.imageSize[0] % tmpSize !== 0 &&
tmpSize < this.imageSize[0] &&
tmpSize > 2) {
if (this.lastGuideSizeX < size) {
tmpSize += 1;
} else {
tmpSize -= 1;
}
}
if (tmpSize !== 2 && tmpSize !== this.imageSize[0]) {
this.guideSizeX = tmpSize;
}
}
this.$emit("params", {
type: "slice",
x: this.guideSizeX,
y: this.guideSizeY,
});
this.lastGuideSizeX = this.guideSizeX;
this.lastGuideSizeY = this.guideSizeY;
},
guideSizeY (size) {
if (this.lockSize) this.guideSizeX = size;
if (this.cleanSize) {
let tmpSize = parseInt(size);
while (this.imageSize[1] % tmpSize !== 0 &&
tmpSize < this.imageSize[1] &&
tmpSize > 2) {
if (this.lastGuideSizeY < size) {
tmpSize += 1;
} else {
tmpSize -= 1;
}
}
if (tmpSize !== 2 && tmpSize !== this.imageSize[1]) {
this.guideSizeY = tmpSize;
}
}
this.$emit("params", {
type: "slice",
x: this.guideSizeX,
y: this.guideSizeY,
});
this.lastGuideSizeX = this.guideSizeX;
this.lastGuideSizeY = this.guideSizeY;
},
slice: function (size) {
this.lockSize = size[0] === size[1];
this.guideSizeX = size[0];
this.guideSizeY = size[1];
},
lockSize: function (locked) {
if (locked) {
if (this.guideSizeX < this.guideSizeY) {
this.guideSizeY = this.guideSizeX;
} else {
this.guideSizeX = this.guideSizeY;
}
this.cleanSize = false;
}
},
cleanSize: function (clean) {
if (clean) {
this.lockSize = false;
}
},
},
computed: {
length: function () {
if (this.imageSize[0] === -1 || this.imageSize[1] === -1) {
return "-";
} else {
let seconds = Math.round(this.slices / this.fps * 100) / 100;
let mins = Math.floor(seconds / 60);
let secs = Math.round(seconds % 60);
return "~" + seconds + " seconds" + (mins > 0 ? (" (" + mins + "m " + secs + "s)") : "");
}
},
noXremainder: function () {
return this.imageSize[0] % this.guideSizeX === 0;
},
noYremainder: function () {
return this.imageSize[1] % this.guideSizeY === 0;
},
},
methods: {
loadImage (e) {
let url = URL.createObjectURL(e.target.files[0]);
this.$emit("loadImage", url);
},
setParams (coords) {
switch (coords.type) {
case "size":
this.lockSize = false;
this.guideSizeX = coords.x;
this.guideSizeY = coords.y;
break;
}
},
},
mounted: function () {
this.$bus.$on("imageLoaded", (image) => {
this.imageSize = [image.width, image.height];
});
this.$emit("guideSize", [this.guideSizeX, this.guideSizeY]);
},
};
</script>
<style scoped>
#sidebar-container {
width: 100%;
height: 100%;
border-right: 1px solid black;
}
.spinBox {
height: 1em;
}
.green {
background-color: green;
}
</style>