switched to Croppa

master
Maksim 2019-01-28 00:35:32 -08:00
rodzic 5e6789fc5c
commit b9ed1d6196
11 zmienionych plików z 100 dodań i 127 usunięć

14
package-lock.json wygenerowano
Wyświetl plik

@ -1622,6 +1622,11 @@
"integrity": "sha512-ogq4NbUWf1uG/j66k0AmiO3GjqJAlQyF8n4w8a954cbCyFKmYGvRtgz6qkq2fWuduTXHibX7GyYL5Pg58Aks2g==",
"dev": true
},
"canvas-exif-orientation": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/canvas-exif-orientation/-/canvas-exif-orientation-0.4.0.tgz",
"integrity": "sha1-tIfzcBmYqeh56xBAELKlgRU2i2s="
},
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
@ -10974,6 +10979,15 @@
"resolved": "https://registry.npmjs.org/vue/-/vue-2.5.21.tgz",
"integrity": "sha512-Aejvyyfhn0zjVeLvXd70h4hrE4zZDx1wfZqia6ekkobLmUZ+vNFQer53B4fu0EjWBSiqApxPejzkO1Znt3joxQ=="
},
"vue-croppa": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/vue-croppa/-/vue-croppa-1.3.8.tgz",
"integrity": "sha512-WwYgEKscTCD7BzhnbfRJfzWIU6RcMq2JRimB3aI5gGzpADmpKuqmDh9+oVfiZaEnpmRthgXZxcAvbxU6CeIU9w==",
"requires": {
"canvas-exif-orientation": "^0.4.0",
"object-assign": "^4.1.1"
}
},
"vue-hot-reload-api": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.1.tgz",

Wyświetl plik

@ -39,6 +39,7 @@
"normalize.css": "^8.0.1",
"pica": "^5.0.0",
"vue": "^2.5.2",
"vue-croppa": "^1.3.8",
"vue-worker": "^1.2.1"
},
"devDependencies": {

Wyświetl plik

@ -11,8 +11,8 @@
<image-chooser @selected="onInputSelected"></image-chooser>
<div class="image-upload" v-if="this.inputType === 'upload'">
<loader v-if="!cropper.loaded" ref="loader" :data="cropper"></loader>
<crop-actions v-if="cropper.loaded" :data="cropper" @change="change"></crop-actions>
<croppa v-model="myCroppa" :width="250" :height="250" :preventWhiteSpace="true" :quality="2"></croppa>
<button @click="uploadCroppedImage">Output JPEG</button>
</div>
<div class="image-webcam" v-if="this.inputType === 'webcam'">
@ -102,24 +102,21 @@
</div>
<div class="actions">
<button class="btn">
PNG
JPG
</button>
<button class="btn">
<button class="btn" @click="downloadSVG">
SVG
</button>
<button class="btn">
ZIP
</button>
</div>
<div class="panel-toggle">
<button id="panelToggler" class="btn"><span class="fa fa-chevron-left"></span></button>
</div>
</aside>
<main>
<div v-if="canvasData" class="svg-container" style="padding: 10px;" ref="container">
<svg-chart :lines="lines" :options="line" :width="settings.width" :height="settings.height"></svg-chart>
<svg-chart ref="svgResult" :lines="lines" :options="line" :width="settings.width" :height="settings.height"></svg-chart>
</div>
<editor v-if="cropper.loaded" ref="editor" :data="cropper"></editor>
</main>
</div>
</div>
@ -127,9 +124,9 @@
</template>
<script>
import Navbar from './components/Navbar'
import Loader from './components/Loader'
import Editor from './components/Editor'
// import Navbar from './components/Navbar'
// import Loader from './components/Loader'
// import Editor from './components/Editor'
import ImageChooser from './components/ImageChooser'
import WebCam from './components/WebCam'
import svgChart from './components/svgChart';
@ -137,15 +134,17 @@
export default {
name: 'App',
components: {
cropActions: Navbar ,
loader: Loader,
editor: Editor,
//cropActions: Navbar ,
//loader: Loader,
//editor: Editor,
imageChooser: ImageChooser,
webcam: WebCam,
svgChart: svgChart
},
data() {
return {
myCroppa: {},
dataUrl: '',
line: {
smoothing: 0.25,
flattening: 0.5
@ -173,16 +172,16 @@
devices: [],
streaming: false
},
cropper: {
cropped: false,
cropping: false,
loaded: false,
name: '',
previousUrl: '',
type: '',
url: '',
croppedImageData: ''
},
// cropper: {
// cropped: false,
// cropping: false,
// loaded: false,
// name: '',
// previousUrl: '',
// type: '',
// url: '',
// croppedImageData: ''
// },
};
},
@ -198,12 +197,12 @@
this.webcam.deviceId = first.deviceId;
}
},
'cropper.croppedImageData': function(){
const canvas = this.cropper.croppedImageData;
const ctx = canvas.getContext("2d");
this.canvasData = ctx.getImageData(0, 0, 500, 500);
return true;
},
// 'cropper.croppedImageData': function(){
// const canvas = this.cropper.croppedImageData;
// const ctx = canvas.getContext("2d");
// this.canvasData = ctx.getImageData(0, 0, 500, 500);
// return true;
// },
'settings.frequency': function(){
this.processImage();
},
@ -219,6 +218,28 @@
},
methods: {
downloadSVG(){
console.log(this.$refs.svgResult.$el.innerHTML);
},
uploadCroppedImage() {
this.myCroppa.generateBlob((blob) => {
let canvas = document.createElement("canvas");
canvas.width = 500;
canvas.height = 500;
// const ctx = canvas.getContext("2d");
// this.canvasData = ctx.getImageData(0, 0, 500, 500);
const ctx = canvas.getContext('2d');
let img = new Image();
img.onload = () => {
ctx.drawImage(img, 0, 0)
this.canvasData = ctx.getImageData(0, 0, 500, 500);
};
img.src = URL.createObjectURL(blob);
}, 'image/jpeg', 1)
},
processImage() {
this.$worker.run((data) => {
// Gather all necessary data from the main thread
@ -252,7 +273,7 @@
// starting pixel for each line will be this
// Loop through pixels from left to right within the current line, advancing by increments of config.SPACING
console.log(config.spacing, width);
//console.log(config.spacing, width);
for (let x = config.spacing; x < width; x += config.spacing ) {
currentHorizontalPixelIndex = x + currentVerticalPixelIndex; // Get array position of current pixel
@ -358,21 +379,21 @@
<style lang="scss">
@import './styles/index.scss';
.cropper-header {
background-color: #666;
height: 3rem;
overflow: hidden;
padding-left: 1rem;
padding-right: 1rem;
position: relative;
z-index: 1;
}
@media (min-width: 768px) {
.cropper-header {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
}
/*.cropper-header {*/
/*background-color: #666;*/
/*height: 3rem;*/
/*overflow: hidden;*/
/*padding-left: 1rem;*/
/*padding-right: 1rem;*/
/*position: relative;*/
/*z-index: 1;*/
/*}*/
/*@media (min-width: 768px) {*/
/*.cropper-header {*/
/*padding-left: 1.5rem;*/
/*padding-right: 1.5rem;*/
/*}*/
/*}*/
.title {
color: #fff;
display: block;

Wyświetl plik

@ -3,7 +3,6 @@
<div class="button-group stretch">
<label>Input:</label>
<button id="upload" :disabled="disabled" v-bind:class="{ active: selectedItem === 'upload' }" class="btn" @click="toggle">File</button>
<!--<button id="url" :disabled="disabled" v-bind:class="{ active: selectedItem === 'url' }" class="btn" @click="toggle">URL</button>-->
<button id="webcam" :disabled="disabled" class="btn" v-bind:class="{ active: selectedItem === 'webcam' }" @click="toggle">WebCam</button>
</div>
</div>

Wyświetl plik

@ -1,13 +0,0 @@
<template>
</template>
<script>
export default {
name: "ImageTransformer"
}
</script>
<style scoped>
</style>

Wyświetl plik

@ -1,13 +0,0 @@
<template>
</template>
<script>
export default {
name: "SquiggleDataRetriever"
}
</script>
<style scoped>
</style>

Wyświetl plik

@ -1,13 +0,0 @@
<template>
</template>
<script>
export default {
name: "SquiggleRenderer"
}
</script>
<style scoped>
</style>

Wyświetl plik

@ -23,5 +23,9 @@
</script>
<style scoped>
path {
fill: none;
stroke: #0f0f0f;
stroke-width: 1.5px;
}
</style>

Wyświetl plik

@ -1,5 +1,5 @@
<template>
<path :style="styles.path" :d="pathD"></path>
<path :d="pathD"></path>
</template>
<script>
@ -9,15 +9,6 @@
name: "svgChartLine",
props: ["d", "o"],
computed: {
styles() {
return {
path: {
fill: 'none',
stroke: "#000",
strokeWidth: 1
}
};
},
pathD() {
return this.pointsPositions.reduce((acc, e, i, a) => i === 0
? `M ${e[0]},${e[1]}`
@ -45,20 +36,16 @@
const flat = lib.map(Math.cos(o.angle) * this.o.flattening, 0, 1, 1, 0)
const angle = o.angle * flat + (reverse ? Math.PI : 0);
const length = o.length * this.o.smoothing;
const x = current[0] + Math.cos(angle) * length;
const y = current[1] + Math.sin(angle) * length;
const x = Math.round((current[0] + Math.cos(angle) * length) * 100) / 100 ;
const y = Math.round((current[1] + Math.sin(angle) * length) * 100) / 100 ;
return [x, y];
},
bezierCommand(point, i, a) {
const cps = this.controlPoint(a[i - 1], a[i - 2], point);
const cpe = this.controlPoint(point, a[i - 1], a[i + 1], true);
//const close = i === a.length - 1 ? " z" : "";
return `C ${cps[0]},${cps[1]} ${cpe[0]},${cpe[1]} ${point[0]},${point[1]}`;
return `C ${cps[0]},${cps[1]} ${cpe[0]},${cpe[1]} ${Math.round(point[0] * 100) / 100},${Math.round(point[1]*100)/100}`;
}
}
}
</script>
<style scoped>
</style>

Wyświetl plik

@ -4,13 +4,18 @@ import 'normalize.css'
import Vue from 'vue'
import App from './App'
import VueWorker from 'vue-worker';
import Croppa from 'vue-croppa'
//import './styles/index.scss'
import 'cropperjs/dist/cropper.css';
//import 'cropperjs/dist/cropper.css';
Vue.config.productionTip = false
import 'vue-croppa/dist/vue-croppa.css'
Vue.config.productionTip = false;
Vue.use(VueWorker);
Vue.use(Croppa);
/* eslint-disable no-new */
@ -18,4 +23,4 @@ new Vue({
el: '#app',
components: { App },
template: '<App/>'
})
});

Wyświetl plik

@ -344,25 +344,6 @@ input[type="range"]:focus::-ms-fill-upper {
align-content: space-between;
}
.panel-toggle {
position: absolute;
right: -12px;
bottom: 50px;
z-index: 1;
//align-self: center;
.btn {
z-index: 100;
background-color: #000;
padding: 20px 0;
}
.btn:hover {
color: #fff;
background-color: #0069d9;
border-color: #0062cc;
}
}
.image-webcam {
position: relative;