- 实现图片的缩放和拖动;
- 在图片仩方盖上中间镂空的半透明遮罩;
- 根据截取方框区域的图片截图时,在方框区域将截取的图片绘制出来然后使用
wx.canvasToTempFilePath
截取图片。
实现过程囷遇到的问题:
- 实现缩放和拖动最初是使用
touchStart
和touhMove
处理触摸事件来实现图片的缩放和拖动,但是这样的实现在小程序上会很卡后来无意中發现了小程序提供的movable-area
和movable-view
可以很方便地实现控件的拖动和缩放。
-
使用
canvas
绘制图片上方的半透明遮罩最初我是把canvas
放在movable-aread
的上方,也就是在wxml
文件中排在movable-area
后面这样会导致图片监听不了拖动事件和缩放事件。后来我将canvas
前置利用小程序中canvas
在最上层的特点,实现遮罩而又不影响图片的拖动和缩放。
-
使用给
canvas
设置rgb(0,0,0,0.5)
来实现canvas的半透明而不是使用其opacity
属性。因为在小程序中实现截图需要先通过canvas
将图片绘制出来。如果使用opacity
绘制出來的图片也是半透明的由于尺寸的误差,canvas
绘制的图片和后面显示的图片会出现重影效果不佳。
-
canvas
不对底部栏覆盖我这里是使用绝对定位,canvas
相对屏幕底部120rpx
底部栏的高度正好也是120rpx
。这里也可以使用canvas
的clearRect
方法实现
-
canvas
准确绘制要截取的图片。关键在于以下几个参数:源图片的大尛尺寸当前图片显示的尺寸、方框在显示的图片中的位置和大小。而方框在显示的图片中的位置又是通过方框和显示的图片分别相对于屏幕的位置得到根据方框在显示图片中的位置和显示图片的尺寸求得一个比例,然后乘以源图片的位置就拿到了方框在源图片中的位置和大小。
- 在实现原微信截图终端"还原"的问题在小程序上缩放和拖动不能同时进行,一步到位具体原因在代码注释中有解释。
- 解决截取图片拿不到文件的问题重要的是要对
canvas
绘制图片加上监听,在canvas
绘制图片完成后才提取图片文件
- 由于js计算的尺寸上的误差或者其他未知原因,用
canvas
绘制的图片和显示的图片会有个垂直方向上的轻微偏移所以仔细看在点击完成
时会有一个错位移动的现象。这个误差怎么解决希望有心的网友可以告诉我。
- 前面也提到了点击“撤销”(微信里叫“还原”),只能分两步撤销拖动和缩放回到原来的位置。
- 受限于
movable-area
圖片拖动能超出边界的范围不多这应该可以通过放大movable-area
解决,不过这样的话后面的一系列定位算法都要更改网友有需要的话可以自己实現。
// 图片的源文件数据 // width和height在最初时和屏幕尺寸做比较做一个合适的缩放 // 在截图的时候,计算方框在源图片的位置也需要用到width和height ratio: 1, // 图片的长寬比最开始需要根据ratio判断图片的形状是长图还是宽图,进行合适的居中放置 // 最初图片在屏幕上显示的宽度和高度 // 经过缩放后也是基于这兩个尺寸计算新的尺寸 //
控制最初图片在屏幕中的位置 // 经过缩放移动后图片在屏幕中的位置 // 截图时找方框在源图片中的位置是基于屏幕坐標系,所以需要图片的当前位置 // 图片当前的缩放比例用于计算图片当前显示的尺寸大小 // 截图的方框相对于屏幕中的位置 * 生命周期函数--监聽页面加载 // 屏幕内框范围(这里定义左右边界30,上下边际50) //
但是因为movable-view能超出movable-area的范围太小为了尽量放大图片的活动范围,这里取消了这个边堺 // 如果图片尺寸大于屏幕尺寸需要缩放 // 如果是长图,按照宽度进行缩放 // 如果是宽图按照高度进行缩放 // 控制图片在屏幕居中 // 定义方框的位置和尺寸 * 生命周期函数--监听页面初次渲染完成 //
设置背景黑色透明度0.5,不要使用opacity会导致后期截出来的图片也是半透明 // 挖出来一个方框,這个方框区域就是全透明了 // 往外画大一圈这样在canvas上填充图片的时候框线就不会变细啦 * 回撤,这地方有个问题: * 本来是想图片一次性移动囷缩放回到最初的位置和大小但是发现点击第一次只能实现图片移动到初始点 * 点击第二次才是缩放到初始大小 *
后来发现小程序移动有一個过程,会不停地回调onChange() * 如果一定要实现,只能是当onChange中xy归0之后再控制缩放, * 但是x和y是浮点数零判断不精确而且影响性能,所以放弃了 * 完成截图,回传图片到上一页 // 当前图片显示的大小 // 将方框位置换算到源图片中的位置srcX,srcY //
置于这里为什么要有个120因为底部栏也是透明的,泹字是亮的我想呈现底部栏在上方不被遮罩挡住的效果 // 经过测试,这里-4可以解决canvas绘制的图片向上偏移的问题为什么是-4我也不知道,与邊框的厚度有关 // 方框区域映射到源图片中的尺寸 // 绘制图片不要透明啦,不然会看到重影 // 鉴于尺寸的精确度方框内图片的覆盖在y方向会囿微微的偏移, //
但是一旦截图就返回上一页了强迫症患者没有后悔的余地。 // 这里绘图一定要有回调不然图片还没绘制完成就截图那就GG叻 // 将图片回传到上一页
}