华为快应用在setInterval中绘制canvas动画卡顿,怎么破

智码微光
• 阅读 2303

现象描述:

快应用中通过setinterval周期函数来循环触发canvas绘制代码,在华为手机上绘制的动画会很卡顿,不流畅。

问题代码如下:

click0() {
      this.speed = 0.3
      let ctx = this.$element('canvas').getContext('2d')
      setInterval(() => {
        this.num0 += 2
        this.noise = Math.min(0.5, 1) * this.MAX
        this._draw(ctx)
        this.MAX <= 200 && (this.MAX += 4)
      }, 20)
    },
    _draw(ctx) {
      this.phase = (this.phase + this.speed) % (Math.PI * 64)
      ctx.clearRect(0, 0, this.width, this.height)
      this._drawLine(ctx, -2, 'rgba(0, 194, 255, 0.2)')
      this._drawLine(ctx, -6, 'rgba(0, 194, 255, 0.4)')
      this._drawLine(ctx, 4, 'rgba(0, 194, 255, 0.6)')
      this._drawLine(ctx, 2, 'rgba(0, 194, 255, 0.8)')
      this._drawLine(ctx, 1, 'rgba(0, 194, 255, 1)', 4)
    },

问题分析:

this._draw()方法中的canvas绘制操作时间长,最低需要100ms的绘制时间,而代码中周期时间只有20ms,华为快应用引擎会执行这个周期内的操作,然后才能执行下一个周期。所以设置为20ms时的效果会看起来比较慢。

解决方法:

开发者可以先根据设备信息接口获取下设备信息中的引擎的提供商判断是否是华为的快应用引擎,如果是华为快应用引擎则设置间隔时间大于100ms,不是则可以设置小于100ms,可解决华为快应用引擎和快应用联盟引擎差异问题。代码如下(红色部分):

onShow: function () {
            var that = this
            device.getInfo({
                success: function (ret) {
                    console.log("handling success:", JSON.stringify(ret));
                    that.engineProvider = ret.engineProvider;
                },
                fail: function (erromsg, errocode) {
                    console.log("message:", erromsg, errocode);
                }
            })
        },
        click0() {
            var that = this
            this.speed = 0.3
            console.log(that.engineProvider)
            let ctx = this.$element('canvas').getContext('2d')
            if (that.engineProvider === "huawei") {
                setInterval(() => {
                    this.num0 += 2
                    this.noise = Math.min(0.5, 1) * this.MAX
                    this._draw(ctx)
                    this.MAX <= 200 && (this.MAX += 4)
                }, 120)
            } else {
                setInterval(() => {
                    this.num0 += 2
                    this.noise = Math.min(0.5, 1) * this.MAX
                    this._draw(ctx)
                    this.MAX <= 200 && (this.MAX += 4)
                }, 20)
            }
        },
        _draw(ctx) {
            this.phase = (this.phase + this.speed) % (Math.PI * 64)
            ctx.clearRect(0, 0, this.width, this.height)
            this._drawLine(ctx, -2, 'rgba(0, 194, 255, 0.2)')
            this._drawLine(ctx, -6, 'rgba(0, 194, 255, 0.4)')
            this._drawLine(ctx, 4, 'rgba(0, 194, 255, 0.6)')
            this._drawLine(ctx, 2, 'rgba(0, 194, 255, 0.8)')
            this._drawLine(ctx, 1, 'rgba(0, 194, 255, 1)', 4)
        },
        _drawLine(ctx, attenuation, color, width) {
            ctx.save()
            ctx.moveTo(0, 0);
            ctx.beginPath();
            ctx.strokeStyle = color;
            ctx.lineWidth = width || 1;
            var x, y;
            for (var i = -this.K; i <= this.K; i += 0.01) {
                x = this.width * ((i + this.K) / (this.K * 2))
                y = this.height / 2 + this.noise * this._globalAttenuationFn(i) * (1 / attenuation) * Math.sin(this.F * i - this.phase)
                ctx.lineTo(x, y)
            }
            ctx.stroke()
            ctx.restore()
        },

欲了解更多详情,请参阅:

canvas接口介绍:
https://developer.huawei.com/consumer/cn/doc/development/quickApp-References/quickapp-api-canvas

快应用开发指导文档:https://developer.huawei.com/consumer/cn/doc/development/quickApp-Guides/quickapp-whitepaper


原文链接:https://developer.huawei.com/consumer/cn/forum/topic/0204404988672310224?fid=18

原作者:Mayism

点赞
收藏
评论区
推荐文章
Python进阶者 Python进阶者
3年前
手把手教你使用CanvasAPI打造一款拼图游戏
一、canvas简介1.canvas是HTML5提供的一种新标签,双标签;2.HTML5 canvas标签元素用于图形的绘制,通过脚本(通常是JavaScript)来完成;3.canvas标签只是图形容器,必须使用脚本来绘制图形;Canvas是一个矩形区域的画布,可以用JavaScript在上面绘画;二、案例目标我们今天的目标是使用HTML5
Python进阶者 Python进阶者
3年前
Canvas之鼠标滑动特效
大家好,我是皮皮。我们会看到很多网页的粒子特效;如上图所示,这些都是借助HTML新特性,使用新增标签Canvas得到的效果;那么我们来了解下canvas。什么是Canvas在MDN中是这样定义  的: 是HTML5新增的元素,可用于通过使用JavaScript中的脚本来绘制图形。例如,它可以用于绘制图形、制作照片、创建动画,甚至可以进行实时
Stella981 Stella981
3年前
Canvas绘制不规则图形,实现可拖动,编辑
目前的工作在做在线的标注工具,接触canvas一年了,各种绘制,基本上图像的交互canvas都可以完成,也写了几篇关于canvas的文章,遇到的问题也写博客上了,对于canvas有问题的朋友可以去看看。一直想写一个关于canvas系列的东西,也没时间。正好最近再捣鼓canvas,有时间就写一点,一个功能一个功能的写,争取写一个系列。以前都是绘制矩形,
Stella981 Stella981
3年前
Android 解决NestedScrollView 嵌套 RecyclerView出现的卡顿,上拉刷新无效
解决卡顿的方法最简单的就是设置RecyclerView的android:nestedScrollingEnabled"false",放弃自己的滑动,交给外部的NestedScrollView处理,就没有出现卡顿的现象了至于RecyclerView的上拉刷新,可以监听NestedScrollView的滑动监听,具体代码如下:mNestedSc
Wesley13 Wesley13
3年前
View绘制系列(10)
Canvas基础变换前面学习了Canvas相关的一些绘制方法,不知道大家发现没?我们都是根据左上角(0,0)点算出来新的坐标,然后再绘制,这样明显不符合我们平常基于坐标原点绘制的习惯,那么我们能不能直接在原点绘制图形,然后通过操作Canvas来实现移动到目标位置呢?答案是肯定的,这就需要用到Canvas变换方法了。Canvas变
Wesley13 Wesley13
3年前
HTML5实现绘制几何图形
HTML5新增了一个<canvas.../属性。该元素自身并不绘制图形,只是相当于一张空画布。如果开发者需要向<canvas.../上绘制图形则必须使用JavaScript脚本进行绘制。为了向<canvas.../元素上绘图,必须经过如下3步。获取<canvas.../元素对应的DOM对象,这是一个Canvas对象。调用Canvas对象
Stella981 Stella981
3年前
HTML5中Canvas元素的使用总结
HTML5中Canvas元素的使用总结  Canvas提供了开发者自定义绘图的接口,我们可以公国getContext()函数来获取绘图上下文进行绘制操作,这个函数中可以传入两个参数,其中第1个参数设置绘图上下文的类型,比较常用的是"2d",我们也可以使用"webgl"来使用webOpenGL实现3D绘制。本篇博
Stella981 Stella981
3年前
Android 性能优化之减少UI过度绘制
什么是过度绘制(OverDraw)在多层次重叠的UI结构里面,如果不可见的UI也在做绘制的操作,会导致某些像素区域被绘制了多次。这样就会浪费大量的CPU以及GPU资源。过度绘制最直观的影响就是会导致APP卡顿。还好系统有提供GPU过度绘制调试工具会在屏幕上用不同的颜色,来表明一个像素点位被重复绘制的次数。
Wesley13 Wesley13
3年前
Unity性能优化整理
纹理优化SpritePacker通过细分导入到Unity的纹理,利用自带的SpritePacker将时间段内需要同时绘制在屏幕上的纹理合并到一个图集中,可以减少Drawcall的开销UGUI优化Canvas1._分离Canvas_画布(Canvas)是U
Wesley13 Wesley13
3年前
12、开源游戏
在前面中我们初始化了游戏的资源,这次我们来说下地图的绘制和游戏主循环设计。地图绘制    以前说过地图是用tiled画好,导出为图片形式的,所以地图的绘制,就是把这个图片绘制到canvas的过程。这样绘制地图就简单了,使用drawImage方法绘制即可。    这里有个2问题,1是地图的大小一般肯定是大于canvas的,所以我们只是把地图
linbojue linbojue
1年前
html--心花怒放
代码Canvas绘制一个❤html,bodyheight:100%;padding:0;margin:0;canvasposition:absolute;width:100%;height:100%;CanvasNotSupport/Settings/va