vue实现图片编辑插件
Vue 图片编辑插件实现方案
使用现成库 vue-cropperjs
安装依赖库:
npm install vue-cropperjs cropperjs
基础组件实现:
<template>
<div>
<input type="file" @change="uploadImage">
<vue-cropper
ref="cropper"
:src="imgSrc"
:aspect-ratio="16/9"
></vue-cropper>
<button @click="cropImage">裁剪</button>
</div>
</template>
<script>
import VueCropper from 'vue-cropperjs'
import 'cropperjs/dist/cropper.css'
export default {
components: { VueCropper },
data() {
return {
imgSrc: ''
}
},
methods: {
uploadImage(e) {
const file = e.target.files[0]
if (!file.type.includes('image/')) return
const reader = new FileReader()
reader.onload = (event) => {
this.imgSrc = event.target.result
}
reader.readAsDataURL(file)
},
cropImage() {
this.$refs.cropper.getCroppedCanvas().toBlob((blob) => {
// 处理裁剪后的图片
}, 'image/jpeg', 0.9)
}
}
}
</script>
自定义基础图片编辑器
核心功能组件结构:
<template>
<div class="image-editor">
<div class="toolbar">
<button @click="rotate(-90)">左旋转</button>
<button @click="rotate(90)">右旋转</button>
<input type="range" v-model="brightness" min="0" max="200">
</div>
<div class="canvas-container">
<canvas ref="canvas"></canvas>
</div>
</div>
</template>
<script>
export default {
props: ['src'],
data() {
return {
brightness: 100,
rotation: 0,
image: null
}
},
mounted() {
this.loadImage()
},
methods: {
loadImage() {
this.image = new Image()
this.image.onload = this.drawImage
this.image.src = this.src
},
drawImage() {
const canvas = this.$refs.canvas
const ctx = canvas.getContext('2d')
canvas.width = this.image.width
canvas.height = this.image.height
ctx.filter = `brightness(${this.brightness}%)`
ctx.save()
ctx.translate(canvas.width/2, canvas.height/2)
ctx.rotate(this.rotation * Math.PI/180)
ctx.drawImage(this.image, -this.image.width/2, -this.image.height/2)
ctx.restore()
},
rotate(degrees) {
this.rotation += degrees
this.drawImage()
}
},
watch: {
brightness() {
this.drawImage()
}
}
}
</script>
集成更多高级功能
添加滤镜和标注功能:
// 在methods中添加
applyFilter(filterType) {
const filters = {
grayscale: 'grayscale(100%)',
sepia: 'sepia(100%)',
invert: 'invert(100%)'
}
this.currentFilter = filters[filterType]
this.drawImage()
},
addText(text, x, y) {
const canvas = this.$refs.canvas
const ctx = canvas.getContext('2d')
ctx.font = '20px Arial'
ctx.fillStyle = 'red'
ctx.fillText(text, x, y)
}
性能优化建议
使用离屏Canvas处理复杂操作:
processImageOffscreen() {
const offscreen = document.createElement('canvas')
const offCtx = offscreen.getContext('2d')
offscreen.width = this.image.width
offscreen.height = this.image.height
// 在离屏Canvas上执行耗时操作
offCtx.drawImage(this.image, 0, 0)
// 应用各种滤镜和变换
// 完成后绘制到主Canvas
const mainCtx = this.$refs.canvas.getContext('2d')
mainCtx.drawImage(offscreen, 0, 0)
}
插件封装与发布
将组件打包为可安装插件:
// index.js
import ImageEditor from './ImageEditor.vue'
const Plugin = {
install(Vue) {
Vue.component('ImageEditor', ImageEditor)
}
}
export default Plugin
export { ImageEditor }
发布到npm前配置package.json:
{
"name": "vue-image-editor",
"version": "1.0.0",
"main": "dist/image-editor.umd.js",
"module": "dist/image-editor.esm.js",
"files": ["dist/*"],
"peerDependencies": {
"vue": "^2.6.0 || ^3.0.0"
}
}






