The specific style
Function:
- Upload file: Upload a file and save the file data
- Preview: Convert the uploaded file into an image address and display it on the page
- Screenshot: Fix the selection box background, then place the image data on the canvas, move it to enlarge and then crop it
- Download: Convert the cropped data into a downloadable picture format for download
View code
<template>
<div class="avatar">
<a-button class="btn">
<span>Upload the picture</span>
<input type="file" name="" id="upload_file" @change="handleChange">
</a-button>
<! -- Preview and cut pop-ups -->
<a-modal v-model="visible" title="Picture Preview or Edit" @ok="handleOk" class="avatar_modal">
<div class="main">
<img :src="imgSrc" alt="" v-if="isView">
<template v-else>
<div>
<! -- Slider to enlarge image -->
<input id="slider" type="range" max="4" min="1" v-model="currentSize" @input="handleRange"/>
</div>
<div id="demo">
<canvas id="myCanvas" width="400px" height="400px" ref="canvas"></canvas>
<canvas id="myImg" width="400px" height="400px" ref="myImg"></canvas>
</div>
</template>
</div>
<div class="model_btn">
<a-button style="margin-right:20px" @click="handleView('VIEW')">preview</a-button>
<a-button @click="handleView('CLIP')">screenshots</a-button>
</div>
</a-modal>
</div>
</template>
Copy the code
Data Data and props data codes
data(){
return {
visible:false.// Open the preview and screenshot pop-up
isView:true.// Switch preview to screenshot again
imgSrc:' '.// Preview the image address
currentSize:1.// Image magnification (1-4)
move: {// Canvas motion path data
lastMoveX:null.lastMoveY:null.currentMoveX:null.currentMoveY:null.isMoving:false
},
canvas_edit: {// Canvas to be edited
el:null./ / canvas element
ctx:null.// Canvas's 2D environment
image:null.// Canvas image element
left:0.// Canvas width to the left of the parent element
top:0 // Canvas height from the top of the parent element
},
blackMask: {// Select the canvas element data of the box
el:null./ / canvas element
ctx:null // Canvas's 2D environment}}},props: {// Limit the upload format
limited: {default:() = >{return ['image/png']},
type:Array}},Copy the code
File upload and image preview
handleChange(e){
let file_dom = document.getElementById('upload_file')
let file = e.target.files[0]
if(this.limited.includes(file.type)){
this.imgSrc = window.URL.createObjectURL(file)
this.visible = true
}else{
let str = this.limited.reduce((total,currentValue) = >{ return total + currentValue.split('/') [1] + ', '},' ')
this.$message.warn('Upload file format error, supported only'+str)
}
file_dom.value = null
}
Copy the code
Description:
- Obtain the uploaded file
file
- judge
file
The format, unqualified to give hints - will
file
Convert to the address of the picture that can be displayedimgSrc
- Preview the image by showing it to the corresponding node
- Clear the cache of uploaded files
Initialize the mask and Canvas images
drawCanavs(){
this.$nextTick(() = >{
this.canvas_edit.el = this.$refs.canvas // This is the canvas to manipulate the image
this.canvas_edit.ctx = this.canvas_edit.el.getContext('2d')
this.canvas_edit.image = new Image()
this.canvas_edit.image.src = this.imgSrc
this.canvas_edit.image.onload = () = >{
this.initCanvas() // Initialize canvas element
}
// Initialize the elements of mask
this.blackMask.el = this.$refs.myImg
this.blackMask.ctx = this.blackMask.el.getContext('2d')
this.blackMask.ctx.fillStyle = 'rgba (0,0,0,0.3)'
this.blackMask.ctx.fillRect(0.0.400.400)
this.blackMask.ctx.clearRect(100.100.200.200)
// Since it is not possible to listen directly on the canvas_edit.el element, you can choose to do so in the mask
this.blackMask.el.onmousedown = (e) = >{
this.move.isMoving = true
this.move.lastMoveX = e.clientX
this.move.lastMoveY = e.clientY
}
this.blackMask.el.onmousemove = (e) = >{
if(this.move.isMoving){
let width = e.clientX - this.move.lastMoveX + this.canvas_edit.left
let height = e.clientY - this.move.lastMoveY+this.canvas_edit.top
this.drawCanvas(width,height)
}
}
this.blackMask.el.onmouseup = (e) = >{
if(this.move.isMoving){
this.move.isMoving = false
let width = e.clientX - this.move.lastMoveX + this.canvas_edit.left
let height = e.clientY - this.move.lastMoveY+this.canvas_edit.top
this.drawCanvas(width,height)
this.canvas_edit.left = width
this.canvas_edit.top = height
}
}
})
},
Copy the code
// Draw the center image to the Canvas image
initCanvas(){
let width = (400 - this.canvas_edit.image.width*this.currentSize)/2 // The initial coordinates of the image (width,heigth)
let height = (400 - this.canvas_edit.image.height*this.currentSize)/2
this.canvas_edit.left = width
this.canvas_edit.top = height
this.canvas_edit.ctx.drawImage(this.canvas_edit.image,width,height,this.canvas_edit.image.width*this.currentSize,this.canvas_edit.image.height*this.currentSize)
},
Copy the code
// Update canvas image
drawMask(width,height){
this.canvas_edit.ctx.clearRect(0.0.400.400)
this.canvas_edit.ctx.drawImage(this.canvas_edit.image,width,height,this.canvas_edit.image.width * this.currentSize,this.currentSize * this.canvas_edit.image.height)
},
Copy the code
Description:
- Draws the image to the Canvas image
- Draw the mask layer
- Bind the pressed, moved, and pressed events in the mask layer
- When pressing, determine the current position of the mouse
- When moving, move the position of the picture in the canvas image according to the distance that the mouse moves, and update the canvas image
- When pressing on, determine the position of the mouse away as the coordinates of the image in the Canvas image, and update the image
Clipping and downloading
handleOk(){
// Retrieve the cropped image data
let image_data = this.canvas_edit.ctx.getImageData(100.100.200.200)
this.canvas_edit.ctx.clearRect(0.0.400.400)
// Change the canvas to the same width and height as the selected image
this.canvas_edit.el.height = 200
this.canvas_edit.el.width = 200
this.canvas_edit.el.style.left = '100px'
this.canvas_edit.el.style.top = '100px'
this.canvas_edit.ctx.putImageData(image_data,0.0) // Put the cropped element into the Canvas
// Convert the Canvas image to a subtractable image format and download it
let base64_img = this.canvas_edit.el.toDataURL('image/png')
let blob_img = this.dataURLToBlob(base64_img)
let url = URL.createObjectURL(blob_img)
let a = document.createElement('a')
a.setAttribute('download'.'Profile picture data' + '.png')
a.setAttribute('href',url)
a.click()
this.visible = false
this.$emit('getUrl',url)
}
Copy the code
// Convert base64 to Blob object
dataURLToBlob(code) {
let parts = code.split('; base64,')
let contentType = parts[0].split(':') [1]
let raw = window.atob(parts[1])
let rawLength = raw.length
let uInt8Array = new Uint8Array(rawLength)
for(let i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i)
}
return new Blob([uInt8Array], {
type: contentType
})
},
Copy the code
Description:
- Gets the selected image data in the Canvas image
- Clear the screen, change the size of the Canvas element, and place the Canvas image in the center
- Put the acquired image data into the Canvas element
- Convert the Canvas into a downloadable image for download