小程序圖片剪裁加旋轉(zhuǎn)的示例代碼
一個(gè)微信小程序圖片剪裁組件,可以通過手勢(shì)控制旋轉(zhuǎn)縮放移動(dòng),也可以點(diǎn)擊旋轉(zhuǎn)進(jìn)行90度旋轉(zhuǎn),先看下效果(視屏不知道為啥用不了,上個(gè)壓縮過度的GIF先):

圖片剪裁毫無疑問用的是canvas,但是開發(fā)過小程序的同學(xué)應(yīng)該了解小程序canvas的一些坑。比如小程序canvas的設(shè)定了畫布的大小后不能像web的canvas那樣通過css樣式來調(diào)整畫布在手機(jī)上顯示的大小、還有canvas不能設(shè)置太大因?yàn)榭赡軙?huì)在某些安卓機(jī)上導(dǎo)致小程序崩潰、canvas繪制過大的圖片會(huì)讓小程序變得非常卡頓等等。
網(wǎng)上能找到的圖片剪裁框架大多采用在canvas上面直接繪制圖片,然后通過監(jiān)聽canvas上的用戶手勢(shì)來控制圖片移動(dòng)旋轉(zhuǎn)等,這樣截出來的圖片會(huì)出現(xiàn)模糊的問題,因?yàn)閏anvas的太小了。一種解決方法是,在頁(yè)面上再放置一個(gè)隱藏的canvas大小設(shè)為原來的兩倍或者再大一點(diǎn)也行用來作為實(shí)際剪裁圖片的canvas,當(dāng)然剪裁數(shù)據(jù)都是從第一個(gè)canvas那里來的。但是這樣還是有些小問題,就是canvas繪制大的圖片會(huì)出現(xiàn)卡頓的問題,這種方案在監(jiān)聽用戶手勢(shì)的變化的時(shí)候要不停的重新繪制canvas,卡頓變得更加嚴(yán)重,體驗(yàn)非常不好。
基于上面原因,我采用的是view里面放置圖片,監(jiān)聽view上面的手勢(shì),通過css樣式控制圖片的旋轉(zhuǎn)、縮放和移動(dòng),最后剪裁用隱藏的canvas。先看下頁(yè)面布局:
<view class="container">
<!-- 剪裁框與初始圖片,剪裁框監(jiān)聽用戶手勢(shì),獲取移動(dòng)縮放旋轉(zhuǎn)值,images通過css樣式顯示變化 -->
<view class="img" style="width:{{ width }}px; height:{{height}}px" catchtouchstart="touchstartCallback" catchtouchmove="touchmoveCallback" catchtouchend="touchendCallback" >
<image style="transform: translate({{stv.offsetX}}px, {{stv.offsetY}}px) scale({{stv.scale}}) rotate({{ stv.rotate }}deg);width:{{originImg.width}}px; height: {{originImg.height}}px" src="{{ originImg.url }}"></image>
</view>
<view class='footer'>
<view bindtap='uploadTap'>選擇圖片</view>
<view bindtap='rotate'>旋轉(zhuǎn)</view>
<view bindtap='cropperImg'>剪裁</view>
</view>
<!-- canvas長(zhǎng)寬設(shè)為初始圖片設(shè)置的長(zhǎng)款的兩倍,使剪裁得到的圖片更清晰,也不至于過大 -->
<canvas class='imgcrop' style="width:{{ width * 2 }}px;height:{{ height * 2}}px;" canvas-id='imgcrop'></canvas>
</view>
最重要的操作是圖片在view中的位置變化如何在canvas中保持一致再剪裁出來,圖片相對(duì)與view中的左上角坐標(biāo)、圖片的長(zhǎng)度和寬度我們都是知道的,還有旋轉(zhuǎn)值通過用戶手勢(shì)變化計(jì)算出來,旋轉(zhuǎn)的時(shí)候?qū)嫴嫉闹行囊苿?dòng)到圖片的中心點(diǎn)再旋轉(zhuǎn)就行了。
let ctx = wx.createCanvasContext('imgcrop',this);
let cropData = _this.data.stv;
ctx.save();
// 縮放偏移值
let x = (_this.data.originImg.width - _this.data.originImg.width * cropData.scale) / 2;
let y = (_this.data.originImg.height - _this.data.originImg.height * cropData.scale) / 2;
//畫布中點(diǎn)坐標(biāo)轉(zhuǎn)移到圖片中心
let movex = (cropData.offsetX + x) * 2 + _this.data.originImg.width * cropData.scale;
let movey = (cropData.offsetY + y) * 2 + _this.data.originImg.height * cropData.scale;
ctx.translate(movex, movey);
ctx.rotate(cropData.rotate * Math.PI / 180);
ctx.translate(-movex, -movey);
ctx.drawImage(_this.data.originImg.url, (cropData.offsetX + x) * 2, (cropData.offsetY + y) * 2, _this.data.originImg.width * 2 * cropData.scale, _this.data.originImg.height * 2 * cropData.scale);
ctx.restore();
查看完整代碼請(qǐng)移步到:https://github.com/yuanwyj/Mini-Program-cropper, 喜歡的畫點(diǎn)個(gè)start~~
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 微信小程序?qū)崿F(xiàn)圖片翻轉(zhuǎn)效果的實(shí)例代碼
- 詳解微信小程序圖片地扯轉(zhuǎn)base64解決方案
- 微信小程序點(diǎn)擊圖片實(shí)現(xiàn)長(zhǎng)按預(yù)覽、保存、識(shí)別帶參數(shù)二維碼、轉(zhuǎn)發(fā)等功能
- 微信小程序?qū)崿F(xiàn)點(diǎn)擊圖片旋轉(zhuǎn)180度并且彈出下拉列表
- 微信小程序內(nèi)拖動(dòng)圖片實(shí)現(xiàn)移動(dòng)、放大、旋轉(zhuǎn)的方法
- 微信小程序 Animation實(shí)現(xiàn)圖片旋轉(zhuǎn)動(dòng)畫示例
- 小程序點(diǎn)擊圖片實(shí)現(xiàn)png轉(zhuǎn)jpg
相關(guān)文章
如何使Chrome控制臺(tái)支持多行js模式——意外發(fā)現(xiàn)
一直以來,Chrome控制臺(tái)都缺少象IE調(diào)試臺(tái)那樣的多行執(zhí)行模式,今天意外發(fā)現(xiàn)Chrome其實(shí)也支持多行模式2013-06-06
基于leaflet.js實(shí)現(xiàn)修改地圖主題樣式的流程分析
這篇文章主要介紹了基于leaflet.js實(shí)現(xiàn)修改地圖主題樣式的流程,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05
JavaScript對(duì)象解構(gòu)的用法實(shí)例解析
解構(gòu)賦值允許你使用類似數(shù)組或?qū)ο笞置媪康恼Z(yǔ)法將數(shù)組和對(duì)象的屬性賦給各種變量,下面這篇文章主要給大家介紹了關(guān)于JavaScript對(duì)象解構(gòu)用法的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-01-01
微信小程序頁(yè)面跳轉(zhuǎn)功能之從列表的item項(xiàng)跳轉(zhuǎn)到下一個(gè)頁(yè)面的方法
這篇文章主要介紹了微信小程序頁(yè)面跳轉(zhuǎn)功能之從列表的item項(xiàng)跳轉(zhuǎn)到下一個(gè)頁(yè)面的方法,結(jié)合具體實(shí)例形式總結(jié)分析了微信小程序頁(yè)面跳轉(zhuǎn)及列表item項(xiàng)跳轉(zhuǎn)頁(yè)面的相關(guān)操作技巧,需要的朋友可以參考下2017-11-11
JavaScript實(shí)現(xiàn)元素滾動(dòng)條到達(dá)一定位置循環(huán)追加內(nèi)容
下面小編就為大家分享一篇JavaScript實(shí)現(xiàn)元素滾動(dòng)條到達(dá)一定位置循環(huán)追加內(nèi)容,具有很好的參考價(jià)值,希望對(duì)大家有所幫助2017-12-12
JS實(shí)現(xiàn)獲取數(shù)組中最大值或最小值功能示例
這篇文章主要介紹了JS實(shí)現(xiàn)獲取數(shù)組中最大值或最小值功能,結(jié)合實(shí)例形式總結(jié)分析了javascript獲取數(shù)組最大值與最小值的三種常見操作技巧,需要的朋友可以參考下2019-03-03
Uniapp如何封裝網(wǎng)絡(luò)請(qǐng)求方法demo
這篇文章主要為大家介紹了Uniapp如何封裝網(wǎng)絡(luò)請(qǐng)求方法demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10

