29 | /**
30 | * Class Scratch
31 | * @class
32 | * @classdesc 九宫格翻纸牌组件逻辑部分
33 | * @author pfan
34 | * @todo 1.drawImage 与 clearRect 清除展示移动端和模拟器不一致
35 | * @todo 2.小程序无globalCompositeOperation = 'destination-out'属性
36 | * @todo 3.小程序无getImageData获取像素点对比擦除范围
37 | * @todo 4.使用 downloadFile 这种方式来先加载图片再绘制
38 | *
39 | * @example
40 | * new Scratch(this,{
41 | * canvasWidth: 197, //画布宽带
42 | * canvasHeight: 72, //画布高度
43 | * imageResource: './images/placeholder.png', //遮罩层图片
44 | * r: 4, //笔触半径
45 | * awardTxt: '中大奖', //底部抽奖文字奖项
46 | * awardTxtColor: "#1AAD16", //底部抽奖文字颜色
47 | * awardTxtFontSize: "24px", //底部抽奖文字大小
48 | * maskColor: "red", //没有图片遮罩层颜色
49 | * callback: () => {
50 | * //清除画布回调
51 | * }
52 | * })
53 | */
54 | class Scratch {
55 |
56 | /**
57 | * @constructs Scratch构造函数
58 | * @param {Object} pageContext page路由指针
59 | * @param {Object} opts 组件所需参数
60 | * @param {Number} opts.canvasWidth 画布宽带
61 | * @param {Number} opts.canvasHeight 画布高度
62 | * @param {String} opts.imageResource 遮罩层图片
63 | * @param {Number} opts.r 笔触半径
64 | * @param {String} opts.awardTxt 底部抽奖文字奖项
65 | * @param {String} opts.awardTxtColor 底部抽奖文字颜色
66 | * @param {String} opts.awardTxtFontSize 底部抽奖文字大小
67 | * @param {String} opts.maskColor 没有图片遮罩层颜色
68 | * @param {Function} opts.callback 结束回调
69 | */
70 | constructor (pageContext, opts) {
71 | this.page = pageContext
72 | this.canvasWidth = opts.canvasWidth
73 | this.canvasHeight = opts.canvasHeight
74 | this.imageResource = opts.imageResource
75 | this.maskColor = opts.maskColor
76 | // this.canvasId = opts.canvasId
77 | this.r = opts.r || 4
78 | this.endCallBack = opts.callback
79 | this.lastX = 0
80 | this.lastY = 0
81 | this.minX = ''
82 | this.minY = ''
83 | this.maxX = ''
84 | this.maxY = ''
85 | this.isStart = false
86 | this.init()
87 |
88 | this.page.touchStart = this.touchStart.bind(this)
89 | this.page.touchMove = this.touchMove.bind(this)
90 | this.page.touchEnd = this.touchEnd.bind(this)
91 | this.page.imgOnLoad = this.imgOnLoad.bind(this)
92 |
93 | this.page.setData({
94 | scratch: {
95 | "awardTxt": opts.awardTxt,
96 | "awardTxtColor": opts.awardTxtColor,
97 | "awardTxtFontSize": opts.awardTxtFontSize,
98 | "awardTxtLineHeight": opts.canvasHeight,
99 | "width": opts.canvasWidth,
100 | "height": opts.canvasHeight,
101 | "imageResource": opts.imageResource
102 | },
103 | "isScroll": true
104 | })
105 | }
106 |
107 | init () {
108 | let {canvasWidth, canvasHeight, imageResource, maskColor} = this
109 | let self = this
110 | this.ctx = wx.createCanvasContext('scratch')
111 | this.ctx.clearRect(0, 0, canvasWidth, canvasHeight)
112 | if(imageResource && imageResource != ''){
113 | wx.downloadFile({
114 | url: imageResource,
115 | success: (res) => {
116 | self.ctx.drawImage(res.tempFilePath, 0, 0, canvasWidth, canvasHeight)
117 | self.ctx.draw()
118 | }
119 | })
120 | }else{
121 | self.ctx.setFillStyle(maskColor)
122 | self.ctx.fillRect(0, 0, canvasWidth, canvasHeight)
123 | self.ctx.draw()
124 | }
125 | }
126 |
127 | drawRect (x, y) {
128 | let {r, canvasWidth, canvasHeight, lastX, lastY, minX, minY, maxX, maxY} = this
129 | let x1 = x - r > 0 ? x - r : 0
130 | let y1 = y - r > 0 ? y - r : 0
131 | if('' != minX){
132 | this.minX = minX > x1 ? x1 : minX
133 | this.minY = minY > y1 ? y1 : minY
134 | this.maxX = maxX > x1 ? maxX : x1
135 | this.maxY = maxY > y1 ? maxY : y1
136 | }else{
137 | this.minX = x1
138 | this.minY = y1
139 | this.maxX = x1
140 | this.maxY = y1
141 | }
142 | this.lastX = x1
143 | this.lastY = y1
144 |
145 | return [x1, y1, 2*r]
146 | }
147 |
148 | start () {
149 | this.isStart = true
150 | this.page.setData({
151 | "isScroll": false
152 | })
153 | }
154 |
155 | restart () {
156 | this.init()
157 | this.lastX = 0
158 | this.lastY = 0
159 | this.minX = ''
160 | this.minY = ''
161 | this.maxX = ''
162 | this.maxY = ''
163 | this.isStart = true
164 | this.page.setData({
165 | "isScroll": false
166 | })
167 | }
168 |
169 | touchStart (e) {
170 | if(!this.isStart)return
171 | let pos = this.drawRect(e.touches[0].x, e.touches[0].y)
172 | this.ctx.clearRect(pos[0] ,pos[1] , pos[2], pos[2])
173 | this.ctx.draw(true)
174 | }
175 |
176 | touchMove (e) {
177 | if(!this.isStart)return
178 | let pos = this.drawRect(e.touches[0].x, e.touches[0].y)
179 | this.ctx.clearRect(pos[0] ,pos[1] , pos[2], pos[2])
180 | this.ctx.draw(true)
181 | }
182 |
183 | touchEnd (e) {
184 | if(!this.isStart)return
185 | //自动清楚采用点范围值方式判断
186 | let {canvasWidth, canvasHeight, minX, minY, maxX, maxY} = this
187 | if(maxX - minX > .7 * canvasWidth && maxY - minY > .7 * canvasHeight ){
188 | this.ctx.draw()
189 | this.endCallBack && this.endCallBack()
190 | this.isStart = false
191 | this.page.setData({
192 | "isScroll": true
193 | })
194 | }
195 | }
196 |
197 | reset () {
198 | this.init()
199 | }
200 |
201 | imgOnLoad () {
202 |
203 | }
204 | }
205 |
206 | export default Scratch
207 |
208 |
209 |