1
头图

背景描述:业务需要在支付宝小程序横屏签字,但是目前支付宝不支持横屏,所以只能用样式引导用户
实现效果:
image.png

思路:
使用transform和translate 去旋转页面,这样就能满足样式的需求,看着是没啥问题,但是当在canvas上绘画的时候,就会看到,我写的是一横,展示的确是一竖
原因:页面是旋转了,但是坐标系统没有改变

image.png

解决方案:调整坐标系统
可借由rotate逆向旋转90°,然后由translate平移坐标系。

context.rotate((degree * Math.PI) / 180);
switch (degree) {
  // 页面顺时针旋转90°后,画布左上角的原点位置落到了屏幕的右上角(此时宽高互换),围绕原点逆时针旋转90°后,画布与原位置垂直,居于屏幕右侧,需要向左平移画布当前高度相同的距离。
  case -90:
    context.translate(-height, 0);
    break;
  // 页面逆时针旋转90°后,画布左上角的原点位置落到了屏幕的左下角(此时宽高互换),围绕原点顺时针旋转90°后,画布与原位置垂直,居于屏幕下侧,需要向上平移画布当前宽度相同的距离。
  case 90:
    context.translate(0, -width);
    break;
  // 页面顺逆时针旋转180°回到了同一个位置(即页面倒立),画布左上角的原点位置落到了屏幕的右下角(此时宽高不变),围绕原点反方向旋转180°后,画布与原位置平行,居于屏幕右侧的下侧,需要向左平移画布宽度相同的距离,向右平移画布高度的距离。
  case -180:
  case 180:
    context.translate(-width, -height);
}

下面是我的代码:

<canvas ref="cxt" id="xfCanvas" class="xfcanvas" :style="{ height: canvasw -52+'px' , width: '100%'}"
      @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" :disable-scroll="true">
    </canvas>
    <view class="btn">
      <view @click="resetImg">重签</view>
      <view @click="goSignDate">下一步签日期</view>
    </view>
    mounted() {
      let that = this;
      uni.getSystemInfo({
        success: function(res) {
          that.canvasw = res.windowWidth;
          that.canvash = res.windowHeight;
          console.log(that.canvasw, that.canvash, '画布尺寸');
          that.$nextTick(() => {
            that.ctx = uni.createCanvasContext('xfCanvas');
//========重点在这里  改变坐标系统,52的高度是我操作按钮的高度=============
            that.ctx.rotate((-90 * Math.PI) / 180); 
            that.ctx.translate(-that.canvash + that.canvasw + 52, 0)
            that.ctx.setStrokeStyle('#000'); // 颜色
            that.ctx.setLineWidth(8); // 粗细
            that.ctx.setLineCap('round'); // 线头形状
            that.ctx.setLineJoin('round'); // 交叉处形状
          });
        },
      });
    },

methods:{
     touchStart(e) {
        console.log('+++++++++++刚开始触摸');
        this.startX = e.changedTouches[0].x;
        this.startY = e.changedTouches[0].y;
        this.ctx.beginPath();
        this.ctx.moveTo(this.startX, this.startY); // 找到起点
      },
      touchMove(e) {
        console.log('+++++++++++触摸进行中');
        this.isSign = true
        let moveX = e.changedTouches[0].x;
        let moveY = e.changedTouches[0].y;
        this.ctx.lineTo(moveX, moveY); // 找到终点
        this.ctx.stroke(); // 描绘路径
        this.ctx.draw(true, function(ret) {});
      },
      touchEnd() {
        this.isSign = true
        console.log('+++++结束啦', this.ctx);
      },}

最后实现效果

image.png
折腾了好一会,参考了大佬的文档,受益匪浅,原文链接:https://segmentfault.com/a/11...


那年
115 声望12 粉丝