H5圖片裁剪升級版


前段時間做了個跟裁剪相關的活動《用H5中的Canvas等技術制作海報》,這次公司要做個與奧運相關的活動,掃車牌贏獎。

於是我就在上一個活動的基礎上,將代碼重新封裝一下,並且將計算方式寫的更通用。下圖是活動中裁剪的頁面:

先來看看兩個活動的不同:

1、原先的活動每次旋轉只能90°,而此次活動可以任意角度旋轉。

2、原先的活動每次旋轉就會生成一段Base64數據,導致頁面卡頓嚴重,而此次只有在裁剪的時候才生成圖片。

以上兩點是最大的不同,其它方面基本一致,如果碰到不明白的可以參考一下《海報制作

Github的插件項目中,index.html頁面是一個示例demo。

 

一、裁剪原理

1)計算坐標

在上一篇海報制作的文章中,提到了裁剪時候各個位置的計算。這次使用的計算方式與上次一樣。

最終也是在分別獲取裁剪框與圖片的x、y和寬高。

只是此次是任意角度的旋轉,所以在裁剪的時候要使用更通用的計算方式。

2)生成旋轉圖片

我在最終裁剪的時候,會先生成一張旋轉后的圖片,然后再在這張圖片中裁剪指定區域。

在上圖中選中的透明藍色部分就是一張旋轉后的圖片,這里只能看到部分,其實完整的應該是會比原圖的寬大很多。

而通過計算后的裁剪框與圖片的位置如下:

image的x和y坐標大概就是上圖中紅點的位置,如果要裁剪就要生成這張旋轉后的圖片。

細的藍色線條描繪了旋轉后的圖片樣子,這里只展示到了部分。接下來就是如何計算得到這張圖片。

 

二、三角函數

要生成上面那張旋轉圖片,需要通過三角函數計算出寬高,以及在Canvas上畫圖的時候需要偏移的值。

通過手工計算,得出旋轉分為四種情況90°以內、180°以內、270°以內和360°以內。

上圖是我手工計算的90°以內的情況,可以計算出x1、x2、y1、y2,旋轉角度是30°。

知道了這四個值就能計算出新圖的寬和高,還能得出需要平移的坐標值,像上圖就是(x2,0)。

插件中函數“radian”,“sin”,“cos”,“caculate1”,“caculate2”,“rotateCanvas”都是在做三角函數相關計算。

其他三個情況以此類推。

    

最終圖片生成是在方法“filterImage”中做的,下面是部分代碼。

順便說下,最后canvas生成了jpeg圖片,並且質量是0.5,這是為了減小圖片的大小,使得在性能差的手機上面也能做操作。

 

三、旋轉

當在操作圖片的時候,我通過手勢庫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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM