uniapp-原生地图截屏返回base64-进行画板编辑功能

一、场景

vue写uniapp打包安卓包,实现原生地图截屏(andirod同事做的)-画板编辑功能

实现效果:uniapp-原生地图截屏返回base64-进行画板编辑功能_第1张图片

二、逻辑步骤简略

1. 由 原生地图nvue部分,回调返回 地图截屏生成的base64 数据,

2. 通过 uni插件市场 image-tools 插件 base64ToPath方法,将base64数据 转成文件路径

3. 通过 uni -API- uni.createCanvasContext() 、ctx.createPattern() 方法,将 图片数据 创建绘图对象

4. 通过 uni - movable-area+movable-view 控制画布缩放

5. 通过 canvas @touchmove="touchmove"  @touchend="touchend"  @touchstart="touchstart" 等方法实现在画布上绘制画笔

6. 生成图片及清空画布

三、具体实现

1.  由 原生地图nvue部分,回调返回 原生地图截屏生成的base64 数据(andirod同事做的)

2.  image-tools 插件 base64ToPath 

image-tools - DCloud 插件市场

import { pathToBase64, base64ToPath } from '@/js_sdk/mmmm-image-tools/index.js'

3.通过 uni -API- uni.createCanvasContext() 、ctx.createPattern() 方法

uni-app官网 API- createPattern()

initC() {
      const that = this
      // 创建绘图对象
      this.ctx = uni.createCanvasContext('mycanvas', this);
      // 在canvas设置背景 - 入参 仅支持包内路径和临时路径
      const pattern = this.ctx.createPattern(this.imageUrl, 'repeat-x')
      this.ctx.fillStyle = pattern
      this.ctx.setStrokeStyle('red')
      this.ctx.fillRect(0, 0, this.dWidth, this.dHeight)
      this.ctx.draw()
      // 方法二  在画布上插入图片
      // this.img = new Image();
      // this.img.src = this.imageUrl;
      // this.img.onload = () => {
      //   console.log('this.img', that.img.width)
      //   that.ctx.drawImage(that.img, 0, 0, this.dWidth, this.dHeight)
      //   // that.ctx.draw()
      // }
    },

4. 通过 uni - movable-area+movable-view 控制画布缩放


      
          
          
      
    

5.通过 canvas @touchmove="touchmove"  等方法实现在画布上绘制画笔

touchstart(e) {
      let startX = e.changedTouches[0].x
      let startY = e.changedTouches[0].y
      if (this.scaleValue > 1) {
        startX = e.changedTouches[0].x / this.scaleValue;
        startY = e.changedTouches[0].y / this.scaleValue;
      } else {
        startX = e.changedTouches[0].x * this.scaleValue;
        startY = e.changedTouches[0].y * this.scaleValue;
      }
      console.log('touchstart()-x', e.changedTouches[0].x, 'scaleValue', this.scaleValue, 'startX', startX)
      let startPoint = { X: startX, Y: startY };
      this.points.push(startPoint);
      // 每次触摸开始,开启新的路径
      this.ctx.beginPath();
	  },
    touchmove(e) {
      if (this.isEdit) {
        let moveX = e.changedTouches[0].x
        let moveY = e.changedTouches[0].y
        if (this.scaleValue > 1) {
          moveX = e.changedTouches[0].x / this.scaleValue;
          moveY = e.changedTouches[0].y / this.scaleValue;
        } else {
          moveX = e.changedTouches[0].x * this.scaleValue;
          moveY = e.changedTouches[0].y * this.scaleValue;
        }
        console.log('touchmove()-x', e.changedTouches[0].x, 'scaleValue', this.scaleValue, 'moveX', moveX)
        let movePoint = { X: moveX, Y: moveY };
        this.points.push(movePoint); // 存点
        let len = this.points.length;
        if (len >= 2) {
          this.draw(); // 绘制路径
        }
      }
	  },
    touchend() {
      this.points = [];
	  },
    draw() {
      let point1 = this.points[0];
      let point2 = this.points[1];
      this.points.shift();
      this.ctx.moveTo(point1.X, point1.Y);
      this.ctx.lineTo(point2.X, point2.Y);
      this.ctx.stroke();
      this.ctx.draw(true);
    },

6.生成图片及清空画布

clear() {
      let that = this;
      this.scaleValue = 1
      this.isEdit = false
      this.movableDisabled = false
      uni.getSystemInfo({
        success: function(res) {
          let canvasw = res.windowWidth;
          let canvash = res.windowHeight;
          that.ctx.clearRect(0, 0, canvasw, canvash);
          const pattern = that.ctx.createPattern(that.imageUrl, 'repeat-x')
          that.ctx.fillStyle = pattern
          that.dWidth = 285
          that.dHeight = 200
          that.ctx.setStrokeStyle('red')
          that.ctx.fillRect(0, 0, that.dWidth, that.dHeight)
          that.ctx.draw()
          // that.ctx.draw(true);
        }
      });
    },
    finish() {
      let that = this;
      uni.canvasToTempFilePath({
          canvasId: 'mycanvas',
          success: function(res) {
            // 这里的res.tempFilePath就是生成的签字图片
            // console.log('tempFilePath', res.tempFilePath);
            that.tempFilePath = res.tempFilePath
            that.$emit('onImgUrl', that.tempFilePath) // 向父级组件传值
          }
      });
    },

utils:

// 是否是 base64数据
export function isBase64Two(str) {
	try {
		return btoa(atob(str)) === str;
	} catch (err) {
		return false;
	}
}
export function isBase64(str) {
	// 正则表达式匹配B4-64编码格式
	const regex = /^[a-zA-Z0-9+\/]+={0,2}$/;
	return regex.test(str);
}
// 校验内容是否包含base64格式的图片
export function isBase64Three(str){
  let imgReg = RegExp(/data:image\/.*;base64,/)
  const res = imgReg.test(str)
  return res
}

四、总结

以下完整代码 DrawingBoard.vue:






由于hbuildex-真机调试-打印很费劲,需要来回构建打包,从而找问题找了好久,其中因为 原生地图截屏返回的是纯base64的数据,未带 data:image\/.*;base64,然后找了半天的问题,需要一步步的推导和确认有没有错,错在那,花费了很多时间和精力;

你可能感兴趣的:(uni-app,javascript,vue.js,前端,canva可画)