In this paper, the image uploading component of Element-UI is mainly used to obtain the image, and then cropper.js is used to cut the image, and then the image is uploaded by itself. The CSS in this paper is compiled by Stylus, if not, please change it by yourself

Effect of cutting

1. Install the plug-in

npm install cropperjs --save
Copy the code

I won’t go into detail about the installation of The Element-UI, which mainly uses the image upload and $message

2. Component writing

  • New directory

Create an Upload folder under the Components folder, then create cropperbox. vue and upcover. vue under the Upload folder

  • writecropperBox.vue

In cropperbox.vue, write the following. (Select the bloB data format for the finishCropImage method. The first is bloB, and the second is plain file.)

<template>
  <div class="cropper-wrap">
    <div class="cropper-alert-mask" :class="{ show: imgHasLoad }"></div>
    <div class="cropper-alert" :class="{ show: imgHasLoad }">
      <div class="cropper">
 <span class="layout-icon-wrap"><i class="el-icon-circle-close" @click="imgHasLoad=false"></i></span>  <div class="cropper-box">  <img ref="uploadPreview" style="width:100px; height:auto;">  </div>  <div class="cropper-res-wrap">  <div class="cropper-res" id="cropperRes">  <img style="width:100px; height:100px;">  </div>  </div>  </div>  <div class="cropper-btns-wrap">  <el-progress  :text-inside="true"  :stroke-width="30"  :percentage="uploadProgress">  </el-progress>  <button  type="button"  class="cropper-btn"  @click="finishCropImage"  :disabled="btnTips.disable"  :class="{'btn-bg': uploading}">  {{ btnTips.value }}  </button>  </div>  </div>  </div> </template>  <script> import Cropper from 'cropperjs'  export default {  name: 'cropper-box'. props: {  options: {  default: {  aspectRatio: 1 / 1. preview: '#cropperRes'. zoomOnWheel: false. minCropBoxWidth: 50. viewMode:2. }  },  uploadProgress: {  default: 0  }  },  data () {  return {  cropper: null. imgHasLoad: false. cropperHasInit: false. uploading: false. rawFile: null  }  },  watch: {  imgHasLoad (val) {  if(! val) { this.uploading = false  }  }  },  computed: {  btnTips () {  if (this.uploading) {  return {  value: 'Uploading, please wait'. disable: true  }  }  return {  value: 'Crop done, upload now'. disable: false  }  }  },  methods: {  show () {  this.imgHasLoad = true  },  close () {  this.imgHasLoad = false  },  loadCropper (rawFile) {  this.rawFile = rawFile  const URL = window.URL || window.webkitURL  const blobURL = URL.createObjectURL(rawFile)  var image = this.$refs.uploadPreview  if (!this.cropper) this.cropper = new Cropper(image, this.options)  this.cropper.reset().replace(blobURL)  },  // Select normal file format or BLOB format. The format conversion method has been wrapped, see the following two methods  finishCropImage () {  this.uploading = true   const croppedCanvas = this.cropper.getCroppedCanvas()  const croppedDataUrl = croppedCanvas.toDataURL(this.rawFile.type)  const blob = this.base64toFile(croppedDataUrl)  this.$emit('finishCropImage', blob)  },  / / dataUrl blob  dataURLtoBlob (dataurl) {  /* eslint-disable */  var arr = dataurl.split(', '), mime = arr[0].match(/ : (. *?) ; /) [1];  var bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);  while(n--){  u8arr[n] = bstr.charCodeAt(n);  }  return new Blob([u8arr], {type:mime});  /* eslint-enable */  },  //base64 converts to a common file format  base64toFile (dataurl, filename = 'file') {  let arr = dataurl.split(', ')  let mime = arr[0].match(/ : (. *?) ; /) [1]  let suffix = mime.split('/') [1]  let bstr = atob(arr[1])  let n = bstr.length  let u8arr = new Uint8Array(n)  while (n--) {  u8arr[n] = bstr.charCodeAt(n)  }  return new File([u8arr], `${filename}.${suffix}`, {  type: mime  })  },  } } </script>  <style lang="stylus">  @import "cropperjs/dist/cropper.min.css"  .cropper-wrap  .cropper-alert-mask  position: fixed  top: 0  left: 0  right: 0  bottom: 0  z-index: 2000  background-color: rgba(#000000.5)  visibility: hidden  height: 0  transition: all .3s ease  .cropper-alert-mask.show  visibility: visible  height: 100%  .cropper-alert  opacity: 0  transition: all .3s ease  visibility: hidden  padding: 10px  position: fixed  z-index: 2000  top: 50px  left: 50%  transform: translateX(-50%) scale(2)  background-color: #ffffff  border-radius: 5px  overflow: hidden  width: 100%  height: 100%  max-width: 600px  max-height: 530px  &.show  opacity: 1  visibility: visible  transform: translateX(-50%) scale(1)  .cropper  position: relative  max-width: 600px  max-height: 460px  height: 100%  padding: 10px  padding-right: 120px  @media (max-width: 1324px)  padding-top: 120px  padding-right: 10px  background-color: #f9fbfc  .layout-icon-wrap  position: absolute  cursor: pointer  right: 0px  top: 0px  font-size: 20px  .cropper-box  position: relative  width: 100%  height: 100%  background-color: #ffffff  .cropper-res-wrap  position: absolute  top: 50%  transform: translateY(-50%)  @media (max-width: 1324px)  top: 0  left: 50%  transform: translateX(-50%)  right: 0  width: 100px  height: auto  padding: 10px  background-color: #a8a8a8  box-sizing: content-box  .cropper-res  width: 100px  height: 100px  overflow: hidden  background-color: #ffffff  .cropper-btns-wrap  position: relative  margin-top: 20px  .cropper-btn  position: absolute  left: 0  top: 0  width: 100%  height: 30px  line-height: 1  background: #ffffff  border: 1px solid #e1e1e1  border-radius: 15px  color: #666666  cursor: pointer  .btn-bg  background: #FF000000 </style> Copy the code
  • writeupCover.vue

In upcover. vue, write the following,(finishCropImage method please add your own image upload call interface method)

<template>
  <div
    class="cover-upload-wrap"
    ref=coverOutWrap
 :style="{  width: width ? (width + 'px') : '100%',  height: calcHeight + 'px',  maxWidth: maxWidth ? (maxWidth + 'px') : '100px',  maxHeight: maxHeight ? (maxHeight + 'px') : '100px'  }">  <el-upload  ref="upload"  class="cover-uploader"  :show-file-list="false"  :before-upload="beforeVipImageUpload"  :auto-upload="false"  :on-change="onFileChange"  :on-progress="onUploadProgress">  <div class="img-wrap">  <img :src="imageUrl" class="cover" v-if="imageUrl">  <div class="img-mask-default" :class="{'img-mask': imageUrl}">  <i class="el-icon-upload"></i>  <div>{{ tip }}</div>  </div>  </div>  </el-upload>  <cropperBox  ref="cropperBox"  :options="options"  :uploadProgress="uploadProgress"  @finishCropImage="finishCropImage">  </cropperBox>  </div> </template> <script> import uploadImage from ".. /.. /mixins/uploadImage"; import cropperBox from './cropperBox' import {upload} from ".. /.. /api/base";  export default {  name: 'up-cover'. mixins:[uploadImage],  components: {  cropperBox  },  props: {  defaultImg: String. ratio: { // Clipping results in aspect ratio  default: 1  },  width: [Number.String]. height: [Number.String]. WHRatio: { // Component aspect ratio  default: 1  },  cropBoxResizable:Boolean.// Can I change the size of the clipping box  maxWidth: String. maxHeight: String. tip: {  default: 'Upload picture'  },  maxSize: { // Select the maximum size of the image in M  default: 3  }  },  data () {  return {  cropper: null. newFile: null. options: {  aspectRatio: 2.166. preview: '#cropperRes'. zoomOnWheel: false. cropBoxResizable:false. minCropBoxWidth: 50. viewMode:2  },  token: {},  uploadProgress: 0. calcHeight: 0  }  },  created() {  this.options.aspectRatio = this.ratio;  this.options.cropBoxResizable = this.cropBoxResizable;  if (this.height) {  this.calcHeight = this.height  }  },  computed: {  imageUrl () {  return this.defaultImg  }  },  mounted() {  if (!this.calcHeight) {  if (this.width) {  this.calcHeight = this.width / this.WHRatio  } else {  this.calcHeight = this.$refs.coverOutWrap.offsetWidth / this.WHRatio  }  }  },  methods: {  // Capture the image upload event, open the clipping box if there is a picture, and pass the file to the clipping box  onFileChange (file, fileList) {  if (file.status === 'ready') {  this.$refs.cropperBox.show();  this.$refs.cropperBox.loadCropper(file.raw)  }  },  // File clipping, nerFile is the final file, adjust the interface for image uploading  finishCropImage (newFile) {  this.newFile = newFile;  // Add your own image upload interface  },  // Size detection before uploading images, file sizes are passed through prop, custom file size limits can be used in components  beforeVipImageUpload(file){  const isLt3M = file.size / 1024 / 1024 < this.maxSize;  if(! isLt3M) { this.$message.error('Upload image size cannot be larger than' + this.maxSize + 'M');  }  return isLt3M;  let uploadFile = new window.File([this.newFile], file.name, { type: this.newFile.type });  uploadFile.uid = this.newFile.uid;  return Promise.resolve(uploadFile)  },  // File upload progress  onUploadProgress (event, file, fileList) {  this.uploadProgress = parseInt(event.percent) - 1  }  } } </script> <style lang="stylus"> .cover-upload-wrap  position: relative  width: 100%  max-width: 300px  height: 150px  border-radius: 5px  .cover-uploader  width: 100%  height: 100%  .el-upload  width: 100%  height: 100%  overflow: hidden  border-radius: 5px  cursor: pointer  border: 1.px solid #dddddd  .img-wrap  position: relative  width: 100%  height: 100%  &:hover  .img-mask-default  opacity: 1. background-color: rgba(0, 0, 0, 0. 5)  color: #ffffff  .cover  position: relative  width: 100%  height: 100%  border-radius: 5px  .img-mask-default  position: absolute  left: 0  top: 0  width: 100%  height: 100%  padding-left: 10px  padding-right: 10px  background-color: #ffffff  color: # 555555  display: flex  flex-direction: column  justify-content: center  font-size: 12px  transition: all .2s linear  .el-icon-upload  font-size18:px  .img-mask  opacity: 0  </style>  Copy the code

Method of use

  • The introduction of the plugin
import UP from '@/components/upload/upCover'

export default {
      components:{UP},
}
Copy the code
  • Use in pages

PictureUrl is the callback address displayed after the image is uploaded successfully. Please fill it in by yourself. MaxSize can limit the size of the image when uploading, width and height can limit the size of the component.

<UP class="upload-cover"
    :default-img="pictureUrl? pictureUrl:''"
    ratio="2.166"
    :cropBoxResizable="true"
 width="156"  height="72"  tip="Upload Level icon"  maxSize="3"  @uploadSuccess="uploadSuccess"> </UP> Copy the code

In uploadSuccess, you can get the callback after uploading the image successfully

uploadSuccess(res){
    //this.pictureUrl=res.data
},
Copy the code

More operations

Javascript operations

this.myCropper.getCroppedCanvas().toDataURL('image/jpeg') // Get the cropped base64 image
this.myCropper.getCropBoxData();    // Get clipping box data
this.myCropper.setCropBoxData();    // Set clipping box data
this.myCropper.getCanvasData();      // Get image data
this.myCropper.setCanvasData();      // Set the image data
Copy the code

A configuration object

  • viewModeView control
    • 0 unlimited
    • 1 Restrict cropping boxes to not go beyond the scope of the picture
    • 2 Limit the clipping box to not exceed the scope of the image and the image fill mode to cover the longest edge fill
    • 3 limit the clipping box can not exceed the scope of the picture and the picture filling mode is the shortest contain
  • dragModeDrag and drop image mode
    • cropForm a new clipping box
    • moveImage can be moved
    • noneNothing at all
  • initialAspectRatioThe initial value of the clipping box aspectRatio is the same as the image aspectRatio by default. This value is available only when aspectRatio is not set
  • aspectRatioSet the clipping box to a fixed aspect ratio
  • dataPreviously stored clipped data is automatically set at initialization and is only available if autoCrop is set to true
  • previewPreview Sets a region container to preview the clipped result
    • Element, Array (elements), NodeList or String (selector)
  • responsiveReactive rerendering after window sizing defaults to True
  • restoreRestores clipped areas after window sizing defaults to True
  • checkCrossOriginThe default is true if the copied image element is crossOrigin and a timestamp is added to SRC to avoid loading errors due to browser caching when reloading images
  • checkOrientationCheck image orientation information (only for JPEG images) Default true Does some processing to the image orientation value when rotating the image to solve some problems on IOS devices
  • modalWhether to show black mask between picture and cropping box Defaults to true
  • guidesWhether to show the dotted line of clipped boxes defaults to true
  • centerWhether to show the ‘+’ indicator in the middle of the clipping box Defaults to true
  • highlightWhether to show the white mask above the cropping box (very light) Defaults to true
  • backgroundWhether to display a gridded background in the container defaults to true
  • autoCropAllows automatic cropping of images with data at initialization using the default true
  • autoCropAreaSet the clipping area to the size of the image from 0 to 1. By default, 0.8 represents 80% of the area
  • movableWhether images can be moved defaults to true
  • rotatableWhether images can be rotated defaults to true
  • scalableWhether the image can be zoomed (width can be changed) defaults to true
  • zoomableWhether the image can be zoomed (changing the focal length) defaults to true
  • zoomOnTouchWhether the picture can be zoomed by dragging and touching defaults to true
  • zoomOnWheelWhether pictures can be zoomed by mouse wheel Defaults to true
  • wheelZoomRatioSet the mouse wheel zoom sensitivity to 0.1 by default
  • cropBoxMovableWhether clipping boxes can be dragged defaults to True
  • cropBoxResizableWhether the clipping box size can be changed default true
  • toggleDragModeOnDblclickCan move and crop modes be toggled by double-clicking? Default true Cannot be toggled when the move mode is None. This setting must be supported by the browser
  • MinContainerWidth (200), minContainerHeight (100), minCanvasWidth (0), minCanvasHeight (0), minCropBoxWidth (0), minCropBoxHeight ( 0)The default values are in parentheses. Note that the minimum width and width of the clipping box are relative to the page, not the image

methods

  • crop()Display clipping box manually
  • reset()Reset the picture and crop box to their initial state
  • replace(url[, hasSameSize])Replace the image path and rebuild the cropping box
    • urlA new path
    • hasSameSizeThe default value is false. If this parameter is set to true, the new and old images have the same size
  • enable()Defrost cropping box
  • disable()Freezing clipping box
  • destroy()Destroy the clipping box and remove the Cropper instance
  • move(offsetX[, offsetY])Moving picture specifies the distance a parameter represents the horizontal and vertical moving distance the same
  • moveTo(x[, y])To move the picture to a specified point, a parameter represents the same distance as the horizontal or vertical movement
  • zoom(ratio)Scaling ratio greater than zero means scaling up less than scaling down
  • zoomTo(ratio[, pivot])Scale and set the center point position
  • rotate(degree)Rotation is like CSS
  • rotateTo(degree)Rotate to an absolute Angle
  • Scale (scaleX[, scaleY]), scaleX(scaleX), scaleY(scaleY)Scaling a parameter represents the horizontal and vertical scaling values as well
  • getData([rounded])Return clipped area based on the original image! The original size! If rounded data is displayed, it can be displayed directly on the original screen. Rounded data is rounded by default
  • setData(data)Changing the clipping area based on the position and size of the original image only works if viewMode is not 0
  • GetContainerData (), getImageData(), getCanvasData(), setCanvasData(data), getCropBoxData(), setCropBoxData(data)Container, picture container (canvas), picture, clipping area relative to the container data set and obtain
  • getCroppedCanvas([options])Gets a Canvas object for the cropped image. Options sets some data for this canvas
    • Width, height, minWidth, minHeight, maxWidth, maxHeight, fillColor, imageSmoothingEnabledImageSmoothingQuality (default: low, medium, high)
  • setAspectRatio(aspectRatio)Change the aspect ratio of the clipping area
  • setDragMode([mode])Set drag and drop image mode

The event

  • readyThe preparation event before rendering (the image is loaded and the Cropper instance is ready)
  • Crop start, cropmove, cropend, cropStart drawing cutting frame (or canvas), cut out of the box (or canvas) midway, cutting box (or canvas) by cutting finished, event event. Detail. OriginalEvent, event. The detail. The action
    • When autoCrop is true, the crop event is emitted before Ready
  • zoomClipping the box zoom event

In this paper, reference to www.cnblogs.com/eightFlying…

This article is formatted using MDNICE