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

相關文章
相關標籤/搜索