前段時間作了個跟裁剪相關的活動《用H5中的Canvas等技術製做海報》,此次公司要作個與奧運相關的活動,掃車牌贏獎。html
因而我就在上一個活動的基礎上,將代碼從新封裝一下,而且將計算方式寫的更通用。下圖是活動中裁剪的頁面:git
先來看看兩個活動的不一樣:github
一、原先的活動每次旋轉只能90°,而這次活動能夠任意角度旋轉。canvas
二、原先的活動每次旋轉就會生成一段Base64數據,致使頁面卡頓嚴重,而這次只有在裁剪的時候才生成圖片。緩存
以上兩點是最大的不一樣,其它方面基本一致,若是碰到不明白的能夠參考一下《海報製做》函數
Github的插件項目中,index.html頁面是一個示例demo。性能
1)計算座標this
在上一篇海報製做的文章中,提到了裁剪時候各個位置的計算。此次使用的計算方式與上次同樣。spa
最終也是在分別獲取裁剪框與圖片的x、y和寬高。插件
只是這次是任意角度的旋轉,因此在裁剪的時候要使用更通用的計算方式。
2)生成旋轉圖片
我在最終裁剪的時候,會先生成一張旋轉後的圖片,而後再在這張圖片中裁剪指定區域。
在上圖中選中的透明藍色部分就是一張旋轉後的圖片,這裏只能看到部分,其實完整的應該是會比原圖的寬大不少。
而經過計算後的裁剪框與圖片的位置以下:
image的x和y座標大概就是上圖中紅點的位置,若是要裁剪就要生成這張旋轉後的圖片。
細的藍色線條描繪了旋轉後的圖片樣子,這裏只展現到了部分。接下來就是如何計算獲得這張圖片。
要生成上面那張旋轉圖片,須要經過三角函數計算出寬高,以及在Canvas上畫圖的時候須要偏移的值。
經過手工計算,得出旋轉分爲四種狀況90°之內、180°之內、270°之內和360°之內。
上圖是我手工計算的90°之內的狀況,能夠計算粗話x一、x二、y一、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
前段時間作了個跟裁剪相關的活動《用H5中的Canvas等技術製做海報》,此次公司要作個與奧運相關的活動,掃車牌贏獎。
因而我就在上一個活動的基礎上,將代碼從新封裝一下,而且將計算方式寫的更通用。下圖是活動中裁剪的頁面:
先來看看兩個活動的不一樣:
一、原先的活動每次旋轉只能90°,而這次活動能夠任意角度旋轉。
二、原先的活動每次旋轉就會生成一段Base64數據,致使頁面卡頓嚴重,而這次只有在裁剪的時候才生成圖片。
以上兩點是最大的不一樣,其它方面基本一致,若是碰到不明白的能夠參考一下《海報製做》
Github的插件項目中,index.html頁面是一個示例demo。
1)計算座標
在上一篇海報製做的文章中,提到了裁剪時候各個位置的計算。此次使用的計算方式與上次同樣。
最終也是在分別獲取裁剪框與圖片的x、y和寬高。
只是這次是任意角度的旋轉,因此在裁剪的時候要使用更通用的計算方式。
2)生成旋轉圖片
我在最終裁剪的時候,會先生成一張旋轉後的圖片,而後再在這張圖片中裁剪指定區域。
在上圖中選中的透明藍色部分就是一張旋轉後的圖片,這裏只能看到部分,其實完整的應該是會比原圖的寬大不少。
而經過計算後的裁剪框與圖片的位置以下:
image的x和y座標大概就是上圖中紅點的位置,若是要裁剪就要生成這張旋轉後的圖片。
細的藍色線條描繪了旋轉後的圖片樣子,這裏只展現到了部分。接下來就是如何計算獲得這張圖片。
要生成上面那張旋轉圖片,須要經過三角函數計算出寬高,以及在Canvas上畫圖的時候須要偏移的值。
經過手工計算,得出旋轉分爲四種狀況90°之內、180°之內、270°之內和360°之內。
上圖是我手工計算的90°之內的狀況,能夠計算粗話x一、x二、y一、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上的地址: