Created
March 29, 2021 18:17
-
-
Save eduPHP/13267549681c3baef01fe15b16b7fdb1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <template> | |
| <div role="button" class="flex flex-col justify-center text-center" id="image-div"> | |
| <label class="cursor-pointer relative"> | |
| <input v-if="!message" type="file" @change="inputImage" class="absolute invisible h-full left-0 top-0 w-full z-20" ref="input" accept="image/*"> | |
| <img ref="preview" class="object-cover h-64 w-full" :src="resultImage"> | |
| <span class="absolute bottom-0 left-0 mb-4 py-1 text-center text-over text-white w-full z-30">{{trans('dashboard.product-create-image-label')}}</span> | |
| <button v-if="enableDelete" :title="originalImage ? 'Restore Original Image' : 'Remove Image'" @click.prevent="doDelete" class="absolute bg-red-500 m-1 right-0 rounded-full text-white top-0"> | |
| <svg class="w-5 h-5 fill-current" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"> | |
| <path d="M512.003 64C264.5703 64 64 264.5702 64 511.9918 64 759.4267 264.5702 960 512.003 960 759.4237 960 960 759.4267 960 511.9918 960 264.5702 759.4236 64 512.003 64zm0 836.2662c-214.0951 0-388.2692-174.169-388.2692-388.2754 0-214.085 174.1792-388.261 388.2693-388.261 214.089 0 388.262 174.176 388.262 388.261 0 214.1064-174.173 388.2754-388.262 388.2754zm44.8452-389.2217L695.218 374.1806c12.5725-12.4129 12.6707-32.6727.2537-45.2441-12.418-12.5796-32.7064-12.6768-45.2492-.2599l-138.559 137.0265L375.219 328.8373c-12.5152-12.509-32.7402-12.5776-45.2502-.0625-12.5132 12.4784-12.5439 32.733-.0624 45.2483l136.255 136.6694L328.782 646.5947c-12.5725 12.4528-12.6707 32.6727-.2537 45.2523 6.2704 6.3338 14.4979 9.4992 22.753 9.4992 8.1252 0 16.2555-3.101 22.4952-9.2496L511.3452 556.039l138.686 139.1351c6.2407 6.2704 14.4344 9.403 22.6568 9.403 8.1927 0 16.3517-3.1336 22.5924-9.3396 12.51-12.4804 12.5438-32.7064.0634-45.2492L556.8482 511.0445z"></path> | |
| </svg> | |
| </button> | |
| </label> | |
| <div class="absolute bottom-0 left-0 right-0 top-0 z-50 flex items-center justify-center overlay" v-show="edit || message"> | |
| <div v-click-outside="cancel" class="bg-white border modal p-4 rounded shadow"> | |
| <div v-if="message"> | |
| <alert-inline type="danger"> | |
| {{ message }} | |
| </alert-inline> | |
| <div class="mt-4"> | |
| <button class="bg-primary-600 border border-gray-400 font-bold px-6 py-1 rounded text-white uppercase" @click="cancel">Ok</button> | |
| </div> | |
| </div> | |
| <div v-show="!message" class="cursor-pointer"> | |
| <img ref="image" :src="resultImage" class="cropper-hidden" alt="Image"> | |
| </div> | |
| <div v-if="!message" class="mt-4"> | |
| <button class="border border-transparent hover:shadow-none hover:underline px-6 py-1" @click="cancel">{{ trans('dashboard.cancel') }}</button> | |
| <button class="bg-primary-600 border border-gray-400 font-bold px-6 py-1 rounded text-white uppercase" @click="getImageData">Ok</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </template> | |
| <script> | |
| import Cropper from 'cropperjs' | |
| import 'cropperjs/src/css/cropper.scss' | |
| import ClickOutside from '../../util/clickOutside' | |
| import { deleteImage } from '../../services/api/checkout' | |
| import AlertInline from '../AlertInline' | |
| export default { | |
| name: 'CheckoutImageCrop', | |
| components: { AlertInline }, | |
| props: { | |
| value: { | |
| required: true | |
| }, | |
| aspectRatio:{ | |
| type: Number, | |
| default: 1, | |
| }, | |
| }, | |
| directives: { ClickOutside }, | |
| data () { | |
| return { | |
| resultImage: '/images/image-placeholder.png', | |
| enableDelete: false, | |
| originalImage: null, | |
| cropper: null, | |
| message: null, | |
| edit: false, | |
| options: { | |
| preview: this.$refs.preview, | |
| aspectRatio: this.aspectRatio, | |
| zoomable: false, | |
| }, | |
| } | |
| }, | |
| watch: { | |
| value (val) { | |
| this.setup() | |
| }, | |
| }, | |
| methods: { | |
| deleteImage, | |
| getImageData () { | |
| if(! this.cropper) | |
| return | |
| let croppedCanvas = this.cropper.getCroppedCanvas({ | |
| maxWidth: 500, | |
| maxHeight: 500, | |
| }); | |
| this.resultImage = croppedCanvas ? croppedCanvas.toDataURL() : this.resultImage | |
| this.$emit('input', this.resultImage) | |
| this.edit = false | |
| this.enableDelete = true | |
| }, | |
| cancel () { | |
| this.edit = false | |
| this.message = null | |
| this.$refs.image.value = null | |
| this.setup() | |
| }, | |
| doDelete () { | |
| if (typeof this.value !== 'string') { | |
| this.deleteImage(this.value).then(r => { | |
| this.$snotify.info('Imagem removida.') | |
| }) | |
| } | |
| this.resultImage = '/images/image-placeholder.png' | |
| this.$emit('input', this.originalImage ? this.originalImage : null) | |
| this.enableDelete = false | |
| this.originalImage = null | |
| }, | |
| inputImage (e) { | |
| if (this.value && this.value.url) { | |
| this.originalImage = this.value | |
| } | |
| let image = this.$refs.image | |
| let files = e.target.files | |
| let file | |
| if (files && files.length && (files[0].size / 1024 / 1024) > 1.5) { | |
| this.message = 'Please use an image with 1.5MB or lower size.' | |
| this.edit = true | |
| } else if (files && files.length) { | |
| file = files[0] | |
| if (files && files.length && /^image\/\w+/.test(file.type)) { | |
| image.src = URL.createObjectURL(file) | |
| if (this.cropper) { | |
| this.cropper.destroy() | |
| } | |
| this.cropper = new Cropper(image, this.options) | |
| e.target.value = null | |
| this.edit = true | |
| } else { | |
| this.message = 'Please choose an image file.' | |
| this.edit = true | |
| } | |
| } | |
| }, | |
| setup () { | |
| if (this.value && this.value.url) { | |
| this.resultImage = this.value.url | |
| this.enableDelete = true | |
| } | |
| let escapeClose = (e) => { | |
| if (e.key === 'Escape') { | |
| this.cancel() | |
| } | |
| if (e.key === 'Enter' && !this.message) { | |
| this.getImageData() | |
| } | |
| } | |
| document.addEventListener('keydown', escapeClose) | |
| this.$on('hook:beforeDestroy', () => { | |
| document.removeEventListener('keydown', escapeClose) | |
| }) | |
| }, | |
| }, | |
| created() { | |
| this.setup(); | |
| } | |
| } | |
| </script> | |
| <style type="text/scss" scoped> | |
| .modal { | |
| max-width: 30rem; | |
| } | |
| .overlay { | |
| background-color: rgba(0, 0, 0, 0.5); | |
| } | |
| .text-over { | |
| background-color: rgba(0, 0, 0, 0.3); | |
| } | |
| #image-div { | |
| max-width: 350px; | |
| min-width: 256px; | |
| } | |
| </style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment