对H5保持敬畏之心

前言

时隔1年多我又来写前端笔记了,这篇记录一下最近一个H5遇到的坑和一些问题的解决方法。

好用的库

PhotoClip:一款移动端手势驱动的裁图插件,很灵活,基本满足图片裁剪的所有需求。

#####Q:长按屏幕保存海报

参照之前做过的项目,生成海报的流程大致是:

  • 按钮 — 触发事件,通过canvas作画生成海报
  • 弹窗弹出画报,用户可以点击下载or关闭

微信中的h5页面,用户长按页面中的某张图片,底部会弹出保存图片,收藏等按钮的弹窗,这是一个微信自发行为,开发者监听不到任何事件,也就没有时机去画海报及之后的一系列操作。(ps:如果要禁止长按图片弹出操作层,可以在img上设置pointer-events: none)

解决思路:

  1. 进入页面canvas作画,用canvas的toDataURL()方法转为base64编码

    2. js生成img标签,插入到页面最高层,透明度设为0 (用户看到的是展示页,长按的是海报页)
    

始料未及的bug

需求:用户点击选择图片按钮,手机弹出从相册选择照片拍照的弹窗,用户选择完照片显示到操作区,进行放大缩小裁剪等操作

bug:使用原生input标签,ios手机及正常的安卓手机都没问题,但是客户的华为p20手机出现了选择照片无反应,google一圈没找到解决办法,焦头烂额。

1
2
3
<input type="file" id="file" multiple accept="image/*" capture="camera">
- 安卓手机同时有 multiple 及 capture="camera"属性,拍照及相册选项共存
- ios手机上出现capture属性直接调用拍照

解决: 曲线救国,调用微信JS-SDK的wx.chooseImage及wx.getLocalImgData接口

  • wx.chooseImage:返回选定照片的本地ID列表

  • wx.getLocalImgData: 通过本地id,转为base64(这里安卓和ios还有坑)

  • 通过七牛将base64转为url,传给PhotoClip实例,进行下一步操作。

    1
    2
    3
    4
    5
    6
    7
    8
    let imageBase64 = ''
    if (localData.indexOf('data:image') === 0) {
    // 苹果的直接赋值,默认生成'data:image/jpeg;base64,'的头部拼接
    imageBase64 = localData
    } else {
    // 此处是安卓中的唯一得坑!在拼接前需要对localData进行换行符的全局替换
    imageBase64 = 'data:image/jpeg;base64,' + localData.replace(/\n/g, '')
    }

最后上项目二维码,有兴趣的可以一玩