From df410b1f4fa87b93de060e4554446fc0d5710224 Mon Sep 17 00:00:00 2001 From: Marvin <454846659@qq.com> Date: Sat, 23 Sep 2023 02:48:35 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A4=B4=E5=83=8F=E8=A3=81=E5=89=AA?= =?UTF-8?q?=E7=BB=84=E4=BB=B6-taro=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../project.private.config.json | 9 +- .../pages/avatarcropper/index.config.ts | 3 + .../business/pages/avatarcropper/index.vue | 50 ++ src/config.json | 4 +- .../__VUE/avatarcropper/canvas-util.ts | 99 +++ src/packages/__VUE/avatarcropper/doc.taro.md | 121 +++- src/packages/__VUE/avatarcropper/index.scss | 14 +- .../__VUE/avatarcropper/index.taro.vue | 612 ++++++++++++++++++ src/packages/__VUE/avatarcropper/types.ts | 2 + 9 files changed, 907 insertions(+), 7 deletions(-) create mode 100644 packages/nutui-taro-demo/src/business/pages/avatarcropper/index.config.ts create mode 100644 packages/nutui-taro-demo/src/business/pages/avatarcropper/index.vue create mode 100644 src/packages/__VUE/avatarcropper/canvas-util.ts create mode 100644 src/packages/__VUE/avatarcropper/index.taro.vue diff --git a/packages/nutui-taro-demo/project.private.config.json b/packages/nutui-taro-demo/project.private.config.json index 79196e4582a..976aa25cb8f 100644 --- a/packages/nutui-taro-demo/project.private.config.json +++ b/packages/nutui-taro-demo/project.private.config.json @@ -6,6 +6,13 @@ "condition": { "miniprogram": { "list": [ + { + "name": "AvatarCropper", + "pathName": "business/pages/avatarcropper/index", + "query": "", + "launchMode": "default", + "scene": null + }, { "name": "exhibition/pages/imagepreview/index", "pathName": "exhibition/pages/imagepreview/index", @@ -65,4 +72,4 @@ }, "projectname": "vue4.x", "libVersion": "2.27.1" -} +} \ No newline at end of file diff --git a/packages/nutui-taro-demo/src/business/pages/avatarcropper/index.config.ts b/packages/nutui-taro-demo/src/business/pages/avatarcropper/index.config.ts new file mode 100644 index 00000000000..7c77e2da510 --- /dev/null +++ b/packages/nutui-taro-demo/src/business/pages/avatarcropper/index.config.ts @@ -0,0 +1,3 @@ +export default { + navigationBarTitleText: 'AvatarCropper' +}; diff --git a/packages/nutui-taro-demo/src/business/pages/avatarcropper/index.vue b/packages/nutui-taro-demo/src/business/pages/avatarcropper/index.vue new file mode 100644 index 00000000000..3e19c2ec0a5 --- /dev/null +++ b/packages/nutui-taro-demo/src/business/pages/avatarcropper/index.vue @@ -0,0 +1,50 @@ + + + + + diff --git a/src/config.json b/src/config.json index c651332f03f..b44e73dd956 100644 --- a/src/config.json +++ b/src/config.json @@ -1309,9 +1309,7 @@ "show": true, "cName": "头像裁剪", "desc": "仿微信头像裁剪功能", - "taro": false, - "exportEmpty": false, - "exportEmptyTaro": false, + "taro": true, "author": "Marvin" } ] diff --git a/src/packages/__VUE/avatarcropper/canvas-util.ts b/src/packages/__VUE/avatarcropper/canvas-util.ts new file mode 100644 index 00000000000..36c36cc9cf7 --- /dev/null +++ b/src/packages/__VUE/avatarcropper/canvas-util.ts @@ -0,0 +1,99 @@ +import Taro from '@tarojs/taro'; +import CanvasContext = Taro.CanvasContext; + +const compareVersion = (v1Old: string, v2Old: string) => { + let v1 = v1Old.split('.'); + let v2 = v2Old.split('.'); + const len = Math.max(v1.length, v2.length); + + while (v1.length < len) { + v1.push('0'); + } + while (v2.length < len) { + v2.push('0'); + } + + for (let i = 0; i < len; i++) { + const num1 = parseInt(v1[i]); + const num2 = parseInt(v2[i]); + + if (num1 > num2) { + return 1; + } else if (num1 < num2) { + return -1; + } + } + + return 0; +}; + +const isWeapp = () => { + return process.env.TARO_ENV === 'weapp'; +}; + +////////////////////////////////////////////////////////////////////////////////// +//////// 微信小程序自1.9.90起废除若干个CanvasContext的函数,改为属性,以下为兼容代码 +////////////////////////////////////////////////////////////////////////////////// + +function _easyCanvasContextBase( + systemInfo: any, + lowCallback: () => void, + highCallback: () => void, + targetVersion: string = '1.9.90' +) { + if (isWeapp() && compareVersion(systemInfo.SDKVersion, targetVersion) >= 0) { + highCallback(); + } else { + lowCallback(); + } +} +/** + * + * 基础库 1.9.90 开始支持,低版本需做兼容处理。填充颜色。用法同 CanvasContext.setFillStyle()。 + * @param systemInfo + * @param canvasContext + * @param color + */ +function easySetStrokeStyle(systemInfo: any, canvasContext: CanvasContext, color: string | CanvasGradient) { + _easyCanvasContextBase( + systemInfo, + () => { + canvasContext.setStrokeStyle(color); + console.log('???'); + }, + () => { + if (typeof color === 'string') { + canvasContext.strokeStyle = color; + } + console.log('2333'); + } + ); +} + +function easySetLineWidth(systemInfo: any, canvasContext: CanvasContext, lineWidth: number) { + _easyCanvasContextBase( + systemInfo, + () => { + canvasContext.setLineWidth(lineWidth); + }, + () => { + canvasContext.lineWidth = lineWidth; + } + ); +} + +function easySetFillStyle(systemInfo: any, canvasContext: CanvasContext, color: string | CanvasGradient) { + _easyCanvasContextBase( + systemInfo, + () => { + canvasContext.setFillStyle(color); + }, + () => { + if (typeof color === 'string') { + canvasContext.fillStyle = color; + } + } + ); +} + +export { easySetStrokeStyle, easySetLineWidth, easySetFillStyle }; diff --git a/src/packages/__VUE/avatarcropper/doc.taro.md b/src/packages/__VUE/avatarcropper/doc.taro.md index 49ca132ad57..d5e2efb89ba 100644 --- a/src/packages/__VUE/avatarcropper/doc.taro.md +++ b/src/packages/__VUE/avatarcropper/doc.taro.md @@ -2,4 +2,123 @@ ### 介绍 -后续再进行开发 +用来对头像进行剪切生成一张新的图片。 + +### 安装 + +```js +import { createApp } from 'vue'; +import { AvatarCropper } from '@nutui/nutui'; + +const app = createApp(); +app.use(AvatarCropper); +``` + +### 基础用法 + +中间直接使用avatar组件,裁剪后图片内容会被替换为新的。 + +:::demo + +```vue + + +``` + +::: + +### 裁剪区域toolbar插槽 + +自定义裁剪区域工具栏,toolbar-position控制工具栏位置 + +:::demo + +```vue + + + + + +``` + +::: + +## API + +### AvatarCropper Props + +| 参数 | 说明 | 类型 | 默认值 | +| ---------------- | -------------------------------------------------- | ------ | -------------------------- | +| max-zoom | 最大缩放倍数 | number | 3 | +| space | 裁剪区域两边预留的间隙 | number | 10 | +| toolbar-position | 裁剪区域工具栏位置,可选值为:`top` `bottom` | string | bottom | +| edit-text | 中间的文字内容 | string | 编辑 | +| cancel-text | 取消按钮的文字 | string | 取消 | +| cancel-confirm | 确认按钮的文字 | string | 确认 | +| size-type | 所选的图片的尺寸: 可选值:`original` `compressed` | Array | ['original', 'compressed'] | +| source-type | 选择图片的来源: 可选值:`album` `camera` | Array | ['album', 'camera'] | + +### AvatarCropper Slots + +| 名称 | 描述 | +| ------- | ----------------------------------------------------------- | +| default | 默认插槽,可放置图片、图标、文本等元素 | +| toolbar | 选择文件后裁剪弹窗底部元素可以自定义,通过ref调用组件的方法 | + +### AvatarCropper Events + +| 名称 | 描述 | 回调参数 | +| ------- | ------------------ | ------------------ | +| confirm | 裁剪后点击确认触发 | url:裁剪后的base64 | +| cancel | 点击取消触发 | - | + +### AvatarCropper Ref + +| 事件名 | 说明 | +| ------- | --------- | +| cancel | 取消裁剪 | +| reset | 重置为0度 | +| rotate | 旋转90度 | +| confirm | 确定裁剪 | diff --git a/src/packages/__VUE/avatarcropper/index.scss b/src/packages/__VUE/avatarcropper/index.scss index 2564505ce82..016984a48eb 100644 --- a/src/packages/__VUE/avatarcropper/index.scss +++ b/src/packages/__VUE/avatarcropper/index.scss @@ -1,6 +1,7 @@ .nut-avatar-cropper { position: relative; - &::after { + &::after, + &__edit-text { content: attr(data-edit-text); position: absolute; top: 0; @@ -14,6 +15,11 @@ justify-content: center; align-items: center; } + &.taro { + &::after { + content: none; + } + } &__input { position: absolute; top: 0; @@ -34,7 +40,8 @@ height: 100%; background: var(--nut-overlay-bg-color, rgba(0, 0, 0, 0.7)); z-index: 1000; - &__canvas { + &__canvas, + &__cut-canvas { position: absolute; bottom: 0; left: 0; @@ -42,6 +49,9 @@ height: 100%; z-index: 1; } + &__cut-canvas { + z-index: 0; + } &__toolbar { position: absolute; bottom: 0; diff --git a/src/packages/__VUE/avatarcropper/index.taro.vue b/src/packages/__VUE/avatarcropper/index.taro.vue new file mode 100644 index 00000000000..46d0011d289 --- /dev/null +++ b/src/packages/__VUE/avatarcropper/index.taro.vue @@ -0,0 +1,612 @@ + + + diff --git a/src/packages/__VUE/avatarcropper/types.ts b/src/packages/__VUE/avatarcropper/types.ts index 47efbe1e5b6..155fcd07e8d 100644 --- a/src/packages/__VUE/avatarcropper/types.ts +++ b/src/packages/__VUE/avatarcropper/types.ts @@ -1 +1,3 @@ export type AvatarCropperToolbarPosition = 'top' | 'bottom'; +export type AvatarCropperSizeType = 'original' | 'compressed'; +export type AvatarCropperSourceType = 'album' | 'camera';