class DrawCanvas { constructor() { this._ctx = null this._canvas = null this._executionArr = [] //每移动一笔的数据 this._pathArr = [] //抬起落下为一笔 this._style = null this._matrix = null this._path = null } _init({ width, height, canvas, dicTypePath = '', callBack }) { if (!width || !height || !canvas) return const ctx = canvas.getContext('2d') canvas.width = width canvas.height = height this._canvas = canvas this._ctx = ctx this._matrix = ctx.getTransform() //IOS真机矩阵没有返回完整参数,导致无法旋转 this._executionArr = [] this._pathArr = [] // 加个背景 this._ctx.fillStyle = "#FFFFFF"; this._ctx.fillRect(0, 0, width, height); // 添加路径底图 const path = this.sPath2cPath(dicTypePath) if (path) { this._ctx.stroke(path) this._ctx.clip(path) //IOS真机裁切后,导致无法画图 this._path = path } callBack() console.log('初始化完成'); } mouseStart() { console.log('开始移动'); this._executionArr = [] } mouseMove({ x = 0, y = 0 }) { console.log('移动中'); this._executionArr.push([x, y]) this._ctx.fillStyle = this._style.fillStyle const X = x - (this._style.w / 2) const Y = y - (this._style.h / 2) this._ctx.fillRect(X, Y, this._style.w, this._style.h) } mouseEnd() { if (!this._style) return this._pathArr.push({ ...this._style, path: this._executionArr }) } mouseBack() { // 删除每个移动数据 if (!this._pathArr.length || !this._ctx) return // 清空画布 this._ctx.clearRect(0, 0, this._ctx.canvas.width, this._ctx.canvas.height) this._ctx.fillStyle = "#FFFFFF"; this._ctx.fillRect(0, 0, this._ctx.canvas.width, this._ctx.canvas.height); if (this._path) this._ctx.stroke(this._path) this._pathArr.pop() // 重画 for (let k = 0; k < this._pathArr.length; k++) { const el = this._pathArr[k]; for (let j = 0; j < el.path.length; j++) { const es = el.path[j]; this._ctx.fillStyle = el.fillStyle const X = es[0] - (el.w / 2) const Y = es[1] - (el.h / 2) this._ctx.fillRect(X, Y, el.w, el.h) } } } // 切换画笔 changeBrush({ url = '', w = 10, h = 10, angle = 0 }) { if (!url || !this._ctx || !this._canvas) return const img = this._canvas.createImage() img.src = url img.onload = () => { const fillStyle = this._ctx.createPattern(img, 'repeat') console.log('画笔样式', fillStyle, this._matrix); // 旋转 + 矩阵变化 if (angle && this._matrix && this._matrix.rotateSelf) { this._matrix.rotateSelf(angle) fillStyle.setTransform(this._matrix) } this._style = { fillStyle, w, h } } } // svg 路径转 canvas 路径 sPath2cPath(path = '') { if (!path || !this._canvas) return null const arr = path.split(/(^|\s+)(?=[A-Z])/).filter(el => el !== ' ') const PATH = this._canvas.createPath2D(); for (let k = 0; k < arr.length; k++) { const el = arr[k].replace(/\s+/g, ','); const key = el.replace(/[^A-Z]/g, '') const value = el.replace(/[A-Z]/g, '').split(',') if (key === 'M') { PATH.moveTo(value[0], value[1]); } else if (key === 'C') { PATH.bezierCurveTo(value[0], value[1], value[2], value[3], value[4], value[5]); } else if (key === 'L') { PATH.lineTo(value[0], value[1]); } } return PATH } // 清除画布 clear() { if (!this._ctx) return // 清空画布 this._ctx.clearRect(0, 0, this._ctx.canvas.width, this._ctx.canvas.height) // 画上背景 this._ctx.fillStyle = "#FFFFFF"; this._ctx.fillRect(0, 0, this._ctx.canvas.width, this._ctx.canvas.height); if (this._path) this._ctx.stroke(this._path) // 清除路径数据 this._pathArr = [] this._executionArr = [] } // 销毁 destory() { this._ctx = null this._canvas = null this._executionArr = [] this._pathArr = [] this._style = null this._matrix = null this._path = null } // 保存 save(callBack) { if (!this._canvas) return callBack('') wx.canvasToTempFilePath({ canvas: this._canvas, success(res) { callBack(res) } }) } } export { DrawCanvas }