autoformat && eslint change

master
Tomáš Mládek 2019-10-31 15:51:31 +01:00
parent 4c3b984b21
commit 676c8f7fe0
14 changed files with 591 additions and 479 deletions

View File

@ -1,12 +1,22 @@
{ {
"presets": [ "presets": [
["env", { [
"modules": false, "env",
"targets": { {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"] "modules": false,
"targets": {
"browsers": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
} }
}], ],
"stage-2" "stage-2"
], ],
"plugins": ["transform-vue-jsx", "transform-runtime"] "plugins": [
"transform-vue-jsx",
"transform-runtime"
]
} }

View File

@ -1,25 +1,35 @@
// https://eslint.org/docs/user-guide/configuring
module.exports = { module.exports = {
root: true, "env": {
parser: 'babel-eslint', "browser": true,
parserOptions: { "es6": true,
sourceType: 'module'
}, },
env: { "extends": [
browser: true, "eslint:recommended",
}, "plugin:vue/essential",
// https://github.com/standard/standard/blob/master/docs/RULES-en.md
extends: 'standard',
// required to lint *.vue files
plugins: [
'html'
], ],
// add your custom rules here "globals": {
rules: { "Atomics": "readonly",
// allow async-await "SharedArrayBuffer": "readonly",
'generator-star-spacing': 'off', },
// allow debugger during development "parserOptions": {
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' "ecmaVersion": 2018,
} "sourceType": "module",
} },
"plugins": [
"vue",
],
"rules": {
"linebreak-style": [
"error",
"unix",
],
"quotes": [
"error",
"double",
],
"semi": [
"error",
"always",
],
},
};

View File

@ -5,6 +5,6 @@ module.exports = {
"postcss-import": {}, "postcss-import": {},
"postcss-url": {}, "postcss-url": {},
// to edit target browsers: use "browserslist" field in package.json // to edit target browsers: use "browserslist" field in package.json
"autoprefixer": {} "autoprefixer": {},
} },
} };

View File

@ -1,7 +1,7 @@
'use strict' "use strict";
const merge = require('webpack-merge') const merge = require("webpack-merge");
const prodEnv = require('./prod.env') const prodEnv = require("./prod.env");
module.exports = merge(prodEnv, { module.exports = merge(prodEnv, {
NODE_ENV: '"development"' NODE_ENV: "\"development\"",
}) });

View File

@ -1,19 +1,19 @@
'use strict' "use strict";
// Template version: 1.2.8 // Template version: 1.2.8
// see http://vuejs-templates.github.io/webpack for documentation. // see http://vuejs-templates.github.io/webpack for documentation.
const path = require('path') const path = require("path");
module.exports = { module.exports = {
dev: { dev: {
// Paths // Paths
assetsSubDirectory: 'static', assetsSubDirectory: "static",
assetsPublicPath: '/', assetsPublicPath: "/",
proxyTable: {}, proxyTable: {},
// Various Dev Server settings // Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST host: "localhost", // can be overwritten by process.env.HOST
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: false, autoOpenBrowser: false,
errorOverlay: true, errorOverlay: true,
@ -33,7 +33,7 @@ module.exports = {
*/ */
// https://webpack.js.org/configuration/devtool/#development // https://webpack.js.org/configuration/devtool/#development
devtool: 'cheap-module-eval-source-map', devtool: "cheap-module-eval-source-map",
// If you have problems debugging vue-files in devtools, // If you have problems debugging vue-files in devtools,
// set this to false - it *may* help // set this to false - it *may* help
@ -45,12 +45,12 @@ module.exports = {
build: { build: {
// Template for index.html // Template for index.html
index: path.resolve(__dirname, '../dist/index.html'), index: path.resolve(__dirname, "../dist/index.html"),
// Paths // Paths
assetsRoot: path.resolve(__dirname, '../dist'), assetsRoot: path.resolve(__dirname, "../dist"),
assetsSubDirectory: 'static', assetsSubDirectory: "static",
assetsPublicPath: '/tools/slitscan', assetsPublicPath: "/tools/slitscan",
/** /**
* Source Maps * Source Maps
@ -58,19 +58,19 @@ module.exports = {
productionSourceMap: true, productionSourceMap: true,
// https://webpack.js.org/configuration/devtool/#production // https://webpack.js.org/configuration/devtool/#production
devtool: '#source-map', devtool: "#source-map",
// Gzip off by default as many popular static hosts such as // Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you. // Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to: // Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin // npm install --save-dev compression-webpack-plugin
productionGzip: false, productionGzip: false,
productionGzipExtensions: ['js', 'css'], productionGzipExtensions: ["js", "css"],
// Run the build command with an extra argument to // Run the build command with an extra argument to
// View the bundle analyzer report after build finishes: // View the bundle analyzer report after build finishes:
// `npm run build --report` // `npm run build --report`
// Set to `true` or `false` to always turn it on or off // Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report bundleAnalyzerReport: process.env.npm_config_report,
} },
} };

View File

@ -1,4 +1,4 @@
'use strict' "use strict";
module.exports = { module.exports = {
NODE_ENV: '"production"' NODE_ENV: "\"production\"",
} };

88
package-lock.json generated
View File

@ -3612,6 +3612,31 @@
"integrity": "sha1-NNDJFbRe3G8BA5PH7vOCOwhWXPI=", "integrity": "sha1-NNDJFbRe3G8BA5PH7vOCOwhWXPI=",
"dev": true "dev": true
}, },
"eslint-plugin-vue": {
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-5.2.3.tgz",
"integrity": "sha512-mGwMqbbJf0+VvpGR5Lllq0PMxvTdrZ/ZPjmhkacrCHbubJeJOt+T6E3HUzAifa2Mxi7RSdJfC9HFpOeSYVMMIw==",
"dev": true,
"requires": {
"vue-eslint-parser": "^5.0.0"
}
},
"eslint-scope": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
"integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
"dev": true,
"requires": {
"esrecurse": "^4.1.0",
"estraverse": "^4.1.1"
}
},
"eslint-visitor-keys": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
"integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
"dev": true
},
"espree": { "espree": {
"version": "3.5.2", "version": "3.5.2",
"resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz", "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz",
@ -11427,6 +11452,69 @@
"resolved": "https://registry.npmjs.org/vue/-/vue-2.5.13.tgz", "resolved": "https://registry.npmjs.org/vue/-/vue-2.5.13.tgz",
"integrity": "sha512-3D+lY7HTkKbtswDM4BBHgqyq+qo8IAEE8lz8va1dz3LLmttjgo0FxairO4r1iN2OBqk8o1FyL4hvzzTFEdQSEw==" "integrity": "sha512-3D+lY7HTkKbtswDM4BBHgqyq+qo8IAEE8lz8va1dz3LLmttjgo0FxairO4r1iN2OBqk8o1FyL4hvzzTFEdQSEw=="
}, },
"vue-eslint-parser": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-5.0.0.tgz",
"integrity": "sha512-JlHVZwBBTNVvzmifwjpZYn0oPWH2SgWv5dojlZBsrhablDu95VFD+hriB1rQGwbD+bms6g+rAFhQHk6+NyiS6g==",
"dev": true,
"requires": {
"debug": "^4.1.0",
"eslint-scope": "^4.0.0",
"eslint-visitor-keys": "^1.0.0",
"espree": "^4.1.0",
"esquery": "^1.0.1",
"lodash": "^4.17.11"
},
"dependencies": {
"acorn": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz",
"integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==",
"dev": true
},
"acorn-jsx": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz",
"integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==",
"dev": true
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"espree": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-4.1.0.tgz",
"integrity": "sha512-I5BycZW6FCVIub93TeVY1s7vjhP9CY6cXCznIRfiig7nRviKZYdRnj/sHEWC6A7WE9RDWOFq9+7OsWSYz8qv2w==",
"dev": true,
"requires": {
"acorn": "^6.0.2",
"acorn-jsx": "^5.0.0",
"eslint-visitor-keys": "^1.0.0"
}
},
"esquery": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
"integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==",
"dev": true,
"requires": {
"estraverse": "^4.0.0"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
}
}
},
"vue-hot-reload-api": { "vue-hot-reload-api": {
"version": "2.2.4", "version": "2.2.4",
"resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.2.4.tgz", "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.2.4.tgz",

View File

@ -41,6 +41,7 @@
"eslint-plugin-node": "^5.2.0", "eslint-plugin-node": "^5.2.0",
"eslint-plugin-promise": "^3.4.0", "eslint-plugin-promise": "^3.4.0",
"eslint-plugin-standard": "^3.0.1", "eslint-plugin-standard": "^3.0.1",
"eslint-plugin-vue": "^5.2.3",
"extract-text-webpack-plugin": "^3.0.0", "extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^1.1.4", "file-loader": "^1.1.4",
"friendly-errors-webpack-plugin": "^1.6.1", "friendly-errors-webpack-plugin": "^1.6.1",

View File

@ -10,53 +10,53 @@
</template> </template>
<script> <script>
import Canvas from './components/Canvas' import Canvas from "./components/Canvas";
import Sidebar from './components/Sidebar' import Sidebar from "./components/Sidebar";
export default { export default {
name: 'app', name: "app",
components: { components: {
Canvas, Sidebar Canvas, Sidebar,
},
methods: {
loadImage: function (url) {
this.$refs.canvas.imageUrl = url;
}, },
methods: { guideSize: function (size) {
loadImage: function (url) { this.$refs.canvas.slice = size;
this.$refs.canvas.imageUrl = url },
}, },
guideSize: function (size) { };
this.$refs.canvas.slice = size
}
}
}
</script> </script>
<style> <style>
html, body, #app { html, body, #app {
height: 100%; height: 100%;
width: 100%; width: 100%;
border: 0; border: 0;
margin: 0; margin: 0;
font-family: Consolas, Inconsolata, monospace, serif; font-family: Consolas, Inconsolata, monospace, serif;
line-height: .97em; line-height: .97em;
font-size: .95em; font-size: .95em;
} }
input { input {
font-size: .95em; font-size: .95em;
} }
#menu-wrap, #canvas-wrap { #menu-wrap, #canvas-wrap {
display: inline-block; display: inline-block;
} }
#menu-wrap { #menu-wrap {
width: 20%; width: 20%;
height: 100%; height: 100%;
float: left; float: left;
} }
#canvas-wrap { #canvas-wrap {
width: 80%; width: 80%;
height: 100%; height: 100%;
} }
</style> </style>

View File

@ -5,94 +5,94 @@
</template> </template>
<script> <script>
import {getDimsFit} from '../helpers/image.js' import {getDimsFit} from "../helpers/image.js";
export default { export default {
name: 'Canvas', name: "Canvas",
data: function () { data: function () {
return { return {
imageUrl: '', imageUrl: "",
image: null, image: null,
imageLoaded: false, imageLoaded: false,
slice: [0, 0] slice: [0, 0],
} };
},
computed: {},
watch: {
imageUrl: function (url) {
this.loadImage(url);
}, },
computed: {}, slice: function () {
watch: { this.refresh();
imageUrl: function (url) {
this.loadImage(url)
},
slice: function () {
this.refresh()
}
}, },
mounted: function () { },
window.addEventListener('resize', this.handleResize) mounted: function () {
this.handleResize() window.addEventListener("resize", this.handleResize);
this.handleResize();
},
methods: {
loadImage: function (imageUrl) {
this.image = new Image();
this.image.onload = () => {
this.imageLoaded = true;
this.$bus.$emit("imageLoaded", this.image);
this.refresh();
};
this.image.src = imageUrl;
}, },
methods: { refresh: function () {
loadImage: function (imageUrl) { if (!this.imageLoaded) return;
this.image = new Image() let image = this.image;
this.image.onload = () => { let canvas = this.$refs.canvas;
this.imageLoaded = true let ctx = canvas.getContext("2d");
this.$bus.$emit('imageLoaded', this.image)
this.refresh() ctx.clearRect(0, 0, canvas.width, canvas.height);
let dims = getDimsFit(image.width, image.height, canvas.width, canvas.height);
ctx.drawImage(image,
0, 0, image.width, image.height,
0, 0, dims.width, dims.height);
let ratio = dims.width / image.width;
let sliceX = parseInt(this.slice[0]) * ratio;
let sliceY = parseInt(this.slice[1]) * ratio;
if (sliceX > 0 && sliceY > 0) {
for (let x = 0; x < dims.width; x += sliceX) {
ctx.beginPath();
ctx.moveTo(x, 0);
ctx.lineTo(x, dims.height);
ctx.strokeStyle = "red";
ctx.stroke();
} }
this.image.src = imageUrl for (let y = 0; y < dims.height; y += sliceY) {
}, ctx.beginPath();
refresh: function () { ctx.moveTo(0, y);
if (!this.imageLoaded) return ctx.lineTo(dims.width, y);
let image = this.image ctx.strokeStyle = "red";
let canvas = this.$refs.canvas ctx.stroke();
let ctx = canvas.getContext('2d')
ctx.clearRect(0, 0, canvas.width, canvas.height)
let dims = getDimsFit(image.width, image.height, canvas.width, canvas.height)
ctx.drawImage(image,
0, 0, image.width, image.height,
0, 0, dims.width, dims.height)
let ratio = dims.width / image.width
let sliceX = parseInt(this.slice[0]) * ratio
let sliceY = parseInt(this.slice[1]) * ratio
if (sliceX > 0 && sliceY > 0) {
for (let x = 0; x < dims.width; x += sliceX) {
ctx.beginPath()
ctx.moveTo(x, 0)
ctx.lineTo(x, dims.height)
ctx.strokeStyle = 'red'
ctx.stroke()
}
for (let y = 0; y < dims.height; y += sliceY) {
ctx.beginPath()
ctx.moveTo(0, y)
ctx.lineTo(dims.width, y)
ctx.strokeStyle = 'red'
ctx.stroke()
}
} }
},
handleResize: function () {
let canvasContainer = document.getElementById('canvas-container')
let canvas = document.getElementById('canvas')
canvas.width = canvasContainer.offsetWidth - 10
canvas.height = canvasContainer.offsetHeight - 10
this.refresh()
} }
} },
} handleResize: function () {
let canvasContainer = document.getElementById("canvas-container");
let canvas = document.getElementById("canvas");
canvas.width = canvasContainer.offsetWidth - 10;
canvas.height = canvasContainer.offsetHeight - 10;
this.refresh();
},
},
};
</script> </script>
<style scoped> <style scoped>
#canvas-container { #canvas-container {
width: 100%; width: 100%;
height: 100%; height: 100%;
margin: 0; margin: 0;
border: 0; border: 0;
padding: 0; padding: 0;
} }
</style> </style>

View File

@ -37,197 +37,197 @@
</template> </template>
<script> <script>
import CCapture from 'ccapture.js' import CCapture from "ccapture.js";
import bowser from 'bowser' import bowser from "bowser";
export default { export default {
name: 'player', name: "player",
props: { props: {
width: Number, width: Number,
height: Number height: Number,
},
data: function () {
return {
image: null,
playing: false,
zoom: 1,
fullscreen: false,
sortBySize: false,
sortDirection: false,
position: 0,
tmp_ctx: null,
animation_id: null,
record: false,
capturer: new CCapture({
format: "webm",
verbose: true,
}),
};
},
computed: {
frames: function () {
if (this.image === null) return 0;
return Math.ceil(this.image.width / this.width) *
Math.ceil(this.image.height / this.height);
}, },
data: function () { canvas_height: function () {
return { return this.height * this.zoom;
image: null, },
playing: false, canvas_width: function () {
zoom: 1, return this.width * this.zoom;
fullscreen: false, },
sortBySize: false, frame_sequence: function () {
sortDirection: false, if (this.image === null) return [];
position: 0,
tmp_ctx: null, let sequence = [];
animation_id: null, for (let pos = 0; pos < this.frames; pos++) {
record: false, let wb = Math.ceil(this.image.width / this.width); // width_blocks
capturer: new CCapture({ let x = (pos % wb) * this.width; // x offset
format: 'webm', let w = x + this.width < this.image.width ? this.width : this.image.width - x; // frame width
verbose: true let y = 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]);
}
if (this.sortBySize) {
let tmpCanvas = document.createElement("canvas");
let ctx = tmpCanvas.getContext("2d");
let sizes = sequence.map((el, i) => {
if (tmpCanvas.width !== el[2] ||
tmpCanvas.height !== el[3]) {
tmpCanvas.width = el[2];
tmpCanvas.height = el[3];
}
ctx.drawImage(this.image, el[0], el[1], el[2], el[3],
0, 0, el[2], el[3]);
return {index: i, length: tmpCanvas.toDataURL("image/png").length};
});
sizes.sort(function (a, b) {
return a.length - b.length;
});
if (!this.sortDirection) {
sizes.reverse();
}
return sizes.map(function (el) {
return sequence[el.index];
});
} else {
return sequence;
} }
}, },
computed: { buttonLabel: function () {
frames: function () { if (!this.playing) {
if (this.image === null) return 0
return Math.ceil(this.image.width / this.width) *
Math.ceil(this.image.height / this.height)
},
canvas_height: function () {
return this.height * this.zoom
},
canvas_width: function () {
return this.width * this.zoom
},
frame_sequence: function () {
if (this.image === null) return []
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 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 h = y + this.height < this.image.height ? this.height : this.image.height - y // frame height
sequence.push([x, y, w, h])
}
if (this.sortBySize) {
let tmpCanvas = document.createElement('canvas')
let ctx = tmpCanvas.getContext('2d')
let sizes = sequence.map((el, i) => {
if (tmpCanvas.width !== el[2] ||
tmpCanvas.height !== el[3]) {
tmpCanvas.width = el[2]
tmpCanvas.height = el[3]
}
ctx.drawImage(this.image, el[0], el[1], el[2], el[3],
0, 0, el[2], el[3])
return {index: i, length: tmpCanvas.toDataURL('image/png').length}
})
sizes.sort(function (a, b) {
return a.length - b.length
})
if (!this.sortDirection) {
sizes.reverse()
}
return sizes.map(function (el) {
return sequence[el.index]
})
} else {
return sequence
}
},
buttonLabel: function () {
if (!this.playing) {
if (this.record) {
return 'RECORD'
} else {
return 'PLAY'
}
} else {
return 'STOP'
}
}
},
mounted: function () {
this.$bus.$on('imageLoaded', (image) => {
this.image = image
})
this.clear('red')
},
watch: {
canvas_width: function () {
setTimeout(() => {
this.clear('red')
}, 0)
},
canvas_height: function () {
setTimeout(() => {
this.clear('red')
}, 0)
},
position: function () {
if (this.playing || this.image === null) return
this.tmp_ctx = this.$refs.canvas.getContext('2d')
this.$render()
},
record: function () {
if (this.record) { if (this.record) {
this.position = 0 return "RECORD";
if (!bowser.chrome) { } else {
alert('Recording only supported in Chrome :( \n' + return "PLAY";
'https://github.com/spite/ccapture.js/#limitations') }
} } else {
return "STOP";
}
},
},
mounted: function () {
this.$bus.$on("imageLoaded", (image) => {
this.image = image;
});
this.clear("red");
},
watch: {
canvas_width: function () {
setTimeout(() => {
this.clear("red");
}, 0);
},
canvas_height: function () {
setTimeout(() => {
this.clear("red");
}, 0);
},
position: function () {
if (this.playing || this.image === null) return;
this.tmp_ctx = this.$refs.canvas.getContext("2d");
this.$render();
},
record: function () {
if (this.record) {
this.position = 0;
if (!bowser.chrome) {
alert("Recording only supported in Chrome :( \n" +
"https://github.com/spite/ccapture.js/#limitations");
} }
} }
}, },
methods: { },
playPause: function () { methods: {
if (this.frames === 0) { playPause: function () {
return if (this.frames === 0) {
} return;
this.playing = !this.playing }
if (this.playing) { this.playing = !this.playing;
this.tmp_ctx = this.$refs.canvas.getContext('2d') if (this.playing) {
if (this.record) this.capturer.start() this.tmp_ctx = this.$refs.canvas.getContext("2d");
this.$render_advance() if (this.record) this.capturer.start();
} else { this.$render_advance();
cancelAnimationFrame(this.animation_id) } else {
} cancelAnimationFrame(this.animation_id);
}, }
clear: function (style) { },
let ctx = this.$refs.canvas.getContext('2d') clear: function (style) {
ctx.fillStyle = style let ctx = this.$refs.canvas.getContext("2d");
ctx.fillRect(0, 0, parseInt(this.canvas_width), parseInt(this.canvas_height)) ctx.fillStyle = style;
}, ctx.fillRect(0, 0, parseInt(this.canvas_width), parseInt(this.canvas_height));
$render: function () { },
let frame = this.frame_sequence[this.position] $render: function () {
if (frame === undefined) return let frame = this.frame_sequence[this.position];
let [x, y, w, h] = frame if (frame === undefined) return;
if (w !== this.width || h !== this.height) this.clear('black') let [x, y, w, h] = frame;
this.tmp_ctx.drawImage(this.image, if (w !== this.width || h !== this.height) this.clear("black");
x, y, w, h, this.tmp_ctx.drawImage(this.image,
0, 0, w * this.zoom, h * this.zoom) x, y, w, h,
}, 0, 0, w * this.zoom, h * this.zoom);
$render_advance: function () { },
this.$render() $render_advance: function () {
if (this.position < this.frames) { this.$render();
this.position += 1 if (this.position < this.frames) {
this.animation_id = requestAnimationFrame(this.$render_advance) this.position += 1;
if (this.record) this.capturer.capture(this.$refs.canvas) this.animation_id = requestAnimationFrame(this.$render_advance);
} else { if (this.record) this.capturer.capture(this.$refs.canvas);
this.playPause() } else {
this.position = 0 this.playPause();
if (this.record) { this.position = 0;
this.capturer.stop() if (this.record) {
this.capturer.save() this.capturer.stop();
} this.capturer.save();
} }
} }
} },
} },
};
</script> </script>
<style scoped> <style scoped>
#player { #player {
text-align: center; text-align: center;
} }
.fullscreen { .fullscreen {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
background-color: rgba(1, 1, 1, .9); background-color: rgba(1, 1, 1, .9);
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.fullscreen-controls { .fullscreen-controls {
position: absolute; position: absolute;
bottom: 0; bottom: 0;
} }
#zoom { #zoom {
width: 3em; width: 3em;
} }
</style> </style>

View File

@ -49,137 +49,140 @@
<!--suppress JSSuspiciousNameCombination --> <!--suppress JSSuspiciousNameCombination -->
<script> <script>
import Player from '@/components/Player' import Player from "@/components/Player";
export default { export default {
name: 'Sidebar', name: "Sidebar",
components: { components: {
player: Player player: Player,
}, },
data: function () { data: function () {
return { return {
imageSize: [-1, -1], imageSize: [-1, -1],
guideSizeX: 64, guideSizeX: 64,
guideSizeY: 64, guideSizeY: 64,
lastGuideSizeX: 64, lastGuideSizeX: 64,
lastGuideSizeY: 64, lastGuideSizeY: 64,
lockSize: true, lockSize: true,
cleanSize: false, cleanSize: false,
fps: 60 fps: 60,
} };
}, },
watch: { watch: {
guideSizeX (size) { guideSizeX (size) {
if (this.lockSize) this.guideSizeY = size if (this.lockSize) this.guideSizeY = size;
if (this.cleanSize) { if (this.cleanSize) {
let tmpSize = parseInt(size) let tmpSize = parseInt(size);
while (this.imageSize[0] % tmpSize !== 0 && while (this.imageSize[0] % tmpSize !== 0 &&
tmpSize < this.imageSize[0] && tmpSize < this.imageSize[0] &&
tmpSize > 2) { tmpSize > 2) {
if (this.lastGuideSizeX < size) { if (this.lastGuideSizeX < size) {
tmpSize += 1 tmpSize += 1;
} else { } else {
tmpSize -= 1 tmpSize -= 1;
}
}
if (tmpSize !== 2 && tmpSize !== this.imageSize[0]) {
this.guideSizeX = tmpSize
} }
} }
this.$emit('guideSize', [this.guideSizeX, this.guideSizeY]) if (tmpSize !== 2 && tmpSize !== this.imageSize[0]) {
this.lastGuideSizeX = this.guideSizeX this.guideSizeX = tmpSize;
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('guideSize', [this.guideSizeX, this.guideSizeY])
this.lastGuideSizeX = this.guideSizeX
this.lastGuideSizeY = this.guideSizeY
},
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
} }
} }
this.$emit("guideSize", [this.guideSizeX, this.guideSizeY]);
this.lastGuideSizeX = this.guideSizeX;
this.lastGuideSizeY = this.guideSizeY;
}, },
computed: { guideSizeY (size) {
slices: function () { if (this.lockSize) this.guideSizeX = size;
if (this.imageSize[0] === -1 || this.imageSize[1] === -1) { if (this.cleanSize) {
return '-' 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("guideSize", [this.guideSizeX, this.guideSizeY]);
this.lastGuideSizeX = this.guideSizeX;
this.lastGuideSizeY = this.guideSizeY;
},
lockSize: function (locked) {
if (locked) {
if (this.guideSizeX < this.guideSizeY) {
this.guideSizeY = this.guideSizeX;
} else { } else {
return Math.ceil(this.imageSize[0] / this.guideSizeX) * this.guideSizeX = this.guideSizeY;
Math.ceil(this.imageSize[1] / this.guideSizeY)
} }
}, this.cleanSize = false;
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: { cleanSize: function (clean) {
loadImage (e) { if (clean) {
let url = URL.createObjectURL(e.target.files[0]) this.lockSize = false;
this.$emit('loadImage', url)
} }
}, },
mounted: function () { },
this.$bus.$on('imageLoaded', (image) => { computed: {
this.imageSize = [image.width, image.height] slices: function () {
}) if (this.imageSize[0] === -1 || this.imageSize[1] === -1) {
this.$emit('guideSize', [this.guideSizeX, this.guideSizeY]) 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 "-";
} 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);
},
},
mounted: function () {
this.$bus.$on("imageLoaded", (image) => {
this.imageSize = [image.width, image.height];
});
this.$emit("guideSize", [this.guideSizeX, this.guideSizeY]);
},
};
</script> </script>
<style scoped> <style scoped>
#sidebar-container { #sidebar-container {
width: 100%; width: 100%;
height: 100%; height: 100%;
border-right: 1px solid black; border-right: 1px solid black;
} }
.spinBox { .spinBox {
height: 1em; height: 1em;
} }
.green { .green {
background-color: green; background-color: green;
} }
</style> </style>

View File

@ -1,16 +1,16 @@
export function getDimsFit (wOriginal, hOriginal, wContain, hContain) { export function getDimsFit (wOriginal, hOriginal, wContain, hContain) {
let origRatio = wOriginal / hOriginal let origRatio = wOriginal / hOriginal;
let containRatio = wContain / hContain let containRatio = wContain / hContain;
if (origRatio > containRatio) { if (origRatio > containRatio) {
return { return {
width: wContain, width: wContain,
height: wContain / origRatio height: wContain / origRatio,
} };
} else { } else {
return { return {
width: origRatio * hContain, width: origRatio * hContain,
height: hContain height: hContain,
} };
} }
} }

View File

@ -1,15 +1,15 @@
// The Vue build version to load with the `import` command // The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias. // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue' import Vue from "vue";
import App from './App' import App from "./App";
Vue.config.productionTip = false Vue.config.productionTip = false;
Vue.prototype.$bus = new Vue({}) Vue.prototype.$bus = new Vue({});
/* eslint-disable no-new */ /* eslint-disable no-new */
new Vue({ new Vue({
el: '#app', el: "#app",
template: '<App/>', template: "<App/>",
components: { App } components: {App},
}) });