V Avatar Cropper
一个支持 PC 端和移动端的 Vue 3 头像裁剪组件,提供直观的拖拽、缩放和裁剪功能。
✨ 特性
- 🖱️ 直观操作 - 支持鼠标拖拽和触摸手势
- 🔍 灵活缩放 - 双指缩放和滑块缩放
- 📱 响应式设计 - 自适应不同屏幕尺寸
- 🎨 现代 UI - 简洁美观的用户界面
- 📦 轻量级 - 无外部依赖,体积小巧
- 🔧 易于集成 - 简单的 API 设计
📦 安装
npm install v-avatar-cropper --save
🚀 快速开始
全局注册
import {createApp} from 'vue'
import avatar from 'v-avatar-cropper'
import App from './App.vue'
const app = createApp(App)
app.use(avatar)
app.mount('#app')
局部引入
import VAvatarCropper from 'v-avatar-cropper'
export default {
components: {
VAvatarCropper,
},
}
基础用法
<template>
<div>
<!-- 文件选择 -->
<input type="file" @change="handleFileChange" accept="image/*" />
<!-- 头像裁剪组件 -->
<v-avatar-cropper v-if="selectedFile" :file="selectedFile" @cancel="handleCancel" @done="handleDone" />
</div>
</template>
<script setup>
import {ref} from 'vue'
const selectedFile = ref(null)
function handleFileChange(event) {
selectedFile.value = event.target.files[0]
}
function handleCancel() {
selectedFile.value = null
}
function handleDone(result) {
console.log('裁剪完成:', result)
// result.base64 - base64格式图片
// result.img - Blob格式图片
// result.url - Blob URL地址
selectedFile.value = null
}
</script>
📖 API 文档
Props
参数 | 类型 | 默认值 | 说明 |
---|---|---|---|
file | File | String | null | 要裁剪的图片文件或图片 URL |
edit | Boolean | true | 是否显示编辑界面(操作按钮和滑块) |
Events
事件名 | 参数 | 说明 |
---|---|---|
cancel | - | 用户点击取消按钮时触发 |
done | result: Object | 用户确认裁剪时触发 |
touch | - | 用户触摸图片时触发 |
Done 事件返回值
{
base64: 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQ...', // base64格式图片
img: Blob, // Blob格式图片对象
url: 'blob:http://localhost:3000/xxx-xxx-xxx' // Blob URL地址
}
🎮 使用示例
完整示例
<template>
<div class="avatar-demo">
<!-- 上传区域 -->
<div v-if="!currentFile" class="upload-area">
<label for="file-input" class="upload-button"> 选择头像图片 </label>
<input id="file-input" type="file" @change="selectFile" accept="image/*" style="display: none;" />
</div>
<!-- 裁剪组件 -->
<v-avatar-cropper v-if="currentFile" :file="currentFile" @cancel="cancelCrop" @done="completeCrop" @touch="onImageTouch" />
<!-- 结果展示 -->
<div v-if="croppedResult" class="result-area">
<h3>裁剪结果</h3>
<img :src="croppedResult.url" alt="裁剪后的头像" class="result-image" />
<div class="result-actions">
<button @click="downloadImage">下载图片</button>
<button @click="resetDemo">重新选择</button>
</div>
</div>
</div>
</template>
<script setup>
import {ref} from 'vue'
const currentFile = ref(null)
const croppedResult = ref(null)
// 选择文件
function selectFile(event) {
const file = event.target.files[0]
if (file) {
currentFile.value = file
}
}
// 取消裁剪
function cancelCrop() {
currentFile.value = null
}
// 完成裁剪
function completeCrop(result) {
croppedResult.value = result
currentFile.value = null
// 可以在这里上传到服务器
// uploadToServer(result.img)
}
// 图片触摸事件
function onImageTouch() {
console.log('用户触摸了图片')
}
// 下载图片
function downloadImage() {
if (croppedResult.value) {
const link = document.createElement('a')
link.download = 'avatar.jpg'
link.href = croppedResult.value.url
link.click()
}
}
// 重置演示
function resetDemo() {
croppedResult.value = null
// 清空文件输入
const input = document.getElementById('file-input')
if (input) input.value = ''
}
</script>
<style scoped>
.avatar-demo {
max-width: 500px;
margin: 0 auto;
padding: 20px;
}
.upload-area {
text-align: center;
padding: 40px;
border: 2px dashed #ddd;
border-radius: 8px;
}
.upload-button {
display: inline-block;
padding: 12px 24px;
background: #007bff;
color: white;
border-radius: 6px;
cursor: pointer;
transition: background 0.3s;
}
.upload-button:hover {
background: #0056b3;
}
.result-area {
text-align: center;
margin-top: 20px;
}
.result-image {
width: 200px;
height: 200px;
border-radius: 50%;
object-fit: cover;
border: 3px solid #007bff;
}
.result-actions {
margin-top: 15px;
}
.result-actions button {
margin: 0 10px;
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
}
</style>
仅预览模式
<template>
<v-avatar-cropper :file="imageUrl" :edit="false" />
</template>
<script setup>
const imageUrl = 'https://example.com/avatar.jpg'
</script>
🎯 操作指南
PC 端操作
- 拖拽移动: 鼠标按住图片拖拽
- 缩放调节: 使用底部滑块调节缩放比例
- 确认裁剪: 点击"确认"按钮完成裁剪
- 取消操作: 点击"取消"按钮退出裁剪
移动端操作
- 单指拖拽: 单指触摸拖拽移动图片位置
- 双指缩放: 双指捏合/展开调节图片大小
- 滑块缩放: 使用底部滑块精确调节缩放
- 触摸确认: 点击"确认"按钮完成裁剪
⚙️ 技术特性
核心功能
- 智能适配: 自动适配图片尺寸和屏幕大小
- 边界检测: 防止图片移出裁剪区域
- 平滑动画: 流畅的交互动画效果
- 内存管理: 自动清理 Blob URL,防止内存泄漏
兼容性
- Vue 版本: Vue 3.x
- 浏览器: 现代浏览器 (Chrome, Firefox, Safari, Edge)
- 移动端: iOS Safari, Android Chrome
- 触摸支持: 完整的触摸手势支持
🔧 开发指南
本地开发
# 克隆项目
git clone https://github.com/varjay/avatar-crop.git
# 安装依赖
cd avatar-crop
npm install
# 启动开发服务器
npm run dev
# 构建项目
npm run build
# 代码检查
npm run lint
项目结构
avatar-crop/
├── lib/ # 组件源码
│ ├── index.js # 入口文件
│ └── components/
│ └── avatar.vue # 主组件
├── src/ # 示例代码
│ ├── App.vue # 示例应用
│ └── main.js # 入口文件
├── public/ # 静态资源
└── package.json # 项目配置
🤝 贡献指南
欢迎提交 Issue 和 Pull Request 来帮助改进这个项目!
提交 Issue
- 详细描述问题和复现步骤
- 提供浏览器和设备信息
- 如果可能,请提供最小复现示例
提交 PR
- Fork 项目并创建特性分支
- 确保代码通过 ESLint 检查
- 添加必要的测试用例
- 更新相关文档
📄 许可证
👨💻 作者
virjay - GitHub
如果这个项目对你有帮助,请给个 ⭐️ 支持一下!