好久没写了,其实可写的还是挺多,主要还是懒吧...

最近公司项目使用小程序做序列帧动画,大概有 116 张图,共9.6M。

比较闲的日子里实验了一番,主要有以下几种方法,

1. css background-image + animation

2. css background-position + animation

3. js background-image

4. js background-position

5. js img src

6. canvas drawImage

结果当然是 canvas 性能最优咯,不会出现掉帧和卡屏的情况,其中最不推荐第一种

所以这次项目也就准备尝试下微信小程序的 canvas 会不会有别样的风味

基本上和 html 的 canvas 区别不大,方法名略有不同,再就是需要一个 draw 方法才会绘制。

canvas.getContext('2d') 等于 wx.createCanvasContext(canvas)。

一般 wx.createCanvasContext 放在 onReady 还是 onShow 并没有什么区别(手里机型太少,没试太多)

接着就开始了填坑之路:

1. Image 对象问题,只需直接使用图片路径

官方案例给的是 wx.chooseImage 返回的缓存文件,显然不是我们要的;

在 html 中如果想 drawImage 那就需要一个 Image 对象,需要先 new Image() 或者获取到 dom 中的 <img>,

那么小程序该怎么办呢,我略一沉凝,准备试它一下,直接使用了图片路径,

ctx = ctx ? ctx : wx.createCanvasContext('imgs');
url = 'https://sum.kdcer.com/test/sw_shake/0/0 (1).jpg';
ctx.drawImage(url, 0, 0, 300, 500); // 直接使用图片路径
ctx.darw()

唔,非常美妙,调试器上是正常的。url 为相对路径也是可以的。

当然,这个时候预加载就是个问题,只能在 wxml 中去 for 出所有的图片并 bindload 了

2. 图片路径不能有特殊符号

上面的情况虽然调试器通了,但手机预览时还是没有任何图片绘制上去呀(其他点线绘制是存在的)。

然后去博客寻找了番,开始我是怀疑可能直接使用图片路径是不支持这种远程资源的(仅能用小程序内部的相对路径)。

于是我采用了 downloadFile 这种方法再次尝试。

wx.downloadFile({
url: url,
success: function (res) {
ctx.drawImage(res.tempFilePath, 0, 0, 300, 500);
ctx.draw();
}
})

结果返回给我的 res.tempFilePath 是个 .htm 结尾的文件,报出 http 400(请求无效)的错误。

我怀疑问题出在了文件本身,于是我改了下文件名,由 0 (1).jpg 改为 1.jpg,就能正常访问了。

后来进行了一些实验,暂时还只发现了 空格+括号 这一种命名会失败。

drawImage 如果直接使用图片路径其实是可以访问远程资源的,只是加载的慢,图片异步没法绘制上去了。

所以更为推荐使用 downloadFile 这种方式来先加载图片再绘制。

比较坑的是,downloadFile 不能下载相对路径的图片,这让我想优化把一部分图片放进小程序变得无比麻烦(其实2M资源放进去小程序就会变得非常卡)。

3. downloadFile 文件数限制

官方表示,downloadFile 这个 api 最大并发限制为 10 个,

意味着直接 for 个 116 下是会报错的。

因此需要换用为递归的方式去预加载图片。

我写的递归不见得都适用,就不放出来了,应该没什么难点的。

(推荐先用 html 写通递归,不然小程序编辑器死循环了很扎心)

4. downloadFile 合法域名的配置

开发完成后出现了小程序仅有打开了调试工具才能正常运行的情况,

后来经过同事点拨,原来还要设置 downloadFile 的合法域名,这个修改就简单了。

每个月只能修改 5 次的限制应该不会造成什么影响。

5. requestAnimationFrame 问题

为了更好的动画优化,当然少不了 requestAnimationFrame 的存在。

然而,安卓机的小程序是有的,苹果机小程序却根本没有这个方法。

好在我们可以写段回退兼容,放在 Page 的外面。

if (typeof requestAnimationFrame == 'undefined') {
var lastTime = 0;
var requestAnimationFrame = function (callback) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = setTimeout(function () { callback(currTime + timeToCall); }, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
}
if (typeof cancelAnimationFrame == 'undefined') {
var cancelAnimationFrame = function (id) {
clearTimeout(id);
};
}

  

6. fps 性能问题

小程序一直吹嘘着接近原生的流畅体验,但这次帧动画的项目中显然打脸了。

html 版的 canvas 每 15ms 绘制一次都是小 case,但小程序则需要 50ms 以上的间隔。否则会出现间断性白屏。

60fps 和 20fps 虽然在 html 中有很大差距,但在小程序中 20fps 并没有太影响用户的浏览体验。

毕竟 js 的运算和 webview 的通信本身就不是多快的一件事,而如果单单只考虑 webview 和 html 的话那当然有差距。

总的来说,填坑的路是比较烦人的,

后一个问题解决了又开始想,是不是前一个问题其实本来是对的,然后又回去重来一遍,

最后的最后,来来回回,才能彻底填平这个坑。

微信小程序 drawImage 问题的更多相关文章

  1. 微信 小程序 drawImage wx.canvasToTempFilePath wx.saveFile 获取设备宽高 尺寸问题

    以下问题测试环境为微信开发者0.10.102800,手机端iphone6,如有不对敬谢指出. 根据我的测试,context.drawImage,在开发者工具中并不能画出来,只有预览到手机中显示. wx ...

  2. 微信小程序 base64 图片 canvas 画布 drawImage 实现

    在微信小程序中 canvas drawImage API 传入的第一个参数是 imageResource 图片资源路径,这个参数通常由从相册选择图片 wx.chooseImage 或 wx.getIm ...

  3. 微信 小程序 canvas

    测试手机为IPHONE6,开发者工具版本0.10.102800.开发者工具0.11.112301版本也一样 微信小程序里的canvas 非 h5 canvas有很多不一样的地方,以下把微信小程序的ca ...

  4. 69个微信小程序常见问题

    本文转自 遇到小程序方面的问题,该去哪里提问呢? 若是能得到微信官方的解答,想必是最叫人安心的.而微信也确实提供了这么一个地方. 在微信公众平台的开发者社区,就置顶了一个「小程序常见问题 FAQ」帖. ...

  5. 官方问答--微信小程序常见FAQ (17.8.21-17.8.27)

    给提问的开发者的建议:提问之前先查询 文档.通过社区右上角搜索搜索已经存在的问题. 写一个简明扼要的标题,并且正文描述清楚你的问题. 提交 BUG:需要带上基础库版本号,设备信息(iOS, Andro ...

  6. 微信小程序--图片相关问题合辑

    图片上传相关文章 微信小程序多张图片上传功能 微信小程序开发(二)图片上传 微信小程序上传一或多张图片 微信小程序实现选择图片九宫格带预览 ETL:微信小程序之图片上传 微信小程序wx.preview ...

  7. 微信小程序之生成图片分享

    通过社交软件分享的方式来进行营销小程序,是一个常用的运营途径.小程序本身支持直接将一个小程序的链接卡片分享至微信好友或微信群,然后别人就可以通过点击该卡片进入该小程序页面.但是小程序目前不支持直接分享 ...

  8. 微信小程序绘制分享图

    微信小程序绘制分享图例子: demo下载地址:https://gitee.com/v-Xie/wxCanvasShar 大致代码会再以下说明 实际开发项目: 基础知识点: 了解canvas基础知识 w ...

  9. 关于微信小程序使用canvas生成图片,内容图片跨域的问题

    最近有个项目是保存为名片(图片),让用户发送给朋友或朋友圈,找了很多方案都不适用,绞尽脑汁之后还是选了使用canvas,但是用这玩意儿生成图片最大的缺点就是,如果你的内容中有图片,并且这个图片是通过外 ...

随机推荐

  1. 模拟window桌面实现

    正在开发中的游戏有个全屏功能--可以在window桌面背景上运行,就像一些视频播放器在桌面背景上播放一样的,花了个上午整了个Demo放出来留个纪念. 实现功能:显示图标,双击图标执行相应的程序,右击图 ...

  2. python的其他安全隐患

    零.绪论 python这里以python2.7为研究对象,对应的我们会简要说明一下python3,其他指与反序列化无关的安全隐患问题. 一.标准输入输出: 1.首先,我们来看下标准输入输出 impor ...

  3. 【BZOJ4071】[Apio2015]巴邻旁之桥 Treap

    [BZOJ4071][Apio2015]巴邻旁之桥 Description 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域 A 和区域 B. 每一块区域沿着河岸都建了恰好 1000000001 ...

  4. 160603、使用pd4ml.jar和ss_css2.jar转pdf的工具类

    注意:需要导入pd4ml.jar和ss_css2.jar import java.awt.Insets;import java.io.BufferedInputStream;import java.i ...

  5. Groovy中的脚本与类

    包名 当你在groovy中定义类的时候需要指定包名,这和java中类似不多介绍. 导入 groovy中的导入也跟java类似,有一下五种: 默认导入 groovy默认导入了一下几个包和类: impor ...

  6. hibernate的日期映射

    2. 映射 Java 的时间, 日期类型 1). 两个基础知识: I. 在 Java 中, 代表时间和日期的类型包括: java.util.Date 和 java.util.Calendar. 此外, ...

  7. java常用队列分析

    一.ArrayBlockingQueue 首先看一段源码: public class ArrayBlockingQueue<E> extends AbstractQueue<E> ...

  8. HDU 4417 Super Mario(线段树)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  9. python学习笔记(四)— 函数

    一.函数是什么? 函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的,编程中的函数在英文中也有很多不同的叫法.在BASIC中叫做subroutine(子过程或子程序),在Pasc ...

  10. 向git服务器添加shh公钥

    步骤一,从客户端获得 SSH 公钥 为了使客户端可以向 Git 服务器提供 SSH 公钥,首先要确认客户端拥有公钥.SSH 的密钥存储在 ~/.ssh/ 目录下,下面我们查看一下这里面都有哪些文件: ...