收藏
回答

安卓手机canvas clearRect 卡顿严重

框架类型 问题类型 终端类型 微信版本 基础库版本
小程序 Bug 客户端 7.0.4 2.7.1


点击按钮,按钮以及按钮后的背景消失,开始绘制canvas


调用drawImage绘制上面的图片,当用户点击、移动时clearRect,在调试工具和iphone上都还可以,但是在安卓上面卡顿特别严重,而且页面会滚动,导致canvas区域移位,下面底层隐藏的图片直接出来了。安卓、ios手指移动时,清除滞后很明显。


class Scratch {

    /**

   * @constructs Scratch构造函数

   * @param  {Object} pageContext page路由指针

   * @param  {Object} opts      组件所需参数

   * @param  {Number} opts.canvasWidth  画布宽带

   * @param  {Number} opts.canvasHeight  画布高度

   * @param  {String} opts.imageResource  遮罩层图片

   * @param  {Number} opts.r    笔触半径

   * @param  {String} opts.awardTxt    底部抽奖文字奖项

   * @param  {String} opts.awardTxtColor    底部抽奖文字颜色

   * @param  {String} opts.awardTxtFontSize    底部抽奖文字大小

   * @param  {String} opts.maskColor     没有图片遮罩层颜色

   * @param  {Function} opts.callback    结束回调

   */

    constructor (pageContext, opts) {

        this.page = pageContext

        this.canvasWidth = opts.canvasWidth

        this.canvasHeight = opts.canvasHeight

        this.imageResource = opts.imageResource

        this.maskColor = opts.maskColor

        // this.canvasId = opts.canvasId

        this.r = opts.r || 4

        this.endCallBack = opts.callback

        this.lastX = 0

        this.lastY = 0

        this.minX = ''

        this.minY = ''

        this.maxX = ''

        this.maxY = ''

        this.isStart = false

        this.init()


        this.page.touchStart = this.touchStart.bind(this)

        this.page.touchMove = this.touchMove.bind(this)

        this.page.touchEnd = this.touchEnd.bind(this)

        this.page.imgOnLoad = this.imgOnLoad.bind(this)


        this.page.setData({

            scratch: {

                'awardTxt': opts.awardTxt,

                'awardTxtColor': opts.awardTxtColor,

                'awardTxtFontSize': opts.awardTxtFontSize,

                'awardTxtLineHeight': opts.canvasHeight,

                'width': opts.canvasWidth,

                'height': opts.canvasHeight,

                'imageResource': opts.imageResource

            },

            'isScroll': true

        })

    }


    init () {

        const { canvasWidth, canvasHeight, imageResource, maskColor } = this

        const self = this

        this.ctx = wx.createCanvasContext('scratch')

        this.ctx.clearRect(0, 0, canvasWidth, canvasHeight)

        console.log(canvasWidth+' == '+ canvasHeight)

        if (imageResource && imageResource != '') {

            wx.downloadFile({

                url: imageResource,

                success: res => {

                    self.ctx.drawImage(res.tempFilePath, 0, 0, canvasWidth, canvasHeight)

                    self.ctx.draw()

                }

            })

        } else {

            self.ctx.setFillStyle(maskColor)

            self.ctx.fillRect(0, 0, canvasWidth, canvasHeight)

            self.ctx.draw()

        }

    }


    drawRect (x, y) {

        const { r, minX, minY, maxX, maxY } = this

        const x1 = x - r > 0 ? x - r : 0

        const y1 = y - r > 0 ? y - r : 0

        if ('' != minX) {

            this.minX = minX > x1 ? x1 : minX

            this.minY = minY > y1 ? y1 : minY

            this.maxX = maxX > x1 ? maxX : x1

            this.maxY = maxY > y1 ? maxY : y1

        } else {

            this.minX = x1

            this.minY = y1

            this.maxX = x1

            this.maxY = y1

        }

        this.lastX = x1

        this.lastY = y1


        return [x1, y1, 2 * r]

    }


    start () {

        console.log('start')

        this.isStart = true

        this.page.setData({

            'isScroll': false

        })

    }


    restart () {

        this.init()

        this.lastX = 0

        this.lastY = 0

        this.minX = ''

        this.minY = ''

        this.maxX = ''

        this.maxY = ''

        this.isStart = true

        this.page.setData({

            'isScroll': false

        })

    }


    touchStart (e) {

        if (!this.isStart) return

        const pos = this.drawRect(e.touches[0].x, e.touches[0].y)

        // this.ctx.clearRect(pos[0], pos[1], pos[2], pos[2])

        this.clearArcFun(pos[0], pos[1], 10, this.ctx)

        this.ctx.draw(true)

    }


    touchMove (e) {

        if (!this.isStart) return

        const pos = this.drawRect(e.touches[0].x, e.touches[0].y)

        // this.ctx.clearRect(pos[0], pos[1], pos[2], pos[2])

        this.clearArcFun(pos[0], pos[1], 20, this.ctx)

        this.ctx.draw(true)

    }


    touchEnd (e) {

        if (!this.isStart) return

        // 自动清楚采用点范围值方式判断

        const { canvasWidth, canvasHeight, minX, minY, maxX, maxY } = this

        if (maxX - minX > .6 * canvasWidth && maxY - minY > .6 * canvasHeight) {

            this.ctx.draw()

            this.endCallBack && this.endCallBack()

            this.isStart = false

            this.page.setData({

                'isScroll': true

            })

        }

    }


    reset () {

        this.init()

    }

    clearArcFun(x, y, r, ctx) {

        var stepClear = 0.1;//这是定义精度 

        clearArc(x, y, r);

        function clearArc(x, y, radius) {

            var calcWidth = radius - stepClear;

            var calcHeight = Math.sqrt(radius * radius - calcWidth * calcWidth);


            var posX = x - calcWidth;

            var posY = y - calcHeight;


            var widthX = 2 * calcWidth;

            var heightY = 2 * calcHeight;


            if (stepClear <= radius) {

                ctx.clearRect(posX, posY, widthX, heightY);

                stepClear += 0.1;

                clearArc(x, y, radius);

            }

        }

    }

}


求各位大神提出宝贵的优化方案!

最后一次编辑于  2019-06-04
回答关注问题邀请回答
收藏
登录 后发表内容