更新记录

2.0.0(2026-11-01)

首个发布版本。

功能

  • 支持矩形 / 圆形 / 圆角裁剪,裁切比例支持 free / original / 1:1 / 3:4 / 4:3 / 9:16 / 16:9 或数值
  • 支持缩放、拖拽、旋转(含 90° 快捷)、水平 / 垂直翻转、撤销 / 重做
  • 支持网格线、遮罩色、角把手、边框、棋盘格背景等外观配置
  • 支持自定义导出:输出尺寸、DPR、格式(PNG / JPEG / WebP)与质量
  • 提供命令式 API(cropImage / getCropController)与组件式(l-crop)两种用法
  • 提供 Hook(useCrop / useCropAgent)便于完全自定义裁剪 UI

平台兼容性

uni-app(4.45)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
√ √ √ √ √ - 5.0 √ √
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
√ - - - - - - - - - - -

uni-app x(5.31)

Chrome Safari Android iOS 鸿蒙 微信小程序
√ √ 5.0 √ √ √

其他

多语言 暗黑模式 宽屏模式 蒸汽模式
× × × √

lime-crop 图片裁剪

一款支持缩放、旋转、翻转、网格、圆形与圆角裁剪,并可自定义导出的图片裁剪插件,兼容 uni-app / uni-app-x。

插件依赖:lime-shared、lime-style、lime-use

::: tip 提示 本插件依赖的插件会在 uni_modules 中自动引入,无需手动导入。 :::

安装方法

  1. 在 uni-app 插件市场中搜索并导入 lime-crop
  2. 首次导入后可能需要重新编译项目
  3. 在页面中使用 l-crop 或 l-crop-agent 组件

代码演示

命令式调用(推荐)

先在页面放置一次 <l-crop-agent />,再调用 cropImage 弹出裁剪界面。

<!-- 在页面中放置代理组件(只需一次) -->
<l-crop-agent />
import { cropImage } from '@/uni_modules/lime-crop'
import type { LimeCropOptions } from '@/uni_modules/lime-crop'

const options: LimeCropOptions = {
  src: '/static/photo.png',
  aspectRatio: '1:1',
  onConfirm: (dataUrl: string) => {
    console.log('裁剪结果:', dataUrl)
  },
  onCancel: () => {
    console.log('用户取消')
  },
  onError: (message: string) => {
    console.log('出错了:', message)
  }
}
cropImage(options)

多实例

同一页面需要多个裁剪入口时,给 <l-crop-agent> 加 id,调用时带上同一个 id。

<l-crop-agent id="avatar" />
<l-crop-agent id="cover" />
import { cropImage, getCropController } from '@/uni_modules/lime-crop'

cropImage({ id: 'avatar', src: avatarSrc, aspectRatio: '1:1' })
cropImage({ id: 'cover', src: coverSrc, aspectRatio: '16:9' })

// 也可以拿到控制器直接操作
const controller = getCropController('avatar')
controller?.rotateLeft()

id 默认为 default,不传时两者都对应默认实例。

组件式使用(自定义 UI)

使用 l-crop 自身搭建界面,适合需要完全自定义操作按钮和布局的场景。

<l-crop
  ref="cropRef"
  src="/static/photo.png"
  aspect-ratio="1:1"
  @change="onCropChange"
  @error="onCropError"
/>
<button @click="handleRotateLeft">向左旋转</button>
<button @click="handleCrop">裁剪</button>
import type { LimeCropActionDetails } from '@/uni_modules/lime-crop'

// LCropComponentPublicInstance 由 uni-app x 自动生成,无需手动引入
const cropRef = ref<LCropComponentPublicInstance | null>(null)

const onCropChange = (actionDetails: LimeCropActionDetails) => {
  console.log('当前旋转角度:', actionDetails.rotateDegrees)
}
const onCropError = (message: string) => {
  uni.showToast({ title: message, icon: 'none' })
}

const handleRotateLeft = () => cropRef.value?.rotateLeft()

const handleCrop = async () => {
  const result = await cropRef.value?.crop()
  console.log('裁剪结果:', result)
}

组件显隐请由调用方通过 v-if 控制:<l-crop v-if="cropVisible" ... />。组件内部不做 v-if,因为卸下 Canvas 后需要重新初始化。

裁剪样式

<!-- 矩形裁剪(默认) -->
<l-crop src="/static/photo.png" crop-style="0" />

<!-- 圆形裁剪 -->
<l-crop src="/static/photo.png" crop-style="1" />

<!-- 圆角矩形裁剪 -->
<l-crop src="/static/photo.png" crop-style="0" corner-radius="20" />

裁切比例

<!-- 自由比例 -->
<l-crop src="/static/photo.png" aspect-ratio="free" />

<!-- 保持原图比例 -->
<l-crop src="/static/photo.png" aspect-ratio="original" />

<!-- 1:1 方形 -->
<l-crop src="/static/photo.png" aspect-ratio="1:1" />

<!-- 3:4 竖版 -->
<l-crop src="/static/photo.png" aspect-ratio="3:4" />

<!-- 16:9 横版 -->
<l-crop src="/static/photo.png" aspect-ratio="16:9" />

自定义导出

<l-crop
  src="/static/photo.png"
  dest-format="image/jpeg"
  dest-quality="0.8"
  dest-width="800"
  dest-DPR="2"
/>

命令式调用同样支持:

cropImage({
  src: '/static/photo.png',
  destFormat: 'image/jpeg',
  destQuality: 0.8,
  destWidth: 800,
  destDPR: 2,
  onConfirm: (dataUrl) => { /* ... */ }
})

性能优化

低端机或 APP 原生平台拖拽不跟手时,通过 throttleFps 限制触摸移动帧率。

<!-- 默认 33(约 30fps) -->
<l-crop src="/static/photo.png" />

<!-- 限制 20fps,进一步降低 GPU 压力 -->
<l-crop src="/static/photo.png" :throttleFps="20" />

<!-- 设为 0 关闭节流 -->
<l-crop src="/static/photo.png" :throttleFps="0" />

默认值即 33(约 30fps),也就是默认开启节流;只有显式传 0 才是完全不限制。

API 文档

命令式 API

方法 说明 参数
cropImage(options) 弹出裁剪界面 LimeCropOptions
getCropController(id?) 获取裁剪控制器,未找到返回 null id?: string,默认 default

Props 分类

🎯 基础配置(最常用)

参数 说明 类型 默认值 可选值
id 多实例标识(仅命令式 / l-crop-agent) string 'default' -
src 图片地址 string - -
aspectRatio 裁切比例 string | number | null null free, original, 1:1, 3:4, 4:3, 9:16, 16:9, 数值
cropStyle 裁剪样式 number 0 0 矩形, 1 圆形
cornerRadius 圆角半径(仅矩形模式有效) number 0 -
initCropRectType 初始裁剪框类型 string 'imageRect' imageRect, layoutRect

🖼️ 导出配置

参数 说明 类型 默认值 可选值
destWidth 输出图片宽度(px) number null 为空则按原图比例计算
destHeight 输出图片高度(px) number null 为空则按原图比例计算
destDPR 输出图片 DPR 倍率 number 1.0 -
destFormat 导出图片格式 string 'image/png' image/png, image/jpeg, image/webp
destQuality 导出图片质量(0.0 ~ 1.0) number 1.0 仅 JPEG/WebP 有效

🎨 样式与外观

参数 说明 类型 默认值 可选值
maskColor 遮罩颜色 string 'rgba(0, 0, 0, 0.8)' -
cornerColor 角把手颜色 string '#ffffff' -
lineColor 边框颜色 string 'rgba(255, 255, 255, 0.8)' -
lineHeight 边框宽度 number 1.0 -
cornerSize 角把手大小 number | UTSJSONObject 30 -
cropRectPadding 裁剪区域内边距 number | UTSJSONObject 20 -
showGrid 是否显示网格线 boolean true -
showCheckerboard 是否显示棋盘格背景 boolean false -
sliderActiveColor 滑块激活颜色(仅 l-crop-agent) string '#07c160' -
sliderBackgroundColor 滑块背景颜色(仅 l-crop-agent) string 'rgba(255,255,255,0.34)' -
lStyle 根元素自定义样式(仅 l-crop) string | UTSJSONObject - -
lClass 根元素自定义类名(仅 l-crop) string | UTSJSONObject - -

⚙️ 行为配置

参数 说明 类型 默认值 可选值
minScale 最小缩放 number 0.5 -
maxScale 最大缩放 number 5.0 -
speed 缩放和拖拽速度 number 1.0 -
hitTestSize 触摸检测区域大小(px) number 20 手指偏粗时可调大
maxHistorySize 历史记录最大数量 number 50 -
throttleFps 触摸移动帧率限制,0 不限制 number 33 低端机推荐 20~30
debug 是否显示调试信息 boolean false -

📞 回调(仅命令式 API)

参数 说明 类型
onConfirm 确认裁剪回调(失败时收到空串) (dataUrl: string) => void
onCancel 取消裁剪回调 () => void
onChange 编辑状态变化回调 (actionDetails: LimeCropActionDetails) => void
onError 图片加载或导出失败回调 (message: string) => void

Events(l-crop 组件)

事件 参数 说明
change LimeCropActionDetails 编辑状态变化时触发(拖动结束、旋转/翻转/缩放、撤销/重做、重置)
error string 图片加载失败、导出尺寸非法、导出失败时触发

Methods(l-crop 组件,通过 ref 调用)

方法 参数 返回值 说明
crop - Promise<string \| null> 执行裁剪,返回图片路径/dataURL,失败返回 null
rotate LimeRotateOptions \| null void 旋转图片(增量)
rotateLeft - void 向左旋转 90°
rotateRight - void 向右旋转 90°
setRotation degree, animation void 设置旋转角度(绝对值)
flip LimeFlipOptions \| null void 翻转图片
flipHorizontal - void 水平翻转
flipVertical - void 垂直翻转
setAspectRatio ratio void 设置裁切比例
updateCropStyle number void 更新裁剪样式,0 矩形,1 圆形
updateCornerRadius number void 更新圆角半径
undo - void 撤销
redo - void 重做
reset - void 重置裁剪状态
canUndo - boolean 是否可撤销(响应式)
canRedo - boolean 是否可重做(响应式)
isReady - boolean 图片是否已加载完成(响应式)

crop() 无论成功失败都会复位 loading;失败时返回 null 并触发 error 事件。

LimeCropImperative(控制器)

cropImage(options) 与 getCropController(id) 的实例方法:

方法 参数 返回值 说明
show LimeCropOptions void 打开裁剪界面并应用配置
hide - void 关闭裁剪界面
crop - Promise<string \| null> 执行裁剪,失败返回 null
rotate LimeRotateOptions \| null void 旋转图片(增量)
setRotation degree, animation void 设置旋转角度(绝对值)
flip LimeFlipOptions \| null void 翻转图片
flipHorizontal - void 水平翻转
flipVertical - void 垂直翻转
reset - void 重置到初始状态
undo - void 撤销
setAspectRatio ratio void 设置裁切比例
updateCropStyle number void 更新裁剪样式,0 矩形,1 圆形
updateCornerRadius number void 更新圆角半径
getId - string 当前实例的 id

只读属性(响应式,可直接用于模板):visible、currentSrc、currentConfig、sliderValue、showRotateTip、rotateTipDegree。

Hook

需要在自定义 UI 中复用裁剪逻辑时,可直接使用两个组合式函数(均由包入口导出)。

useCrop

import { useCrop } from '@/uni_modules/lime-crop'
import type { CropProps } from '@/uni_modules/lime-crop'

const {
  isReady, canUndo, canRedo,
  crop, rotate, rotateLeft, rotateRight, flip, flipHorizontal, flipVertical,
  reset, undo, redo, setAspectRatio, updateCropStyle, updateCornerRadius, setRotation,
  , , , ,
  imageCanvasId, cropCanvasId, exportCanvasId,
  showExportCanvas, exportCanvasStyle,
} = useCrop(props)

返回的 imageCanvasId / cropCanvasId / exportCanvasId 需要绑到你自己模板里的 <canvas> 上, showExportCanvas / exportCanvasStyle 用于控制导出画布。返回类型见 UseCropReturn。

useCropAgent

import { useCropAgent } from '@/uni_modules/lime-crop'

const { visible, currentSrc, currentConfig, cropRef, sliderValue, showRotateTip, rotateTipDegree, imperative } = useCropAgent()

imperative 即 LimeCropImperative 实例,用于搭建自定义的裁剪代理组件。

类型定义

LimeRotateOptions

所有字段均可省略,省略时取表中默认值。

参数 类型 默认值 说明
degree? number 90 旋转角度(正数顺时针,负数逆时针)
animation? boolean true 是否启用动画
duration? number 200 动画时长(ms)
rotateCropRect? boolean true 是否同时旋转裁剪框

LimeFlipOptions

所有字段均可省略,省略时取表中默认值。

参数 类型 默认值 说明
horizontal? boolean true 是否水平翻转(false 为垂直翻转)
animation? boolean false 是否启用动画
duration? number 200 动画时长(ms)

LimeCropActionDetails

change 事件与 onChange 回调的载荷,常用只读字段:

字段 类型 说明
cropRect Rect \| null 当前裁剪框(屏幕坐标)
rotateDegrees number 当前旋转角度(度)
rotateRadians number 当前旋转弧度
totalScale number 当前缩放比例
flipX boolean 是否水平翻转
flipY boolean 是否垂直翻转
cropAspectRatio number \| null 当前裁剪比例
originalAspectRatio number \| null 原图宽高比
circleMode boolean 是否圆形模式
needCrop boolean 相对原图是否需要裁剪
needFlip boolean 是否处于翻转状态
hasEditAction boolean 是否有过编辑操作
delta Offset 当前位移量

裁剪样式说明

矩形裁剪(cropStyle = 0)

默认模式,支持自由比例和固定比例裁剪。配合 cornerRadius 可实现圆角矩形。

圆形裁剪(cropStyle = 1)

圆形模式下自动锁定 1:1 比例,导出图片为圆形透明背景 PNG。

圆形模式下调用 setAspectRatio 传入非 1:1 的比例会被强制为 1:1。

圆角矩形

设置 cornerRadius > 0 即可,圆角半径最大不超过角标宽度(cornerSize 的宽度),导出时圆角外侧为透明区域。

主题定制

组件样式主要通过 props 定制;l-crop-agent 另提供 CSS 变量。

使用示例

方式一:通过 props 设置(推荐)

<l-crop
  src="/static/photo.png"
  mask-color="rgba(0,0,0,0.6)"
  line-color="#07c160"
  corner-color="#07c160"
  :line-height="2"
/>

方式二:通过 lStyle 设置

<l-crop src="/static/photo.png" :l-style="{ width: '100%', height: '100%' }" />

方式三:通过 CSS 变量定制 l-crop-agent

<view class="crop-wrapper">
  <l-crop-agent />
</view>

<style>
.crop-wrapper {
  --l-crop-agent-confirm-bg: #1989fa;
  --l-crop-agent-text-color: #333;
}
</style>

常用变量:

变量名称 默认值 描述
--l-crop-agent-text-color #fff 文字颜色
--l-crop-agent-text-size 14px 文字大小
--l-crop-agent-confirm-bg #07c160 确认按钮背景色
--l-crop-agent-confirm-color #fff 确认按钮文字颜色
--l-crop-agent-confirm-border-radius 9999px 确认按钮圆角
--l-crop-agent-icon-size 24px 图标大小
--l-crop-agent-rotate-tip-bg rgba(0, 0, 0, 0.8) 旋转提示背景色
--l-crop-agent-rotate-tip-text-color #ffffff 旋转提示文字颜色

⚠️ 重要提示

关于 class 的使用

请不要直接在 lime- 组件上使用 class 属性! 推荐以下三种方式:

方式一:在父级或根节点上设置 class

<view class="crop-wrapper">
  <l-crop src="/static/photo.png" />
</view>
<style>
.crop-wrapper {
  /* 在这里设置相关样式 */
}
</style>

方式二:使用 lStyle 直接设置

<l-crop src="/static/photo.png" :l-style="{ width: '100%' }" />

方式三:使用 lClass 配合样式

<l-crop src="/static/photo.png" lClass="custom-crop" />
<style>
.custom-crop {
  /* 在这里设置相关样式 */
}
</style>

快速预览

导入插件后,可以直接使用以下标签查看演示效果:

<!-- 代码位于 uni_modules/lime-crop/components/lime-crop -->
<lime-crop />

插件标签说明

标签类型 示例 说明
组件标签 l-crop 裁剪核心组件,适合自定义 UI
组件标签 l-crop-agent 裁剪代理组件,内置完整操作 UI
演示标签 lime-crop 演示组件,用于查看完整功能演示

平台差异与已知限制

项目 说明
单 Canvas 模式 iOS / Android / Web 上图片层与裁剪框层共用一个 Canvas context;其余平台使用两个 Canvas
iOS 初始化 首帧后(requestAnimationFrame)才初始化编辑器,避免读到错误的 Canvas 尺寸
Android 导出 导出前需在新 Canvas 上重新解码一次图片(实现在 platform-uni.ts)
鸿蒙导出 导出 Canvas 不做 pixelRatio 放大,CSS 尺寸相应除以 pixelRatio,避免超出鸿蒙 Canvas 分辨率上限
小程序 / H5 使用 uni.createCanvasContextAsync 查询节点;未取到 2D 节点时回退到 uni.createCanvasContext
slider 属性 使用 activeColor 而非 activeBackgroundColor,因为后者在微信小程序端不支持
最低版本 uni.createCanvasContextAsync 需要 uni-app x 4.25+;styleIsolation 需要支持 uni-app-x.styleIsolationVersion: "2"

注意事项

  1. 本组件基于 Canvas 2D 实现,需要平台支持 Canvas 2D API
  2. uni-app x 项目使用 .uvue 文件,非 uni-app x 项目使用 .vue 文件
  3. cornerRadius 最大值受 cornerSize 的宽度限制
  4. cropImage 依赖页面中已放置的 <l-crop-agent />;没有匹配 id 的实例时 cropImage 不做任何事
  5. 裁剪内核为纯逻辑,不调用 uni API,源码不随插件包分发,包内仅有压缩产物 crop-core.esm.min.js
  6. 图片解码完成前调用 setAspectRatio 不会报错:比例会暂存,等图片就绪后自动生效;此时调用 rotate / flip 会被忽略(可通过 isReady 判断就绪状态)

常见问题

命令式调用没有反应?

请确认页面中已放置 <l-crop-agent />,且 cropImage({ id }) 的 id 与该组件一致(默认都是 default)。

在弹窗中使用时裁剪区尺寸异常?

裁剪组件初始化时需要读取 Canvas 的真实尺寸,弹窗未展开时尺寸可能为 0。请确保弹窗展开后再渲染:

<l-popup v-model="show">
  <l-crop v-if="show" src="/static/photo.png" />
</l-popup>

导出的图片是空白 / 透明?

  • 确认图片已加载完成(isReady 为 true)后再调 crop()
  • 圆形与圆角模式下,裁剪区域外本来就是透明区域

支持与赞赏

如果你觉得本插件解决了你的问题,可以考虑支持作者:

支付宝赞助 微信赞助

隐私、权限声明

1. 本插件需要申请的系统权限列表:

无

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

无

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

暂无用户评论。