最新时时彩平台演示 中新时时彩要不要交税 新时时彩三星组六技巧 最新时时彩源码修改 新时时彩遗漏走势图 新时时彩预测方法 新时时彩计算器 新时时彩开奖皇冠网址 新时时彩组三怎么玩 最新时时彩后四稳赚 新时时彩官方开奖网站 新时时彩人工计划 新时时彩开奖漏洞 新时时彩最长遗漏 新时时彩中奖顺序 360新时时彩技巧-轴承资讯 新时时彩停售 最新时时彩杀号高手 新时时彩三星走势图 玩新时时彩有什么技巧 新时时彩3星和尾走势 新时时彩后一公式 重新时时彩网站 新时时彩遗漏统计软件 吉林新时时彩走势图 新时时彩中奖怎么查 新时时彩是什么地方 新时时彩中奖怎么查 新时时彩下载手机版下载 新时时彩贴吧 最新时时彩计划软件 大赢家新时时彩 新时时彩注册送彩金 新时时彩组选投注技巧 新时时彩走势图 新时时彩万能5码 新时时彩模拟 新疆新时时彩往期开奖号码 新时时彩的玩法 新时时彩稳赚计划 最新时时彩70注 新时时彩返奖率 新时时彩杀号定胆360 新时时彩后二杀号 新时时彩振幅走势 最新时时彩教程 新时时彩后台软件 新时时彩几点开始 新时时彩日赚几百 最新时时彩注册送20
用户
 ?#19968;?#23494;码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,登录网站

小程序社区 首页 资讯/观点 查看内容

小程序的一些总结:画canvas和内嵌webview

Rolan 2019-1-2 00:04

做了一些小程序项目,着重记录一下小程序内嵌webview以及小程序画canvas遇到的一些坑。小程序画canvas的坑第一个坑,canvas无法画base64格式的二维码。需求:前端将一些动态数据,以及动态生成的小程序二维码图片用c ...

做了一些小程序项目,着重记录一下小程序内嵌webview以及小程序画canvas遇到的一些坑。

小程序画canvas的坑

第一个坑,canvas无法画base64格式的二维码。

需求:前端将一些动态数据,以及动态生成的小程序二维码图片用canvas画出来,最后生成且可保存的一张图片。

前端显示二维码图片一般有两种方法:

1.后端调用微信api,直接返回的二进制数据到前端会乱码,一般后端先将二进制数据转为base64格式数据,然后返回到前端。若是当普通的图片显示只需要设置图片:

<image src="data:image/png;base64,图片base64数据"></image> 

2.后台在服务器上将二进制数据保存为一张图片,然后返回给前端一个二维码的绝对路径。

若后台因为各种原因不好实现第2种,且第1种方法微信官方的回复是:真机上小程序的canvas无法绘制base64格式的图片,难道就无法在canvas里绘制二维码了?

此时还有第3种方法就是利用小程序的文件系统 FileSystemManager.writeFile() Api,将base64数据的图片写入到本地,之后去操作这个本地的图片。

第一步创建写入文件的文件夹

mkdir() {
    return new Promise((resolve, reject) => {
        this.fs.access({ // 先判断有没有resource目录
            path: `${wx.env.USER_DATA_PATH}/resource`, // wx.env.USER_DATA_PATH获取本地文件路径,开发者工具是:"http://usr",真机是:"wxfile://usr"
            success: (res) => {
                console.log('access:',res)
                resolve(res)
            },
            fail: (err) => {
                console.error('access:',err)
                // 不存在,创建一个文件夹
                this.fs.mkdir({
                    dirPath: `${wx.env.USER_DATA_PATH}/resource`,
                    success: (res) => {
                        console.log('mkdir:', res)
                        resolve(res)
                    }, 
                    fail: (err) => {
                        console.error(err)
                        reject(res)
                    }
                })
            }
        })
    })
}
复制代码

第二步将base64图片写入创建的文件夹

writeBase64Image() {
    return this.mkdir().then(() => {
        return new Promise((resolve, reject) => {
            this.fs.writeFile({
                filePath: `${wx.env.USER_DATA_PATH}/resource/${this.openId}.png`, // 可以用openId来命名此图片
                data: this.base64Code, //后台返回的base64编码的图片,不需要加'data:image/png;base64,'
                encoding: 'base64', // 存的文件类型的选择base64
                success:(res) => {
                    console.log('writeFile:', res)
                    resolve(res) 
                },
                fail:(err) => {
                    console.error('writeFile:',err)
                    reject(err)
                }
            })
        })
    })
}
复制代码

第三步获得图片的缓存临时地址

如果是绝对路径的网络图片,绘制图片前需要将图片缓存到本地,如果是写入的本地文件则可以直接绘制。

getImageSrc(src) {
        return new Promise((resolve, reject) => {
            // 如果是本地图片则直接返回;如果是网络路径的图片,则先缓存到本地,wx.getImageInfo或者wx.downloadFile获得本地临时路径
            !src.includes('https') ? resolve(src) :
                wx.getImageInfo({
                    src,
                    success(res) {
                        resolve(res) // res.path:返回的临时路径
                    },
                    fail(err) {
                        reject(err)
                    }
                })
        })
    },
复制代码

之后通过获得临时文件路径用canvas绘制图片。

以前遇到这个问题,绝对大多数的开发者都是采用后端返回图片绝对路径给前端,而第3种则可以前端去做保存图片的事,减少很多后端服务器的操作。

第二个坑,一些android机生成的canvas图片,文字样式混乱

尤其是华为P20,哈哈真真是bug神机了。 小程序的canvas组件是原生组件,原生组件脱离在 WebView 渲染流程外,对于频繁绘制而机型?#21482;?#21046;?#19979;保?#23601;很容易样式错乱,解决方法就是生成图片时给一定时间的延迟。

// 在绘制canvas的回调里,导出生成的图片,如果是andriod则延迟500ms生成。如果500ms还会有样式问题,那就增加延迟时间。
ctx.draw(() => {
    // some code
    isAndroid && setTimeout(() => {
        wx.canvasToTempFilePath({
            // some code
        })
    },500)
    // some code
})
复制代码

第三个坑,在ios上只能绘制显示的canvas元素,若设置wx:if或hidden,在初始化时必须是显示的。

如果你想绘制一个隐藏的canvas元素(hidden=true),将这个canvas转为图片保存,android下正常,ios下则不会绘制canvas。

其他的一些问题

用css3的旋转动画,在真机上没效果,最好使用wx.createAnimation代替;

canvas元素不能添加css动画,会非常的卡,即使使用wx.createAnimation代替,也是很卡。这个官方文档也有提到。

小程序内嵌webview的一些坑

第一个坑,判断是否在小程序环境内

如果app的首页以及一些其他页面是服务端渲染,那么官方的提供的方法,并不一定能判断准确,尤其在android下。

如果想通过,navigator.userAgent里的miniprogram?#22336;?#20018;判断小程序,我劝你还是放弃吧....,真机下miniprogram?#22336;?#20018;时有时无,官方的回复永远都是这是最近出现的bug,会在后续版本修复......

// 在服务端渲染的页面下,下面的方法无法保证准确的判断,尤其在andriod下
function ready() {
  console.log(window.__wxjs_environment === 'miniprogram') // true
}
if (!window.WeixinJSBridge || !WeixinJSBridge.invoke) {
  document.addEventListener('WeixinJSBridgeReady', ready, false)
} else {
  ready()
}
// 或者
wx.miniProgram.getEnv(function (res) {
  console.log(res.miniprogram) // true
})
复制代码

解决:1.将小程序标识拼在web-view的src属性上

<web-view src="https://XXXX.com?isMiniProgram=1"></web-view>
复制代码

第二个坑,微信浏览器和小程序会共用localStorage

微信浏览器内访问的是正常的H5,小程序内访问的是内嵌的webview下的H5,很多时候需要这俩个环境各有不同的数据缓存,区分功能。 而微信在某次更新后就开始共用微信浏览器和小程序的storage了,也是哭哭啊。。。。

解决:如果只是一个页面打开的后续页面间互相传递数据,那么可以使用sessionStorage去临时缓存数据而不用localStorage。

鲜花
鲜花
鸡蛋
鸡蛋
分享至 : QQ空间
收藏
原作者: 我是好好 来自: 掘金
新时时彩软件