diff --git a/src/App.vue b/src/App.vue index 2d2051f..d0972a3 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,10 +1,10 @@ @@ -18,15 +18,25 @@ export default { components: { Canvas, Sidebar, }, + data () { + return { + slice: [64, 64], + offset: [0, 0], + }; + }, methods: { loadImage: function (url) { this.$refs.canvas.imageUrl = url; }, - guideSize: function (size) { - this.$refs.canvas.slice = size; - }, setParams: function (coords) { - this.$refs.sidebar.setParams(coords); + switch (coords.type) { + case "slice": + this.slice = [Math.max(2, coords.x), Math.max(2, coords.y)]; + break; + case "offset": + this.offset = [coords.x, coords.y]; + break; + } }, }, }; diff --git a/src/components/Canvas.vue b/src/components/Canvas.vue index 9425e31..9d778f3 100644 --- a/src/components/Canvas.vue +++ b/src/components/Canvas.vue @@ -14,10 +14,10 @@ export default { imageUrl: "", image: null, imageLoaded: false, - slice: [0, 0], ratio: 1, }; }, + props: ["slice", "offset"], computed: {}, watch: { imageUrl: function (url) { @@ -26,6 +26,9 @@ export default { slice: function () { this.refresh(); }, + offset: function () { + this.refresh(); + }, }, mounted: function () { window.addEventListener("resize", this.handleResize); @@ -60,16 +63,16 @@ export default { let sliceY = parseInt(this.slice[1]) * this.ratio; if (sliceX > 0 && sliceY > 0) { - for (let x = 0; x < dims.width; x += sliceX) { + for (let x = this.offset[0] * this.ratio; x < dims.width; x += sliceX) { ctx.beginPath(); - ctx.moveTo(x, 0); + ctx.moveTo(x, this.offset[1] * this.ratio); ctx.lineTo(x, dims.height); ctx.strokeStyle = "red"; ctx.stroke(); } - for (let y = 0; y < dims.height; y += sliceY) { + for (let y = this.offset[1] * this.ratio; y < dims.height; y += sliceY) { ctx.beginPath(); - ctx.moveTo(0, y); + ctx.moveTo(this.offset[0] * this.ratio, y); ctx.lineTo(dims.width, y); ctx.strokeStyle = "red"; ctx.stroke(); @@ -91,17 +94,23 @@ export default { ev.preventDefault(); const type = { - 1: "size", + 1: "slice", 2: "offset", }[ev.buttons]; if (type !== undefined) { - const coords = { - "type": type, - "x": Math.round((ev.x - ev.target.offsetLeft) / this.ratio), - "y": Math.round((ev.y - ev.target.offsetTop) / this.ratio), - }; - this.$emit("params", coords); + let x, y; + switch (type) { + case "slice": + x = Math.round((ev.x - ev.target.offsetLeft) / this.ratio - this.offset[0]); + y = Math.round((ev.y - ev.target.offsetTop) / this.ratio - this.offset[1]); + break; + case "offset": + x = Math.round((ev.x - ev.target.offsetLeft) / this.ratio); + y = Math.round((ev.y - ev.target.offsetTop) / this.ratio); + break; + } + this.$emit("params", {type, x, y}); } return false; }, diff --git a/src/components/Player.vue b/src/components/Player.vue index f36c516..3242b19 100644 --- a/src/components/Player.vue +++ b/src/components/Player.vue @@ -45,6 +45,7 @@ export default { props: { width: Number, height: Number, + offset: Array, }, data: function () { return { @@ -67,8 +68,7 @@ export default { computed: { frames: function () { if (this.image === null) return 0; - return Math.ceil(this.image.width / this.width) * - Math.ceil(this.image.height / this.height); + return Math.ceil((this.image.width - this.offset[0]) / this.width) * Math.ceil((this.image.height - this.offset[1]) / this.height); }, canvas_height: function () { return this.height * this.zoom; @@ -81,10 +81,10 @@ export default { let sequence = []; for (let pos = 0; pos < this.frames; pos++) { - let wb = Math.ceil(this.image.width / this.width); // width_blocks - let x = (pos % wb) * this.width; // x offset + let wb = Math.ceil((this.image.width - this.offset[0]) / this.width); // width_blocks + let x = this.offset[0] + (pos % wb) * this.width; // x offset let w = x + this.width < this.image.width ? this.width : this.image.width - x; // frame width - let y = Math.floor(pos / wb) * this.height; // y offset + let y = this.offset[1] + Math.floor(pos / wb) * this.height; // y offset let h = y + this.height < this.image.height ? this.height : this.image.height - y; // frame height sequence.push([x, y, w, h]); } @@ -146,6 +146,9 @@ export default { this.clear("red"); }, 0); }, + frames: function () { + this.$emit("frames", this.frames); + }, position: function () { if (this.playing || this.image === null) return; this.tmp_ctx = this.$refs.canvas.getContext("2d"); diff --git a/src/components/Sidebar.vue b/src/components/Sidebar.vue index f580e8c..b6dd7ab 100644 --- a/src/components/Sidebar.vue +++ b/src/components/Sidebar.vue @@ -32,6 +32,11 @@
+
+ + +
+
@@ -43,7 +48,7 @@
- + @@ -56,6 +61,7 @@ export default { components: { player: Player, }, + props: ["slice", "offset"], data: function () { return { imageSize: [-1, -1], @@ -65,6 +71,7 @@ export default { lastGuideSizeY: 64, lockSize: true, cleanSize: false, + slices: 0, fps: 60, }; }, @@ -86,7 +93,11 @@ export default { this.guideSizeX = tmpSize; } } - this.$emit("guideSize", [this.guideSizeX, this.guideSizeY]); + this.$emit("params", { + type: "slice", + x: this.guideSizeX, + y: this.guideSizeY, + }); this.lastGuideSizeX = this.guideSizeX; this.lastGuideSizeY = this.guideSizeY; }, @@ -107,10 +118,19 @@ export default { this.guideSizeY = tmpSize; } } - this.$emit("guideSize", [this.guideSizeX, this.guideSizeY]); + 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) { @@ -128,14 +148,6 @@ export default { }, }, computed: { - slices: function () { - if (this.imageSize[0] === -1 || this.imageSize[1] === -1) { - return "-"; - } else { - return Math.ceil(this.imageSize[0] / this.guideSizeX) * - Math.ceil(this.imageSize[1] / this.guideSizeY); - } - }, length: function () { if (this.imageSize[0] === -1 || this.imageSize[1] === -1) { return "-";