"vue js image resize"
Bootstrap 3.0.0 Snippet by evarevirus

<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> <script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script> <script src="//code.jquery.com/jquery-1.11.1.min.js"></script> <!------ Include the above in your HEAD tag ----------> <!DOCTYPE html><html class=''> <head><script src='//production-assets.codepen.io/assets/editor/live/console_runner-079c09a0e3b9ff743e39ee2d5637b9216b3545af0de366d4b9aad9dc87e26bfd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/events_runner-73716630c22bbc8cff4bd0f07b135f00a0bdc5d14629260c3ec49e5606f98fdd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/css_live_reload_init-2c0dc5167d60a5af3ee189d570b1835129687ea2a61bee3513dee3a50c115a77.js'></script><meta charset='UTF-8'><meta name="robots" content="noindex"><link rel="shortcut icon" type="image/x-icon" href="//production-assets.codepen.io/assets/favicon/favicon-8ea04875e70c4b0bb41da869e81236e54394d63638a1ef12fa558a4a835f1164.ico" /><link rel="mask-icon" type="" href="//production-assets.codepen.io/assets/favicon/logo-pin-f2d2b6d2c61838f7e76325261b7195c27224080bc099486ddd6dccb469b8e8e6.svg" color="#111" /><link rel="canonical" href="https://codepen.io/dannyrb/pen/ZLWVBq" /> <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,700" rel="stylesheet"> <link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css'> <style class="cp-pen-styles">/******************************* * HTML5 Canvas Image Uploader *******************************/ /* Trickery to allow hidden input, but get around safety checks by browsers */ .image-input__input { position: absolute; top: -10px; left: -10px; width: 9px; height: 9px; cursor: pointer; } .image-input__container { position: absolute; overflow: hidden; border: 1px dashed #FFF; box-sizing: border-box; /* display border inside */ -moz-box-sizing: border-box; -webkit-box-sizing: border-box; } .image-input__container:hover { border: 1px solid #7FCC29; -webkit-transition: 0.15s border; transition: 0.15s border; background: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/424395/camera.svg"); background-size: 50px 41px; background-position: center; background-repeat: no-repeat; } .image-input__overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; cursor: pointer; } .image-loaded .image-input__overlay { display: none; } .image-input__control-buttons { display: none; position: absolute; top: 5px; left: 5px; } .image-loaded .image-input__control-buttons { display: block; } .image-input__control-buttons button { margin: 0; padding: 0; width: 25px; height: 25px; } .image-input__canvas.is-draggable { cursor: move; } /******************************* * Demo Styles *******************************/ body { color: #FFF; background-color: #533A71; font-family: 'Roboto', sans-serif; } h1 { margin-bottom: 0; } .sub { font-style: italic; font-weight: 300; } .app-container { margin: 0 auto; min-width: 650px; max-width: 800px; } #app { position: relative; } .image-uploader { position: absolute; margin: 20px 10px; left: 0; } .text-area-section { position: absolute; margin: 20px 10px; padding: 0; width: 300px; height: 200px; overflow: hidden; right: 0; } textarea { width: 100%; height: 100%; } </style></head><body> <main class="app-container"> <h1>VueJS + HTML5 Canvas</h1> <span class="sub">Image upload, resize, crop, and base64 converter</span> <div id="app"> <image-uploader width="300px" height="200px"> </image-uploader> <section class="text-area-section"> <textarea v-model="sharedData.imageData"> </textarea> </section> </div> </main> <!-- --> <script type="text/x-template" id="image-uploader-template"> <div class="image-input__container image-uploader" v-bind:style="containerStyles" v-bind:class="{ 'image-loaded': isImageLoaded }"> <!-- Hidden input we use to access file contents --> <form class="image-input__form" ref="form"> <input @change="previewThumbnail" class="image-input__input" ref="fileInput" type="file" /> </form> <div v-on:click="triggerInput" class="image-input__overlay"></div> <div class="image-input__control-buttons"> <button v-on:click="toBase64" type="button" class="to-base64">64</button> <button v-on:click="scaleUp" type="button" class="scale-up">+</button> <button v-on:click="scaleDown" type="button" class="scale-down">-</button> <button v-on:click="resetInput" type="button" class="reset-input">x</button> </div> <!-- Used in place of an image tag --> <canvas class="image-input__canvas" ref="canvas" v-bind:height="height" v-bind:width="width" v-bind:class="{ 'is-draggable': hoverIsDraggable }"> </canvas> </div> </script> <script src='//production-assets.codepen.io/assets/common/stopExecutionOnTimeout-b2a7b3fe212eaa732349046d8416e00a9dec26eb7fd347590fbced3ab38af52e.js'></script><script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.5/vue.min.js'></script><script src='https://cdnjs.cloudflare.com/ajax/libs/vue-router/2.0.1/vue-router.min.js'></script><script src='https://cdnjs.cloudflare.com/ajax/libs/vue-resource/1.0.3/vue-resource.min.js'></script><script src='https://cdnjs.cloudflare.com/ajax/libs/vuex/2.0.0/vuex.js'></script> <script >'use strict'; var sharedData = { imageData: '', updateImageData: function updateImageData(newData) { this.imageData = newData; } }; Vue.component('image-uploader', { template: '#image-uploader-template', props: ['id', 'width', 'height'], // Must be a function in component definition data: function data() { return { isImageLoaded: false, hoverIsDraggable: false, // Image ctx: null, canvas: null, img: null, // Properties scaleSteps: 0, imageX: 0, imageY: 0, scaledImageWidth: 0, scaledImageHeight: 0, imageWidth: 0, imageHeight: 0, imageRight: 0, imageBottom: 0, // State draggingImage: false, // Mouse startX: 0, startY: 0, mouseX: 0, mouseY: 0, sharedData: window.sharedData }; }, computed: { containerStyles: function containerStyles() { return { width: this.width, height: this.height }; } }, mounted: function mounted() { this.$on('get-image-base64', function () { console.log("ON'ING"); this.updateTemplateImage(); }); // Instantiate this.canvas = this.$refs.canvas; this.ctx = this.canvas.getContext("2d"); this.img = document.createElement("img"); }, methods: { toBase64: function toBase64() { var imageData = this.canvas.toDataURL("image/png"); imageData.replace('data:image/png;base64,', ''); this.sharedData.updateImageData(imageData); }, draw: function draw(withBorders) { // clear the canvas this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); // some maths var scaleFactor = 1 - this.scaleSteps * .1; this.scaledImageWidth = this.img.width * scaleFactor; this.scaledImageHeight = this.scaledImageWidth * (this.img.height / this.img.width); // draw the image // this.ctx.drawImage( // this.img, (top left coords of source to use (x,y)), // width & height of source to use (width, height) // (x,y) on canvas // width & height on canvas this.ctx.drawImage(this.img, 0, 0, this.img.width, this.img.height, this.imageX, this.imageY, this.scaledImageWidth, this.scaledImageHeight); this.imageRight = this.imageX + this.scaledImageWidth; this.imageBottom = this.imageY + this.scaledImageHeight; // optionally draw a box around the image (indicates "selected") if (withBorders) { this.ctx.beginPath(); this.ctx.moveTo(this.imageX, this.imageY); this.ctx.lineTo(this.imageRight, this.imageY); this.ctx.lineTo(this.imageRight, this.imageBottom); this.ctx.lineTo(this.imageX, this.imageBottom); this.ctx.closePath(); this.ctx.stroke(); } }, resetInput: function resetInput() { // clear the canvas this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); // Reset state this.$refs.form.reset(); this.isImageLoaded = false; }, scaleUp: function scaleUp() { this.scaleSteps--; this.draw(false); }, scaleDown: function scaleDown() { this.scaleSteps++; this.draw(false); }, getMousePos: function getMousePos(evt) { var rect = this.canvas.getBoundingClientRect(), // abs. size of element scaleX = this.canvas.width / rect.width, // relationship bitmap vs. element for X scaleY = this.canvas.height / rect.height; // relationship bitmap vs. element for Y return { x: (evt.clientX - rect.left) * scaleX, // scale mouse coordinates after they have y: (evt.clientY - rect.top) * scaleY // been adjusted to be relative to element }; }, isImageHit: function isImageHit(x, y) { return x > this.imageX && x < this.imageX + this.imageWidth && y > this.imageY && y < this.imageY + this.imageHeight; }, triggerInput: function triggerInput(event) { event.preventDefault(); this.$refs.fileInput.click(); }, previewThumbnail: function previewThumbnail(event) { var vm = this; var input = event.target; if (input.files && input.files[0]) { var reader = new FileReader(); // Set as source reader.onload = function (e) { vm.img.src = e.target.result; }; reader.readAsDataURL(input.files[0]); vm.img.onload = function () { // Draw vm.ctx.drawImage(vm.img, 0, 0); // Grab position info vm.imageWidth = vm.img.width; vm.imageHeight = vm.img.height; vm.imageRight = vm.imageX + vm.imageWidth; vm.imageBottom = vm.imageY + vm.imageHeight; // Update CTX vm.draw(false); // Notify component vm.isImageLoaded = true; }; } function handleMouseDown(e) { var pos = vm.getMousePos(e); vm.startX = pos.x; vm.startY = pos.y; vm.draggingImage = vm.hoverIsDraggable; } function handleMouseUp(e) { vm.draggingImage = false; vm.draw(false); } function handleMouseOut(e) { handleMouseUp(e); } function handleMouseMove(e) { // Update cursor property var (; var pos = vm.getMousePos(e); vm.hoverIsDraggable = vm.isImageHit(pos.x, pos.y); if (vm.draggingImage) { // vm.mouseX = pos.x; vm.mouseY = pos.y; // move the image by the amount of the latest drag var dx = vm.mouseX - vm.startX; var dy = vm.mouseY - vm.startY; // Lock image to canvas viewport var collidedOnLeft = vm.imageX > 0 && dx > 0; var collidedOnRight = vm.imageRight < vm.canvas.width && dx < 0; var collidedOnTop = vm.imageY > 0 && dy > 0; var collidedOnBottom = vm.imageBottom < vm.canvas.height && dy < 0; if (collidedOnLeft) { vm.imageX = 0; vm.imageRight = vm.scaledImageWidth; } else if (collidedOnRight) { vm.imageX = vm.canvas.width - vm.scaledImageWidth; vm.imageRight = vm.canvas.width; } else { vm.imageX += dx; vm.imageRight += dx; } if (collidedOnTop) { vm.imageY = 0; vm.imageBottom = vm.scaledImageHeight; } else if (collidedOnBottom) { vm.imageY = vm.canvas.height - vm.scaledImageHeight; vm.imageBottom = vm.canvas.height; } else { vm.imageY += dy; vm.imageBottom += dy; } // Reset the startXY for next time vm.startX = vm.mouseX; vm.startY = vm.mouseY; // Redraw the image with border vm.draw(true); } } // END MOUSEMOVE // LISTEN (: vm.canvas.addEventListener('mousedown', handleMouseDown, false); vm.canvas.addEventListener('mousemove', handleMouseMove, false); vm.canvas.addEventListener('mouseup', handleMouseUp, false); vm.canvas.addEventListener('mouseout', handleMouseOut, false); } } }); var app = new Vue({ el: '#app', data: { sharedData: window.sharedData }, methods: {} }); //# sourceURL=pen.js </script> </body></html>

Related: See More


Questions / Comments: