mGY#Xn$XV@+D3HBuUP_MKbp
z>^o}&_wvwDrisWAKK%rMF+ytadb@Mc!XJv)&Zt)O9loScN9{_YDJ)RS$vMGAwqPVF
z_SJVOu(|uVrE`Q)Xn;s~;EwLbv1@DJ=1_|#Qu-*EyTUi^heK>(?{(3+&N9VE=ETFE
zQz-{aut3v3S3z@qlwktQ**y9fy=!KF6IQ*x??`3YdC;8EA$C-;NTva
zvw2#Dyqg`YL(?BRIaEbRoi3Tf%7;$%2Kn(fzHF`m&D-`DaR}f~K~Qta*hm>&xONF-W_xyB7`MgRH~
zo*umx;NfM!P51eLa2p&zKfsnTK=4?UWCoAMRXTNib+1rwAxY0fZOd-K1ynW3MQ=m?
z8g4xCBhd*u|KvA6e~CrRw9E?g$ys_$R@l0zCC6X#39lPbY`Lq?_bPY3BFDW1;MAgZ
z@=C3GI@DC$B$Gi*v-yaA&8X=ZS)@EFT_487{Y@B*l)n=NZ~5wyz9u%JQrt2#z4_6*
zfk(pIBaBj3jBeWhG<3}EjCXGPVtW9er*2rmiAY|X9`gBz(k!81{yWB>vD{V+I$93g
Tk*#;_{|5z(C(ff88JYPnu8*-u
literal 0
HcmV?d00001
diff --git a/src/image-clipper/images/rotate-inverse.png b/src/image-clipper/images/rotate-inverse.png
new file mode 100755
index 0000000000000000000000000000000000000000..ec77b6b55b31ce92efac9fd60c3ee9bff3832f45
GIT binary patch
literal 1786
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
VXF {
+ // 计算图片尺寸
+ this.imgComputeSize(res.width, res.height);
+ if (this.properties.limitMove) {
+ // 限制移动,不留空白处理
+ this.imgMarginDetectionScale();
+ eventUtil.emit(this, 'linimageready', res);
+ }
+ },
+ fail: () => {
+ this.imgComputeSize();
+ if (this.properties.limitMove) {
+ this.imgMarginDetectionScale();
+ }
+ }
+ });
+ },
+ 'clipWidth, clipHeight'(widthVal, heightVal) {
+ let { minWidth, minHeight } = this.data;
+ minWidth = minWidth / 2;
+ minHeight = minHeight / 2;
+ if (widthVal < minWidth) {
+ dataUtil.setDiffData(this, { clipWidth: minWidth });
+ }
+ if (heightVal < minHeight) {
+ dataUtil.setDiffData(this, { clipHeight: minHeight });
+ }
+ this.computeCutSize();
+ },
+ 'rotateAngle'(val) {
+ dataUtil.setDiffData(this, { cutAnimation: true, angle: val });
+ },
+ 'angle'(val) {
+ this.moveStop();
+ const {
+ limitMove
+ } = this.properties;
+ if (limitMove && val % 90) {
+ dataUtil.setDiffData(this, { angle: Math.round(val / 90) * 90 });
+ }
+ this.imgMarginDetectionScale();
+ },
+ 'cutAnimation'(val) {
+ // 开启过渡260毫秒之后自动关闭
+ clearTimeout(this.data._cutAnimationTime);
+ if (val) {
+ let _cutAnimationTime = setTimeout(() => {
+ dataUtil.setDiffData(this, { cutAnimation: false });
+ }, 260);
+ dataUtil.setDiffData(this, { _cutAnimationTime });
+ }
+ },
+ 'limitMove'(val) {
+ if (val) {
+ if (this.data.angle % 90) {
+ dataUtil.setDiffData(this, { angle: Math.round(this.data.angle / 90) * 90 });
+ }
+ this.imgMarginDetectionScale();
+ }
+ },
+ 'cutY, cutX'() {
+ this.cutDetectionPosition();
+ },
+ 'width, height'(width, height) {
+ if(width !== this.width) {
+ dataUtil.setDiffData(this, {clipWidth: width / 2});
+ }
+ if(height !== this.height) {
+ dataUtil.setDiffData(this, {clipHeight: height / 2});
+ }
+ }
+ },
+ /**
+ * 组件的方法列表
+ */
+ methods: {
+ /**
+ * 设置裁剪框的一些信息
+ */
+ setCutInfo() {
+ const {
+ width,
+ height
+ } = this.properties;
+ const {
+ _SYS_INFO
+ } = this.data;
+ // 本组件动态style默认单位为px,需将用户传入值/2
+ const clipWidth = width / 2;
+ const clipHeight = height / 2;
+ const cutY = (_SYS_INFO.windowHeight - clipHeight) / 2;
+ const cutX = (_SYS_INFO.windowWidth - clipWidth) / 2;
+ const imageLeft = _SYS_INFO.windowWidth / 2;
+ const imageTop = _SYS_INFO.windowHeight / 2;
+ const _ctx = wx.createCanvasContext('image-clipper', this);
+ this.setData({
+ clipWidth,
+ clipHeight,
+ cutX,
+ cutY,
+ CANVAS_HEIGHT: clipHeight,
+ CANVAS_WIDTH: clipWidth,
+ _ctx,
+ imageLeft,
+ imageTop
+ });
+ },
+ /**
+ * 裁剪框居中
+ */
+ setCutCenter() {
+ const { sysInfo, clipHeight, clipWidth, imageTop, imageLeft } = this.data;
+ let sys = sysInfo || wx.getSystemInfoSync();
+ let cutY = (sys.windowHeight - clipHeight) * 0.5;
+ let cutX = (sys.windowWidth - clipWidth) * 0.5;
+ this.setData({
+ imageTop: imageTop - this.data.cutY + cutY,
+ imageLeft: imageLeft - this.data.cutX + cutX,
+ cutY,
+ cutX
+ });
+ },
+ /**
+ * 开始拖动裁剪框
+ * 需在此处查找到是否拖动的裁剪框四角
+ */
+ clipTouchStart(event) {
+ if (!this.properties.imageUrl) {
+ wx.showToast({
+ title: '请选择图片',
+ icon: 'none'
+ });
+ return;
+ }
+ const currentX = event.touches[0].clientX;
+ const currentY = event.touches[0].clientY;
+ const { cutX, cutY, clipWidth, clipHeight } = this.data;
+ const corner = determineDirection(cutX, cutY, clipWidth, clipHeight, currentX, currentY);
+ this.moveDuring();
+ const _CUT_START = {
+ width: clipWidth,
+ height: clipHeight,
+ x: currentX,
+ y: currentY,
+ cutY,
+ cutX,
+ corner
+ };
+ this.setData({ _flagCutTouch: true, _flagEndTouch: true, _CUT_START });
+ },
+ /**
+ * 拖动裁剪框
+ * 当拖动的裁剪框区域时处理数据
+ */
+ clipTouchMove(event) {
+ if (!this.properties.imageUrl) {
+ wx.showToast({
+ title: '请选择图片',
+ icon: 'none'
+ });
+ return;
+ }
+
+ const { _flagCutTouch, _MOVE_THROTTLE_FLAG } = this.data;
+ if (_flagCutTouch && _MOVE_THROTTLE_FLAG) {
+ const { lockRatio, lockHeight, lockWidth } = this.properties;
+ if (lockRatio && (lockWidth || lockHeight)) return;
+ dataUtil.setDiffData(this, { _MOVE_THROTTLE_FLAG: false });
+ this.moveThrottle();
+ const { width, height, cutX, cutY } = clipTouchMoveOfCalculate(this.data, event);
+ if (!lockWidth && !lockHeight) {
+ dataUtil.setDiffData(this, { clipWidth: width, clipHeight: height, cutX, cutY });
+ } else if (!lockWidth) {
+ dataUtil.setDiffData(this, { clipWidth: width, cutX });
+ } else if (!lockHeight) {
+ dataUtil.setDiffData(this, { clipHeight: height, cutY });
+ }
+ this.imgMarginDetectionScale();
+ }
+ },
+ /**
+ * 拖动裁剪框结束
+ * 当拖动的裁剪框区域时处理数据
+ */
+ clipTouchEnd() {
+ this.moveStop();
+ this.setData({ _flagCutTouch: false });
+ },
+ /**
+ * 清空之前的自动居中延迟函数
+ */
+ moveDuring() {
+ clearTimeout(this.data._TIME_CUT_CENTER);
+ },
+ /**
+ * 停止移动时需要做的操作
+ * 清空之前的自动居中延迟函数并添加最新的
+ */
+ moveStop() {
+ clearTimeout(this.data._TIME_CUT_CENTER);
+ const _TIME_CUT_CENTER = setTimeout(() => {
+ //动画启动
+ if (!this.data.cutAnimation) {
+ dataUtil.setDiffData(this, { cutAnimation: true });
+ }
+ this.setCutCenter();
+ }, 800);
+ dataUtil.setDiffData(this, { _TIME_CUT_CENTER });
+ },
+ /**
+ * 重置延迟函数
+ */
+ moveThrottle() {
+ if (this.data._SYS_INFO.platform === 'android') {
+ clearTimeout(this.data._MOVE_THROTTLE);
+ const _MOVE_THROTTLE = setTimeout(() => {
+ dataUtil.setDiffData(this, { _MOVE_THROTTLE_FLAG: true });
+ }, 800 / 40);
+ dataUtil.setDiffData(this, { _MOVE_THROTTLE });
+ } else {
+ dataUtil.setDiffData(this, { _MOVE_THROTTLE_FLAG: true });
+ }
+ },
+ /**
+ * 图片初始化
+ */
+ imageReset() {
+ const sys = this.data._SYS_INFO || wx.getSystemInfoSync();
+ this.setData({ scale: 1, angle: 0, imageTop: sys.windowHeight / 2, imageLeft: sys.windowWidth / 2 });
+ },
+ /**
+ * 图片加载完成
+ */
+ imageLoad() {
+ this.imageReset();
+ wx.hideLoading();
+ eventUtil.emit(this, 'linimageload', detail);
+ },
+ /**
+ * 计算图片尺寸
+ */
+ imgComputeSize(width, height) {
+ const { imageWidth, imageHeight } = calcImageSize(width, height, this.data);
+ this.setData({ imageWidth, imageHeight });
+ },
+ /**
+ * 图片边缘检测-缩放
+ */
+ imgMarginDetectionScale(scale) {
+ if (!this.properties.limitMove) return;
+ const currentScale = calcImageScale(this.data, scale);
+ this.imgMarginDetectionPosition(currentScale);
+ },
+ /**
+ * 图片边缘检测-位置
+ */
+ imgMarginDetectionPosition(scale) {
+ if (!this.properties.limitMove) return;
+ const { scale: currentScale, left, top } = calcImageOffset(this.data, scale);
+ dataUtil.setDiffData(this, { imageLeft: left, imageTop: top, scale: currentScale });
+ },
+ /**
+ * 开始图片触摸
+ */
+ imageTouchStart(e) {
+ this.setData({ _flagEndTouch: false });
+ const { imageLeft, imageTop } = this.data;
+ // 双指左指坐标
+ const clientXForLeft = e.touches[0].clientX;
+ const clientYForLeft = e.touches[0].clientY;
+
+ let _touchRelative = [];
+ if (e.touches.length === 1) {
+ // 单指拖动
+ _touchRelative[0] = {
+ x: clientXForLeft - imageLeft,
+ y: clientYForLeft - imageTop
+ };
+ this.setData({ _touchRelative });
+ } else {
+ // 双指右指坐标
+ const clientXForRight = e.touches[1].clientX;
+ const clientYForRight = e.touches[1].clientY;
+ // 双指放大
+ let width = Math.abs(clientXForLeft - clientXForRight);
+ let height = Math.abs(clientYForLeft - clientYForRight);
+ // 勾股定理求出斜边长度
+ const _hypotenuseLength = calcPythagoreanTheorem(width, height);
+
+ _touchRelative = [{
+ x: clientXForLeft - imageLeft,
+ y: clientYForLeft - imageTop
+ },
+ {
+ x: clientXForRight - imageLeft,
+ y: clientYForRight - imageTop
+ }
+ ];
+ this.setData({_touchRelative, _hypotenuseLength});
+ }
+ },
+ /**
+ * 图片放大旋转等操作
+ */
+ imageTouchMove(e) {
+ const {
+ _flagEndTouch,
+ _MOVE_THROTTLE_FLAG
+ } = this.data;
+ if (_flagEndTouch || !_MOVE_THROTTLE_FLAG) return;
+ // 双指左指坐标
+ const clientXForLeft = e.touches[0].clientX;
+ const clientYForLeft = e.touches[0].clientY;
+
+ dataUtil.setDiffData(this, { _MOVE_THROTTLE_FLAG: false });
+ this.moveThrottle();
+ this.moveDuring();
+ if (e.touches.length === 1) {
+ //单指拖动
+ const { left, top } = imageTouchMoveOfCalcOffset(this.data, clientXForLeft, clientYForLeft);
+ dataUtil.setDiffData(this, { imageLeft: left, imageTop: top});
+ // 图像边缘检测,防止截取到空白
+ this.imgMarginDetectionPosition();
+ } else {
+ // 双指右指坐标
+ const clientXForRight = e.touches[1].clientX;
+ const clientYForRight = e.touches[1].clientY;
+ // 双指放大
+ let width = Math.abs(clientXForLeft - clientXForRight),
+ height = Math.abs(clientYForLeft - clientYForRight),
+ // 勾股定理求出斜边长度
+ hypotenuse = calcPythagoreanTheorem(width, height), // 斜边
+ scale = this.data.scale * (hypotenuse / this.data._hypotenuseLength);
+ // 计算出真实缩放倍率
+ // 如果禁止缩放则倍率一直为1
+ if (this.properties.disableScale) {
+ scale = 1;
+ } else {
+ scale = scale <= this.properties.minRatio ? this.properties.minRatio : scale;
+ scale = scale >= this.properties.maxRatio ? this.properties.maxRatio : scale;
+ eventUtil.emit(this, 'linsizechange', {
+ imageWidth: this.data.imageWidth * scale,
+ imageHeight: this.data.imageHeight * scale
+ });
+ }
+
+ this.imgMarginDetectionScale(scale);
+ dataUtil.setDiffData(this, {
+ _hypotenuseLength: Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)),
+ scale
+ });
+ }
+ },
+ /**
+ * 图片手指触摸结束
+ */
+ imageTouchEnd() {
+ dataUtil.setDiffData(this, { _flagEndTouch: true });
+ this.moveStop();
+ },
+
+ /**
+ * 检测剪裁框位置是否在允许的范围内(屏幕内)
+ */
+ cutDetectionPosition() {
+ const { cutX, cutY, _SYS_INFO, clipHeight, clipWidth } = this.data;
+ let cutDetectionPositionTop = () => {
+ //检测上边距是否在范围内
+ if (cutY < 0) {
+ dataUtil.setDiffData(this, { cutY: 0 });
+ }
+ if (cutY > _SYS_INFO.windowHeight - clipHeight) {
+ dataUtil.setDiffData(this, { cutY: _SYS_INFO.windowHeight - clipHeight });
+ }
+ },
+ cutDetectionPositionLeft = () => {
+ //检测左边距是否在范围内
+ if (cutX < 0) {
+ dataUtil.setDiffData(this, { cutX: 0 });
+ }
+ if (cutX > _SYS_INFO.windowWidth - clipWidth) {
+ dataUtil.setDiffData(this, { cutX: _SYS_INFO.windowWidth - clipWidth });
+ }
+ };
+ //裁剪框坐标处理(如果只写一个参数则另一个默认为0,都不写默认居中)
+ if (cutY === null && cutX === null) {
+ let newCutY = (_SYS_INFO.windowHeight - clipHeight) * 0.5;
+ let newCutX = (_SYS_INFO.windowWidth - clipWidth) * 0.5;
+ dataUtil.setDiffData(this, {
+ cutX: newCutX, // 截取的框上边距
+ cutY: newCutY // 截取的框左边距
+ });
+ } else if (cutY !== null && cutX !== null) {
+ cutDetectionPositionTop();
+ cutDetectionPositionLeft();
+ } else if (cutY !== null && cutX === null) {
+ cutDetectionPositionTop();
+ dataUtil.setDiffData(this, { cutX: (_SYS_INFO.windowWidth - clipWidth) / 2 });
+ } else if (cutY === null && cutX !== null) {
+ cutDetectionPositionLeft();
+ dataUtil.setDiffData(this, { cutY: (_SYS_INFO.windowHeight - clipHeight) / 2 });
+ }
+ },
+ /**
+ * 改变截取框大小
+ */
+ computeCutSize() {
+ const { clipHeight, clipWidth, _SYS_INFO, cutX, cutY } = this.data;
+ if (clipWidth > _SYS_INFO.windowWidth) {
+ // 设置裁剪框宽度
+ dataUtil.setDiffData(this, { clipWidth: _SYS_INFO.windowWidth });
+ } else if (clipWidth + cutX > _SYS_INFO.windowWidth) {
+ dataUtil.setDiffData(this, { cutX: _SYS_INFO.windowWidth - cutX });
+ }
+ if (clipHeight > _SYS_INFO.windowHeight) {
+ // 设置裁剪框高度
+ dataUtil.setDiffData(this, { clipHeight: _SYS_INFO.windowHeight });
+ } else if (clipHeight + cutY > _SYS_INFO.windowHeight) {
+ dataUtil.setDiffData(this, { cutY: _SYS_INFO.windowHeight - cutY });
+ }
+ },
+ /**
+ * 获取图片数据
+ */
+ getImageData() {
+ if (!this.properties.imageUrl) {
+ wx.showToast({
+ title: '请选择图片',
+ icon: 'none'
+ });
+ return;
+ }
+ wx.showLoading({
+ title: '加载中'
+ });
+
+ const { clipHeight, clipWidth, _ctx, scale, imageLeft, imageTop, cutX, cutY, angle } = this.data;
+ let { CANVAS_HEIGHT, CANVAS_WIDTH } = this.data;
+ const { scaleRatio, imageUrl, quality, type: imageType } = this.properties;
+ // 绘制函数
+ const draw = () => {
+ // 图片真实大小
+ const imageWidth = this.data.imageWidth * scale * scaleRatio;
+ const imageHeight = this.data.imageHeight * scale * scaleRatio;
+ // canvas和图片的相对距离
+ const xpos = imageLeft - cutX;
+ const ypos = imageTop - cutY;
+ // 旋转画布
+ _ctx.translate(xpos * scaleRatio, ypos * scaleRatio);
+ _ctx.rotate((angle * Math.PI) / 180);
+ _ctx.drawImage(imageUrl, -imageWidth / 2, -imageHeight / 2, imageWidth, imageHeight);
+ _ctx.draw(false, () => {
+ let params = {
+ width: clipWidth * scaleRatio,
+ height: Math.round(clipHeight * scaleRatio),
+ destWidth: clipWidth * scaleRatio,
+ destHeight: Math.round(clipHeight) * scaleRatio,
+ fileType: 'png',
+ quality
+ };
+
+ let data = {
+ url: '',
+ base64: '',
+ width: clipWidth * scaleRatio,
+ height: clipHeight * scaleRatio
+ };
+
+ if (IMAGE_TYPE.base64 === imageType) {
+ wx.canvasGetImageData({
+ canvasId: 'image-clipper',
+ x: 0,
+ y: 0,
+ width: clipWidth * scaleRatio,
+ height: Math.round(clipHeight * scaleRatio),
+ success: res => {
+ const arrayBuffer = new Uint8Array(res.data);
+ const base64 = wx.arrayBufferToBase64(arrayBuffer);
+ data.url = base64;
+ data.base64 = base64;
+ wx.hideLoading();
+ eventUtil.emit(this, 'linclip', data);
+ }
+ });
+ } else {
+ wx.canvasToTempFilePath({
+ ...params,
+ canvasId: 'image-clipper',
+ success: res => {
+ data.url = res.tempFilePath;
+ data.base64 = res.tempFilePath;
+ wx.hideLoading();
+ eventUtil.emit(this, 'linclip', data);
+ },
+ fail(res) {
+ throw res;
+ }
+ },
+ this
+ );
+ }
+ });
+ };
+
+ if (CANVAS_WIDTH !== clipWidth || CANVAS_HEIGHT !== clipHeight) {
+ CANVAS_WIDTH = clipWidth;
+ CANVAS_HEIGHT = clipHeight;
+ _ctx.draw();
+ setTimeout(() => {
+ draw();
+ }, 100);
+ } else {
+ draw();
+ }
+ },
+ /**
+ * 上传图片
+ */
+ uploadImage() {
+ wx.chooseImage({
+ count: 1,
+ sizeType: ['original', 'compressed'],
+ sourceType: ['album', 'camera'],
+ success: (res) => {
+ const tempFilePaths = res.tempFilePaths;
+ this.setData({ imageUrl: tempFilePaths });
+ }
+ });
+ },
+ /**
+ * 工具栏旋转
+ */
+ rotate(event) {
+ if (this.properties.disableRotate) return;
+ if (!this.properties.imageUrl) {
+ wx.showToast({
+ title: '请选择图片',
+ icon: 'none'
+ });
+ return;
+ }
+ const { rotateAngle } = this.properties;
+ const originAngle = this.data.angle;
+ const type = event.currentTarget.dataset.type;
+ if (type === 'along') {
+ this.setData({ angle: originAngle + rotateAngle });
+ } else {
+ this.setData({ angle: originAngle - rotateAngle});
+ }
+ eventUtil.emit(this, 'linrotate', { currentDeg: this.data.angle });
+ },
+ /**
+ * 关闭
+ */
+ close() {
+ this.setData({ show: false });
+ },
+ },
+
+ /**
+ * 组件的生命周期
+ */
+ lifetimes: {
+ ready() {
+ const _SYS_INFO = wx.getSystemInfoSync();
+ this.setData({ _SYS_INFO });
+ this.setCutInfo();
+ this.setCutCenter();
+ this.computeCutSize();
+ this.cutDetectionPosition();
+ }
+ }
+});
diff --git a/src/image-clipper/index.json b/src/image-clipper/index.json
new file mode 100644
index 00000000..e8cfaaf8
--- /dev/null
+++ b/src/image-clipper/index.json
@@ -0,0 +1,4 @@
+{
+ "component": true,
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/src/image-clipper/index.less b/src/image-clipper/index.less
new file mode 100644
index 00000000..ac8fa2ad
--- /dev/null
+++ b/src/image-clipper/index.less
@@ -0,0 +1,131 @@
+.container {
+ width: 100vw;
+ height: 100vh;
+ background-color: rgba(0, 0, 0, 0.6);
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 1;
+
+ .clip-wrapper {
+ position: absolute;
+ width: 100vw;
+ height: 100vh;
+
+ .clip-content {
+ width: 100vw;
+ height: 100vh;
+ position: absolute;
+ z-index: 99;
+ display: flex;
+ flex-direction: column;
+ pointer-events: none;
+
+ .flex-auto {
+ flex: auto;
+ }
+
+ .clip-content-top,
+ .clip-content-footer {
+ width: 100%;
+ pointer-events: none;
+ }
+
+ .clip-content-middle {
+ width: 100%;
+ height: 400rpx;
+ display: flex;
+ box-sizing: border-box;
+
+ .clip-content-middle-left,
+ .clip-content-middle-right {
+ height: 100%;
+ }
+
+ .clip-content-middle-center {
+ position: relative;
+ border: 1px solid;
+ box-sizing: border-box;
+
+ .clip-edge {
+ position: absolute;
+ left: 6rpx;
+ width: 34rpx;
+ height: 34rpx;
+ border: 2rpx solid #ffffff;
+ pointer-events: auto;
+ box-sizing: border-box;
+
+ &.clip-edge-top-left {
+ border-bottom-width: 0 !important;
+ border-right-width: 0 !important;
+ }
+
+ &.clip-edge-top-right {
+ border-bottom-width: 0 !important;
+ border-left-width: 0 !important;
+ }
+
+ &.clip-edge-bottom-left {
+ border-top-width: 0 !important;
+ border-right-width: 0 !important;
+ }
+
+ &.clip-edge-bottom-right {
+ border-top-width: 0 !important;
+ border-left-width: 0 !important;
+ }
+ }
+ }
+ }
+ }
+
+ .bg-transparent {
+ background-color: rgba(0, 0, 0, 0.6);
+ transition-duration: 0.35s;
+ }
+ }
+
+ .cropper-image {
+ width: 100%;
+ border-style: none;
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 2;
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+ transform-origin: center;
+ }
+
+ .clipper-canvas {
+ position: fixed;
+ z-index: 10;
+ left: -2000px;
+ top: -2000px;
+ pointer-events: none;
+ }
+
+ .footer-tools {
+ position: absolute;
+ left: 0;
+ bottom: 0;
+ width: 100%;
+ z-index: 99;
+ .tools-icon {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ width: 100%;
+ padding: 20rpx 40rpx;
+ box-sizing: border-box;
+
+ image {
+ display: block;
+ width: 50rpx;
+ height: 50rpx;
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/image-clipper/index.wxml b/src/image-clipper/index.wxml
new file mode 100644
index 00000000..7bc12fd6
--- /dev/null
+++ b/src/image-clipper/index.wxml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
From b9c5e583ecd575ce1377f532da17e04d37e052d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=A1=94=E5=AD=90?=
Date: Tue, 4 Aug 2020 15:21:40 +0800
Subject: [PATCH 02/37] =?UTF-8?q?refactor(Counter):=20=E5=88=A0=E9=99=A4?=
=?UTF-8?q?=20count-selector=20=E7=BB=84=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
count-selector 是 counter 更名前的组件,现在已无用
BREAKING CHANGE: 删除 CountSelector 组件
---
examples/app.json | 2 +-
.../shopping/pages/count-selector/index.wxml | 5 -
.../{count-selector => counter}/count-nav.js | 0
.../{count-selector => counter}/index.js | 2 +-
.../{count-selector => counter}/index.json | 4 +-
.../shopping/pages/counter/index.wxml | 5 +
.../{count-selector => counter}/index.wxss | 0
src/count-selector/index.js | 158 ------------------
src/count-selector/index.json | 6 -
src/count-selector/index.less | 68 --------
src/count-selector/index.wxml | 22 ---
11 files changed, 9 insertions(+), 263 deletions(-)
delete mode 100644 examples/pages/components/shopping/pages/count-selector/index.wxml
rename examples/pages/components/shopping/pages/{count-selector => counter}/count-nav.js (100%)
rename examples/pages/components/shopping/pages/{count-selector => counter}/index.js (94%)
rename examples/pages/components/shopping/pages/{count-selector => counter}/index.json (72%)
create mode 100644 examples/pages/components/shopping/pages/counter/index.wxml
rename examples/pages/components/shopping/pages/{count-selector => counter}/index.wxss (100%)
delete mode 100644 src/count-selector/index.js
delete mode 100644 src/count-selector/index.json
delete mode 100644 src/count-selector/index.less
delete mode 100644 src/count-selector/index.wxml
diff --git a/examples/app.json b/examples/app.json
index b359f126..b6565f20 100644
--- a/examples/app.json
+++ b/examples/app.json
@@ -122,7 +122,7 @@
"root": "pages/components/shopping",
"pages": [
"pages/price/index",
- "pages/count-selector/index",
+ "pages/counter/index",
"pages/search-bar/index"
]
},
diff --git a/examples/pages/components/shopping/pages/count-selector/index.wxml b/examples/pages/components/shopping/pages/count-selector/index.wxml
deleted file mode 100644
index d7421f16..00000000
--- a/examples/pages/components/shopping/pages/count-selector/index.wxml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/examples/pages/components/shopping/pages/count-selector/count-nav.js b/examples/pages/components/shopping/pages/counter/count-nav.js
similarity index 100%
rename from examples/pages/components/shopping/pages/count-selector/count-nav.js
rename to examples/pages/components/shopping/pages/counter/count-nav.js
diff --git a/examples/pages/components/shopping/pages/count-selector/index.js b/examples/pages/components/shopping/pages/counter/index.js
similarity index 94%
rename from examples/pages/components/shopping/pages/count-selector/index.js
rename to examples/pages/components/shopping/pages/counter/index.js
index 2e4d28a7..97327303 100644
--- a/examples/pages/components/shopping/pages/count-selector/index.js
+++ b/examples/pages/components/shopping/pages/counter/index.js
@@ -1,5 +1,5 @@
// pages/shopping/pages/count/index.js
-import countConfig from '../count-selector/count-nav.js';
+import countConfig from './count-nav.js';
Page({
diff --git a/examples/pages/components/shopping/pages/count-selector/index.json b/examples/pages/components/shopping/pages/counter/index.json
similarity index 72%
rename from examples/pages/components/shopping/pages/count-selector/index.json
rename to examples/pages/components/shopping/pages/counter/index.json
index 614acaf4..ece83113 100644
--- a/examples/pages/components/shopping/pages/count-selector/index.json
+++ b/examples/pages/components/shopping/pages/counter/index.json
@@ -2,6 +2,6 @@
"usingComponents": {
"content-title": "/components/content-title/index",
"content-card": "/components/content-card/index",
- "l-count-selector": "/dist/count-selector/index"
+ "l-counter": "/dist/counter/index"
}
-}
\ No newline at end of file
+}
diff --git a/examples/pages/components/shopping/pages/counter/index.wxml b/examples/pages/components/shopping/pages/counter/index.wxml
new file mode 100644
index 00000000..e3714ffc
--- /dev/null
+++ b/examples/pages/components/shopping/pages/counter/index.wxml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/examples/pages/components/shopping/pages/count-selector/index.wxss b/examples/pages/components/shopping/pages/counter/index.wxss
similarity index 100%
rename from examples/pages/components/shopping/pages/count-selector/index.wxss
rename to examples/pages/components/shopping/pages/counter/index.wxss
diff --git a/src/count-selector/index.js b/src/count-selector/index.js
deleted file mode 100644
index c037e059..00000000
--- a/src/count-selector/index.js
+++ /dev/null
@@ -1,158 +0,0 @@
-Component({
- externalClasses: [
- 'l-class',
- 'l-symbol-class',
- 'l-count-class',
- 'l-disabled-class'
- ],
- properties: {
- count: {
- type: Number,
- value: 1
- },
- max: {
- type: Number,
- value: 9999
- },
- min: {
- type: Number,
- value: 1
- },
- step: {
- type: Number,
- value: 1
- },
- disabled: Boolean,
- iconSize: String,
- iconColor: String
- },
-
- /**
- * 组件的初始数据
- */
- data: {
- focus: false,
- result: 1
- },
-
- observers: {
- 'count,min,max': function () {
- this.valueRange(this.data.count, 'parameter');
- }
- },
-
- /**
- * 组件的方法列表
- */
- methods: {
- doNothing(e) {
- const { type } = e.currentTarget.dataset;
- this.triggerEvent('linout', { type, way: 'icon' }, {
- bubbles: true,
- composed: true
- });
- },
-
- onCount() {
- this.setData({
- focus: true
- });
- },
-
- onBlur(e) {
- this.setData({
- focus: false
- });
- let {
- value
- } = e.detail;
- setTimeout(() => {
- this.blurCount(Number(value), () => {
- this.data.count = this.data.result;
- this.triggerEvent('lintap', {
- count: this.data.result,
- type: 'blur'
- }, {
- bubbles: true,
- composed: true
- });
- });
- }, 50);
- },
-
- blurCount(value, callback) {
- if (value) {
- this.valueRange(value);
- } else {
- this.setData({
- result: this.properties.count
- });
- }
- callback && callback();
- },
-
- valueRange(value, way = 'input') {
- if (value > this.properties.max) {
- this.setData({
- result: this.properties.max
- }, () => {
- this.triggerEvent('linout', { type: 'overflow_max', way }, {
- bubbles: true,
- composed: true
- });
- });
- } else if (value < this.properties.min) {
- this.setData({
- result: this.properties.min
- }, () => {
- this.triggerEvent('linout', { type: 'overflow_min', way }, {
- bubbles: true,
- composed: true
- });
- });
- } else {
- this.setData({
- result: value
- });
- }
- },
-
- reduceTap() {
- let distance = this.data.count - this.properties.step;
- if (distance <= this.properties.min) {
- this.data.count = this.properties.min;
- } else {
- this.data.count -= this.properties.step;
- }
- this.setData({
- result: this.data.count
- });
- this.triggerEvent('lintap', {
- count: this.data.result,
- type: 'reduce'
- }, {
- bubbles: true,
- composed: true
- });
- },
-
- addTap() {
- let distance = this.data.count + this.properties.step;
- if (distance >= this.properties.max) {
- this.data.count = this.properties.max;
- } else {
- this.data.count += this.properties.step;
- }
- this.setData({
- result: this.data.count
- });
- this.triggerEvent('lintap', {
- count: this.data.result,
- type: 'add'
- }, {
- bubbles: true,
- composed: true
- });
- },
- }
-});
\ No newline at end of file
diff --git a/src/count-selector/index.json b/src/count-selector/index.json
deleted file mode 100644
index c01e2d7e..00000000
--- a/src/count-selector/index.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "component": true,
- "usingComponents": {
- "l-icon":"../icon/index"
- }
-}
\ No newline at end of file
diff --git a/src/count-selector/index.less b/src/count-selector/index.less
deleted file mode 100644
index 4345f8b2..00000000
--- a/src/count-selector/index.less
+++ /dev/null
@@ -1,68 +0,0 @@
-.container-count {
- display : flex;
- flex-direction: row;
- width : 170rpx;
- height : 56rpx;
-}
-
-.symbol {
- height : 100%;
- width : 56rpx;
- font-size : 28rpx;
- color : #596C8E;
- display : flex;
- align-items : center;
- justify-content: center;
-}
-
-.disabled {
- background-color: #f3f3f3;
- color : #c4c9d2;
-}
-
-.abled {
- background-color: #ecf1f8;
- color : #596c8e;
-}
-
-.count {
- height : 100%;
- flex : 1;
- min-height : 56rpx;
- line-height : 56rpx;
- font-size : 24rpx;
- color : #596c8e;
- background : #f6f7f9;
- text-align : center;
- overflow : hidden;
- text-overflow: ellipsis;
- white-space : nowrap;
-}
-
-@font-face {
- font-family: "iconfont";
- src : url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAALEAAsAAAAABqwAAAJ3AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDBgqBFIEWATYCJAMMCwgABCAFhG0HNxvdBcgekiSBqhRCJKIogADMEYRr5GySu0dQoBAloETFRVKmqpWoK1wVG1th2Ij732n7N5fsqTh2xyneKfa2N3/anZKGvYXFohGGrUFIEA6JogD/fZ7L6U2gA7nGtyynNW3s8fyoF2AcUEBjbYqsRALxFtlF3ImLOE6g3ZheoYOxmRVIKtC4QLww9QYkCxFFMfKtQt2wtIjXKq3pZfrEq+j78d9qJEmqDE09fTTahoFf6deHfNxwgxOiBHl1hYx5oBC3GjMXIsLgItpN0e7yWhHSXPEmkcq31Dv94yWihmo7wbQcS/yiMoJf9yskkEFdzE0Diwo7eF2IkexeNr35cvtSjmQ/fjt5zeTy++93z1I4x8LHT3u9VVdH6SHr0r8+OjOTtCopyONe0uFsIlZDiaMZyTdAmzFfZzrm0+EOQPOcP/IeANGP4rNA8KN0+V8rbPwlMwX83P7UK0Wa5wJwS+sZvMEfUwMbiq9F1lxcFVWFvmwE4ErICtOvARTo9zPeMgROEVoL2hG+FqMeslbjZGHnUemwjlqrbbSbM766wwAuIkobZl1ICL0ekXT7jqzXF1nYb1SG/aLWGxG0O4uBLTtMhpne59gQ2CbNHWK2mEeJXaTj+iXUN5wGz2sjfg15YMaJJqvl/Dh6yOeYEWzqFSEooZy5ZEw6DR2HEZ8zC1tCNoTwq4pCm94kt5gLafs41CCgNqJpB2FqYTyUtxbSlc8vQboNjgbeIejJr0FcwOyc0MhUADlu8kCCe3klsElXIQgUQXGMixiTBiGHgyH85kEW1CLIjBEpX5WCm1GoSV7f4n7fNmiH9syRIkeR77bbiWdmwzMaDAAA') format('woff2')
-}
-
-.l-icon-add:before {
- content: "\e602";
-}
-
-.l-icon-reduce:before {
- content: "\e69c";
-}
-
-.l-icon {
- font-family : "iconfont";
- font-style : normal;
- -webkit-font-smoothing : antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-.l-icon::before {
- display: inline-flex;
-}
-
-.count-hover{
- opacity: .8;
-}
\ No newline at end of file
diff --git a/src/count-selector/index.wxml b/src/count-selector/index.wxml
deleted file mode 100644
index c1b1cff4..00000000
--- a/src/count-selector/index.wxml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
- {{result}}
-
-
-
-
\ No newline at end of file
From 01544c2feb460b78c63665855dfbfa989798f8e2 Mon Sep 17 00:00:00 2001
From: Juzi
Date: Wed, 5 Aug 2020 10:12:11 +0800
Subject: [PATCH 03/37] build: Travis CI automatic compilation
---
dist/image-clipper-tools/index.js | 1 +
dist/image-clipper-tools/index.json | 1 +
dist/image-clipper-tools/index.wxml | 28 +
dist/image-clipper-tools/index.wxss | 1 +
dist/image-clipper/calculate.js | 1 +
dist/image-clipper/images/close.png | Bin 0 -> 2768 bytes
dist/image-clipper/images/photo.png | Bin 0 -> 1288 bytes
dist/image-clipper/images/rotate-along.png | Bin 0 -> 1796 bytes
dist/image-clipper/images/rotate-inverse.png | Bin 0 -> 1786 bytes
dist/image-clipper/images/sure.png | Bin 0 -> 2620 bytes
dist/image-clipper/index.js | 1 +
dist/image-clipper/index.json | 1 +
dist/image-clipper/index.wxml | 45 +
dist/image-clipper/index.wxss | 1 +
examples/dist/image-clipper-tools/index.js | 80 ++
examples/dist/image-clipper-tools/index.json | 4 +
examples/dist/image-clipper-tools/index.wxml | 28 +
examples/dist/image-clipper-tools/index.wxss | 1 +
examples/dist/image-clipper/calculate.js | 276 ++++++
examples/dist/image-clipper/images/close.png | Bin 0 -> 2768 bytes
examples/dist/image-clipper/images/photo.png | Bin 0 -> 1288 bytes
.../image-clipper/images/rotate-along.png | Bin 0 -> 1796 bytes
.../image-clipper/images/rotate-inverse.png | Bin 0 -> 1786 bytes
examples/dist/image-clipper/images/sure.png | Bin 0 -> 2620 bytes
examples/dist/image-clipper/index.js | 802 ++++++++++++++++++
examples/dist/image-clipper/index.json | 4 +
examples/dist/image-clipper/index.wxml | 68 ++
examples/dist/image-clipper/index.wxss | 1 +
28 files changed, 1344 insertions(+)
create mode 100644 dist/image-clipper-tools/index.js
create mode 100644 dist/image-clipper-tools/index.json
create mode 100644 dist/image-clipper-tools/index.wxml
create mode 100644 dist/image-clipper-tools/index.wxss
create mode 100644 dist/image-clipper/calculate.js
create mode 100755 dist/image-clipper/images/close.png
create mode 100755 dist/image-clipper/images/photo.png
create mode 100755 dist/image-clipper/images/rotate-along.png
create mode 100755 dist/image-clipper/images/rotate-inverse.png
create mode 100755 dist/image-clipper/images/sure.png
create mode 100644 dist/image-clipper/index.js
create mode 100644 dist/image-clipper/index.json
create mode 100644 dist/image-clipper/index.wxml
create mode 100644 dist/image-clipper/index.wxss
create mode 100644 examples/dist/image-clipper-tools/index.js
create mode 100644 examples/dist/image-clipper-tools/index.json
create mode 100644 examples/dist/image-clipper-tools/index.wxml
create mode 100644 examples/dist/image-clipper-tools/index.wxss
create mode 100644 examples/dist/image-clipper/calculate.js
create mode 100755 examples/dist/image-clipper/images/close.png
create mode 100755 examples/dist/image-clipper/images/photo.png
create mode 100755 examples/dist/image-clipper/images/rotate-along.png
create mode 100755 examples/dist/image-clipper/images/rotate-inverse.png
create mode 100755 examples/dist/image-clipper/images/sure.png
create mode 100644 examples/dist/image-clipper/index.js
create mode 100644 examples/dist/image-clipper/index.json
create mode 100644 examples/dist/image-clipper/index.wxml
create mode 100644 examples/dist/image-clipper/index.wxss
diff --git a/dist/image-clipper-tools/index.js b/dist/image-clipper-tools/index.js
new file mode 100644
index 00000000..5d71273c
--- /dev/null
+++ b/dist/image-clipper-tools/index.js
@@ -0,0 +1 @@
+Component({relations:{"../image-clipper/index":{type:"parent"}},externalClasses:["l-class"],properties:{zIndex:{type:Number,value:999},lockWidth:{type:Boolean,value:!1},lockHeight:{type:Boolean,value:!1},lockRatio:{type:Boolean,value:!1},disableScale:{type:Number,value:!1},disableRotate:{type:Number,value:!1},limitMove:{type:Boolean,value:!1}},data:{formColor:"#3963bc",lockWidthValue:!1,lockHeightValue:!1,lockRatioValue:!0,disableScaleValue:!1,disableRotateValue:!1,limitMoveValue:!1},methods:{bindSwitchChange:async function(e){const a=e.detail.value,l=e.currentTarget.dataset.type;let t=this.getRelationNodes("../image-clipper/index")[0];await t.setData({[l]:a})}}});
\ No newline at end of file
diff --git a/dist/image-clipper-tools/index.json b/dist/image-clipper-tools/index.json
new file mode 100644
index 00000000..1450e2ec
--- /dev/null
+++ b/dist/image-clipper-tools/index.json
@@ -0,0 +1 @@
+{"component":true,"usingComponents":{}}
\ No newline at end of file
diff --git a/dist/image-clipper-tools/index.wxml b/dist/image-clipper-tools/index.wxml
new file mode 100644
index 00000000..0add6c56
--- /dev/null
+++ b/dist/image-clipper-tools/index.wxml
@@ -0,0 +1,28 @@
+
+
+
+ 锁定裁剪框宽
+
+
+
+ 锁定裁剪框高
+
+
+
+ 锁定裁剪框比例
+
+
+
+ 限制移动范围
+
+
+
+ 禁止缩放
+
+
+
+ 禁止旋转
+
+
+
+
\ No newline at end of file
diff --git a/dist/image-clipper-tools/index.wxss b/dist/image-clipper-tools/index.wxss
new file mode 100644
index 00000000..f072ec77
--- /dev/null
+++ b/dist/image-clipper-tools/index.wxss
@@ -0,0 +1 @@
+.tools-container{width:100%;padding:20rpx 40rpx;box-sizing:border-box}.tools-container .tools-form{margin-top:20rpx;display:flex;flex-wrap:wrap;color:#fff}.tools-container .tools-form .slider-wrapper{display:flex;align-items:center}.tools-container .tools-form switch{transform:scale(.7)}
\ No newline at end of file
diff --git a/dist/image-clipper/calculate.js b/dist/image-clipper/calculate.js
new file mode 100644
index 00000000..fea59075
--- /dev/null
+++ b/dist/image-clipper/calculate.js
@@ -0,0 +1 @@
+export function determineDirection(t,e,i,c,h,a){let n;const r=h>t+i-24&&ht-24&&he+c-24&&ae-24&&at*e/2,u=g(h),d=g(a);return i=n+u>=i?i:n+u,i=n+r-u<=i?i:n+r-u,c=l+d>=c?c:l+d,c=l+o-d<=c?c:l+o-d,{left:i,top:c,scale:e}}export function calcImageScale(t,e){e=e||t.scale;let i=t.imageWidth,c=t.imageHeight;return t.angle/90%2&&(i=t.imageHeight,c=t.imageWidth),i*e(i.clipWidth||i.width)/(i.clipWidth||i.height)?(h=i.clipHeight||i.height,c=t/e*h):(c=i.clipWidth||i.width,h=e/t*c);else{c=(i._SYS_INFO||wx.getSystemInfoSync()).windowWidth,h=0}return{imageWidth:c,imageHeight:h}}export function calcPythagoreanTheorem(t,e){return Math.sqrt(Math.pow(t,2)+Math.pow(e,2))}export function clipTouchMoveOfCalculate(t,e){const i=e.touches[0].clientX,c=e.touches[0].clientY,{clipWidth:h,clipHeight:a,cutY:n,cutX:r,_CUT_START:l,lockRatio:o}=t;let{maxWidth:g,minWidth:u,maxHeight:d,minHeight:p}=t;g/=2,u/=2,p/=2,d/=2;let m=h,f=a,s=n,x=r,w=()=>{m=m<=g?m>=u?m:u:g,f=f<=d?f>=p?f:p:d},W=()=>(m>g||md||f1&&l.corner<4?1:-1)*(l.y-c),l.corner){case 1:if(m=l.width-l.x+i,o&&(f=m/(h/a)),!W())return;break;case 2:if(m=l.width-l.x+i,o&&(f=m/(h/a)),!W())return;s=l.cutY-(f-l.height);break;case 3:if(m=l.width+l.x-i,o&&(f=m/(h/a)),!W())return;s=l.cutY-(f-l.height),x=l.cutX-(m-l.width);break;case 4:if(m=l.width+l.x-i,o&&(f=m/(h/a)),!W())return;x=l.cutX-(m-l.width)}return{width:m,height:f,cutX:x,cutY:s}}export function imageTouchMoveOfCalcOffset(t,e,i){return{left:e-t._touchRelative[0].x,top:i-t._touchRelative[0].y}}
\ No newline at end of file
diff --git a/dist/image-clipper/images/close.png b/dist/image-clipper/images/close.png
new file mode 100755
index 0000000000000000000000000000000000000000..a1c6c99c250b02bce100042a50b460444cf9ddc8
GIT binary patch
literal 2768
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
literal 0
HcmV?d00001
diff --git a/dist/image-clipper/images/photo.png b/dist/image-clipper/images/photo.png
new file mode 100755
index 0000000000000000000000000000000000000000..80928c3ba4ef40c66af2ba0df3b6ea33cbbc61ef
GIT binary patch
literal 1288
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
Tk*#;_{|5z(C(ff88JYPnu8*-u
literal 0
HcmV?d00001
diff --git a/dist/image-clipper/images/rotate-inverse.png b/dist/image-clipper/images/rotate-inverse.png
new file mode 100755
index 0000000000000000000000000000000000000000..ec77b6b55b31ce92efac9fd60c3ee9bff3832f45
GIT binary patch
literal 1786
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
VXF{this.imgComputeSize(t.width,t.height),this.properties.limitMove&&(this.imgMarginDetectionScale(),eventUtil.emit(this,"linimageready",t))},fail:()=>{this.imgComputeSize(),this.properties.limitMove&&this.imgMarginDetectionScale()}}))},"clipWidth, clipHeight"(t,e){let{minWidth:i,minHeight:a}=this.data;i/=2,a/=2,t{dataUtil.setDiffData(this,{cutAnimation:!1})},260);dataUtil.setDiffData(this,{_cutAnimationTime:t})}},limitMove(t){t&&(this.data.angle%90&&dataUtil.setDiffData(this,{angle:90*Math.round(this.data.angle/90)}),this.imgMarginDetectionScale())},"cutY, cutX"(){this.cutDetectionPosition()},"width, height"(t,e){t!==this.width&&dataUtil.setDiffData(this,{clipWidth:t/2}),e!==this.height&&dataUtil.setDiffData(this,{clipHeight:e/2})}},methods:{setCutInfo(){const{width:t,height:e}=this.properties,{_SYS_INFO:i}=this.data,a=t/2,s=e/2,o=(i.windowHeight-s)/2,h=(i.windowWidth-a)/2,l=i.windowWidth/2,n=i.windowHeight/2,c=wx.createCanvasContext("image-clipper",this);this.setData({clipWidth:a,clipHeight:s,cutX:h,cutY:o,CANVAS_HEIGHT:s,CANVAS_WIDTH:a,_ctx:c,imageLeft:l,imageTop:n})},setCutCenter(){const{sysInfo:t,clipHeight:e,clipWidth:i,imageTop:a,imageLeft:s}=this.data;let o=t||wx.getSystemInfoSync(),h=.5*(o.windowHeight-e),l=.5*(o.windowWidth-i);this.setData({imageTop:a-this.data.cutY+h,imageLeft:s-this.data.cutX+l,cutY:h,cutX:l})},clipTouchStart(t){if(!this.properties.imageUrl)return void wx.showToast({title:"请选择图片",icon:"none"});const e=t.touches[0].clientX,i=t.touches[0].clientY,{cutX:a,cutY:s,clipWidth:o,clipHeight:h}=this.data,l=determineDirection(a,s,o,h,e,i);this.moveDuring();const n={width:o,height:h,x:e,y:i,cutY:s,cutX:a,corner:l};this.setData({_flagCutTouch:!0,_flagEndTouch:!0,_CUT_START:n})},clipTouchMove(t){if(!this.properties.imageUrl)return void wx.showToast({title:"请选择图片",icon:"none"});const{_flagCutTouch:e,_MOVE_THROTTLE_FLAG:i}=this.data;if(e&&i){const{lockRatio:e,lockHeight:i,lockWidth:a}=this.properties;if(e&&(a||i))return;dataUtil.setDiffData(this,{_MOVE_THROTTLE_FLAG:!1}),this.moveThrottle();const{width:s,height:o,cutX:h,cutY:l}=clipTouchMoveOfCalculate(this.data,t);a||i?a?i||dataUtil.setDiffData(this,{clipHeight:o,cutY:l}):dataUtil.setDiffData(this,{clipWidth:s,cutX:h}):dataUtil.setDiffData(this,{clipWidth:s,clipHeight:o,cutX:h,cutY:l}),this.imgMarginDetectionScale()}},clipTouchEnd(){this.moveStop(),this.setData({_flagCutTouch:!1})},moveDuring(){clearTimeout(this.data._TIME_CUT_CENTER)},moveStop(){clearTimeout(this.data._TIME_CUT_CENTER);const t=setTimeout(()=>{this.data.cutAnimation||dataUtil.setDiffData(this,{cutAnimation:!0}),this.setCutCenter()},800);dataUtil.setDiffData(this,{_TIME_CUT_CENTER:t})},moveThrottle(){if("android"===this.data._SYS_INFO.platform){clearTimeout(this.data._MOVE_THROTTLE);const t=setTimeout(()=>{dataUtil.setDiffData(this,{_MOVE_THROTTLE_FLAG:!0})},20);dataUtil.setDiffData(this,{_MOVE_THROTTLE:t})}else dataUtil.setDiffData(this,{_MOVE_THROTTLE_FLAG:!0})},imageReset(){const t=this.data._SYS_INFO||wx.getSystemInfoSync();this.setData({scale:1,angle:0,imageTop:t.windowHeight/2,imageLeft:t.windowWidth/2})},imageLoad(){this.imageReset(),wx.hideLoading(),eventUtil.emit(this,"linimageload",!0)},imgComputeSize(t,e){const{imageWidth:i,imageHeight:a}=calcImageSize(t,e,this.data);this.setData({imageWidth:i,imageHeight:a})},imgMarginDetectionScale(t){if(!this.properties.limitMove)return;const e=calcImageScale(this.data,t);this.imgMarginDetectionPosition(e)},imgMarginDetectionPosition(t){if(!this.properties.limitMove)return;const{scale:e,left:i,top:a}=calcImageOffset(this.data,t);dataUtil.setDiffData(this,{imageLeft:i,imageTop:a,scale:e})},imageTouchStart(t){this.setData({_flagEndTouch:!1});const{imageLeft:e,imageTop:i}=this.data,a=t.touches[0].clientX,s=t.touches[0].clientY;let o=[];if(1===t.touches.length)o[0]={x:a-e,y:s-i},this.setData({_touchRelative:o});else{const h=t.touches[1].clientX,l=t.touches[1].clientY;let n=Math.abs(a-h),c=Math.abs(s-l);const u=calcPythagoreanTheorem(n,c);o=[{x:a-e,y:s-i},{x:h-e,y:l-i}],this.setData({_touchRelative:o,_hypotenuseLength:u})}},imageTouchMove(t){const{_flagEndTouch:e,_MOVE_THROTTLE_FLAG:i}=this.data;if(e||!i)return;const a=t.touches[0].clientX,s=t.touches[0].clientY;if(dataUtil.setDiffData(this,{_MOVE_THROTTLE_FLAG:!1}),this.moveThrottle(),this.moveDuring(),1===t.touches.length){const{left:t,top:e}=imageTouchMoveOfCalcOffset(this.data,a,s);dataUtil.setDiffData(this,{imageLeft:t,imageTop:e}),this.imgMarginDetectionPosition()}else{const e=t.touches[1].clientX,i=t.touches[1].clientY;let o=Math.abs(a-e),h=Math.abs(s-i),l=calcPythagoreanTheorem(o,h),n=this.data.scale*(l/this.data._hypotenuseLength);this.properties.disableScale?n=1:(n=n<=this.properties.minRatio?this.properties.minRatio:n,n=n>=this.properties.maxRatio?this.properties.maxRatio:n,eventUtil.emit(this,"linsizechange",{imageWidth:this.data.imageWidth*n,imageHeight:this.data.imageHeight*n})),this.imgMarginDetectionScale(n),dataUtil.setDiffData(this,{_hypotenuseLength:Math.sqrt(Math.pow(o,2)+Math.pow(h,2)),scale:n})}},imageTouchEnd(){dataUtil.setDiffData(this,{_flagEndTouch:!0}),this.moveStop()},cutDetectionPosition(){const{cutX:t,cutY:e,_SYS_INFO:i,clipHeight:a,clipWidth:s}=this.data;let o=()=>{e<0&&dataUtil.setDiffData(this,{cutY:0}),e>i.windowHeight-a&&dataUtil.setDiffData(this,{cutY:i.windowHeight-a})},h=()=>{t<0&&dataUtil.setDiffData(this,{cutX:0}),t>i.windowWidth-s&&dataUtil.setDiffData(this,{cutX:i.windowWidth-s})};if(null===e&&null===t){let t=.5*(i.windowHeight-a),e=.5*(i.windowWidth-s);dataUtil.setDiffData(this,{cutX:e,cutY:t})}else null!==e&&null!==t?(o(),h()):null!==e&&null===t?(o(),dataUtil.setDiffData(this,{cutX:(i.windowWidth-s)/2})):null===e&&null!==t&&(h(),dataUtil.setDiffData(this,{cutY:(i.windowHeight-a)/2}))},computeCutSize(){const{clipHeight:t,clipWidth:e,_SYS_INFO:i,cutX:a,cutY:s}=this.data;e>i.windowWidth?dataUtil.setDiffData(this,{clipWidth:i.windowWidth}):e+a>i.windowWidth&&dataUtil.setDiffData(this,{cutX:i.windowWidth-a}),t>i.windowHeight?dataUtil.setDiffData(this,{clipHeight:i.windowHeight}):t+s>i.windowHeight&&dataUtil.setDiffData(this,{cutY:i.windowHeight-s})},getImageData(){if(!this.properties.imageUrl)return void wx.showToast({title:"请选择图片",icon:"none"});wx.showLoading({title:"加载中"});const{clipHeight:t,clipWidth:e,_ctx:i,scale:a,imageLeft:s,imageTop:o,cutX:h,cutY:l,angle:n}=this.data;let{CANVAS_HEIGHT:c,CANVAS_WIDTH:u}=this.data;const{scaleRatio:g,imageUrl:r,quality:d,type:m}=this.properties,p=()=>{const c=this.data.imageWidth*a*g,u=this.data.imageHeight*a*g,p=s-h,f=o-l;i.translate(p*g,f*g),i.rotate(n*Math.PI/180),i.drawImage(r,-c/2,-u/2,c,u),i.draw(!1,()=>{let i={width:e*g,height:Math.round(t*g),destWidth:e*g,destHeight:Math.round(t)*g,fileType:"png",quality:d},a={url:"",base64:"",width:e*g,height:t*g};IMAGE_TYPE.base64===m?wx.canvasGetImageData({canvasId:"image-clipper",x:0,y:0,width:e*g,height:Math.round(t*g),success:t=>{const e=new Uint8Array(t.data),i=wx.arrayBufferToBase64(e);a.url=i,a.base64=i,wx.hideLoading(),eventUtil.emit(this,"linclip",a)}}):wx.canvasToTempFilePath({...i,canvasId:"image-clipper",success:t=>{a.url=t.tempFilePath,a.base64=t.tempFilePath,wx.hideLoading(),eventUtil.emit(this,"linclip",a)},fail(t){throw t}},this)})};u!==e||c!==t?(u=e,c=t,i.draw(),setTimeout(()=>{p()},100)):p()},uploadImage(){wx.chooseImage({count:1,sizeType:["original","compressed"],sourceType:["album","camera"],success:t=>{const e=t.tempFilePaths;this.setData({imageUrl:e})}})},rotate(t){if(this.properties.disableRotate)return;if(!this.properties.imageUrl)return void wx.showToast({title:"请选择图片",icon:"none"});const{rotateAngle:e}=this.properties,i=this.data.angle;"along"===t.currentTarget.dataset.type?this.setData({angle:i+e}):this.setData({angle:i-e}),eventUtil.emit(this,"linrotate",{currentDeg:this.data.angle})},close(){this.setData({show:!1})}},lifetimes:{ready(){const t=wx.getSystemInfoSync();this.setData({_SYS_INFO:t}),this.setCutInfo(),this.setCutCenter(),this.computeCutSize(),this.cutDetectionPosition()}}});
\ No newline at end of file
diff --git a/dist/image-clipper/index.json b/dist/image-clipper/index.json
new file mode 100644
index 00000000..1450e2ec
--- /dev/null
+++ b/dist/image-clipper/index.json
@@ -0,0 +1 @@
+{"component":true,"usingComponents":{}}
\ No newline at end of file
diff --git a/dist/image-clipper/index.wxml b/dist/image-clipper/index.wxml
new file mode 100644
index 00000000..b7c48546
--- /dev/null
+++ b/dist/image-clipper/index.wxml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dist/image-clipper/index.wxss b/dist/image-clipper/index.wxss
new file mode 100644
index 00000000..cf1b26bc
--- /dev/null
+++ b/dist/image-clipper/index.wxss
@@ -0,0 +1 @@
+.container{width:100vw;height:100vh;background-color:rgba(0,0,0,.6);position:fixed;top:0;left:0;z-index:1}.container .clip-wrapper{position:absolute;width:100vw;height:100vh}.container .clip-wrapper .clip-content{width:100vw;height:100vh;position:absolute;z-index:99;display:flex;flex-direction:column;pointer-events:none}.container .clip-wrapper .clip-content .flex-auto{flex:auto}.container .clip-wrapper .clip-content .clip-content-footer,.container .clip-wrapper .clip-content .clip-content-top{width:100%;pointer-events:none}.container .clip-wrapper .clip-content .clip-content-middle{width:100%;height:400rpx;display:flex;box-sizing:border-box}.container .clip-wrapper .clip-content .clip-content-middle .clip-content-middle-left,.container .clip-wrapper .clip-content .clip-content-middle .clip-content-middle-right{height:100%}.container .clip-wrapper .clip-content .clip-content-middle .clip-content-middle-center{position:relative;border:1px solid;box-sizing:border-box}.container .clip-wrapper .clip-content .clip-content-middle .clip-content-middle-center .clip-edge{position:absolute;left:6rpx;width:34rpx;height:34rpx;border:2rpx solid #fff;pointer-events:auto;box-sizing:border-box}.container .clip-wrapper .clip-content .clip-content-middle .clip-content-middle-center .clip-edge.clip-edge-top-left{border-bottom-width:0!important;border-right-width:0!important}.container .clip-wrapper .clip-content .clip-content-middle .clip-content-middle-center .clip-edge.clip-edge-top-right{border-bottom-width:0!important;border-left-width:0!important}.container .clip-wrapper .clip-content .clip-content-middle .clip-content-middle-center .clip-edge.clip-edge-bottom-left{border-top-width:0!important;border-right-width:0!important}.container .clip-wrapper .clip-content .clip-content-middle .clip-content-middle-center .clip-edge.clip-edge-bottom-right{border-top-width:0!important;border-left-width:0!important}.container .clip-wrapper .bg-transparent{background-color:rgba(0,0,0,.6);transition-duration:.35s}.container .cropper-image{width:100%;border-style:none;position:absolute;top:0;left:0;z-index:2;-webkit-backface-visibility:hidden;backface-visibility:hidden;transform-origin:center}.container .clipper-canvas{position:fixed;z-index:10;left:-2000px;top:-2000px;pointer-events:none}.container .footer-tools{position:absolute;left:0;bottom:0;width:100%;z-index:99}.container .footer-tools .tools-icon{display:flex;align-items:center;justify-content:space-between;width:100%;padding:20rpx 40rpx;box-sizing:border-box}.container .footer-tools .tools-icon image{display:block;width:50rpx;height:50rpx}
\ No newline at end of file
diff --git a/examples/dist/image-clipper-tools/index.js b/examples/dist/image-clipper-tools/index.js
new file mode 100644
index 00000000..3226d451
--- /dev/null
+++ b/examples/dist/image-clipper-tools/index.js
@@ -0,0 +1,80 @@
+Component({
+
+ relations: {
+ '../image-clipper/index': {
+ type: 'parent'
+ }
+ },
+ externalClasses: ['l-class'],
+
+ /**
+ * 组件的属性列表
+ */
+ properties: {
+ // 组件层级
+ zIndex: {
+ type: Number,
+ value: 999
+ },
+ // 是否显示锁定裁剪框宽度按钮
+ lockWidth: {
+ type: Boolean,
+ value: false
+ },
+ // 是否显示锁定裁剪框高度按钮
+ lockHeight: {
+ type: Boolean,
+ value: false
+ },
+ // 是否显示锁定裁剪框比例按钮
+ lockRatio: {
+ type: Boolean,
+ value: false
+ },
+ // 是否显示禁止缩放按钮
+ disableScale: {
+ type: Number,
+ value: false
+ },
+ // 是否显示禁止旋转按钮
+ disableRotate: {
+ type: Number,
+ value: false
+ },
+ // 是否显示限制移动范围按钮
+ limitMove: {
+ type: Boolean,
+ value: false
+ }
+ },
+
+ /**
+ * 组件的初始数据
+ */
+ data: {
+ formColor: '#3963bc',
+ lockWidthValue: false,
+ lockHeightValue: false,
+ lockRatioValue: true,
+ disableScaleValue: false,
+ disableRotateValue: false,
+ limitMoveValue: false
+ },
+
+ /**
+ * 组件的方法列表
+ */
+ methods: {
+ /**
+ * switch change事件
+ */
+ bindSwitchChange: async function(event) {
+ const value = event.detail.value;
+ const type = event.currentTarget.dataset.type;
+ let parent = this.getRelationNodes('../image-clipper/index')[0];
+ await parent.setData({
+ [type]: value
+ });
+ },
+ }
+});
diff --git a/examples/dist/image-clipper-tools/index.json b/examples/dist/image-clipper-tools/index.json
new file mode 100644
index 00000000..e8cfaaf8
--- /dev/null
+++ b/examples/dist/image-clipper-tools/index.json
@@ -0,0 +1,4 @@
+{
+ "component": true,
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/examples/dist/image-clipper-tools/index.wxml b/examples/dist/image-clipper-tools/index.wxml
new file mode 100644
index 00000000..35f37ef2
--- /dev/null
+++ b/examples/dist/image-clipper-tools/index.wxml
@@ -0,0 +1,28 @@
+
+
+
+ 锁定裁剪框宽
+
+
+
+ 锁定裁剪框高
+
+
+
+ 锁定裁剪框比例
+
+
+
+ 限制移动范围
+
+
+
+ 禁止缩放
+
+
+
+ 禁止旋转
+
+
+
+
\ No newline at end of file
diff --git a/examples/dist/image-clipper-tools/index.wxss b/examples/dist/image-clipper-tools/index.wxss
new file mode 100644
index 00000000..f072ec77
--- /dev/null
+++ b/examples/dist/image-clipper-tools/index.wxss
@@ -0,0 +1 @@
+.tools-container{width:100%;padding:20rpx 40rpx;box-sizing:border-box}.tools-container .tools-form{margin-top:20rpx;display:flex;flex-wrap:wrap;color:#fff}.tools-container .tools-form .slider-wrapper{display:flex;align-items:center}.tools-container .tools-form switch{transform:scale(.7)}
\ No newline at end of file
diff --git a/examples/dist/image-clipper/calculate.js b/examples/dist/image-clipper/calculate.js
new file mode 100644
index 00000000..1dffc8e7
--- /dev/null
+++ b/examples/dist/image-clipper/calculate.js
@@ -0,0 +1,276 @@
+/**
+ * 判断手指触摸位置
+ *
+ * @param {*} cutX
+ * @param {*} cutY
+ * @param {*} clipWidth
+ * @param {*} clipHeight
+ * @param {*} currentX
+ * @param {*} currentY
+ * @returns
+ */
+export function determineDirection(cutX, cutY, clipWidth, clipHeight, currentX, currentY) {
+ /*
+ * (右下>>1 右上>>2 左上>>3 左下>>4)
+ * left_x: 裁剪框左边线距离视口最左侧两点位置 [3,4]
+ * right_x: 裁剪框右边线距离视口最右侧两点位置 [1,2]
+ * top_y: 裁剪框顶部线距离视口最顶部两点位置 [2,3]
+ * bottom_y:裁剪框底部线距离视口最底部两点位置 [1,4]
+ */
+ // 用户体验优化,增加裁剪框四角可触摸区域
+ const EXPAND_SIZE = 24;
+
+ let left_x1 = cutX - EXPAND_SIZE;
+ let left_x2 = cutX + EXPAND_SIZE;
+
+ let top_y1 = cutY - EXPAND_SIZE;
+ let top_y2 = cutY + EXPAND_SIZE;
+
+ let right_x1 = cutX + clipWidth - EXPAND_SIZE;
+ let right_x2 = cutX + clipWidth + EXPAND_SIZE;
+
+ let bottom_y1 = cutY + clipHeight - EXPAND_SIZE;
+ let bottom_y2 = cutY + clipHeight + EXPAND_SIZE;
+ /*
+ * 四角
+ * (右下>>1 右上>>2 左上>>3 左下>>4)
+ */
+ let corner;
+
+ const isRight = currentX > right_x1 && currentX < right_x2;
+ const isLeft = currentX > left_x1 && currentX < left_x2;
+ const isBottom = currentY > bottom_y1 && currentY < bottom_y2;
+ const isTop = currentY > top_y1 && currentY < top_y2;
+
+ if (isRight && isBottom) {
+ corner = 1;
+ } else if (isRight && isTop) {
+ corner = 2;
+ } else if (isLeft && isTop) {
+ corner = 3;
+ } else if (isLeft && isBottom) {
+ corner = 4;
+ }
+ return corner;
+}
+
+/**
+ * 图片边缘检测检测时,计算图片偏移量
+ *
+ * @param {*} data
+ * @param {*} scale
+ * @returns
+ */
+export function calcImageOffset(data, scale) {
+ let left = data.imageLeft;
+ let top = data.imageTop;
+ scale = scale || data.scale;
+
+ let imageWidth = data.imageWidth;
+ let imageHeight = data.imageHeight;
+ if ((data.angle / 90) % 2) {
+ imageWidth = data.imageHeight;
+ imageHeight = data.imageWidth;
+ }
+ const {
+ cutX,
+ clipWidth,
+ cutY,
+ clipHeight
+ } = data;
+ // 当前图片宽度/高度
+ const currentImageSize = (size) => (size * scale) / 2;
+ const currentImageWidth = currentImageSize(imageWidth);
+ const currentImageHeight = currentImageSize(imageHeight);
+
+ left = cutX + currentImageWidth >= left ? left : cutX + currentImageWidth;
+ left = cutX + clipWidth - currentImageWidth <= left ? left : cutX + clipWidth - currentImageWidth;
+ top = cutY + currentImageHeight >= top ? top : cutY + currentImageHeight;
+ top = cutY + clipHeight - currentImageHeight <= top ? top : cutY + clipHeight - currentImageHeight;
+ return {
+ left,
+ top,
+ scale
+ };
+}
+
+/**
+ * 图片边缘检测时,计算图片缩放比例
+ *
+ * @param {*} data
+ * @param {*} scale
+ * @returns
+ */
+export function calcImageScale(data, scale) {
+ scale = scale || data.scale;
+ let imageWidth = data.imageWidth;
+ let imageHeight = data.imageHeight;
+ if ((data.angle / 90) % 2) {
+ imageWidth = data.imageHeight;
+ imageHeight = data.imageWidth;
+ }
+ if (imageWidth * scale < data.clipWidth) {
+ scale = data.clipWidth / imageWidth;
+ }
+ if (imageHeight * scale < data.clipHeight) {
+ scale = Math.max(scale, data.clipHeight / imageHeight);
+ }
+ return scale;
+}
+
+/**
+ * 计算图片尺寸
+ *
+ * @export
+ * @param {*} width
+ * @param {*} height
+ * @param {*} data
+ * @returns
+ */
+export function calcImageSize(width, height, data) {
+ // 默认按图片最小边 = 对应裁剪框尺寸
+ let imageWidth = width,
+ imageHeight = height;
+ if (imageWidth && imageHeight) {
+ if (imageWidth / imageHeight > (data.clipWidth || data.width) / (data.clipWidth || data.height)) {
+ imageHeight = data.clipHeight || data.height;
+ imageWidth = (width / height) * imageHeight;
+ } else {
+ imageWidth = data.clipWidth || data.width;
+ imageHeight = (height / width) * imageWidth;
+ }
+ } else {
+ let sys = data._SYS_INFO || wx.getSystemInfoSync();
+ imageWidth = sys.windowWidth;
+ imageHeight = 0;
+ }
+ return {
+ imageWidth,
+ imageHeight
+ };
+}
+
+/**
+ * 勾股定理求斜边
+ *
+ * @param {*} width
+ * @param {*} height
+ * @returns
+ */
+export function calcPythagoreanTheorem(width, height) {
+ return Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));
+}
+
+/**
+ * 拖动裁剪框时计算
+ *
+ * @export
+ * @param {*} data
+ * @param {*} event
+ * @returns
+ */
+export function clipTouchMoveOfCalculate(data, event) {
+ const clientX = event.touches[0].clientX;
+ const clientY = event.touches[0].clientY;
+
+ const {
+ clipWidth,
+ clipHeight,
+ cutY: oldCutY,
+ cutX: oldCutX,
+ _CUT_START,
+ lockRatio
+ } = data;
+ let {
+ maxWidth,
+ minWidth,
+ maxHeight,
+ minHeight
+ } = data;
+ maxWidth = maxWidth / 2;
+ minWidth = minWidth / 2;
+ minHeight = minHeight / 2;
+ maxHeight = maxHeight / 2;
+
+ let width = clipWidth,
+ height = clipHeight,
+ cutY = oldCutY,
+ cutX = oldCutX,
+ // 获取裁剪框实际宽度/高度
+ // 如果大于最大值则使用最大值
+ // 如果小于最小值则使用最小值
+ size_correct = () => {
+ width = width <= maxWidth ? (width >= minWidth ? width : minWidth) : maxWidth;
+ height = height <= maxHeight ? (height >= minHeight ? height : minHeight) : maxHeight;
+ },
+ size_inspect = () => {
+ if ((width > maxWidth || width < minWidth || height > maxHeight || height < minHeight) && lockRatio) {
+ size_correct();
+ return false;
+ } else {
+ size_correct();
+ return true;
+ }
+ };
+ height = _CUT_START.height + (_CUT_START.corner > 1 && _CUT_START.corner < 4 ? 1 : -1) * (_CUT_START.y - clientY);
+ switch (_CUT_START.corner) {
+ case 1:
+ width = _CUT_START.width - _CUT_START.x + clientX;
+ if (lockRatio) {
+ height = width / (clipWidth / clipHeight);
+ }
+ if (!size_inspect()) return;
+ break;
+ case 2:
+ width = _CUT_START.width - _CUT_START.x + clientX;
+ if (lockRatio) {
+ height = width / (clipWidth / clipHeight);
+ }
+ if (!size_inspect()) return;
+ cutY = _CUT_START.cutY - (height - _CUT_START.height);
+ break;
+ case 3:
+ width = _CUT_START.width + _CUT_START.x - clientX;
+ if (lockRatio) {
+ height = width / (clipWidth / clipHeight);
+ }
+ if (!size_inspect()) return;
+ cutY = _CUT_START.cutY - (height - _CUT_START.height);
+ cutX = _CUT_START.cutX - (width - _CUT_START.width);
+ break;
+ case 4:
+ width = _CUT_START.width + _CUT_START.x - clientX;
+ if (lockRatio) {
+ height = width / (clipWidth / clipHeight);
+ }
+ if (!size_inspect()) return;
+ cutX = _CUT_START.cutX - (width - _CUT_START.width);
+ break;
+ default:
+ break;
+ }
+ return {
+ width,
+ height,
+ cutX,
+ cutY
+ };
+}
+
+/**
+ * 单指拖动图片计算偏移
+ *
+ * @export
+ * @param {*} data
+ * @param {*} clientXForLeft
+ * @param {*} clientYForLeft
+ * @returns
+ */
+export function imageTouchMoveOfCalcOffset(data, clientXForLeft, clientYForLeft) {
+ let left = clientXForLeft - data._touchRelative[0].x,
+ top = clientYForLeft - data._touchRelative[0].y;
+ return {
+ left,
+ top
+ };
+}
diff --git a/examples/dist/image-clipper/images/close.png b/examples/dist/image-clipper/images/close.png
new file mode 100755
index 0000000000000000000000000000000000000000..a1c6c99c250b02bce100042a50b460444cf9ddc8
GIT binary patch
literal 2768
zcmdUx`9Bkm1ID*Dd^T6ET%Qlg<|a$n_I(u^3xTp!n@5xJ(Ul&g}E
z8KcD9XNQtpnU;v9`1biTzR&CRJntW#U!EVIbVqv|ai|g$004+%F=*#MeEFaM0{zM2
z)Qh!$(BNq2YW0VE|5s|J6H5M!J{9F`?*bSn>u^7$E3NZpwtG~w?aXiH1vr!oHQZBQ
zD3WSRbv0m>-0&WWl!FqlXG{9*~s_g9I4%IGqypE+qSYbO=9=%z8>c0H@$2Y
z8oI|23c%wK$>PWY!Zw;#ngYIakhXcOTPaJ*&XJY2+zI_e(ax60_=^luhFBrG04Y&q
zA%-6d%+tsSR+1?q12asm`4UIw&;Cl+QidUN_M{*}UYZoAvFVi~O4t$BKym_7%Tg>-
zI6%VC+UqMItLVa8khB-LMfN-Uqwk#J#&(v}V{4Xu-Ne90qqhDg6R8qU_!{$r%YCxTh=d+}ElL^d8OX;Q1pZD0c6~~5ma>0FO8NbYb4nyWp(o6aN
zw^k_QSai%y_H6%WjbQn%XX+RLoD=vvIavvo*x=R_Pfhk4Yt??z%P@~Mi^YJ$Lm=K~
zHAxnQiyKZ%i{s`teBP@MwpT5b4>4iQgzzDu%kq`PUPL?r=PZ-r*B-51_3QB#q$P
zzY4c4*EKG0a+MEOu}6Q*xXpj9K){|}xvz)n$+(x;TuP%{v9)ZJ(OpgWq&l{hD9i`&
zPVREB{+K0fj^$Jo6naQWgU7e!(&Eep;JjG5qFX}Rc$nW~lOf#Eqz7BOEuzPQR*D@Z
z1>sunLX!;t{&ib2&0Oll*?lW&du4izeS%NR0^;gYkZoPCYQO4qtFaGV@mD3vfmmz=
zIRf)QW#_254cn-XdcB98LHhiN5>;TIMvvp=+uM6G*yfk6NorZu-97+&aJe{wh^@QhY%8$F_p}a%X@1yuT__w-e$NI
zOk%+f0k)QxNi^S)FF_=h80V&jz`e1UAB#G82j-5wU0?)NMYd3X!kFnH9Y^^86+%|u
zg4MJYPCmFPmnqVp{3gVofa{{a>hu3bmJ+~|%AWx2X;~1-3*K~LKyu|zIlH3cDx2lT
zNnz2H{%aR$z-i>@7CEzAdrYGxWqMwwL&Oj4{Q#|FZJ<%25;fUwKf%)dV1xw%2&ADG
zz4Q{P8ZwZ!oI42`QK+;Wc`0j0N5rzs`FBHUzZsSp?`0)jS5z3{#W`(oA0(FZqrx+H;Lh~JzjeSO`j_^s)sD>fJu_7fd
zd#o$q?Ar%JWs?O=;K&_BY%`9QES;$F*W=yg`@$URf
z^w=f*Ko`94=IgFn?49nYrQ2m0vgaqeD`V#S6S&Rfpc#gxA+t+l)i3~AlYX&8Q@qH9
z=zZb?_BjFRQ#n4RLoHi8K%vIa9+xLPg$%}<^kJ|(j)n-aKvJwJQ3=m!ibYooxLq3O
zIuC3Xet%IL<~kasW4PSF+0q3FpmjDWZABJboW83TW-vOg9(g|MmQQDpg-ol%t&VfJ
z9G98_Y((J^K|QvtdEdQWMO46?nb$~_Ox~LBbe7u0c1}Lt
zL4DXJ>LI`3G)vkDqBtBz4_m
z1X_p=g>{2#LrC)|c55L-{6%kCMD*~Nu9%#QG5+DI$X6=pfjfDX)Sn|)w6ocfb}QHQ
z!-1-=)0sqpB>`}j=bTZS=?%?m8Vs)~H7gf**mqd~eRCU77U}4KC$8&jht%qxR$#Hr
zj#%W2s_D20pgzvC-nkI^TZY6w67ed?B;QN#`IC;ggg6IUc!Zv82}&Y0m=MLAbv1DO
z9Uq~>%zTV0WmdjKlOWF?#dMKRx;Q)QXmZpC
z2g1g;sU9FnNHBiktDm_VBf;nS)SL4UVJqu1&jI=&W|XG}pno1kx5X7lTj5KGTsx%W
zH+~1M0GEcph+CQX%0LL>sl@6m0xqH
zTB)i2B8p&q0aLGZtPXN@CRf23Gfk$~(uQK+yl{4zac4rIWWW8}80LM~9V-mjPh2C$
zBkWPR(;dJBCNez4EHWu!Py{+v6Ad=x*S+GZKI1=4rauGES^(jj3#2twhwVOJRqLzu
zGSTg;vO-gba|!+@4cM1_n5yk>Vaw13wTvkwvLy~d{ket{Rq1H-6WdFwj52cny%$xY`Y*Ru{mb-D0eun4;}Nmg04Q>D#Mkq8@=rX7M-Zi1A>Ndh(&7os?$qO(1|v4
zklya56DF)4Y&q7Wke;41y)nxISIJnG2VJhea)KXsxVnTjnO#B=uo-V1c(>Vo`aD^igJxTzA0f+s0beH-+LS
zwBSZ69_IEDtG2>ZS3tkJdW^HaF!9>^12f%2olc%sklcZ$8v7wkxzF%*i~~&{pAh5R
z1D`+4^>MEt~2Q{Z(_PYZ9@ct;sYxlgf-gVNq-+Ai8;~V43{EK%zQvw2hyr;-}yT9@4yLZ*h
x?0TCA_v(URSK!LM5&{vpPVN0#G^^{Ax4LNT{Zb{J`{(5WuvYfyM;2a5{{!ori2wiq
literal 0
HcmV?d00001
diff --git a/examples/dist/image-clipper/images/photo.png b/examples/dist/image-clipper/images/photo.png
new file mode 100755
index 0000000000000000000000000000000000000000..80928c3ba4ef40c66af2ba0df3b6ea33cbbc61ef
GIT binary patch
literal 1288
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
Tk*#;_{|5z(C(ff88JYPnu8*-u
literal 0
HcmV?d00001
diff --git a/examples/dist/image-clipper/images/rotate-inverse.png b/examples/dist/image-clipper/images/rotate-inverse.png
new file mode 100755
index 0000000000000000000000000000000000000000..ec77b6b55b31ce92efac9fd60c3ee9bff3832f45
GIT binary patch
literal 1786
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
VXF {
+ // 计算图片尺寸
+ this.imgComputeSize(res.width, res.height);
+ if (this.properties.limitMove) {
+ // 限制移动,不留空白处理
+ this.imgMarginDetectionScale();
+ eventUtil.emit(this, 'linimageready', res);
+ }
+ },
+ fail: () => {
+ this.imgComputeSize();
+ if (this.properties.limitMove) {
+ this.imgMarginDetectionScale();
+ }
+ }
+ });
+ },
+ 'clipWidth, clipHeight'(widthVal, heightVal) {
+ let { minWidth, minHeight } = this.data;
+ minWidth = minWidth / 2;
+ minHeight = minHeight / 2;
+ if (widthVal < minWidth) {
+ dataUtil.setDiffData(this, { clipWidth: minWidth });
+ }
+ if (heightVal < minHeight) {
+ dataUtil.setDiffData(this, { clipHeight: minHeight });
+ }
+ this.computeCutSize();
+ },
+ 'rotateAngle'(val) {
+ dataUtil.setDiffData(this, { cutAnimation: true, angle: val });
+ },
+ 'angle'(val) {
+ this.moveStop();
+ const {
+ limitMove
+ } = this.properties;
+ if (limitMove && val % 90) {
+ dataUtil.setDiffData(this, { angle: Math.round(val / 90) * 90 });
+ }
+ this.imgMarginDetectionScale();
+ },
+ 'cutAnimation'(val) {
+ // 开启过渡260毫秒之后自动关闭
+ clearTimeout(this.data._cutAnimationTime);
+ if (val) {
+ let _cutAnimationTime = setTimeout(() => {
+ dataUtil.setDiffData(this, { cutAnimation: false });
+ }, 260);
+ dataUtil.setDiffData(this, { _cutAnimationTime });
+ }
+ },
+ 'limitMove'(val) {
+ if (val) {
+ if (this.data.angle % 90) {
+ dataUtil.setDiffData(this, { angle: Math.round(this.data.angle / 90) * 90 });
+ }
+ this.imgMarginDetectionScale();
+ }
+ },
+ 'cutY, cutX'() {
+ this.cutDetectionPosition();
+ },
+ 'width, height'(width, height) {
+ if(width !== this.width) {
+ dataUtil.setDiffData(this, {clipWidth: width / 2});
+ }
+ if(height !== this.height) {
+ dataUtil.setDiffData(this, {clipHeight: height / 2});
+ }
+ }
+ },
+ /**
+ * 组件的方法列表
+ */
+ methods: {
+ /**
+ * 设置裁剪框的一些信息
+ */
+ setCutInfo() {
+ const {
+ width,
+ height
+ } = this.properties;
+ const {
+ _SYS_INFO
+ } = this.data;
+ // 本组件动态style默认单位为px,需将用户传入值/2
+ const clipWidth = width / 2;
+ const clipHeight = height / 2;
+ const cutY = (_SYS_INFO.windowHeight - clipHeight) / 2;
+ const cutX = (_SYS_INFO.windowWidth - clipWidth) / 2;
+ const imageLeft = _SYS_INFO.windowWidth / 2;
+ const imageTop = _SYS_INFO.windowHeight / 2;
+ const _ctx = wx.createCanvasContext('image-clipper', this);
+ this.setData({
+ clipWidth,
+ clipHeight,
+ cutX,
+ cutY,
+ CANVAS_HEIGHT: clipHeight,
+ CANVAS_WIDTH: clipWidth,
+ _ctx,
+ imageLeft,
+ imageTop
+ });
+ },
+ /**
+ * 裁剪框居中
+ */
+ setCutCenter() {
+ const { sysInfo, clipHeight, clipWidth, imageTop, imageLeft } = this.data;
+ let sys = sysInfo || wx.getSystemInfoSync();
+ let cutY = (sys.windowHeight - clipHeight) * 0.5;
+ let cutX = (sys.windowWidth - clipWidth) * 0.5;
+ this.setData({
+ imageTop: imageTop - this.data.cutY + cutY,
+ imageLeft: imageLeft - this.data.cutX + cutX,
+ cutY,
+ cutX
+ });
+ },
+ /**
+ * 开始拖动裁剪框
+ * 需在此处查找到是否拖动的裁剪框四角
+ */
+ clipTouchStart(event) {
+ if (!this.properties.imageUrl) {
+ wx.showToast({
+ title: '请选择图片',
+ icon: 'none'
+ });
+ return;
+ }
+ const currentX = event.touches[0].clientX;
+ const currentY = event.touches[0].clientY;
+ const { cutX, cutY, clipWidth, clipHeight } = this.data;
+ const corner = determineDirection(cutX, cutY, clipWidth, clipHeight, currentX, currentY);
+ this.moveDuring();
+ const _CUT_START = {
+ width: clipWidth,
+ height: clipHeight,
+ x: currentX,
+ y: currentY,
+ cutY,
+ cutX,
+ corner
+ };
+ this.setData({ _flagCutTouch: true, _flagEndTouch: true, _CUT_START });
+ },
+ /**
+ * 拖动裁剪框
+ * 当拖动的裁剪框区域时处理数据
+ */
+ clipTouchMove(event) {
+ if (!this.properties.imageUrl) {
+ wx.showToast({
+ title: '请选择图片',
+ icon: 'none'
+ });
+ return;
+ }
+
+ const { _flagCutTouch, _MOVE_THROTTLE_FLAG } = this.data;
+ if (_flagCutTouch && _MOVE_THROTTLE_FLAG) {
+ const { lockRatio, lockHeight, lockWidth } = this.properties;
+ if (lockRatio && (lockWidth || lockHeight)) return;
+ dataUtil.setDiffData(this, { _MOVE_THROTTLE_FLAG: false });
+ this.moveThrottle();
+ const { width, height, cutX, cutY } = clipTouchMoveOfCalculate(this.data, event);
+ if (!lockWidth && !lockHeight) {
+ dataUtil.setDiffData(this, { clipWidth: width, clipHeight: height, cutX, cutY });
+ } else if (!lockWidth) {
+ dataUtil.setDiffData(this, { clipWidth: width, cutX });
+ } else if (!lockHeight) {
+ dataUtil.setDiffData(this, { clipHeight: height, cutY });
+ }
+ this.imgMarginDetectionScale();
+ }
+ },
+ /**
+ * 拖动裁剪框结束
+ * 当拖动的裁剪框区域时处理数据
+ */
+ clipTouchEnd() {
+ this.moveStop();
+ this.setData({ _flagCutTouch: false });
+ },
+ /**
+ * 清空之前的自动居中延迟函数
+ */
+ moveDuring() {
+ clearTimeout(this.data._TIME_CUT_CENTER);
+ },
+ /**
+ * 停止移动时需要做的操作
+ * 清空之前的自动居中延迟函数并添加最新的
+ */
+ moveStop() {
+ clearTimeout(this.data._TIME_CUT_CENTER);
+ const _TIME_CUT_CENTER = setTimeout(() => {
+ //动画启动
+ if (!this.data.cutAnimation) {
+ dataUtil.setDiffData(this, { cutAnimation: true });
+ }
+ this.setCutCenter();
+ }, 800);
+ dataUtil.setDiffData(this, { _TIME_CUT_CENTER });
+ },
+ /**
+ * 重置延迟函数
+ */
+ moveThrottle() {
+ if (this.data._SYS_INFO.platform === 'android') {
+ clearTimeout(this.data._MOVE_THROTTLE);
+ const _MOVE_THROTTLE = setTimeout(() => {
+ dataUtil.setDiffData(this, { _MOVE_THROTTLE_FLAG: true });
+ }, 800 / 40);
+ dataUtil.setDiffData(this, { _MOVE_THROTTLE });
+ } else {
+ dataUtil.setDiffData(this, { _MOVE_THROTTLE_FLAG: true });
+ }
+ },
+ /**
+ * 图片初始化
+ */
+ imageReset() {
+ const sys = this.data._SYS_INFO || wx.getSystemInfoSync();
+ this.setData({ scale: 1, angle: 0, imageTop: sys.windowHeight / 2, imageLeft: sys.windowWidth / 2 });
+ },
+ /**
+ * 图片加载完成
+ */
+ imageLoad() {
+ this.imageReset();
+ wx.hideLoading();
+ eventUtil.emit(this, 'linimageload', detail);
+ },
+ /**
+ * 计算图片尺寸
+ */
+ imgComputeSize(width, height) {
+ const { imageWidth, imageHeight } = calcImageSize(width, height, this.data);
+ this.setData({ imageWidth, imageHeight });
+ },
+ /**
+ * 图片边缘检测-缩放
+ */
+ imgMarginDetectionScale(scale) {
+ if (!this.properties.limitMove) return;
+ const currentScale = calcImageScale(this.data, scale);
+ this.imgMarginDetectionPosition(currentScale);
+ },
+ /**
+ * 图片边缘检测-位置
+ */
+ imgMarginDetectionPosition(scale) {
+ if (!this.properties.limitMove) return;
+ const { scale: currentScale, left, top } = calcImageOffset(this.data, scale);
+ dataUtil.setDiffData(this, { imageLeft: left, imageTop: top, scale: currentScale });
+ },
+ /**
+ * 开始图片触摸
+ */
+ imageTouchStart(e) {
+ this.setData({ _flagEndTouch: false });
+ const { imageLeft, imageTop } = this.data;
+ // 双指左指坐标
+ const clientXForLeft = e.touches[0].clientX;
+ const clientYForLeft = e.touches[0].clientY;
+
+ let _touchRelative = [];
+ if (e.touches.length === 1) {
+ // 单指拖动
+ _touchRelative[0] = {
+ x: clientXForLeft - imageLeft,
+ y: clientYForLeft - imageTop
+ };
+ this.setData({ _touchRelative });
+ } else {
+ // 双指右指坐标
+ const clientXForRight = e.touches[1].clientX;
+ const clientYForRight = e.touches[1].clientY;
+ // 双指放大
+ let width = Math.abs(clientXForLeft - clientXForRight);
+ let height = Math.abs(clientYForLeft - clientYForRight);
+ // 勾股定理求出斜边长度
+ const _hypotenuseLength = calcPythagoreanTheorem(width, height);
+
+ _touchRelative = [{
+ x: clientXForLeft - imageLeft,
+ y: clientYForLeft - imageTop
+ },
+ {
+ x: clientXForRight - imageLeft,
+ y: clientYForRight - imageTop
+ }
+ ];
+ this.setData({_touchRelative, _hypotenuseLength});
+ }
+ },
+ /**
+ * 图片放大旋转等操作
+ */
+ imageTouchMove(e) {
+ const {
+ _flagEndTouch,
+ _MOVE_THROTTLE_FLAG
+ } = this.data;
+ if (_flagEndTouch || !_MOVE_THROTTLE_FLAG) return;
+ // 双指左指坐标
+ const clientXForLeft = e.touches[0].clientX;
+ const clientYForLeft = e.touches[0].clientY;
+
+ dataUtil.setDiffData(this, { _MOVE_THROTTLE_FLAG: false });
+ this.moveThrottle();
+ this.moveDuring();
+ if (e.touches.length === 1) {
+ //单指拖动
+ const { left, top } = imageTouchMoveOfCalcOffset(this.data, clientXForLeft, clientYForLeft);
+ dataUtil.setDiffData(this, { imageLeft: left, imageTop: top});
+ // 图像边缘检测,防止截取到空白
+ this.imgMarginDetectionPosition();
+ } else {
+ // 双指右指坐标
+ const clientXForRight = e.touches[1].clientX;
+ const clientYForRight = e.touches[1].clientY;
+ // 双指放大
+ let width = Math.abs(clientXForLeft - clientXForRight),
+ height = Math.abs(clientYForLeft - clientYForRight),
+ // 勾股定理求出斜边长度
+ hypotenuse = calcPythagoreanTheorem(width, height), // 斜边
+ scale = this.data.scale * (hypotenuse / this.data._hypotenuseLength);
+ // 计算出真实缩放倍率
+ // 如果禁止缩放则倍率一直为1
+ if (this.properties.disableScale) {
+ scale = 1;
+ } else {
+ scale = scale <= this.properties.minRatio ? this.properties.minRatio : scale;
+ scale = scale >= this.properties.maxRatio ? this.properties.maxRatio : scale;
+ eventUtil.emit(this, 'linsizechange', {
+ imageWidth: this.data.imageWidth * scale,
+ imageHeight: this.data.imageHeight * scale
+ });
+ }
+
+ this.imgMarginDetectionScale(scale);
+ dataUtil.setDiffData(this, {
+ _hypotenuseLength: Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)),
+ scale
+ });
+ }
+ },
+ /**
+ * 图片手指触摸结束
+ */
+ imageTouchEnd() {
+ dataUtil.setDiffData(this, { _flagEndTouch: true });
+ this.moveStop();
+ },
+
+ /**
+ * 检测剪裁框位置是否在允许的范围内(屏幕内)
+ */
+ cutDetectionPosition() {
+ const { cutX, cutY, _SYS_INFO, clipHeight, clipWidth } = this.data;
+ let cutDetectionPositionTop = () => {
+ //检测上边距是否在范围内
+ if (cutY < 0) {
+ dataUtil.setDiffData(this, { cutY: 0 });
+ }
+ if (cutY > _SYS_INFO.windowHeight - clipHeight) {
+ dataUtil.setDiffData(this, { cutY: _SYS_INFO.windowHeight - clipHeight });
+ }
+ },
+ cutDetectionPositionLeft = () => {
+ //检测左边距是否在范围内
+ if (cutX < 0) {
+ dataUtil.setDiffData(this, { cutX: 0 });
+ }
+ if (cutX > _SYS_INFO.windowWidth - clipWidth) {
+ dataUtil.setDiffData(this, { cutX: _SYS_INFO.windowWidth - clipWidth });
+ }
+ };
+ //裁剪框坐标处理(如果只写一个参数则另一个默认为0,都不写默认居中)
+ if (cutY === null && cutX === null) {
+ let newCutY = (_SYS_INFO.windowHeight - clipHeight) * 0.5;
+ let newCutX = (_SYS_INFO.windowWidth - clipWidth) * 0.5;
+ dataUtil.setDiffData(this, {
+ cutX: newCutX, // 截取的框上边距
+ cutY: newCutY // 截取的框左边距
+ });
+ } else if (cutY !== null && cutX !== null) {
+ cutDetectionPositionTop();
+ cutDetectionPositionLeft();
+ } else if (cutY !== null && cutX === null) {
+ cutDetectionPositionTop();
+ dataUtil.setDiffData(this, { cutX: (_SYS_INFO.windowWidth - clipWidth) / 2 });
+ } else if (cutY === null && cutX !== null) {
+ cutDetectionPositionLeft();
+ dataUtil.setDiffData(this, { cutY: (_SYS_INFO.windowHeight - clipHeight) / 2 });
+ }
+ },
+ /**
+ * 改变截取框大小
+ */
+ computeCutSize() {
+ const { clipHeight, clipWidth, _SYS_INFO, cutX, cutY } = this.data;
+ if (clipWidth > _SYS_INFO.windowWidth) {
+ // 设置裁剪框宽度
+ dataUtil.setDiffData(this, { clipWidth: _SYS_INFO.windowWidth });
+ } else if (clipWidth + cutX > _SYS_INFO.windowWidth) {
+ dataUtil.setDiffData(this, { cutX: _SYS_INFO.windowWidth - cutX });
+ }
+ if (clipHeight > _SYS_INFO.windowHeight) {
+ // 设置裁剪框高度
+ dataUtil.setDiffData(this, { clipHeight: _SYS_INFO.windowHeight });
+ } else if (clipHeight + cutY > _SYS_INFO.windowHeight) {
+ dataUtil.setDiffData(this, { cutY: _SYS_INFO.windowHeight - cutY });
+ }
+ },
+ /**
+ * 获取图片数据
+ */
+ getImageData() {
+ if (!this.properties.imageUrl) {
+ wx.showToast({
+ title: '请选择图片',
+ icon: 'none'
+ });
+ return;
+ }
+ wx.showLoading({
+ title: '加载中'
+ });
+
+ const { clipHeight, clipWidth, _ctx, scale, imageLeft, imageTop, cutX, cutY, angle } = this.data;
+ let { CANVAS_HEIGHT, CANVAS_WIDTH } = this.data;
+ const { scaleRatio, imageUrl, quality, type: imageType } = this.properties;
+ // 绘制函数
+ const draw = () => {
+ // 图片真实大小
+ const imageWidth = this.data.imageWidth * scale * scaleRatio;
+ const imageHeight = this.data.imageHeight * scale * scaleRatio;
+ // canvas和图片的相对距离
+ const xpos = imageLeft - cutX;
+ const ypos = imageTop - cutY;
+ // 旋转画布
+ _ctx.translate(xpos * scaleRatio, ypos * scaleRatio);
+ _ctx.rotate((angle * Math.PI) / 180);
+ _ctx.drawImage(imageUrl, -imageWidth / 2, -imageHeight / 2, imageWidth, imageHeight);
+ _ctx.draw(false, () => {
+ let params = {
+ width: clipWidth * scaleRatio,
+ height: Math.round(clipHeight * scaleRatio),
+ destWidth: clipWidth * scaleRatio,
+ destHeight: Math.round(clipHeight) * scaleRatio,
+ fileType: 'png',
+ quality
+ };
+
+ let data = {
+ url: '',
+ base64: '',
+ width: clipWidth * scaleRatio,
+ height: clipHeight * scaleRatio
+ };
+
+ if (IMAGE_TYPE.base64 === imageType) {
+ wx.canvasGetImageData({
+ canvasId: 'image-clipper',
+ x: 0,
+ y: 0,
+ width: clipWidth * scaleRatio,
+ height: Math.round(clipHeight * scaleRatio),
+ success: res => {
+ const arrayBuffer = new Uint8Array(res.data);
+ const base64 = wx.arrayBufferToBase64(arrayBuffer);
+ data.url = base64;
+ data.base64 = base64;
+ wx.hideLoading();
+ eventUtil.emit(this, 'linclip', data);
+ }
+ });
+ } else {
+ wx.canvasToTempFilePath({
+ ...params,
+ canvasId: 'image-clipper',
+ success: res => {
+ data.url = res.tempFilePath;
+ data.base64 = res.tempFilePath;
+ wx.hideLoading();
+ eventUtil.emit(this, 'linclip', data);
+ },
+ fail(res) {
+ throw res;
+ }
+ },
+ this
+ );
+ }
+ });
+ };
+
+ if (CANVAS_WIDTH !== clipWidth || CANVAS_HEIGHT !== clipHeight) {
+ CANVAS_WIDTH = clipWidth;
+ CANVAS_HEIGHT = clipHeight;
+ _ctx.draw();
+ setTimeout(() => {
+ draw();
+ }, 100);
+ } else {
+ draw();
+ }
+ },
+ /**
+ * 上传图片
+ */
+ uploadImage() {
+ wx.chooseImage({
+ count: 1,
+ sizeType: ['original', 'compressed'],
+ sourceType: ['album', 'camera'],
+ success: (res) => {
+ const tempFilePaths = res.tempFilePaths;
+ this.setData({ imageUrl: tempFilePaths });
+ }
+ });
+ },
+ /**
+ * 工具栏旋转
+ */
+ rotate(event) {
+ if (this.properties.disableRotate) return;
+ if (!this.properties.imageUrl) {
+ wx.showToast({
+ title: '请选择图片',
+ icon: 'none'
+ });
+ return;
+ }
+ const { rotateAngle } = this.properties;
+ const originAngle = this.data.angle;
+ const type = event.currentTarget.dataset.type;
+ if (type === 'along') {
+ this.setData({ angle: originAngle + rotateAngle });
+ } else {
+ this.setData({ angle: originAngle - rotateAngle});
+ }
+ eventUtil.emit(this, 'linrotate', { currentDeg: this.data.angle });
+ },
+ /**
+ * 关闭
+ */
+ close() {
+ this.setData({ show: false });
+ },
+ },
+
+ /**
+ * 组件的生命周期
+ */
+ lifetimes: {
+ ready() {
+ const _SYS_INFO = wx.getSystemInfoSync();
+ this.setData({ _SYS_INFO });
+ this.setCutInfo();
+ this.setCutCenter();
+ this.computeCutSize();
+ this.cutDetectionPosition();
+ }
+ }
+});
diff --git a/examples/dist/image-clipper/index.json b/examples/dist/image-clipper/index.json
new file mode 100644
index 00000000..e8cfaaf8
--- /dev/null
+++ b/examples/dist/image-clipper/index.json
@@ -0,0 +1,4 @@
+{
+ "component": true,
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/examples/dist/image-clipper/index.wxml b/examples/dist/image-clipper/index.wxml
new file mode 100644
index 00000000..7bc12fd6
--- /dev/null
+++ b/examples/dist/image-clipper/index.wxml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/dist/image-clipper/index.wxss b/examples/dist/image-clipper/index.wxss
new file mode 100644
index 00000000..cf1b26bc
--- /dev/null
+++ b/examples/dist/image-clipper/index.wxss
@@ -0,0 +1 @@
+.container{width:100vw;height:100vh;background-color:rgba(0,0,0,.6);position:fixed;top:0;left:0;z-index:1}.container .clip-wrapper{position:absolute;width:100vw;height:100vh}.container .clip-wrapper .clip-content{width:100vw;height:100vh;position:absolute;z-index:99;display:flex;flex-direction:column;pointer-events:none}.container .clip-wrapper .clip-content .flex-auto{flex:auto}.container .clip-wrapper .clip-content .clip-content-footer,.container .clip-wrapper .clip-content .clip-content-top{width:100%;pointer-events:none}.container .clip-wrapper .clip-content .clip-content-middle{width:100%;height:400rpx;display:flex;box-sizing:border-box}.container .clip-wrapper .clip-content .clip-content-middle .clip-content-middle-left,.container .clip-wrapper .clip-content .clip-content-middle .clip-content-middle-right{height:100%}.container .clip-wrapper .clip-content .clip-content-middle .clip-content-middle-center{position:relative;border:1px solid;box-sizing:border-box}.container .clip-wrapper .clip-content .clip-content-middle .clip-content-middle-center .clip-edge{position:absolute;left:6rpx;width:34rpx;height:34rpx;border:2rpx solid #fff;pointer-events:auto;box-sizing:border-box}.container .clip-wrapper .clip-content .clip-content-middle .clip-content-middle-center .clip-edge.clip-edge-top-left{border-bottom-width:0!important;border-right-width:0!important}.container .clip-wrapper .clip-content .clip-content-middle .clip-content-middle-center .clip-edge.clip-edge-top-right{border-bottom-width:0!important;border-left-width:0!important}.container .clip-wrapper .clip-content .clip-content-middle .clip-content-middle-center .clip-edge.clip-edge-bottom-left{border-top-width:0!important;border-right-width:0!important}.container .clip-wrapper .clip-content .clip-content-middle .clip-content-middle-center .clip-edge.clip-edge-bottom-right{border-top-width:0!important;border-left-width:0!important}.container .clip-wrapper .bg-transparent{background-color:rgba(0,0,0,.6);transition-duration:.35s}.container .cropper-image{width:100%;border-style:none;position:absolute;top:0;left:0;z-index:2;-webkit-backface-visibility:hidden;backface-visibility:hidden;transform-origin:center}.container .clipper-canvas{position:fixed;z-index:10;left:-2000px;top:-2000px;pointer-events:none}.container .footer-tools{position:absolute;left:0;bottom:0;width:100%;z-index:99}.container .footer-tools .tools-icon{display:flex;align-items:center;justify-content:space-between;width:100%;padding:20rpx 40rpx;box-sizing:border-box}.container .footer-tools .tools-icon image{display:block;width:50rpx;height:50rpx}
\ No newline at end of file
From e570cdf65153f9ee80cc919938497b1f62e22035 Mon Sep 17 00:00:00 2001
From: Juzi
Date: Wed, 5 Aug 2020 10:13:33 +0800
Subject: [PATCH 04/37] build: Travis CI automatic compilation
---
dist/count-selector/index.js | 1 -
dist/count-selector/index.json | 1 -
dist/count-selector/index.wxml | 10 --
dist/count-selector/index.wxss | 1 -
examples/dist/count-selector/index.js | 158 ------------------------
examples/dist/count-selector/index.json | 6 -
examples/dist/count-selector/index.wxml | 22 ----
examples/dist/count-selector/index.wxss | 1 -
8 files changed, 200 deletions(-)
delete mode 100644 dist/count-selector/index.js
delete mode 100644 dist/count-selector/index.json
delete mode 100644 dist/count-selector/index.wxml
delete mode 100644 dist/count-selector/index.wxss
delete mode 100644 examples/dist/count-selector/index.js
delete mode 100644 examples/dist/count-selector/index.json
delete mode 100644 examples/dist/count-selector/index.wxml
delete mode 100644 examples/dist/count-selector/index.wxss
diff --git a/dist/count-selector/index.js b/dist/count-selector/index.js
deleted file mode 100644
index 2f9d831a..00000000
--- a/dist/count-selector/index.js
+++ /dev/null
@@ -1 +0,0 @@
-Component({externalClasses:["l-class","l-symbol-class","l-count-class","l-disabled-class"],properties:{count:{type:Number,value:1},max:{type:Number,value:9999},min:{type:Number,value:1},step:{type:Number,value:1},disabled:Boolean,iconSize:String,iconColor:String},data:{focus:!1,result:1},observers:{"count,min,max":function(){this.valueRange(this.data.count,"parameter")}},methods:{doNothing(t){const{type:e}=t.currentTarget.dataset;this.triggerEvent("linout",{type:e,way:"icon"},{bubbles:!0,composed:!0})},onCount(){this.setData({focus:!0})},onBlur(t){this.setData({focus:!1});let{value:e}=t.detail;setTimeout(()=>{this.blurCount(Number(e),()=>{this.data.count=this.data.result,this.triggerEvent("lintap",{count:this.data.result,type:"blur"},{bubbles:!0,composed:!0})})},50)},blurCount(t,e){t?this.valueRange(t):this.setData({result:this.properties.count}),e&&e()},valueRange(t,e="input"){t>this.properties.max?this.setData({result:this.properties.max},()=>{this.triggerEvent("linout",{type:"overflow_max",way:e},{bubbles:!0,composed:!0})}):t{this.triggerEvent("linout",{type:"overflow_min",way:e},{bubbles:!0,composed:!0})}):this.setData({result:t})},reduceTap(){this.data.count-this.properties.step<=this.properties.min?this.data.count=this.properties.min:this.data.count-=this.properties.step,this.setData({result:this.data.count}),this.triggerEvent("lintap",{count:this.data.result,type:"reduce"},{bubbles:!0,composed:!0})},addTap(){this.data.count+this.properties.step>=this.properties.max?this.data.count=this.properties.max:this.data.count+=this.properties.step,this.setData({result:this.data.count}),this.triggerEvent("lintap",{count:this.data.result,type:"add"},{bubbles:!0,composed:!0})}}});
\ No newline at end of file
diff --git a/dist/count-selector/index.json b/dist/count-selector/index.json
deleted file mode 100644
index e11651a3..00000000
--- a/dist/count-selector/index.json
+++ /dev/null
@@ -1 +0,0 @@
-{"component":true,"usingComponents":{"l-icon":"../icon/index"}}
\ No newline at end of file
diff --git a/dist/count-selector/index.wxml b/dist/count-selector/index.wxml
deleted file mode 100644
index 95ba7c1a..00000000
--- a/dist/count-selector/index.wxml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
- {{result}}
-
-
-
-
\ No newline at end of file
diff --git a/dist/count-selector/index.wxss b/dist/count-selector/index.wxss
deleted file mode 100644
index 929666b8..00000000
--- a/dist/count-selector/index.wxss
+++ /dev/null
@@ -1 +0,0 @@
-.container-count{display:flex;flex-direction:row;width:170rpx;height:56rpx}.symbol{height:100%;width:56rpx;font-size:28rpx;color:#596c8e;display:flex;align-items:center;justify-content:center}.disabled{background-color:#f3f3f3;color:#c4c9d2}.abled{background-color:#ecf1f8;color:#596c8e}.count{height:100%;flex:1;min-height:56rpx;line-height:56rpx;font-size:24rpx;color:#596c8e;background:#f6f7f9;text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@font-face{font-family:iconfont;src:url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAALEAAsAAAAABqwAAAJ3AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDBgqBFIEWATYCJAMMCwgABCAFhG0HNxvdBcgekiSBqhRCJKIogADMEYRr5GySu0dQoBAloETFRVKmqpWoK1wVG1th2Ij732n7N5fsqTh2xyneKfa2N3/anZKGvYXFohGGrUFIEA6JogD/fZ7L6U2gA7nGtyynNW3s8fyoF2AcUEBjbYqsRALxFtlF3ImLOE6g3ZheoYOxmRVIKtC4QLww9QYkCxFFMfKtQt2wtIjXKq3pZfrEq+j78d9qJEmqDE09fTTahoFf6deHfNxwgxOiBHl1hYx5oBC3GjMXIsLgItpN0e7yWhHSXPEmkcq31Dv94yWihmo7wbQcS/yiMoJf9yskkEFdzE0Diwo7eF2IkexeNr35cvtSjmQ/fjt5zeTy++93z1I4x8LHT3u9VVdH6SHr0r8+OjOTtCopyONe0uFsIlZDiaMZyTdAmzFfZzrm0+EOQPOcP/IeANGP4rNA8KN0+V8rbPwlMwX83P7UK0Wa5wJwS+sZvMEfUwMbiq9F1lxcFVWFvmwE4ErICtOvARTo9zPeMgROEVoL2hG+FqMeslbjZGHnUemwjlqrbbSbM766wwAuIkobZl1ICL0ekXT7jqzXF1nYb1SG/aLWGxG0O4uBLTtMhpne59gQ2CbNHWK2mEeJXaTj+iXUN5wGz2sjfg15YMaJJqvl/Dh6yOeYEWzqFSEooZy5ZEw6DR2HEZ8zC1tCNoTwq4pCm94kt5gLafs41CCgNqJpB2FqYTyUtxbSlc8vQboNjgbeIejJr0FcwOyc0MhUADlu8kCCe3klsElXIQgUQXGMixiTBiGHgyH85kEW1CLIjBEpX5WCm1GoSV7f4n7fNmiH9syRIkeR77bbiWdmwzMaDAAA') format('woff2')}.l-icon-add:before{content:"\e602"}.l-icon-reduce:before{content:"\e69c"}.l-icon{font-family:iconfont;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.l-icon::before{display:inline-flex}.count-hover{opacity:.8}
\ No newline at end of file
diff --git a/examples/dist/count-selector/index.js b/examples/dist/count-selector/index.js
deleted file mode 100644
index c037e059..00000000
--- a/examples/dist/count-selector/index.js
+++ /dev/null
@@ -1,158 +0,0 @@
-Component({
- externalClasses: [
- 'l-class',
- 'l-symbol-class',
- 'l-count-class',
- 'l-disabled-class'
- ],
- properties: {
- count: {
- type: Number,
- value: 1
- },
- max: {
- type: Number,
- value: 9999
- },
- min: {
- type: Number,
- value: 1
- },
- step: {
- type: Number,
- value: 1
- },
- disabled: Boolean,
- iconSize: String,
- iconColor: String
- },
-
- /**
- * 组件的初始数据
- */
- data: {
- focus: false,
- result: 1
- },
-
- observers: {
- 'count,min,max': function () {
- this.valueRange(this.data.count, 'parameter');
- }
- },
-
- /**
- * 组件的方法列表
- */
- methods: {
- doNothing(e) {
- const { type } = e.currentTarget.dataset;
- this.triggerEvent('linout', { type, way: 'icon' }, {
- bubbles: true,
- composed: true
- });
- },
-
- onCount() {
- this.setData({
- focus: true
- });
- },
-
- onBlur(e) {
- this.setData({
- focus: false
- });
- let {
- value
- } = e.detail;
- setTimeout(() => {
- this.blurCount(Number(value), () => {
- this.data.count = this.data.result;
- this.triggerEvent('lintap', {
- count: this.data.result,
- type: 'blur'
- }, {
- bubbles: true,
- composed: true
- });
- });
- }, 50);
- },
-
- blurCount(value, callback) {
- if (value) {
- this.valueRange(value);
- } else {
- this.setData({
- result: this.properties.count
- });
- }
- callback && callback();
- },
-
- valueRange(value, way = 'input') {
- if (value > this.properties.max) {
- this.setData({
- result: this.properties.max
- }, () => {
- this.triggerEvent('linout', { type: 'overflow_max', way }, {
- bubbles: true,
- composed: true
- });
- });
- } else if (value < this.properties.min) {
- this.setData({
- result: this.properties.min
- }, () => {
- this.triggerEvent('linout', { type: 'overflow_min', way }, {
- bubbles: true,
- composed: true
- });
- });
- } else {
- this.setData({
- result: value
- });
- }
- },
-
- reduceTap() {
- let distance = this.data.count - this.properties.step;
- if (distance <= this.properties.min) {
- this.data.count = this.properties.min;
- } else {
- this.data.count -= this.properties.step;
- }
- this.setData({
- result: this.data.count
- });
- this.triggerEvent('lintap', {
- count: this.data.result,
- type: 'reduce'
- }, {
- bubbles: true,
- composed: true
- });
- },
-
- addTap() {
- let distance = this.data.count + this.properties.step;
- if (distance >= this.properties.max) {
- this.data.count = this.properties.max;
- } else {
- this.data.count += this.properties.step;
- }
- this.setData({
- result: this.data.count
- });
- this.triggerEvent('lintap', {
- count: this.data.result,
- type: 'add'
- }, {
- bubbles: true,
- composed: true
- });
- },
- }
-});
\ No newline at end of file
diff --git a/examples/dist/count-selector/index.json b/examples/dist/count-selector/index.json
deleted file mode 100644
index c01e2d7e..00000000
--- a/examples/dist/count-selector/index.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "component": true,
- "usingComponents": {
- "l-icon":"../icon/index"
- }
-}
\ No newline at end of file
diff --git a/examples/dist/count-selector/index.wxml b/examples/dist/count-selector/index.wxml
deleted file mode 100644
index c1b1cff4..00000000
--- a/examples/dist/count-selector/index.wxml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
- {{result}}
-
-
-
-
\ No newline at end of file
diff --git a/examples/dist/count-selector/index.wxss b/examples/dist/count-selector/index.wxss
deleted file mode 100644
index 929666b8..00000000
--- a/examples/dist/count-selector/index.wxss
+++ /dev/null
@@ -1 +0,0 @@
-.container-count{display:flex;flex-direction:row;width:170rpx;height:56rpx}.symbol{height:100%;width:56rpx;font-size:28rpx;color:#596c8e;display:flex;align-items:center;justify-content:center}.disabled{background-color:#f3f3f3;color:#c4c9d2}.abled{background-color:#ecf1f8;color:#596c8e}.count{height:100%;flex:1;min-height:56rpx;line-height:56rpx;font-size:24rpx;color:#596c8e;background:#f6f7f9;text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@font-face{font-family:iconfont;src:url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAALEAAsAAAAABqwAAAJ3AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDBgqBFIEWATYCJAMMCwgABCAFhG0HNxvdBcgekiSBqhRCJKIogADMEYRr5GySu0dQoBAloETFRVKmqpWoK1wVG1th2Ij732n7N5fsqTh2xyneKfa2N3/anZKGvYXFohGGrUFIEA6JogD/fZ7L6U2gA7nGtyynNW3s8fyoF2AcUEBjbYqsRALxFtlF3ImLOE6g3ZheoYOxmRVIKtC4QLww9QYkCxFFMfKtQt2wtIjXKq3pZfrEq+j78d9qJEmqDE09fTTahoFf6deHfNxwgxOiBHl1hYx5oBC3GjMXIsLgItpN0e7yWhHSXPEmkcq31Dv94yWihmo7wbQcS/yiMoJf9yskkEFdzE0Diwo7eF2IkexeNr35cvtSjmQ/fjt5zeTy++93z1I4x8LHT3u9VVdH6SHr0r8+OjOTtCopyONe0uFsIlZDiaMZyTdAmzFfZzrm0+EOQPOcP/IeANGP4rNA8KN0+V8rbPwlMwX83P7UK0Wa5wJwS+sZvMEfUwMbiq9F1lxcFVWFvmwE4ErICtOvARTo9zPeMgROEVoL2hG+FqMeslbjZGHnUemwjlqrbbSbM766wwAuIkobZl1ICL0ekXT7jqzXF1nYb1SG/aLWGxG0O4uBLTtMhpne59gQ2CbNHWK2mEeJXaTj+iXUN5wGz2sjfg15YMaJJqvl/Dh6yOeYEWzqFSEooZy5ZEw6DR2HEZ8zC1tCNoTwq4pCm94kt5gLafs41CCgNqJpB2FqYTyUtxbSlc8vQboNjgbeIejJr0FcwOyc0MhUADlu8kCCe3klsElXIQgUQXGMixiTBiGHgyH85kEW1CLIjBEpX5WCm1GoSV7f4n7fNmiH9syRIkeR77bbiWdmwzMaDAAA') format('woff2')}.l-icon-add:before{content:"\e602"}.l-icon-reduce:before{content:"\e69c"}.l-icon{font-family:iconfont;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.l-icon::before{display:inline-flex}.count-hover{opacity:.8}
\ No newline at end of file
From 7f9aabe39847549f110c644c494ef69a39e6017c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=A1=94=E5=AD=90?=
Date: Tue, 4 Aug 2020 19:34:14 +0800
Subject: [PATCH 05/37] =?UTF-8?q?refactor(Example):=20=E6=96=B0=E5=A2=9E?=
=?UTF-8?q?=20Transition=20=E7=BB=84=E4=BB=B6=E5=9B=BE=E6=A0=87?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
examples/pages/navigator/content/config/animation-navi.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/pages/navigator/content/config/animation-navi.js b/examples/pages/navigator/content/config/animation-navi.js
index d0c8088b..5f8050c1 100644
--- a/examples/pages/navigator/content/config/animation-navi.js
+++ b/examples/pages/navigator/content/config/animation-navi.js
@@ -1,7 +1,7 @@
const animationNaviConfigs = [
{
- icon: '/images/component/icon.png',
+ icon: 'cloud://env-9eb476.656e-env-9eb476-1258886794/images/components/transition/transition-icon.png',
title: 'Transition',
desc: '过渡',
componentsPath: '/pages/components/animation/pages/transition/index'
From c90b08312bfd09ed5ed009553f944a67d3bc232e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=A1=94=E5=AD=90?=
Date: Tue, 4 Aug 2020 19:07:11 +0800
Subject: [PATCH 06/37] =?UTF-8?q?feat(Counter):=20=E6=96=B0=E5=A2=9E=20lin?=
=?UTF-8?q?cahnge=20=E4=BA=8B=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
数量选择器值改变时触发 linchange 事件
close #992
---
src/counter/index.js | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/counter/index.js b/src/counter/index.js
index 6a3a6b7d..20ed35b3 100644
--- a/src/counter/index.js
+++ b/src/counter/index.js
@@ -1,4 +1,5 @@
import hover from '../behaviors/hover';
+import eventUtil from '../core/utils/event-util';
Component({
behaviors: [hover],
@@ -39,9 +40,12 @@ Component({
},
observers: {
+ 'result': function (count) {
+ eventUtil.emit(this, 'linchange', { value: count });
+ },
'count,min,max': function () {
this.valueRange(this.data.count, 'parameter');
- }
+ },
},
/**
@@ -158,4 +162,4 @@ Component({
});
},
}
-});
\ No newline at end of file
+});
From f4d4483f9c2fef253936e9067ec7e5d93270bfbc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=A1=94=E5=AD=90?=
Date: Tue, 4 Aug 2020 19:10:15 +0800
Subject: [PATCH 07/37] =?UTF-8?q?refactor(Counter):=20=E4=BD=BF=E7=94=A8?=
=?UTF-8?q?=20EventUtil=20=E9=87=8D=E6=9E=84=E4=BA=8B=E4=BB=B6=E8=A7=A6?=
=?UTF-8?q?=E5=8F=91=E9=80=BB=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/counter/index.js | 25 +++++--------------------
1 file changed, 5 insertions(+), 20 deletions(-)
diff --git a/src/counter/index.js b/src/counter/index.js
index 20ed35b3..96499fc0 100644
--- a/src/counter/index.js
+++ b/src/counter/index.js
@@ -41,7 +41,7 @@ Component({
observers: {
'result': function (count) {
- eventUtil.emit(this, 'linchange', { value: count });
+ eventUtil.emit(this, 'linchange', { count });
},
'count,min,max': function () {
this.valueRange(this.data.count, 'parameter');
@@ -54,10 +54,7 @@ Component({
methods: {
doNothing(e) {
const { type } = e.currentTarget.dataset;
- this.triggerEvent('linout', { type, way: 'icon' }, {
- bubbles: true,
- composed: true
- });
+ eventUtil.emit(this, 'linout', { type, way: 'icon' });
},
onCount() {
@@ -76,13 +73,7 @@ Component({
setTimeout(() => {
this.blurCount(Number(value), () => {
this.data.count = this.data.result;
- this.triggerEvent('lintap', {
- count: this.data.result,
- type: 'blur'
- }, {
- bubbles: true,
- composed: true
- });
+ eventUtil.emit(this, 'lintap', { count: this.data.result, type: 'blur' });
});
}, 50);
},
@@ -103,19 +94,13 @@ Component({
this.setData({
result: this.properties.max
}, () => {
- this.triggerEvent('linout', { type: 'overflow_max', way }, {
- bubbles: true,
- composed: true
- });
+ eventUtil.emit(this, 'linout', { type: 'overflow_max', way });
});
} else if (value < this.properties.min) {
this.setData({
result: this.properties.min
}, () => {
- this.triggerEvent('linout', { type: 'overflow_min', way }, {
- bubbles: true,
- composed: true
- });
+ eventUtil.emit(this, 'linout', { type: 'overflow_min', way });
});
} else {
this.setData({
From e6a62f6346665867a48d3ed91977dde889fb7669 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=A1=94=E5=AD=90?=
Date: Tue, 4 Aug 2020 14:37:33 +0800
Subject: [PATCH 08/37] =?UTF-8?q?refactor(Album):=20=E4=BF=AE=E6=94=B9=20b?=
=?UTF-8?q?ind:tap=20=E4=B8=BA=20mut-bind:tap?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/album/index.wxml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/album/index.wxml b/src/album/index.wxml
index 274d4d6f..4ed36dbc 100644
--- a/src/album/index.wxml
+++ b/src/album/index.wxml
@@ -1,6 +1,6 @@
-
+
From 05587be6920b2bc1465f026e2733ae55118a13fa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=A1=94=E5=AD=90?=
Date: Tue, 4 Aug 2020 14:38:08 +0800
Subject: [PATCH 09/37] =?UTF-8?q?refactor(Avatar):=20=E4=BF=AE=E6=94=B9=20?=
=?UTF-8?q?bind:tap=20=E4=B8=BA=20mut-bind:tap?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/avatar/index.wxml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/avatar/index.wxml b/src/avatar/index.wxml
index 7f9ae0bc..b7529cf4 100644
--- a/src/avatar/index.wxml
+++ b/src/avatar/index.wxml
@@ -1,5 +1,5 @@
-
+
From 03f5963ddd524bb61cec9d25a7785824053a6bdc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=A1=94=E5=AD=90?=
Date: Tue, 4 Aug 2020 14:38:40 +0800
Subject: [PATCH 10/37] =?UTF-8?q?refactor(Badge):=20=E4=BF=AE=E6=94=B9=20b?=
=?UTF-8?q?ind:tap=20=E4=B8=BA=20mut-bind:tap?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/badge/index.wxml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/badge/index.wxml b/src/badge/index.wxml
index 2854d246..33c6be88 100644
--- a/src/badge/index.wxml
+++ b/src/badge/index.wxml
@@ -1,7 +1,7 @@
-
+
{{finalCount}}
-
\ No newline at end of file
+
From 26df49c3f43edddc7a0a68d2bdba27c135b6eccf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=A1=94=E5=AD=90?=
Date: Tue, 4 Aug 2020 14:39:05 +0800
Subject: [PATCH 11/37] =?UTF-8?q?refactor(Button):=20=E4=BF=AE=E6=94=B9=20?=
=?UTF-8?q?bind:tap=20=E4=B8=BA=20mut-bind:tap?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/button/index.wxml | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/src/button/index.wxml b/src/button/index.wxml
index 3738cc7c..51d7dc3d 100644
--- a/src/button/index.wxml
+++ b/src/button/index.wxml
@@ -1,11 +1,11 @@
-