Loading src/components/editors/ImageResourceEditor.vue +209 −74 Original line number Diff line number Diff line Loading @@ -22,23 +22,42 @@ <div class="crop-box" :style="getCropBoxCSS"> <!-- <img :src="scaledAndRotatedImageUrl"/>--> <span class="crop-move-all" @mousedown="dragStart($event,dragDirections.all)"/> <!-- cropping lines --> <span class="crop-line crop-line-n" @mousedown="dragStart($event,dragDirections.north)"/> <span class="crop-line crop-line-e" @mousedown="dragStart($event,dragDirections.east)"/> <span class="crop-line crop-line-s" @mousedown="dragStart($event,dragDirections.south)"/> <span class="crop-line crop-line-w" @mousedown="dragStart($event,dragDirections.west)"/> <!--cropping points --> <span class="crop-point crop-point-n" :style="'background-color:'+this.color" @mousedown="dragStart($event,dragDirections.north)"/> <span class="crop-point crop-point-e" :style="'background-color:'+this.color" @mousedown="dragStart($event,dragDirections.east)"/> <span class="crop-point crop-point-s" :style="'background-color:'+this.color" @mousedown="dragStart($event,dragDirections.south)"/> <span class="crop-point crop-point-w" :style="'background-color:'+this.color" @mousedown="dragStart($event,dragDirections.west)"/> <span class="crop-point crop-point-se" :style="'background-color:'+this.color" @mousedown="dragStart($event,dragDirections.southeast)"/> <span class="crop-point crop-point-sw" :style="'background-color:'+this.color" @mousedown="dragStart($event,dragDirections.southwest)"/> <span class="crop-point crop-point-ne" :style="'background-color:'+this.color" @mousedown="dragStart($event,dragDirections.northeast)"/> <span class="crop-point crop-point-nw" :style="'background-color:'+this.color" @mousedown="dragStart($event,dragDirections.northwest)"/> </div> </div> </div> <!-- <div v-else id="img-preview" :style="getPreviewImageCSS"></div>--> <canvas v-else id="preview-canvas" class="mt-2"> <canvas v-else id="preview-canvas" class="mt-2"></canvas> </canvas> <v-card id="form" class="d-flex flex-column caption" width="80px" color="#272727"> <v-card v-if="!preview" id="form" class="d-flex flex-column caption" width="80px" color="#272727"> <v-card-text> <input type="color" v-model="color" class="mb-2"/> <v-btn small @click="reset" class="mb-5" title="reset"><v-icon>mdi-reload</v-icon></v-btn> <v-btn small @click="reset" class="mb-5" title="reset"> <v-icon>mdi-reload</v-icon> </v-btn> <v-text-field dark class="caption" hide-details dense label="Gauche" step="1" type="number" min="0" v-model="cropLeft"/> <v-text-field dark hide-details dense class="mt-8 caption" label="Haut" step="1" type="number" min="0" Loading @@ -47,7 +66,8 @@ v-model="cropRight"/> <v-text-field dark hide-details dense class="mt-8 caption" label="Bas" step="1" type="number" min="0" v-model="cropBottom"/> <v-text-field dark hide-details dense label="Rotation" class="mt-8 caption" step="0.01" type="number" min="-360" max="360" <v-text-field dark hide-details dense label="Rotation" class="mt-8 caption" step="0.01" type="number" min="-360" max="360" v-model="rotation"/> <div class="mt-5 pa-0"> <span class="mt-8 pt-5 grey--text">Zoom</span> Loading Loading @@ -77,6 +97,11 @@ const DRAG_E = 'E'; const DRAG_S = 'S'; const DRAG_W = 'W'; const DRAG_ALL = 'A'; const DRAG_SE = 'SE'; const DRAG_SW = 'SW'; const DRAG_NE = 'NE'; const DRAG_NW = 'NW'; const DEFAULT_CROP = 10; export default { name: "ImageResourceEditor", Loading Loading @@ -174,11 +199,11 @@ export default { maxHeight: null, maxWidth: null, imageDimensions: null, cropTop: 200, cropRight: 50, cropBottom: 20, cropLeft: 500, rotation: 0, cropTop: DEFAULT_CROP, cropRight: DEFAULT_CROP, cropBottom: DEFAULT_CROP, cropLeft: DEFAULT_CROP, rotation: DEFAULT_CROP, margin: 100, renderedImageDimensions: null, dragPos: {}, Loading @@ -187,6 +212,10 @@ export default { east: DRAG_E, south: DRAG_S, west: DRAG_W, southeast: DRAG_SE, southwest : DRAG_SW, northeast : DRAG_NE, northwest: DRAG_NW, all: DRAG_ALL }, preview: false, Loading Loading @@ -255,6 +284,10 @@ export default { this.dragPos.lastX = evt.clientX / this.zoom; break; case DRAG_ALL: case DRAG_SE: case DRAG_SW: case DRAG_NE : case DRAG_NW : this.dragPos.yStart = evt.clientY / this.zoom; this.dragPos.lastY = evt.clientY / this.zoom; this.dragPos.xStart = evt.clientX / this.zoom; Loading @@ -278,6 +311,22 @@ export default { case DRAG_W : this.cropLeft = Math.max(Math.floor(this.cropLeft), 0); break; case DRAG_SE: this.cropRight = Math.max(Math.floor(this.cropRight), 0); this.cropBottom = Math.max(Math.floor(this.cropBottom), 0); break; case DRAG_SW: this.cropBottom = Math.max(Math.floor(this.cropBottom), 0); this.cropLeft = Math.max(Math.floor(this.cropLeft), 0); break; case DRAG_NE : this.cropTop = Math.max(Math.floor(this.cropTop), 0); this.cropRight = Math.max(Math.floor(this.cropRight), 0); break; case DRAG_NW: this.cropTop = Math.max(Math.floor(this.cropTop), 0); this.cropLeft = Math.max(Math.floor(this.cropLeft), 0); break; case DRAG_ALL : this.cropLeft = Math.max(Math.floor(this.cropLeft), 0); this.cropRight = Math.max(Math.floor(this.cropRight), 0); Loading Loading @@ -308,6 +357,30 @@ export default { this.cropLeft += (evt.clientX / this.zoom - this.dragPos.lastX) / this.scale; this.dragPos.lastX = evt.clientX / this.zoom; break; case DRAG_SE: this.cropBottom -= (evt.clientY / this.zoom - this.dragPos.lastY) / this.scale; this.cropRight -= (evt.clientX / this.zoom - this.dragPos.lastX) / this.scale; this.dragPos.lastY = evt.clientY / this.zoom; this.dragPos.lastX = evt.clientX / this.zoom; break; case DRAG_SW: this.cropBottom -= (evt.clientY / this.zoom - this.dragPos.lastY) / this.scale; this.cropLeft += (evt.clientX / this.zoom - this.dragPos.lastX) / this.scale; this.dragPos.lastY = evt.clientY / this.zoom; this.dragPos.lastX = evt.clientX / this.zoom; break; case DRAG_NE : this.cropRight -= (evt.clientX / this.zoom - this.dragPos.lastX) / this.scale; this.cropTop += (evt.clientY / this.zoom - this.dragPos.lastY) / this.scale; this.dragPos.lastY = evt.clientY / this.zoom; this.dragPos.lastX = evt.clientX / this.zoom; break; case DRAG_NW : this.cropLeft += (evt.clientX / this.zoom - this.dragPos.lastX) / this.scale; this.cropTop += (evt.clientY / this.zoom - this.dragPos.lastY) / this.scale; this.dragPos.lastY = evt.clientY / this.zoom; this.dragPos.lastX = evt.clientX / this.zoom; break; case DRAG_ALL : this.cropLeft += (evt.clientX / this.zoom - this.dragPos.lastX) / this.scale; this.cropRight -= (evt.clientX / this.zoom - this.dragPos.lastX) / this.scale; Loading Loading @@ -362,7 +435,6 @@ export default { } } } </script> Loading @@ -374,6 +446,7 @@ export default { max-height: 100vh; overflow-x: hidden; } #form { position: fixed; top: 20px; Loading Loading @@ -442,4 +515,66 @@ input[type=color]{ left: 0; } .crop-point { //background-color: #0000FF; height: 5px; opacity: 0.75; width: 5px; display: block; position: absolute; } .crop-point-e { cursor: e-resize; margin-top: -3px; right: -3px; top: 50%; } .crop-point-n { cursor: s-resize; margin-left: -3px; top: -3px; left: 50%; } .crop-point-s { bottom: -3px; cursor: s-resize; left: 50%; margin-left: -3px; } .crop-point-w { cursor: w-resize; left: -3px; margin-top: -3px; top: 50%; } .crop-point-se { //height: 5px; //opacity: 0.75; //width: 5px; bottom: -3px; cursor: nwse-resize; right: -3px; } .crop-point-sw { bottom: -3px; cursor: nesw-resize; left: -3px; } .crop-point-ne { cursor: nesw-resize; right: -3px; top: -3px; } .crop-point-nw { cursor: nwse-resize; left: -3px; top: -3px; } </style> Loading
src/components/editors/ImageResourceEditor.vue +209 −74 Original line number Diff line number Diff line Loading @@ -22,23 +22,42 @@ <div class="crop-box" :style="getCropBoxCSS"> <!-- <img :src="scaledAndRotatedImageUrl"/>--> <span class="crop-move-all" @mousedown="dragStart($event,dragDirections.all)"/> <!-- cropping lines --> <span class="crop-line crop-line-n" @mousedown="dragStart($event,dragDirections.north)"/> <span class="crop-line crop-line-e" @mousedown="dragStart($event,dragDirections.east)"/> <span class="crop-line crop-line-s" @mousedown="dragStart($event,dragDirections.south)"/> <span class="crop-line crop-line-w" @mousedown="dragStart($event,dragDirections.west)"/> <!--cropping points --> <span class="crop-point crop-point-n" :style="'background-color:'+this.color" @mousedown="dragStart($event,dragDirections.north)"/> <span class="crop-point crop-point-e" :style="'background-color:'+this.color" @mousedown="dragStart($event,dragDirections.east)"/> <span class="crop-point crop-point-s" :style="'background-color:'+this.color" @mousedown="dragStart($event,dragDirections.south)"/> <span class="crop-point crop-point-w" :style="'background-color:'+this.color" @mousedown="dragStart($event,dragDirections.west)"/> <span class="crop-point crop-point-se" :style="'background-color:'+this.color" @mousedown="dragStart($event,dragDirections.southeast)"/> <span class="crop-point crop-point-sw" :style="'background-color:'+this.color" @mousedown="dragStart($event,dragDirections.southwest)"/> <span class="crop-point crop-point-ne" :style="'background-color:'+this.color" @mousedown="dragStart($event,dragDirections.northeast)"/> <span class="crop-point crop-point-nw" :style="'background-color:'+this.color" @mousedown="dragStart($event,dragDirections.northwest)"/> </div> </div> </div> <!-- <div v-else id="img-preview" :style="getPreviewImageCSS"></div>--> <canvas v-else id="preview-canvas" class="mt-2"> <canvas v-else id="preview-canvas" class="mt-2"></canvas> </canvas> <v-card id="form" class="d-flex flex-column caption" width="80px" color="#272727"> <v-card v-if="!preview" id="form" class="d-flex flex-column caption" width="80px" color="#272727"> <v-card-text> <input type="color" v-model="color" class="mb-2"/> <v-btn small @click="reset" class="mb-5" title="reset"><v-icon>mdi-reload</v-icon></v-btn> <v-btn small @click="reset" class="mb-5" title="reset"> <v-icon>mdi-reload</v-icon> </v-btn> <v-text-field dark class="caption" hide-details dense label="Gauche" step="1" type="number" min="0" v-model="cropLeft"/> <v-text-field dark hide-details dense class="mt-8 caption" label="Haut" step="1" type="number" min="0" Loading @@ -47,7 +66,8 @@ v-model="cropRight"/> <v-text-field dark hide-details dense class="mt-8 caption" label="Bas" step="1" type="number" min="0" v-model="cropBottom"/> <v-text-field dark hide-details dense label="Rotation" class="mt-8 caption" step="0.01" type="number" min="-360" max="360" <v-text-field dark hide-details dense label="Rotation" class="mt-8 caption" step="0.01" type="number" min="-360" max="360" v-model="rotation"/> <div class="mt-5 pa-0"> <span class="mt-8 pt-5 grey--text">Zoom</span> Loading Loading @@ -77,6 +97,11 @@ const DRAG_E = 'E'; const DRAG_S = 'S'; const DRAG_W = 'W'; const DRAG_ALL = 'A'; const DRAG_SE = 'SE'; const DRAG_SW = 'SW'; const DRAG_NE = 'NE'; const DRAG_NW = 'NW'; const DEFAULT_CROP = 10; export default { name: "ImageResourceEditor", Loading Loading @@ -174,11 +199,11 @@ export default { maxHeight: null, maxWidth: null, imageDimensions: null, cropTop: 200, cropRight: 50, cropBottom: 20, cropLeft: 500, rotation: 0, cropTop: DEFAULT_CROP, cropRight: DEFAULT_CROP, cropBottom: DEFAULT_CROP, cropLeft: DEFAULT_CROP, rotation: DEFAULT_CROP, margin: 100, renderedImageDimensions: null, dragPos: {}, Loading @@ -187,6 +212,10 @@ export default { east: DRAG_E, south: DRAG_S, west: DRAG_W, southeast: DRAG_SE, southwest : DRAG_SW, northeast : DRAG_NE, northwest: DRAG_NW, all: DRAG_ALL }, preview: false, Loading Loading @@ -255,6 +284,10 @@ export default { this.dragPos.lastX = evt.clientX / this.zoom; break; case DRAG_ALL: case DRAG_SE: case DRAG_SW: case DRAG_NE : case DRAG_NW : this.dragPos.yStart = evt.clientY / this.zoom; this.dragPos.lastY = evt.clientY / this.zoom; this.dragPos.xStart = evt.clientX / this.zoom; Loading @@ -278,6 +311,22 @@ export default { case DRAG_W : this.cropLeft = Math.max(Math.floor(this.cropLeft), 0); break; case DRAG_SE: this.cropRight = Math.max(Math.floor(this.cropRight), 0); this.cropBottom = Math.max(Math.floor(this.cropBottom), 0); break; case DRAG_SW: this.cropBottom = Math.max(Math.floor(this.cropBottom), 0); this.cropLeft = Math.max(Math.floor(this.cropLeft), 0); break; case DRAG_NE : this.cropTop = Math.max(Math.floor(this.cropTop), 0); this.cropRight = Math.max(Math.floor(this.cropRight), 0); break; case DRAG_NW: this.cropTop = Math.max(Math.floor(this.cropTop), 0); this.cropLeft = Math.max(Math.floor(this.cropLeft), 0); break; case DRAG_ALL : this.cropLeft = Math.max(Math.floor(this.cropLeft), 0); this.cropRight = Math.max(Math.floor(this.cropRight), 0); Loading Loading @@ -308,6 +357,30 @@ export default { this.cropLeft += (evt.clientX / this.zoom - this.dragPos.lastX) / this.scale; this.dragPos.lastX = evt.clientX / this.zoom; break; case DRAG_SE: this.cropBottom -= (evt.clientY / this.zoom - this.dragPos.lastY) / this.scale; this.cropRight -= (evt.clientX / this.zoom - this.dragPos.lastX) / this.scale; this.dragPos.lastY = evt.clientY / this.zoom; this.dragPos.lastX = evt.clientX / this.zoom; break; case DRAG_SW: this.cropBottom -= (evt.clientY / this.zoom - this.dragPos.lastY) / this.scale; this.cropLeft += (evt.clientX / this.zoom - this.dragPos.lastX) / this.scale; this.dragPos.lastY = evt.clientY / this.zoom; this.dragPos.lastX = evt.clientX / this.zoom; break; case DRAG_NE : this.cropRight -= (evt.clientX / this.zoom - this.dragPos.lastX) / this.scale; this.cropTop += (evt.clientY / this.zoom - this.dragPos.lastY) / this.scale; this.dragPos.lastY = evt.clientY / this.zoom; this.dragPos.lastX = evt.clientX / this.zoom; break; case DRAG_NW : this.cropLeft += (evt.clientX / this.zoom - this.dragPos.lastX) / this.scale; this.cropTop += (evt.clientY / this.zoom - this.dragPos.lastY) / this.scale; this.dragPos.lastY = evt.clientY / this.zoom; this.dragPos.lastX = evt.clientX / this.zoom; break; case DRAG_ALL : this.cropLeft += (evt.clientX / this.zoom - this.dragPos.lastX) / this.scale; this.cropRight -= (evt.clientX / this.zoom - this.dragPos.lastX) / this.scale; Loading Loading @@ -362,7 +435,6 @@ export default { } } } </script> Loading @@ -374,6 +446,7 @@ export default { max-height: 100vh; overflow-x: hidden; } #form { position: fixed; top: 20px; Loading Loading @@ -442,4 +515,66 @@ input[type=color]{ left: 0; } .crop-point { //background-color: #0000FF; height: 5px; opacity: 0.75; width: 5px; display: block; position: absolute; } .crop-point-e { cursor: e-resize; margin-top: -3px; right: -3px; top: 50%; } .crop-point-n { cursor: s-resize; margin-left: -3px; top: -3px; left: 50%; } .crop-point-s { bottom: -3px; cursor: s-resize; left: 50%; margin-left: -3px; } .crop-point-w { cursor: w-resize; left: -3px; margin-top: -3px; top: 50%; } .crop-point-se { //height: 5px; //opacity: 0.75; //width: 5px; bottom: -3px; cursor: nwse-resize; right: -3px; } .crop-point-sw { bottom: -3px; cursor: nesw-resize; left: -3px; } .crop-point-ne { cursor: nesw-resize; right: -3px; top: -3px; } .crop-point-nw { cursor: nwse-resize; left: -3px; top: -3px; } </style>