当前位置:   article > 正文

微信小程序可移动缩放图片裁剪框_前端小程序如何实现给张图片上添加多个类似裁剪一样可放大缩小的框

前端小程序如何实现给张图片上添加多个类似裁剪一样可放大缩小的框

效果预览

在这里插入图片描述

提示:模拟器下由于微信自己的原因,裁剪按钮会被canvas覆盖,真机测试正常。

代码获取:https://download.csdn.net/download/anbuqi/88608193

前言

图片裁剪框应用很普遍,也有很多成熟的组件,但是很多组件都是固定裁剪框的位置,通过移动图片来完成图片指定区域的裁剪。这种方法比较容易实现,但是同时存在灵活性不高,裁剪区域选择不精确,图片尺寸不能灵活改变的局限性。下面介绍一种通过使用微信小程序canvas来实现一个可移动缩放的图片裁剪框的方法。

技术要点分析

使用canvas组件实现图片裁剪框涉及以下技术内容:
(1)使用canvas绘制图片
(2)绘制图片裁剪框
(3)裁剪框四个缩放点位置计算
(4)裁剪框的移动和缩放
(5)防止裁剪框超出屏幕
(6)在裁剪框发生变化时重绘图片和裁剪框
(7)生成指定图片区域的裁剪图片
以上这些技术的实现需要进行一定的几何计算,在这里,裁剪框的原点坐标是左上角缩放点的坐标,另外三个缩放点可以根据裁剪框的宽度和高度进行坐标偏移得到。

具体实现

(0)页面数据结构

data:{
// 是否打开相机拍照
  open_camera: true,
  // 剪切图片的canvas上下文
  cut_image_canvas: {},
  // canvas实例
  mycanvas: {},
  // 图片对象
  image_obj: {},
  // 屏幕宽度和高度
  window_width: 0,
  window_heigt: 0,
  // 画布宽高
  cut_img_canvas_w: 0,
  cut_img_canvas_h: 0,
  // 裁剪区域
  cut_area: {
    // 裁剪区域左上角离屏幕原点坐标
    x: 0,
    y: 0,
    // 裁剪宽高
    cut_width: 0,
    cut_height: 60,
    // 裁剪区域边框颜色
    cut_area_color: 'red',
  },
  // 屏幕像素比
  pixelRatio: 1,
  // 裁剪区域移动和缩放时上一个触摸点坐标
  // 用来计算移动距离和移动方向
  last_touches_x: 0,
  last_touches_y: 0,
  // 裁剪框变换类型,可选值有:
  // move,left_up_scale,left_down_scale,
  // right_up_scale,right_down_scale
  cut_area_change_status: 'move',
  // 裁剪好的图片临时文件链接
  cut_image: ''
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

(1)wxml,wxss和页面数据初始化

图片裁剪主要涉及的系统参数有三个:屏幕窗口宽度(windowWidth),窗口高度(windowHeight,除去状态栏和小程序导航栏剩下的高度)和像素比例(pixelRatio,定义参考微信官方文档:相对像素和像素比计算
注意事项: 推荐在pageonReady或者自定义组件的ready生命周期中进行初始化。
wxml:

<view wx:if="{{!cut_image}}">
  <!-- 相机组件 -->
  <camera flash="off" style="width: 100%; height: 100vh;" wx:if="{{open_camera}}"></camera>
  <!-- 裁剪按钮 -->
  <cover-view class="take_photo" hover-class="take_photo_hover" bindtap="cut_image" wx:if="{{!open_camera}}">
    <cover-view>裁剪</cover-view>
  </cover-view>
  <!-- 图片裁剪画布 -->
  <canvas id="cut_image_canvas" style="width:{{cut_img_canvas_w}}px;height:{{cut_img_canvas_h}}px;" type="2d" wx:if="{{!open_camera}}" disable-scroll="true" bindtouchmove="cut_area_move_and_scale" bindtouchstart="get_cut_area_change_status" canvas-id="cut_image_canvas"></canvas>

  <!-- 拍照按钮 -->
  <cover-view class="take_photo" hover-class="take_photo_hover" wx:if="{{open_camera}}" bindtap="take_photo">
    <cover-view>拍照</cover-view>
  </cover-view>
</view>
<!-- 裁剪图片预览 -->
<view class="preview" wx:if="{{cut_image}}">
  <image mode="widthFix" src="{{cut_image}}"></image>
</view>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

wxss

/* 拍照按钮 和图片裁剪按钮*/
.take_photo  {
  width: 240rpx;
  height: 96rpx;
  background: white;
  z-index: 1000;
  display: flex;
  flex-direction: row;
  align-content: center;
  align-items: center;
  justify-content: space-around;
  justify-items: center;
  border-radius: 10rpx;
  background: rgba(0, 0, 0, 0.4);
  color: white;
  position: fixed;
  bottom: 8%;
  left: 35%;
  text-align: center;
  font-size: 30rpx;
}
/* 拍照和图片裁剪按钮点击态 */
.take_photo_hover{
  transform: scale(0.9);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

js数据初始化

//在page中用时放到onReady方法中
ready: function() {
      const that = this
      // 获取屏幕宽高和像素比
      wx.getSystemInfo({
        success: function(res) {
          that.data.window_heigt = res.windowHeight
          that.data.window_width = res.windowWidth
          that.data.pixelRatio = res.pixelRatio
        },
      })
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

(2)待裁剪图片生成

微信小程序上的图片来源基本就两种,一种是从相册选取或者相机拍摄,另一种是网络图片,一般情况下图片裁剪主要在用户拍摄并上传图片的时候出现,因此这里使用的待裁剪图片由相机拍摄生成,代码如下:

/**
     * 拍照
     */
    take_photo: function() {
      const that = this
      //相机上下文对象
      const ctx = wx.createCameraContext()
      ctx.takePhoto({
        quality: 'high',
        success: (res) => {
        //loading,防止闪屏
          wx.showLoading({
            title: '',
          })
           // 隐藏相机
          that.setData({
            open_camera: false
          })
          //创建图片裁剪画布并绘制图片
          that.create_cut_image_canvas(res.tempImagePath)
        }
      })
    },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

微信官方文档:系统相机

(3)创建canvas绘制图片和裁剪框

绘制图片到canvas使用的APIdrawImage,绘制图片分为两步:
1.根据相机生成的临时图片链接生成要绘制的图片对象。
2.绘制图片
具体实现如下:

/**
 * 创建图片裁剪画布和图片裁剪框
 * image_url:要绘制的图片,只接受微信小程序临时文件链接
 * 网络图片需要先下载到本地
 *
 */
create_cut_image_canvas:function(image_url) {
  const that=this
  // 在page中使用时应改为wx.createSelectorQuery()
  const query = that.createSelectorQuery()
  query.select('#cut_image_canvas')
    .fields({
      node: true,
      size: true
    })
    .exec((res) => {
      //获取画布实例
      const canvas = res[0].node
      that.data.mycanvas = canvas
      //获取画布上下文
      that.data.cut_image_canvas = canvas.getContext('2d')
      let w = 0
      let h = 0
      // 根据要绘制的图片调整画布宽高
      wx.getImageInfo({
        src: image_url,
        success: function(res) {
          // 画布宽度
          canvas.width = that.data.window_width;
          w = that.data.window_width
          // 画布高度
          canvas.height = that.data.window_width / res.width * res.height
          h = canvas.height

          // 预先设置裁剪区域宽度为屏幕宽度的80%
          that.data.cut_area.cut_width = 0.8 * w
          // 预先设定的裁剪区域左上角顶点位置
          that.data.cut_area.x = (w - that.data.cut_area.cut_width) / 2
          that.data.cut_area.y = (h - that.data.cut_area.cut_height) / 2
          // 设置画布宽高
          that.setData({
            cut_img_canvas_h: h,
            cut_img_canvas_w: w
          })
          // 绘制图片
          that.data.image_obj = canvas.createImage();
          that.data.image_obj.src = image_url
          that.data.image_obj.onload = () => {
            that.data.cut_image_canvas.drawImage(that.data.image_obj, 0, 0, w, 
            h)
            // 创建图片裁剪区域
            that.create_cut_area()
          }
        }
      })

    })
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

绘制裁剪框

/**
 * 绘制裁剪区域
 * that:自定义组件实例或page实例,即this
 */
create_cut_area:function() {
  const that=this
  // 创建预先选中的图片裁剪区域
  that.data.cut_image_canvas.strokeStyle = that.data.cut_area.cut_area_color
  // 裁剪区域边界线
  that.data.cut_image_canvas.strokeRect(that.data.cut_area.x, that.data.cut_area.y, that.data.cut_area.cut_width, that.data.cut_area.cut_height)

  // 裁剪区域边界的缩放圆点

  // 左上角外圆点
  that.data.cut_image_canvas.beginPath()
  that.data.cut_image_canvas.arc(that.data.cut_area.x, that.data.cut_area.y, 5 * that.data.pixelRatio, 0, 2 * Math.PI)
  that.data.cut_image_canvas.fillStyle = 'white'
  that.data.cut_image_canvas.fill()
  // 左上角内圆点
  that.data.cut_image_canvas.beginPath()
  that.data.cut_image_canvas.arc(that.data.cut_area.x, that.data.cut_area.y, 2.5 * that.data.pixelRatio, 0, 2 * Math.PI)
  that.data.cut_image_canvas.fillStyle = '#1296db'
  that.data.cut_image_canvas.fill()

  // 左下角外圆点
  that.data.cut_image_canvas.beginPath()
  that.data.cut_image_canvas.arc(that.data.cut_area.x, that.data.cut_area.y + that.data.cut_area.cut_height, 5 * that.data.pixelRatio, 0, 2 * Math.PI)
  that.data.cut_image_canvas.fillStyle = 'white'
  that.data.cut_image_canvas.fill()
  // 左下角内圆点
  that.data.cut_image_canvas.beginPath()
  that.data.cut_image_canvas.arc(that.data.cut_area.x, that.data.cut_area.y + that.data.cut_area.cut_height, 2.5 * that.data.pixelRatio, 0, 2 * Math.PI)
  that.data.cut_image_canvas.fillStyle = '#1296db'
  that.data.cut_image_canvas.fill()

  // 右下角外圆点
  that.data.cut_image_canvas.beginPath()
  //绘制圆点,半径乘以pixelRatio的目的是在不同屏幕下保持圆点大小一致
  that.data.cut_image_canvas.arc(that.data.cut_area.x + that.data.cut_area.cut_width, that.data.cut_area.y + that.data.cut_area.cut_height, 5 * that.data.pixelRatio, 0, 2 * Math.PI)
  that.data.cut_image_canvas.fillStyle = 'white'
  that.data.cut_image_canvas.fill()
  // 右下角内圆点
  that.data.cut_image_canvas.beginPath()
  that.data.cut_image_canvas.arc(that.data.cut_area.x + that.data.cut_area.cut_width, that.data.cut_area.y + that.data.cut_area.cut_height, 2.5 * that.data.pixelRatio, 0, 2 * Math.PI)
  that.data.cut_image_canvas.fillStyle = '#1296db'
  that.data.cut_image_canvas.fill()

  // 右上角外圆点
  that.data.cut_image_canvas.beginPath()
  that.data.cut_image_canvas.arc(that.data.cut_area.x + that.data.cut_area.cut_width, that.data.cut_area.y, 5 * that.data.pixelRatio, 0, 2 * Math.PI)
  that.data.cut_image_canvas.fillStyle = 'white'
  that.data.cut_image_canvas.fill()
  // 右上角内圆点
  that.data.cut_image_canvas.beginPath()
  that.data.cut_image_canvas.arc(that.data.cut_area.x + that.data.cut_area.cut_width, that.data.cut_area.y, 2.5 * that.data.pixelRatio, 0, 2 * Math.PI)
  that.data.cut_image_canvas.fillStyle = '#1296db'
  that.data.cut_image_canvas.fill()
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

(4)计算四个缩放点位置

裁剪框缩放和移动时需要进行重绘,因此需要不断计算新的缩放点位置,计算实现如下:

    /**
     * 获取裁剪框四个缩放点位置
     */
    get_scale_point_location: function() {
      const that = this
      return {
        // 裁剪框左上角缩放点位置
        left_up_point_x: that.data.cut_area.x,
        left_up_point_y: that.data.cut_area.y,
        // 左下角缩放点位置
        left_down_point_x: that.data.cut_area.x,
        left_down_point_y: that.data.cut_area.y + that.data.cut_area.cut_height,
        // 右下角缩放点位置
        right_down_point_x: that.data.cut_area.x + that.data.cut_area.cut_width,
        right_down_point_y: that.data.cut_area.y + that.data.cut_area.cut_height,
        // 右上角缩放点位置
        right_up_point_x: that.data.cut_area.x + that.data.cut_area.cut_width,
        right_up_point_y: that.data.cut_area.y

      }
    },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

(5)辨别裁剪框移动和缩放手势

创建完裁剪框之后,接下来需要给裁剪框添加缩放和移动响应,裁剪框缩放和移动的原理是首先根据canvas 使用bindtouchstart绑定的get_cut_area_change_status方法,计算第一次触摸屏幕的位置,根据触点位置判断接下来裁剪框是要进行缩放(触点离缩放点很近)还是移动(触点离缩放点远但是落在裁剪框内),然后根据使用bindtouchmove绑定的cut_area_move_and_scale方法计算触摸移动距离,然后根据之前的判断结果进行响应的缩放和移动。get_cut_area_change_status方法如下:

/**
 * 根据触点位置辨别是移动还是缩放图片裁剪框
 * e:点击事件
 */
get_cut_area_change_status:function (e) {
  const that=this
  // 触摸点位置
  let x = e.touches[0].x
  let y = e.touches[0].y
  // 复位裁剪框变化状态
  that.data.cut_area_change_status = ''
  // 缩放感应区域半径,触点落入该区域响应缩放
  //目的是防止缩放点太小,缩放反应迟钝
  let scale_reponse_radius = 30

  // 记录当前坐标,用来计算触摸移动距离
  that.data.last_touches_x = x
  that.data.last_touches_y = y

  // 获取四个缩放点位置
  const scale_point_location = that.get_scale_point_location()
  // 裁剪框左上角缩放点位置
  let left_up_point_x = scale_point_location.left_up_point_x
  let left_up_point_y = scale_point_location.left_up_point_y
  // 左下角缩放点位置
  let left_down_point_x = scale_point_location.left_down_point_x
  let left_down_point_y = scale_point_location.left_down_point_y
  // 右下角缩放点位置
  let right_down_point_x = scale_point_location.right_down_point_x
  let right_down_point_y = scale_point_location.right_down_point_y
  // 右上角缩放点位置
  let right_up_point_x = scale_point_location.right_up_point_x
  let right_up_point_y = scale_point_location.right_up_point_y

  // 判断是否是在移动裁剪框
  if ((left_up_point_x + scale_reponse_radius) < x && x < (right_down_point_x - scale_reponse_radius) && left_up_point_y < y && y < right_down_point_y) {
    that.data.cut_area_change_status = 'move'
  }
  // 按住左上角缩放
  if (Math.sqrt(Math.pow(x - left_up_point_x, 2) + Math.pow(y - left_up_point_y, 2)) < scale_reponse_radius) {
    that.data.cut_area_change_status = 'left_up_scale'
  }
  // 按住左下角缩放
  if (Math.sqrt(Math.pow(x - left_down_point_x, 2) + Math.pow(y - left_down_point_y, 2)) < scale_reponse_radius) {
    that.data.cut_area_change_status = 'left_down_scale'
  }
  // 按住右上角缩放
  if (Math.sqrt(Math.pow(x - right_up_point_x, 2) + Math.pow(y - right_up_point_y, 2)) < scale_reponse_radius) {
    that.data.cut_area_change_status = 'right_up_scale'
  }
  // 按住右下角缩放
  if (Math.sqrt(Math.pow(x - right_down_point_x, 2) + Math.pow(y - right_down_point_y, 2)) < scale_reponse_radius) {
    that.data.cut_area_change_status = 'right_down_scale'
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

缩放感应区域和移动感应区域划分如下:
在这里插入图片描述
红圈中就是缩放感应区域,矩形中除去红圈剩下的区域就是移动感应区域。

(6)canvas重绘

canvas重绘的目的是在裁剪框发生变化时,更新canvas,防止裁剪框绘制发生重叠。实现如下:

    /**
     * 画布重绘
     */
    redraw: function(mode = 0) {
      const that = this
      // 清空画布
      that.data.cut_image_canvas.clearRect(0, 0, that.data.cut_img_canvas_w, that.data.cut_img_canvas_h)
      // 重绘图片
      that.data.cut_image_canvas.drawImage(that.data.image_obj, 0, 0, that.data.cut_img_canvas_w, that.data.cut_img_canvas_h)
      // 重绘裁剪框
      // mode=0时重绘裁剪框
      // mode=1时不绘制裁剪框,防止切图时裁剪框被切入
      if (mode == 0) {
        that.create_cut_area()
      }
    },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

(7)防止裁剪框超出屏幕边界

裁剪框进行移动和缩放时,可能会超出屏幕,因此需要根据四个缩放点的位置判断是否超出屏幕,在超出屏幕时阻止裁剪框缩放和移动,实现如下:

/**
 * 防止裁剪框超出屏幕
 * that:自定义组件或者页面实例,即this
 */
watch_cut_area_overflow:function () {
  const that=this
  // 距离屏幕边界裕度
  let margin = 5 * that.data.pixelRatio
  // 获取四个缩放点位置
  const scale_point_location = that.get_scale_point_location()
  // 裁剪框左上角缩放点位置
  let left_up_point_x = scale_point_location.left_up_point_x
  let left_up_point_y = scale_point_location.left_up_point_y
  // 左下角缩放点位置
  let left_down_point_x = scale_point_location.left_down_point_x
  let left_down_point_y = scale_point_location.left_down_point_y
  // 右下角缩放点位置
  let right_down_point_x = scale_point_location.right_down_point_x
  let right_down_point_y = scale_point_location.right_down_point_y
  // 右上角缩放点位置
  let right_up_point_x = scale_point_location.right_up_point_x
  let right_up_point_y = scale_point_location.right_up_point_y
  // 裁剪框左边超出屏幕
  if (left_up_point_x < margin) {
    return 1
  }
  //裁剪框右边超出屏幕
  if (right_down_point_x > (that.data.window_width - margin)) {
    return 1
  }
  // 裁剪框上边超出屏幕
  if (left_up_point_y < margin) {
    return 1
  }
  //裁剪框下边超出屏幕
  if (right_down_point_y > (that.data.window_heigt - margin)) {
    return 1
  }
  return 0
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

(8)裁剪框移动和缩放

做完(4)——(7)所述的工作,接下来可以实现裁剪框的移动和缩放和响应了。具体实现如下:

/**
 * 裁剪框移动和缩放
 * e:微信小程序点击事件
 */
cut_area_move_and_scale:function(e) {
  const that=this
  // 当前触点x和y坐标
  let touch_x = e.touches[0].x
  let touch_y = e.touches[0].y
  // 坐标变化量
  let dx = touch_x - that.data.last_touches_x
  let dy = touch_y - that.data.last_touches_y
  // 按住左上角缩放点缩放
  if (that.data.cut_area_change_status == "left_up_scale" || that.data.cut_area_change_status == "left_down_scale") {
    // 更新裁剪框高度
    that.data.cut_area.cut_height += -dy
    that.data.cut_area.cut_width += -dx
    // 更新左上角坐标
    that.data.cut_area.x += dx
    that.data.cut_area.y += dy
    // 裁剪框超出屏幕
    if (that.watch_cut_area_overflow()) {
      // 超出屏幕,撤销变化
      that.data.cut_area.cut_height -= -dy
      that.data.cut_area.cut_width -= -dx
      that.data.cut_area.x -= dx
      that.data.cut_area.y -= dy
      return;
    }
    // 重绘画布
    that.redraw()
  }
  // 按住其他缩放点缩放
  if (that.data.cut_area_change_status == "right_up_scale" || that.data.cut_area_change_status == "right_down_scale") {
    // 更新裁剪框高度
    that.data.cut_area.cut_height += dy
    that.data.cut_area.cut_width += dx
    // 裁剪框超出屏幕
    if (that.watch_cut_area_overflow()) {
      // 超出屏幕,撤销坐标变化
      that.data.cut_area.cut_width -= dx
      that.data.cut_area.cut_height -= dy
      return;
    }
    // 重绘画布
    that.redraw()
  }
  // 整体移动裁剪框
  if (that.data.cut_area_change_status == "move") {
    // 更新裁剪框左上角坐标量
    that.data.cut_area.x += dx
    that.data.cut_area.y += dy
    // 裁剪框超出屏幕
    if (that.watch_cut_area_overflow()) {
      // 超出屏幕,撤销坐标增量
      that.data.cut_area.x -= dx
      that.data.cut_area.y -= dy
      return;
    }
    // 重绘画布
    that.redraw()

  }
  // 更新点坐标
  that.data.last_touches_x = touch_x
  that.data.last_touches_y = touch_y
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

(9)生成裁剪后的图片及图片预览

最后,还需要把裁剪的图片区域导出成图片,代码实现如下:

/**
     * 图片裁剪
     */
    cut_image: function() {
      const that = this
      //此处重绘的目的是隐藏裁剪框,
      //防止裁剪框被切入图片
      that.redraw(1)
      wx.canvasToTempFilePath({
        // 除以像素比例,因为切图时使用的是相对像素
        x: that.data.cut_area.x / that.data.pixelRatio,
        y: that.data.cut_area.y / that.data.pixelRatio,
        //必须取整,否则安卓下回切图失败
        width: Math.round(that.data.cut_area.cut_width / that.data.pixelRatio),
        height: Math.round(that.data.cut_area.cut_height / that.data.pixelRatio),
        canvas: that.data.mycanvas,
        filetype: 'png',
        success: function(res) {
          console.log("裁剪的图片", res.tempFilePath)
          // 预览剪切好的图片
          that.setData({
            cut_image: res.tempFilePath
          })
        },
        fail: function(err) {
          console.log("裁剪图片失败", err)
          wx.showModal({
            title: '错误',
            content: '剪切图片失败',
          })
        }
      }, this)
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/565217
推荐阅读
相关标签
  

闽ICP备14008679号