html2canvas
canvas 无法调用 toDataURL
详情描述
canvas 设置了 allowTaint
- ps:
- allowTaint:Whether to allow cross-origin images to taint the canvas
允许绘制跨域图片, 但是不允许调用 canvas.toDataURL
解决方案
如果需要得到 Base64 的话, 不适合开启 allowTaint
1. 禁用 allowTaint
2. 解决跨域图片, 参考一下个问题
canvas 无法加载跨域图片
详情描述
canvas 绘制的时候需要 load 跨域图片 (比如 cdn, 或者其他域的图片)
解决方案
在 img 标签上面增加 crossorigin="anonymous"
config 设置 useCORS: true
注意: base64 的图片, 不要添加 crossorigin="anonymous"
iOS 上面偶发截图不全
详情描述
在 iOS 上面, 特别是 iphonex 容易出现偶发截图不全 (某张图片丢失)
猜测是图片已经加载完毕, 但是还未渲染完毕, 就开始转 base64, 导致截图不全 (iOS 特有...)
解决方案
查看 html2canvas 日志, 发现有一个
有一个图片的 Finished loading 钩子
在这里做了一个 sleep..
图片丢失状态 (不一定丢失下面你这种, 还有可能是背景)
正常截图
pad 宽屏适配
详情描述
在宽度大于 540 的机型上面, rem 适配失败, 定位不准
解决方案
适配的方案是采用的 flexible.JS + px2rem, 通过观察 flexible 源码得知
这一段代码限定住了 HTML 的元素 fontSize, 因此将 if 语句中的 540 改为 width 可以完成简单的适配
微信 / 支付宝的 sdk 差异
需要注意的
1. Wechat 可以长按识别 base64 的图片, 但是其他 webview 不行
2. 微信不支持 canvas 跨域加载本地的 base64 图片, 支付宝可以
3. 微信 / 支付宝 sdk 选择照片返回的是 App 内的图片地址, 如果想获得图片上传, 需要自己转 base64, 微信的转出 Base64 需要自己添加 data:image/jpeg;base64, 头部信息
分离 Promise 的 res, 不在 Promise 的构造函数中 res/rej 一个 Promise 对象, 封装一个获得 file 的举例
- class myPormise {
- constructor() {
- this.init();
- }
- res(value) {
- this.$r(value);
- }
- init() {
- console.log("初始化 promise");
- this.p = new Promise(res => {
- this.$r = res;
- });
- }
- }
- export class GetInputFile {
- constructor(type) {
- this.inputEle = document.createElement("input");
- this.inputEle.setAttribute("accept", "image/*");
- this.inputEle.setAttribute("type", "file");
- if (type == "camera") {
- // 如果是 camera 则直接调用照相机
- this.inputEle.setAttribute("capture", "camera");
- }
- this.inputEle.addEventListener("change", this.uploadFile.bind(this));
- //document.append(this.inputEle);
- this.avatarFile = new myPormise();
- Windows.inputEle = this.inputEle;
- console.log("创建 GetInputFile", this.inputEle);
- }
- click() {
- this.inputEle.click();
- return this;
- }
- uploadFile(e) {
- let files = e.target.files || e.dataTransfer.files;
- if (!files.length) {
- console.log("not image");
- return;
- }
- this.avatarFile.res(files[0]);
- }
- getfile() {
- return this.avatarFile.p;
- }
- destroyed() {
- for (let i in this) {
- if (i !== "destroyed") this[i] = null;
- }
- }
- }
- export function chooseImageH5(sourceType) {
- const getInputFile = new GetInputFile(sourceType[0]);
- return new Promise(res => {
- console.log("other 选择图片");
- getInputFile
- .click()
- .getfile()
- .then(e => {
- res(e);
- });
- });
- }
来源: https://juejin.im/post/5c80e15af265da2d9e17818c