H5图片裁剪升级版

前段时间作了个跟裁剪相关的活动《用H5中的Canvas等技术制做海报》,此次公司要作个与奥运相关的活动,扫车牌赢奖。html

因而我就在上一个活动的基础上,将代码从新封装一下,而且将计算方式写的更通用。下图是活动中裁剪的页面:git

先来看看两个活动的不一样:github

一、原先的活动每次旋转只能90°,而这次活动能够任意角度旋转。canvas

二、原先的活动每次旋转就会生成一段Base64数据,致使页面卡顿严重,而这次只有在裁剪的时候才生成图片。缓存

以上两点是最大的不一样,其它方面基本一致,若是碰到不明白的能够参考一下《海报制做函数

Github的插件项目中,index.html页面是一个示例demo。性能

 

1、裁剪原理

1)计算坐标this

在上一篇海报制做的文章中,提到了裁剪时候各个位置的计算。此次使用的计算方式与上次同样。spa

最终也是在分别获取裁剪框与图片的x、y和宽高。插件

只是这次是任意角度的旋转,因此在裁剪的时候要使用更通用的计算方式。

2)生成旋转图片

我在最终裁剪的时候,会先生成一张旋转后的图片,而后再在这张图片中裁剪指定区域。

在上图中选中的透明蓝色部分就是一张旋转后的图片,这里只能看到部分,其实完整的应该是会比原图的宽大不少。

而经过计算后的裁剪框与图片的位置以下:

image的x和y坐标大概就是上图中红点的位置,若是要裁剪就要生成这张旋转后的图片。

细的蓝色线条描绘了旋转后的图片样子,这里只展现到了部分。接下来就是如何计算获得这张图片。

 

2、三角函数

要生成上面那张旋转图片,须要经过三角函数计算出宽高,以及在Canvas上画图的时候须要偏移的值。

经过手工计算,得出旋转分为四种状况90°之内、180°之内、270°之内和360°之内。

上图是我手工计算的90°之内的状况,能够计算粗话x一、x二、y一、y2,旋转角度是30°。

知道了这四个值就能计算出新图的宽和高,还能得出须要平移的坐标值,像上图就是(x2,0)。

插件中函数“radian”,“sin”,“cos”,“caculate1”,“caculate2”,“rotateCanvas”都是在作三角函数相关计算。

其余三个状况以此类推。

    

最终图片生成是在方法“filterImage”中作的,下面是部分代码。

顺便说下,最后canvas生成了jpeg图片,而且质量是0.5,这是为了减少图片的大小,使得在性能差的手机上面也能作操做。

 

3、旋转

当在操做图片的时候,我经过手势库touch.js绑定的事件,获取到了角度,而后再将这个角度设置到CSS属性“rotate”中,使得图片旋转了起来。

平移和缩放分别用到了“translate3d”和“scale3d”,用3d属性是为了加强性能。

在插件的“initTouch”方法中配置了手势事件。插件的私有属性“param”缓存了平移、缩放和角度的值。

veCropProtytype.initTouch = function() {
        var currScale, _this = this,
            Touch = this.opts.Touch,
            frame = this.opts.frame;

        Touch.on(frame, 'rotate', function (ev) {
            var totalAngle = _this.param.deg + ev.rotation;
            if(ev.fingerStatus === 'end'){
                _this.param.deg = _this.param.deg + ev.rotation;
            }
            _this.formatTransform(_this.param.offsetX, _this.param.offsetY, _this.param.scale, totalAngle);
        });
        //......
    };

 

 

Github上的地址:

https://github.com/pwstrick/veCrop

相关文章
相关标签/搜索