Painter是由酷家樂移動前端團隊打造的一款小程序繪圖組件。css
原項目地址:github.com/Kujiale-Mob…前端
新版地址:github.com/shesw/Paint…vue
這款交互版原來是爲了針對業務中的新需求而由我本身開發的,後來需求改動,因此並無用上。組裏大佬考慮種種緣由(主要是項目沒用上,=0=~~),讓我先在本身的github上開源。這版painter與原版的區別在於:git
指原版的painter的功能。這些功能依然是本項目的主(實)要(用)功能。程序員
原版的使用簡介請參見 juejin.im/post/5b40b1…github
簡單來說,使用過程以下圖所示,能夠結合demo來看:json
距離首次開源Painter庫已經有一段時間了,這期間獲益於各路道友的幫助和提點,Painter進行了幾波更新(原項目地址):canvas
這一版的特點主要是具有元素的點擊事件實現以及拖拽功能,作出來之後由於項目上暫時用不上,因此感受功能上可能比較雞肋。不過還蠻好玩的😄小程序
在demo中稱之爲dancing-painter。app
**強調:**要使用交互功能,有一下兩點須要注意:
緣由:小程序頁面向組件傳值時,會把對象參數作一個相似於JSON.parse(JSON.stringfy())的拷貝,致使對象中的函數在傳遞後丟失。所以在dancing-painter中,選擇講palette(即生成圖片的json代碼)的路徑傳遞給painter組件,在組件內require到這個文件,再合成所需的json數據。
導入代碼以下:
//直接導入數據
// const template = new DCard().palette();
//導入絕對路徑
const template = {
path: '/palette/dancing-card.js',
data: {},
};
this.setData({
template: template,
});
複製代碼
palette:
//位於/palette/dancing-card.js
class PaletteCard {
context = {}
constructor(data) {
this.data = data;
}
palette() {
return{
...
}
}
}
module.exports = PaletteCard;
複製代碼
Painter的元素繪製是以json的形式給出的,其交互行爲和拖拽效果也定義在相應的json文件裏。
在須要設定某一個元素的點擊事件的時候,只須要在其相應的json代碼里加入methods屬性便可。該屬性支持一下幾種點擊方式:
name | description |
---|---|
tap | 點擊 |
longpress | 長按 |
touchstart | 開始觸摸 |
touchmove | 移動 |
touchend | 觸摸結束 |
每個方法能夠返回一個boolean值,以表示是否攔截該事件。在dancing-painter中,若是在頁面上元素有重疊,則方法的傳遞默認是由下而上的;在任意一個元素的methods方法中,能夠返回true來攔截該事件。
使用animation屬性,目前只支持拖拽能力。因爲存在與屏幕的滑動衝突(若是有大神知道怎麼截獲屏幕的滑動事件,如長頁面的滾動,請千萬不吝賜教告訴我哈),須要在使用時固定住整個頁面,如設置overflow: hidden。
使用:設置animation:{drag:true}
{
width: '700rpx',
height: '1000rpx',
background: '#eee',
views: [{
type: 'qrcode',
content: 'https://github.com/Kujiale-Mobile/Painter',
css: {
top: '40rpx',
left: '180rpx',
color: 'red',
borderWidth: '10rpx',
borderColor: 'blue',
width: '120rpx',
height: '120rpx',
align: 'center',
},
methods: {
tap() {
console.log('qrcode');
},
}
},
{
type: 'rect',
css: {
top: '40rpx',
left: '180rpx',
color: 'green',
borderRadius: '20rpx',
borderWidth: '10rpx',
width: '120rpx',
height: '120rpx',
},
methods: {
tap() {
// 調用當前頁面的function方法
const pages = this.getCurrentPages();
const currentPage = pages[pages.length-1];
currentPage.function();
},
},
animation: {
drag: true,
},
}]
}
複製代碼
事件默認是冒泡傳遞的。示例以下:
上面的代碼中是兩個部分重疊的二維碼和方形:
點擊兩者的重合部分,控制檯輸出:
拖拽功能是一種動畫現象,涉及到canvas的重繪。通過測試,在IDE上重繪速度很快,在真機上有數量級的差異。
動畫效果的連貫性主要是由canvas.draw()的速度決定的。
下圖展現了在demo主頁上,canvas.draw()方法在ide和真機上運行的時間差異(單位:ms):
IDE: 真機(華爲榮耀8):
感謝大佬在開發中對個人無限幫助。
感謝 demi520 的 wxapp-qrcode 庫,Painter 中二維碼繪製部分使用了該庫的部分代碼,並作了些修改。
另外這裏有一篇wiki簡單介紹了怎樣在mpvue中使用Painter。
坑::mpvue在更新某一個頁面元素的值的時候,會同時把全部data中存在的元素都更新一遍。
這就形成了這個問題:Painter繪製完成後,會觸發onImgOK函數,傳出圖片的url。這時將該url傳入某image的src中去,同時就會觸發Painter的template的再賦值,從而致使無限重繪。
最後,做爲程序員屆的新手和菜鳥,誠邀各路大神用issue和建議砸死我😂
最後,做爲程序員屆的新手和菜鳥,誠邀各路大神用issue和建議砸死我😂
最後,做爲程序員屆的新手和菜鳥,誠邀各路大神用issue和建議砸死我😂