html2canvas

  • (一)官网下载安装
  • (二)基础用法
  • (三)生成海报问题
    • canvas高分屏下的模糊问题
    • html2canvas图片模糊问题
    • canvas图片getImageData,toDataURL跨域问题
      • 1) 首先,图片服务器需要配置Access-Control-Allow-Origin
      • 2) canvas图片getImageData cross-origin跨域问题
    • 图片加载导致海报生成不了
    • ios的兼容性问题
    • ios 生成图片时显示时不显的,大图几乎不显示

(一)官网下载安装

下载:https://html2canvas.hertzen.com/
vue 安装:npm install html2canvas

(二)基础用法

以vue为例子

<div @click="handlePoster()" class="btn">生成海报</div>
<div id="weeklyPoster" ref="weeklyPoster" class="poster"><h1>poster content</h1><img class="poster__logo" src="./assets/img/share-logo.png" alt="" crossOrigin="anonymous">
</div>
<div v-if="sharePoster.show" class="poster__save"><img class="poster__logo" :src="sharePoster.url" alt="">
</div>
<script>
import html2canvas from 'html2canvas';
data () {return {sharePoster: { // 海报内容show: false,url: '',height: 0,width: 0},}
}
methods: {handlePoster() {this.getWeeklyWxCode(()=>{ // 向获取二维码接口发起请求if(!this.sharePoster.url) { // 第一次生成海报// 提示海报生成中...this.$nextTick(() => {setTimeout(()=>{html2canvas(document.querySelector('#myPoster'), {scrollX: 0,scrollY: 0,allowTaint: true,useCORS: true,backgroundColor: null // 解决生成的图片有白边}).then((canvas) => {// 隐藏提示海报生成中let dataURL = canvas.toDataURL('image/jpeg');this.sharePoster.url = dataURL;this.sharePoster.show = true;this.sharePoster.height = canvas.height / 100; // 单位remthis.sharePoster.width = canvas.width / 100;});},600)});} else {this.sharePoster.show = true;}})},
}
</script>

(三)生成海报问题

canvas高分屏下的模糊问题

介绍:
开发手机 canvas 应用,在高分屏下,尤其是手持设备,如搭载高分屏的手机平板等,其显示效果会变得模糊,带给用户的体验很不好。

问题分析:

解决方案:

  1. 首先我们计算 webkitBackingStorePixelRatio / devicePixelRatio 的比值,这里为了方便称之为倍率 ratio
  2. 把 canvas 的 width 和 height 设置为 ratio 倍,这样浏览器便会按照 ratio * ratio 倍像素去渲染该 canvas
  3. 我们在用 CSS 把 canvas 的大小强制再调节为原始大小
  4. 使用 canvas 画布 context 的 scale 方法把渲染区域扩大 ratio 倍以填充屏幕 ( 后面会有解释 )
// 获取 ratio 比例
function getPixelRatio(context) {// 获取 canvas 的 backingStorePixelRatio 值var backingStore = context.backingStorePixelRatio ||context.webkitBackingStorePixelRatio ||context.mozBackingStorePixelRatio ||context.msBackingStorePixelRatio ||context.oBackingStorePixelRatio ||context.backingStorePixelRatio || 1;// 若 devicePixelRatio 不存在,默认为 1return (window.devicePixelRatio || 1) / backingStore;
}
// 调整 canvas
function adjustCanvas(canvas, context) {var ratio = getPixelRatio(context);// 获取 canvas 的原始大小var oldWidth = canvas.width;var oldHeight = canvas.height;// 按照比例放大 canvascanvas.width = oldWidth * ratio;canvas.height = oldHeight * ratio;// 用 css 将 canvas 再调整成原来大小canvas.style.width = oldWidth + 'px';canvas.style.height = oldHeight + 'px';// 按照比率把 context 再缩放回来context.scale(ratio, ratio);
}// 调用
// 此处默认你的 canvas 已经是你要的实际尺寸
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
adjustCanvas(canvas, ctx);

转载链接

html2canvas图片模糊问题

问题: html2canvas 渲染背景图片 background-image 会不清晰。
解决方法:使用 Img 标签。

canvas图片getImageData,toDataURL跨域问题

1) 首先,图片服务器需要配置Access-Control-Allow-Origin

一般团队都会有一个专门域名放置静态资源,例如腾讯是gtimg.com,百度是bdimg.com;或者很多团队使用的是腾讯云或者阿里云的服务。
而主页面所在域名往往不一样,当需要需要对canvas图片进行getImageData()或toDataURL()操作的时候,跨域问题就出来了,而且跨域问题还不止一层。
eg:PHP添加响应头信息

// *通配符表示允许任意域名
header("Access-Control-Allow-Origin: *");// 指定域名
header("Access-Control-Allow-Origin: www.zhangxinxu.com");

此时,Chrome浏览器就不会有Access-Control-Allow-Origin相关的错误信息了,但是,还会有其他的跨域错误信息。

2) canvas图片getImageData cross-origin跨域问题

对于跨域的图片,只要能够在网页中正常显示出来,就可以使用canvas的drawImage() API绘制出来。但是如果你想更进一步,通过getImageData()方法获取图片的完整的像素信息,则多半会出错。

var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');var img = new Image();
img.onload = function () {context.drawImage(this, 0, 0);context.getImageData(0, 0, this.width, this.height);
};
img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';

解决方案:可以试试crossOrigin属性

1)HTML5中,有些元素提供了支持CORS(Cross-Origin Resource Sharing)(跨域资源共享)的属性,这些元素包括<img>,<video>,<script>等。

<img src="img/png" alt=""  crossorigin="anonymous">
  1. 增加一个img.crossOrigin = ''即可,虽然JS代码这里设置的是空字符串,实际上起作用的属性值是anonymous。
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');var img = new Image();
img.crossOrigin = '';
img.onload = function () {context.drawImage(this, 0, 0);context.getImageData(0, 0, this.width, this.height);
};
img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';

或者这样写:

drawCanvas() {if (!this.isLoadImg) {Promise.all([new Promise((resolve, reject) => {this.saveImgObj = new Image();this.saveImgObj.onload = () => {resolve();};this.saveImgObj.src = this.saveImg;this.saveImgObj.setAttribute("crossOrigin","Anonymous");}),new Promise((resolve, reject) => {this.codeImgObj = new Image();this.codeImgObj.onload = () => {resolve();};this.codeImgObj.src = this.codeImg;this.codeImgObj.setAttribute("crossOrigin","Anonymous");})]).then(() => {this.isLoadImg = true;this.drawHandler();this.posterImg = this.$refs.canvasPad.toDataURL();});} else {this.drawHandler();this.posterImg = this.$refs.canvasPad.toDataURL();}
},
drawHandler () {let canvas= this.$refs.canvasPad;let ctx= cav.getContext("2d");adjustCanvas(canvas, ctx);
}

注意:
crossOrigin兼容性:IE11+(IE Edge),Safari,Chrome,Firefox浏览器均支持,IE9和IE10会报SecurityError安全错误

图片加载导致海报生成不了

用原生的方法等待所有图片加载完成后,在执行绘制
解决方法:

function imgLoad(imgArr, ck) { let imgs = imgArr Promise.all(imgs.map((src, index) => { return new Promise((resolve, reject) => { let img = new Image() img.onload = () => { resolve(img)}img.onerror = () => { reject(src, index) } img.crossOrigin = 'anonymous' img.src = src }) })).then(arr => { ck(arr) }).catch(e => { console.log(e) })
},

ios的兼容性问题

html2canvas: "1.0.0-rc. 5"版本在运行在苹果13.4 系统 iphone7 iphonex iPhone11下都生成不了的时候,安卓没问题,微信内置浏览器不行(真机);
请看看html2canvas的版本,只有1.0.0-rc.4这个版本是可行的,如果你指定下载这个版本在package.json中看到是 ^ 1.0.0-rc.4,则不一定就是1.0.0-rc.4版本,它是指1.0.0-rc.4以上的版本,把^去掉再重新安装依赖就可以了

解决办法:
卸载npm uninstall html2canvas
重新npm i html2canvas@1.0.0-rc.4;
package.json中看到是 ^ 1.0.0-rc.4,^去掉再重新安装依赖

ios 生成图片时显示时不显的,大图几乎不显示

猜测是图片渲染的原因,为了确保能够生成图片
html2canvas库的工作原理:需要我们先提供一段DOM节点,然后它再读取并解析这一段DOM节点生成canvas对象。如果DOM节点中已经使用了<img>标签的话,它也会解析这个<img>标签的src属性,然后重新创建一个Image对象,给它添加crossOrigin="anonymous"属性后尝试以跨域的方式重新读取图片数据。需要注意的是,一般CDN上的图片都是带有缓存响应头并且会在浏览器端缓存的,而且缓存的不仅仅是图片数据,还有HTTP响应头。所以问题的根本原因我们就找到了,当html2canvas尝试以跨域的方式去读取图片数据时,它读取到的是浏览器的缓存数据,而且因为我们没有给DOM节点中的<img>标签添加crossOrigin="anonymous"属性,所以缓存数据是不带Access-Control-Allow-Origin响应头的,进而导致html2canvas库读取到的图片数据污染了生成的canvas对象,最终致使canvas导出数据报错
解决方法:
给DOM节点中的每一个<img>标签都加上crossOrigin="anonymous"属性就可以了

https://segmentfault.com/a/1190000017086056
https://blog.csdn.net/qq_41227106/article/details/106764421

html2canvas生成海报的各种问题相关推荐

  1. 前端生成海报图:html2canvas 生成海报图/网页html转图片

    html2canvas 生成海报图 <html><head> <title>生成海报图Demo</title> </head><bod ...

  2. h5 uniapp html2canvas生成海报,保存到本地功能实现;

    html2canvas生成海报,保存到本地功能实现 1. 在开发过程中我们将HTML2canvas封装成一个组件,通过prop传递ID参数 2. 组件的使用,伪代码不要直接复制uniapp语法 3. ...

  3. uniapp中,H5端使用html2canvas生成海报

    项目中H5需要实现canvas生成海报,于是用了html2canvas,中间各种BUG,其中跨域问题一直没有处理好,后台服务器设置了支持跨域也不可以.最后解决方案是,把网络图片全部转成base64展示 ...

  4. js常用插件(三)之html2canvas生成海报

    js常用插件之html2canvas截图生成海报 欢迎点击: 个人官网博客 先引用cdn或自己下载下来 <script src="https://cdn.bootcdn.net/aja ...

  5. php html生成海报jpg,html2canvas 生成海报

    应用场景 移动端H5 分享海报 安装html2canvas 插件 npm install --save html2canvas Vue中使用 // 在Vue页面中引入 import html2canv ...

  6. html2canvas手机黑屏,html2canvas 生成海报图 开发中遇到的问题

    ios里,生成的图片不显示 canvas.toDataURL('image/jpeg', 1.0) 使用image/jpeg格式,在指定图片格式为 image/jpeg 或 image/webp的情况 ...

  7. 用vue PHP实现海报设计功能,有关vue html2canvas生成海报功能的实现

    这是我第一篇简书文章,作为一名前端,而且现在电商比较流行的情况下 很多电商公众号商城都用到了生成海报图片长按保存到相册然后可以转发给好友或者分享到朋友圈  在Web前端中,生成图片非Canvas莫属 ...

  8. uni-app 使用html2canvas生成海报,一步到位

    ps: 如果图片存在跨域问题,请现在后台配置解决图片跨域问题; app不能操作dom,所以app使用renderJS处理 示例在最后 步骤分为三步 1.安装html2canvas npm i html ...

  9. Vue + html2canvas 生成海报

    Html: <div class="record"><!-- 如果没有生成过海报,则先拼接成海报样式展示 --> <div v-show=" ...

最新文章

  1. DCMTK:DSRNumericMeasurementValue类的测试程序
  2. Android笔记(六十七) 自定义控件
  3. P4331-[BalticOI2004]Sequence数字序列【左偏树】
  4. vantUI 弹出层(轻提示)案例 - 踩坑篇
  5. Android笔记 codeUI与html UI
  6. 【高并发】JUC中的循环栅栏CyclicBarrier的6种使用场景
  7. 海报设计素材|中国风的插画设计,国画浓抹中国色彩
  8. 微课|中学生可以这样学Python(2.3.3节):filter()函数
  9. javascript学习笔记之入门
  10. OO第一单元总结——多项式求导
  11. MySQL核心之分组函数(sum() avg() min() max() distinct count() )
  12. 疯狂java讲义第6版_疯狂java讲义第6版
  13. 为什么说甲骨文裁员也属无奈之举?
  14. DEEPIN 设置U盘启动
  15. 坐标反算计算起始方位角_平面坐标反算(测量上常用于计算坐标方位角)
  16. AD19画原理图和PCB注意事项和步骤(主要为PCB和总结注意事项)
  17. C++ 计算多边形的面积,计算IOU
  18. HTML如何实现多个空格
  19. 修改google搜索引擎非hk方法
  20. 订单23系统服务器,死亡搁浅寻物系统服务器任务内容介绍-死亡搁浅寻物系统服务器任务流程详情_牛游戏网...

热门文章

  1. ZooKeeper典型应用场
  2. Sybase用户登录以后的自动运行脚本
  3. myeclipse8.5安装反编译工具
  4. plotly django_使用Plotly为Django HTML页面进行漂亮的可视化
  5. 结构化数据建模——titanic数据集的模型建立和训练(Pytorch版)
  6. leetcode 19. 删除链表的倒数第N个节点(双指针)
  7. leetcode542. 01 矩阵(bfs/dp)
  8. 时间序列预测 预测时间段_应用时间序列预测:美国住宅
  9. 美剧迷失_迷失(机器)翻译
  10. 特征工程之特征选择_特征工程与特征选择