1***@qq.com
1***@qq.com
  • 发布:2023-08-10 18:05
  • 更新:2023-08-11 20:03
  • 阅读:209

【报Bug】movable-view标签在支付宝小程序中,使用scale缩放后坐标轴X、Y的值错乱

分类:uni-app

产品分类: uniapp/小程序/阿里

PC开发环境操作系统: Windows

PC开发环境操作系统版本号: windows10

HBuilderX类型: 正式

HBuilderX版本号: 3.8.12

第三方开发者工具版本号: v3.7.9 稳定版

基础库版本号: v3.7.9

项目创建方式: HBuilderX

示例代码:
<template> <view class="index-warp"> <button @click="selectImage">选择图片</button> <radio-group @change="radioChange"> <label class="uni-list-cell uni-list-cell-pd" v-for="(item, index) in items" key="item.value" >
<view>
<radio :value="item.value" :checked="index === current" />
</view>
<view>{{ item.name }}</view>
</label>
</radio-group>
<view class="content">
<movable-area
v-if="imageInfo.movableWidth"
class="map-area-wrap" style="{ width: imageInfo.movableWidth + 'px',
height: imageInfo.movableHeight + 'px',
}"
>
<movable-view
direction="all"
@change="movablechange"
@scale="movablescale"
scale style="{ width: imageInfo.dWidth + 'px',
height: imageInfo.dHeight + 'px',
}"
>
<image src="imageUrl" alt=""
mode="aspectFit"
class="img"
id="elementId"
v-if="imageUrl"

style="{ width: imageInfo.dWidth + 'px',
height: imageInfo.dHeight + 'px',
}"
/>
</movable-view>
</movable-area>

<view
class="line"

style="{ width: imageInfo.movableWidth + 'px',
height: imageInfo.movableHeight + 'px',
marginLeft: '-' + imageInfo.movableWidth / 2 + 'px',
}"

</view>
</view>

图片信息:
<view>原图宽度: {{ imageInfo.width }}</view>
<view>原图高度: {{ imageInfo.height }}</view>
<view>裁剪后宽度: {{ imageInfo.cWidth }}</view>
<view>裁剪后高度: {{ imageInfo.cHeight }}</view>
<view

绘制页面宽度: {{ imageInfo.movableWidth }} 渲染图片宽度:
{{ imageInfo.dWidth }}</view

<view
绘制页面高度: {{ imageInfo.movableHeight }} 渲染图片宽度:
{{ imageInfo.dHeight }}</view

<view>绘制图片/画布宽度: {{ imageInfo.canvasWidth }}</view>
<view>绘制图片/画布高度: {{ imageInfo.canvasHeight }}</view>
<button @click="test">裁剪图片</button>
<canvas
class="canvas"
canvas-id="myCanvas"

style="{ width: imageInfo.canvasWidth + 'px',
height: imageInfo.canvasHeight + 'px',
}"
></canvas>
</view>
</template>

<script>
import { mapGetters } from "vuex";

export default {
computed: {
...mapGetters(["configList", "isLogin"]),
},
onLoad() {},
data() {
return {
items: [
{ value: "295x413", name: "295x413" },
{ value: "413x579", name: "413x579" },
{ value: "144x192", name: "144x192" },
{ value: "480x640", name: "480x640" },
{ value: "1050x1499", name: "1050x1499" },
{ value: "898x1205", name: "898x1205" },
],
imageUrl: "",
imageInfo: {},
current: 0,
corX: 0,
corY: 0,
scale: 1,
scleNum: 1,
};
},
methods: {
radioChange(value) {
this.imageInfo.cWidth = value.detail.value.split("x")[0];
this.imageInfo.cHeight = value.detail.value.split("x")[1];
this.imageInfo.movableWidth = Number(this.imageInfo.cWidth) / 2;
this.imageInfo.movableHeight = Number(this.imageInfo.cHeight) / 2;
this.imageInfo.canvasWidth = this.imageInfo.cWidth;
this.imageInfo.canvasHeight = this.imageInfo.cHeight;
console.log(value.detail.value);
console.log(this.imageInfo);
this.$forceUpdate();
},

selectImage() {  
  uni.chooseImage({  
    count: 1,  
    success: (res) => {  
      this.imageUrl = res.tempFilePaths[0];  
      this.$forceUpdate();  
      // 获取图片信息  
      uni.getImageInfo({  
        src: this.imageUrl,  
        success: (infoRes) => {  
          console.log(infoRes);  
          this.imageInfo = { ...this.imageInfo, ...infoRes }; // 将图片信息存储到data中  
          // 图片宽度适配裁剪框  
          this.scleNum =  
            this.imageInfo.width / 2 / this.imageInfo.movableWidth;  

          this.imageInfo.dWidth = this.imageInfo.movableWidth;  
          this.imageInfo.dHeight = this.imageInfo.height / 2 / this.scleNum;  

          if (this.imageInfo.dHeight < this.imageInfo.movableHeight) {  
            this.scleNum =  
              this.imageInfo.height / 2 / this.imageInfo.movableHeight;  

            this.imageInfo.dWidth = this.imageInfo.width / 2 / this.scleNum;  
            this.imageInfo.dHeight = this.imageInfo.movableHeight;  
          }  
        },  
        fail: (infoErr) => {  
          console.error(infoErr);  
        },  
      });  
    },  
  });  
},  

// 移动  
movablechange(event) {  
  console.log("移动", event.detail);  
  this.corX = event.detail.x * 2; // 页面上缩小了2倍 回调  
  this.corY = event.detail.y * 2;  
},  

// 缩放  
movablescale(event) {  
  this.scale = event.detail.scale;  
  this.corX = event.detail.x * 2; // 页面上缩小了2倍 回调  
  this.corY = event.detail.y * 2;  
  console.log("缩放", event.detail);  
},  

test() {  
  console.log(this.corX, this.corY, this.imageInfo.canvasWidth);  
  // 创建canvas绘图上下文  
  const context = uni.createCanvasContext("myCanvas", this);  
  context.drawImage(  
    this.imageUrl,  
    0, // 源图像的矩形选择框的左上角 X 坐标  
    0, // 源图像的矩形选择框的左上角 Y 坐标  
    this.imageInfo.canvasWidth, // 源图像的矩形选择框的宽度  
    this.imageInfo.canvasHeight, // 源图像的矩形选择框的高度  
    this.corX, // 图像的左上角在目标canvas上 X 轴的位置  
    this.corY, // 图像的左上角在目标canvas上 Y 轴的位置  
    (this.imageInfo.width * this.scale) / this.scleNum, // 在目标画布上绘制图像的宽度,允许对绘制的图像进行缩放  
    (this.imageInfo.height * this.scale) / this.scleNum // 在目标画布上绘制图像的高度,允许对绘制的图像进行缩放  
  ); // 替换为实际图片路径  

  // 将canvas内容转换为临时文件路径  
  context.draw(false, () => {  
    uni.canvasToTempFilePath({  
      canvasId: "myCanvas",  
      // canvas,  
      // canvasId,  
      // x: 200,  
      // y: 200,  
      // width: this.imageInfo.canvasWidth,  
      // height: this.imageInfo.canvasHeight,  
      // destWidth: this.imageInfo.canvasWidth, // 必要,保证生成图片宽度不受设备分辨率影响  
      // destHeight: this.imageInfo.canvasHeight, // 必要,保证生成图片高度不受设备分辨率影响  
      // fileType: "png", // 目标文件的类型,默认png  
      success: (res) => {  
        const tempFilePath = res.tempFilePath;  
        console.log(tempFilePath);  
        // 使用 uni.compressImage() 方法对图片进行压缩  
        uni.compressImage({  
          src: tempFilePath,  
          // quality: 1, // 设置压缩质量,范围为 1-100  
          success: (compressRes) => {  
            const compressedFilePath = compressRes.tempFilePath;  
            // 保存图片到相册  
            uni.saveImageToPhotosAlbum({  
              filePath: compressedFilePath,  
              success: () => {  
                uni.showToast({  
                  title: "保存成功",  
                  icon: "success",  
                });  
              },  
              fail: (error) => {  
                uni.showToast({  
                  title: "保存失败",  
                  icon: "none",  
                });  
                console.error(error);  
              },  
            });  
          },  
          fail: (compressErr) => {  
            console.error(compressErr);  
          },  
        });  
      },  
      fail: (res) => {  
        console.error(res);  
      },  
    });  
  });  
},  

generateImage() {  
  uni  
    .createSelectorQuery()  
    .select("#elementId")  
    .boundingClientRect((rect) => {  
      console.log(rect);  
      // 创建canvas绘图上下文  
      const context = uni.createCanvasContext("myCanvas", this);  

      // context.drawImage('/static/images/index/icon-left.png', rect.left, rect.top, rect.width, rect.height, 0, 0, rect.width, rect.height); // 替换为实际图片路径  
      context.drawImage(  
        "/static/images/index/icon-left.png",  
        200,  
        200,  
        616,  
        768,  
        0,  
        0,  
        616,  
        768  
      ); // 替换为实际图片路径  
      // context.drawImage("/static/images/index/icon-left.png"); // 替换为实际图片路径  
      // 将canvas内容转换为临时文件路径  
      context.draw(false, () => {  
        uni.canvasToTempFilePath({  
          canvasId: "myCanvas",  
          success: (res) => {  
            const tempFilePath = res.tempFilePath;  
            console.log(tempFilePath);  
            // 使用 uni.compressImage() 方法对图片进行压缩  
            uni.compressImage({  
              src: tempFilePath,  
              quality: 30, // 设置压缩质量,范围为 1-100  
              success: (compressRes) => {  
                const compressedFilePath = compressRes.tempFilePath;  
                // 保存图片到相册  
                uni.saveImageToPhotosAlbum({  
                  filePath: compressedFilePath,  
                  success: () => {  
                    uni.showToast({  
                      title: "保存成功",  
                      icon: "success",  
                    });  
                  },  
                  fail: (error) => {  
                    uni.showToast({  
                      title: "保存失败",  
                      icon: "none",  
                    });  
                    console.error(error);  
                  },  
                });  
              },  
              fail: (compressErr) => {  
                console.error(compressErr);  
              },  
            });  
          },  
          fail: (res) => {  
            console.error(res);  
          },  
        });  
      });  
    })  
    .exec();  
},  

},
};
</script>

<style lang="scss">
.img {
width: 300px;
}
.canvas {
width: 616px;
height: 768px;
}

.map-area-wrap {
margin: 0 auto;
background-color: #eee;
margin-bottom: 50px;

.max {
width: 100%;
height: 100%;
}
}

.content {
position: relative;

.line {
position: absolute;
left: 50%;
top: 0;
border: 1px solid #fff;
}
}
</style>

操作步骤:

选择图片,对图片进行缩放,获得缩放后坐标轴X、Y的值,可以直接使用官方demo重现

预期结果:

缩放后坐标轴X、Y的值同步更新,且保持正确

实际结果:

支付宝小程序中缩放后坐标轴X、Y的值错乱

bug描述:

movable-view标签在支付宝小程序中,使用scale缩放后坐标轴X、Y的值错乱。经测试微信小程序是正常的,缩放后X、Y的值应该随之变化。需要在真机调试模式下重现

2023-08-10 18:05 负责人:无 分享
已邀请:
DCloud_UNI_Anne

DCloud_UNI_Anne

单独测试一下支付宝小程序(不使用 uni-app 时),是否存在此问题

  • 1***@qq.com (作者)

    确实支付宝小程序的写法也存在这个问题

    2023-08-14 09:33

  • DCloud_UNI_Anne

    回复 1***@qq.com: 请反馈到支付宝小程序社区

    2023-08-14 14:15

要回复问题请先登录注册