微信小程序簡單的canvas裁剪圖片功能詳解
小程序miniso的一個發(fā)布內(nèi)容截圖功能,話不多,先上代碼
wxml文件:
<view class="cut-1-1 t-c {{cutSelect == 1? 'cut-select':''}}" data-cut="1" bindtap="selectCutType">1:1</view>
<view class="cut-3-4 t-c {{cutSelect == 2? 'cut-select':''}}" data-cut="2" bindtap="selectCutType">3:4</view>
<block wx:for="{{imgList}}" wx:key="{{index}}" >
<swiper-item>
<scroll-view scroll-top="{{topNum}}" scroll-y class="imgFile {{cutSelect == 1?'view-1-1':'view-3-4'}}" bindscroll="endTou">
<image src='{{item}}' mode="widthFix"></image>
</scroll-view >
</swiper-item>
</block>
<canvas wx:for="{{imgList}}" wx:for-index="i" canvas-id="myCanvas_{{i}}" style="width: {{width[i]?width[i]*2:750}}rpx; height: {{height[i]?height[i]*2:750}}rpx;"></canvas>
這里是對多張圖片進行統(tǒng)一處理,用戶選了哪種截圖比例,所有圖片用統(tǒng)一規(guī)格裁剪。
因為簡單,不提供縮放和左右移動,所以只能裁剪豎長圖,不支持橫長圖裁剪。
topNum用于scroll-view的reset處理
wxss文件
.view-1-1 {
width: 750rpx;
height: 750rpx;
overflow: hidden;
}
.view-3-4 {
width: 750rpx;
height: 750rpx;
padding: 0 94rpx;
box-sizing: border-box;
overflow: hidden;
}
canvas {
position: absolute;
/* display: none; */
left: -999rpx;
z-index: 0;
}
裁剪比例的樣式,1:1裁剪使用750rpx,3:4使用padding進行視覺上的拉長
接下來就是重要的代碼部分了
js文件
cutPic() {
const _this = this
if (this.data.cutting) {
return
}
let promiseList = [], ctx = []
_this.data.imgList.forEach((v, i) => {
promiseList.push(_this.draw(ctx, v, i))
})
wx.showLoading({
title: '截取中...',
icon: 'none'
})
this.setData({
cutting: true
})
Promise.all(promiseList).then((arr) => {
wx.setStorageSync("interimImagesList", _this.data.imgFileList)
_this.uploadPic()
}, err => {
})
},
使用微信自帶api,wx.chooseImage將圖片保存在imgList數(shù)組里,因為裁剪圖片用canvas處理會有一定的延遲,所以使用promise進行異步處理
//獲取豎向滑動坐標
endTou(e) {
const _this = this
let y = 'y[' + (_this.data.currentIndex - 1) + '].top'
_this.setData({
[y]: e.detail.scrollTop
})
},
定義的y數(shù)組用于記錄每張圖片截取的位置。
//繪制
draw(ctx, v, i) {
const _this = this
let width, height
return new Promise((resolve, reject) => {
ctx[i] = wx.createCanvasContext(`myCanvas_${i}`)
wx.getImageInfo({
src: v,
success: function (res) {
width = 'width[' + i + ']'
height = 'height[' + i + ']'
var str = res.height / res.width;//圖片的寬高比
_this.setData({
[width]: 375,
[height]: 375 * str
}, () => {
ctx[i].drawImage(v, 0, 0, _this.data.width[i], _this.data.height[i])
ctx[i].draw(false, () => {
setTimeout(() => {
wx.canvasToTempFilePath({//調(diào)用方法,開始截取
x: 0,
y: _this.data.y[i] ? _this.data.cutSelect == 1 ? _this.data.y[i].top : _this.data.y[i].top / 0.75 : 0,
width: 375,
height: _this.data.cutSelect == 1 ? 375 : 500,
destWidth: 375,
destHeight: _this.data.cutSelect == 1 ? 375 : 500,
canvasId: 'myCanvas_' + i,
success: function (res) {
resolve(res.tempFilePath)
console.info('canvas', res.tempFilePath)
let img = 'imgFileList[' + i + ']'
_this.setData({
[img]: res.tempFilePath
})
},
fail: function (err) {
reject(err)
console.info(err)
}
})
}, 1000) // 渲染時間
})
})
}
})
})
},
渲染圖片最重要的一步是獲得寬高比,所以在canvas繪制之前使用getImageInfo獲取到圖片信息,var str=res.height/res.width獲得高寬比例。
canvas繪制圖片是需要時間,所以setTime了個1秒,不然截出來的圖是失敗的。這里也可以使用遞歸的方式來繪制
canvas 代碼就不給出了,可以自己搜一下。
總結(jié)
一個簡單的canvas截圖就制作完成了。值得注意的是canvas渲染是需要時間的。
這也算是一個簡單的練手吧,下次有什么復(fù)雜的截圖功能再分享出來吧。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
layui實現(xiàn)數(shù)據(jù)分頁功能(ajax異步)
這篇文章主要為大家詳細介紹了layui實現(xiàn)數(shù)據(jù)分頁功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-07-07
ionic App問題總結(jié)系列之ionic點擊系統(tǒng)返回鍵退出App
本篇文章主要介紹了ionic App問題總結(jié)系列之ionic點擊系統(tǒng)返回鍵退出App,具有一定的參考價值,有興趣的可以了解一下2017-08-08
JavaScript 程序錯誤Cannot use ''in'' operator to search的解決方法
下面小編就為大家?guī)硪黄狫avaScript 程序錯誤Cannot use 'in' operator to search的解決方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07

