108 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
		
		
			
		
	
	
			108 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
|  | class Scratch { | ||
|  | 	constructor(page, opts) { | ||
|  | 		opts = opts || {} | ||
|  | 		this.page = page | ||
|  | 		this.canvasId = opts.canvasId || 'canvas' | ||
|  | 		this.width = opts.width || 340 | ||
|  | 		this.height = opts.height + 20 || 150 | ||
|  | 		this.maskColor = opts.maskColor || '#D2D2D2' | ||
|  | 		this.size = opts.size || 10 | ||
|  | 		this.r = this.size * 2 | ||
|  | 		this.area = this.r * this.r | ||
|  | 		this.scale = opts.scale || 0.3 | ||
|  | 		this.totalArea = this.width * this.height | ||
|  | 
 | ||
|  | 		this.init() | ||
|  | 	} | ||
|  | 
 | ||
|  | 	init() { | ||
|  | 		this.show = false | ||
|  | 		this.clearPoints = [] | ||
|  | 		this.ctx = uni.createCanvasContext(this.canvasId) | ||
|  | 		this.drawMask() | ||
|  | 		this.bindTouch() | ||
|  | 	} | ||
|  | 
 | ||
|  | 	drawMask() { | ||
|  | 		this.ctx.setFillStyle(this.maskColor) | ||
|  | 		this.ctx.fillRect(0, 0, this.width, this.height) | ||
|  | 		this.ctx.draw() | ||
|  | 	} | ||
|  | 
 | ||
|  | 	bindTouch() { | ||
|  | 		this.page.touchStart = (e) => { | ||
|  | 			this.eraser(e, true) | ||
|  | 		} | ||
|  | 		this.page.touchMove = (e) => { | ||
|  | 			this.eraser(e, false) | ||
|  | 		} | ||
|  | 		this.page.touchEnd = (e) => { | ||
|  | 			if (this.show) { | ||
|  | 				this.ctx.clearRect(0, 0, this.width, this.height) | ||
|  | 				this.ctx.draw() | ||
|  | 			} | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	eraser(e, bool) { | ||
|  | 		const len = this.clearPoints.length | ||
|  | 		let count = 0 | ||
|  | 		const x = e.touches[0].x; | ||
|  | 		const y = e.touches[0].y | ||
|  | 		const x1 = x - this.size | ||
|  | 		const y1 = y - this.size | ||
|  | 		if (bool) { | ||
|  | 			this.clearPoints.push({ | ||
|  | 				x1: x1, | ||
|  | 				y1: y1, | ||
|  | 				x2: x1 + this.r, | ||
|  | 				y2: y1 + this.r | ||
|  | 			}) | ||
|  | 		} | ||
|  | 		for (const item of this.clearPoints) { | ||
|  | 			if (item.x1 > x || item.y1 > y || item.x2 < x || item.y2 < y) { | ||
|  | 				count++ | ||
|  | 			} else { | ||
|  | 				break | ||
|  | 			} | ||
|  | 		} | ||
|  | 		if (len === count) { | ||
|  | 			this.clearPoints.push({ | ||
|  | 				x1: x1, | ||
|  | 				y1: y1, | ||
|  | 				x2: x1 + this.r, | ||
|  | 				y2: y1 + this.r | ||
|  | 			}) | ||
|  | 		} | ||
|  | 		if (len && this.r * this.r * len > this.scale * this.totalArea) { | ||
|  | 			this.show = true | ||
|  | 		} | ||
|  | 		this.clearArcFun(x, y, this.r, this.ctx) | ||
|  | 		this.ctx.draw(true) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	clearArcFun(x, y, r, ctx) { | ||
|  | 		let stepClear = 1 | ||
|  | 		clearArc(x, y, r) | ||
|  | 
 | ||
|  | 		function clearArc(x, y, radius) { | ||
|  | 			const calcWidth = radius - stepClear | ||
|  | 			const calcHeight = Math.sqrt(radius * radius - calcWidth * calcWidth) | ||
|  | 
 | ||
|  | 			const posX = x - calcWidth | ||
|  | 			const posY = y - calcHeight | ||
|  | 
 | ||
|  | 			const widthX = 2 * calcWidth | ||
|  | 			const heightY = 2 * calcHeight | ||
|  | 
 | ||
|  | 			if (stepClear <= radius) { | ||
|  | 				ctx.clearRect(posX, posY, widthX, heightY) | ||
|  | 				stepClear += 1 | ||
|  | 				clearArc(x, y, radius) | ||
|  | 			} | ||
|  | 		} | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | export default Scratch |