html5头像裁剪,H5头像裁剪的实现与坑位

最近有个需求,需要在H5上实现用户头像裁剪。需求如下:

html5头像裁剪,H5头像裁剪的实现与坑位_第1张图片

1.穿透效果的透明蒙层

使用canvas的ctx.globalCompositeOperation='destination-out'实现。

(该特性还可以实现类似刮刮乐的效果)

html5头像裁剪,H5头像裁剪的实现与坑位_第2张图片

坑位1:在一些高分辨率的安卓机子上,绘制canvas图形会出现模糊的现象。因为canvas元素依赖于设备像素比,所以适配高清屏,canvas内容的宽高需要设置为实际的宽高的dpr倍。但是如果这么设置会导致画面空白一片,无法显示。

html5头像裁剪,H5头像裁剪的实现与坑位_第3张图片

2.可平移缩放的图片显示器

html5头像裁剪,H5头像裁剪的实现与坑位_第4张图片

html5头像裁剪,H5头像裁剪的实现与坑位_第5张图片

坑位2:在做安卓平板兼容时,有时候多点触摸操作后,再进行单点触摸,touch事件返回的touchList不是只有一个触摸点的信息,也会有多个触摸点的信息。导致依赖触摸点去判断平移还是缩放操作的准则失效。

解决方法:发现如果多点触摸后再单点触摸,如果touchList的长度不为1时,touch[0]之后的触摸点的位置都是维持不变的,只有touch[0]的位置坐标会发生变化,因此利用此点来追加判断单点触摸还是多点触摸。

3.图片裁剪编辑器

html5头像裁剪,H5头像裁剪的实现与坑位_第6张图片

html5头像裁剪,H5头像裁剪的实现与坑位_第7张图片

坑位3:利用屏幕显示的图片尺寸,去进行裁剪,怎么裁剪都不对。

解决方法:裁剪操作的图片大小并不是在屏幕上显示的图片大小,而是源图片的大小。需要使用element.naturalWidth和element.naturalHeight属性来正确计算裁剪和缩放区域等内容,而不是element.width和element.height。

html5头像裁剪,H5头像裁剪的实现与坑位_第8张图片

坑位4:采用naturalWidth、naturalHeight与width和height的比例来纠正裁剪源图的坐标,在首次加载图片裁剪的效果是正确的,但是二次加载图片裁剪后的效果又是不正确的。

解决方法:不使用element.width和element.heightl来进行源图片与屏幕显示图片的比例换算。是因为当图片有缓存时,首次加载完成的width和height分别与naturalWidth和naturalHeight相等(后面又会恢复正常),width和height获取不到正确的图片屏幕显示尺寸,导致裁剪算法异常。这里使用element.clientWidth和element.clientHeight进行与源图片的比例换算。

坑位5:IOS手机编辑时,显示的图片方向是正确的,但是经过裁剪后,获取的图片不正确。IOS在显示的时候,会根据图片EXIF属性中的orientation值,进行自动旋转纠正图片的显示方向。

html5头像裁剪,H5头像裁剪的实现与坑位_第9张图片

解决方法:引入一个exif.js的库,获取图片的orientation值,来对图片进行方向旋转的处理。在此只需要处理:1.顺时针旋转90°,2.逆时针旋转90°,3.顺时针旋转180°,三种情况。

html5头像裁剪,H5头像裁剪的实现与坑位_第10张图片

html5头像裁剪,H5头像裁剪的实现与坑位_第11张图片

html5头像裁剪,H5头像裁剪的实现与坑位_第12张图片

html5头像裁剪,H5头像裁剪的实现与坑位_第13张图片

(引入exif.js的代码网上有很多,但是没有具体的旋转分析图,当时这个想了挺久的TOT~)

坑位6:裁剪经过旋转显示的宽度大于屏幕宽度的图片,往往会出现裁剪部分缺失或裁剪出空白的图片,但是裁剪的坐标和宽度经过推算是没有错。

html5头像裁剪,H5头像裁剪的实现与坑位_第14张图片

html5头像裁剪,H5头像裁剪的实现与坑位_第15张图片

解决方法:屏幕上加载显示的图片,并非缓存中的原图片经过旋转缩放获取,如果image图片的style限定了宽度和高度,那么缓存中的原图片加载的宽度和高度会受此限制。因此需要另外加载一个没有宽高样式限制的图片作为裁剪的源图片。

坑位7:高度小于裁剪高度时,会导致裁剪框的参数计算异常。

解决方法:维持裁剪的sX坐标不变,将sY坐标设置为0,裁剪高度和宽度为图片的源高度。

html5头像裁剪,H5头像裁剪的实现与坑位_第16张图片

4.展望

更多可能性的操作,例如图片可旋转的操作,那么裁剪坐标该如何计算。

html5头像裁剪,H5头像裁剪的实现与坑位_第17张图片

如何简化计算?可以利用线性代数进行运算(两个不同矩阵相乘记得齐次方程处理)。

html5头像裁剪,H5头像裁剪的实现与坑位_第18张图片为了便于进行旋转、平移、缩放等混合操作运算,矩阵需要作齐次方程处理。

html5头像裁剪,H5头像裁剪的实现与坑位_第19张图片

可以进一步将矩阵的计算抽取为公共工具函数类:

html5头像裁剪,H5头像裁剪的实现与坑位_第20张图片

其灵感来自于学习WebGL的矩阵转换运算,笔者也是刚入门学习中,欢迎交流~~

你可能感兴趣的:(html5头像裁剪)