需求

在开发过程中遇到这么一个需求,h5页面需要将一个html dom转化成图片,便于用户保存。

面向百度搜索第三方得 html2canvas 和 dom-to-image

两者在写这篇笔记之前在github上的星星数分别是

dom-to-image 4k ️

html2canvas 13.7k ️

两者都有尝试过,都有意想不到的bug,包括

  1. 部分手机有某些背景图片无法展示,为空白
  2. iphone8 plus ios 11中根本不调用这个转换方法,从而得不到想要的图片。

等等

自己动手

思路

利用canvas的toDataURL来拿到canvas转化的base64码,来替换img的url, 也可以把图片上传到公司的服务器上,得到图片的地址来进行下载,或作为参数来传递

那么canvas的绘制主要就是文本和图片的绘制,文本绘制相对简单,图片绘制有一些注意点。

canvas 初始化

由于最后生成的图片可能会模糊,可以尽量画大一点画布,可以按照设计图来

<canvas id="canvas" width="750" height="1164">
你的浏览器居然不支持Canvas?!赶快换一个吧!!
</canvas>
let c = document.getElementById("canvas");
let ctx = c.getContext("2d");

文本绘制

官方文档如图

详细文档请参考 canvas手册

代码示例

ctx.fillStyle = "#fff";
ctx.font = "32px PingFangSC-Regular";
ctx.textAlign = "left";
ctx.fillText("这是一些文字", 280, 755);

图片绘制

官方文档如图

详细文档请参考 canvas手册

注意事项

  1. 图片需要进行跨域处理,否则后期无法生成图片,也就是在img标签中增加crossOrigin属性,值为anonymous
const instBanner = document.getElementById("instBanner");
instBanner.crossOrigin = "anonymous";
  1. 需要等到图片加载完成再画到画布上,否则有可能没画上去
const posterBg = new Image();
posterBg.src = mainBg;
posterBg.onload = () => {
ctx.drawImage(posterBg, 0, 0, 750, 1164);
}

完整代码示例

const posterBg = new Image();
posterBg.src = 'https:....'; //这里是图片url
posterBg.crossOrigin = "anonymous";
posterBg.onload = () => {
ctx.drawImage(posterBg, 0, 0, 750, 1164);
}

生成图片

替换img src

let dataURL = c.toDataURL("image/png");
let canvasImg = document.getElementById("canvasImg");
canvas.src = dataURL;

上传服务器,得到img url(可作为参数,保存图片)

let dataURL = c.toDataURL("image/png");
function getImgUrl(dataURL){
//一些上传服务器的代码
return imgUrl
}
let imgUrl = getImgUrl();
let canvasImg = document.getElementById("canvasImg");
canvas.src = imgUrl;

最后奉上一些,常用的canvas处理方法

圆形图片的绘制

ctx.save();

ctx.beginPath(); //开始绘制
//先画个圆 前两个参数确定了圆心 (x,y) 坐标 第三个参数是圆的半径 四参数是绘图方向 默认是false,即顺时针
ctx.arc(60, 60, 30, 0 * Math.PI, 2 * Math.PI); ctx.clip();//画好了圆 剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内 这也是我们要save上下文的原因 ctx.drawImage('https:....', 30, 30, 60, 60); contex.restore(); //恢复之前保存的绘图上下文 恢复之前保存的绘图上下午即状态 还可以继续绘制

圆角矩形绘制


/**该方法用来绘制圆角矩形
*@param cxt:canvas的上下文环境
*@param x:左上角x轴坐标
*@param y:左上角y轴坐标
*@param width:矩形的宽度
*@param height:矩形的高度
*@param radius:圆的半径
*@param lineWidth:线条粗细
*@param strokeColor:线条颜色
**/
function strokeRoundRect(cxt,x,y,width,height,radius,/*optional*/lineWidth,/*optional*/strokeColor){
//圆的直径必然要小于矩形的宽高
if(2*radius>width || 2*radius>height){return false;} cxt.save();
cxt.translate(x,y);
//绘制圆角矩形的各个边
drawRoundRectPath(cxt,width,height,radius);
cxt.lineWidth = lineWidth||2;//若是给定了值就用给定的值否则给予默认值2
cxt.strokeStyle=strokeColor||"#000";
cxt.stroke();
cxt.restore();
} /**该方法用来绘制一个有填充色的圆角矩形
*@param cxt:canvas的上下文环境
*@param x:左上角x轴坐标
*@param y:左上角y轴坐标
*@param width:矩形的宽度
*@param height:矩形的高度
*@param radius:圆的半径
*@param fillColor:填充颜色
**/
function fillRoundRect(cxt,x,y,width,height,radius,/*optional*/fillColor){
//圆的直径必然要小于矩形的宽高
if(2*radius>width || 2*radius>height){return false;} cxt.save();
cxt.translate(x,y);
//绘制圆角矩形的各个边
drawRoundRectPath(cxt,width,height,radius);
cxt.fillStyle=fillColor||"#000";//若是给定了值就用给定的值否则给予默认值
cxt.fill();
cxt.restore();
} function drawRoundRectPath(cxt,width,height,radius){
cxt.beginPath(0);
//从右下角顺时针绘制,弧度从0到1/2PI
cxt.arc(width-radius,height-radius,radius,0,Math.PI/2); //矩形下边线
cxt.lineTo(radius,height); //左下角圆弧,弧度从1/2PI到PI
cxt.arc(radius,height-radius,radius,Math.PI/2,Math.PI); //矩形左边线
cxt.lineTo(0,radius); //左上角圆弧,弧度从PI到3/2PI
cxt.arc(radius,radius,radius,Math.PI,Math.PI*3/2); //上边线
cxt.lineTo(width-radius,0); //右上角圆弧
cxt.arc(width-radius,radius,radius,Math.PI*3/2,Math.PI*2); //右边线
cxt.lineTo(width,height-radius);
cxt.closePath();
}

» 点击阅读原文

html dom 转化成图片踩坑记(canvas toDataURL)的更多相关文章

  1. vue的html2canvas将dom转化为图片时踩得坑

    一.html2canvas中图片涉及跨域图片 应用场景:做个投票活动,将参赛者的信息转化成图片截图分享.用户上传图片上传到腾讯云cos桶中,html2canvas只能转换本地资源的图片,涉及跨域的图片 ...

  2. Vue + TypeScript + Element 搭建简洁时尚的博客网站及踩坑记

    前言 本文讲解如何在 Vue 项目中使用 TypeScript 来搭建并开发项目,并在此过程中踩过的坑 . TypeScript 具有类型系统,且是 JavaScript 的超集,TypeScript ...

  3. Hook踩坑记:React Hook react-unity-webgl

    自公司前后分离上手React以来,一个坑一个坑的踩,Class的全生命周期云里雾里,还么屡明白,就抱上了Hook的大腿不松手,确实爽到飞起.修改到Hook的过程基本比较顺畅,直接少了三分之一的代码,组 ...

  4. Spark踩坑记——Spark Streaming+Kafka

    [TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...

  5. 【踩坑记】从HybridApp到ReactNative

    前言 随着移动互联网的兴起,Webapp开始大行其道.大概在15年下半年的时候我接触到了HybridApp.因为当时还没毕业嘛,所以并不清楚自己未来的方向,所以就投入了HybridApp的怀抱. Hy ...

  6. Spark踩坑记——从RDD看集群调度

    [TOC] 前言 在Spark的使用中,性能的调优配置过程中,查阅了很多资料,之前自己总结过两篇小博文Spark踩坑记--初试和Spark踩坑记--数据库(Hbase+Mysql),第一篇概况的归纳了 ...

  7. vue踩坑记

    vue踩坑记 易错点 语法好难啊qwq 不要把'data'写成'date' 在v-html/v-bind中使用vue变量时不需要加变量名 在非vue事件中使用vue中变量时需要加变量名 正确 < ...

  8. Spark踩坑记:Spark Streaming+kafka应用及调优

    前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark streaming从k ...

  9. vue 使用html2canvas将DOM转化为图片

    一.前言 我发现将DOM转化为图片是一个非常常见的需求,而自己手动转是非常麻烦的,于是找到了html2canvas这个插件,既是用得比较多的也是维护得比较好的一个插件. 注意:版本比较多,这里介绍最新 ...

随机推荐

  1. c语言刷lleetcode记录

    155. 最小栈 笔记: 在push(压栈)的时候思路: typedef struct MinStack{ int data; struct MinStack *next; } MinStack; / ...

  2. DateTime TryParse方法,介绍

    1.与Date.Parse()方法的区别:Date.Parse(object o)方法接受一个object类型的参数,当参数为空或转换失败时会抛出异常DateTime.TryParse方法不会抛出异常 ...

  3. LeetCode-043-字符串相乘

    字符串相乘 题目描述:给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式. 示例说明请见LeetCode官网. 来源:力扣( ...

  4. 【Java分享客栈】一个包装过简历的新同事写完微信支付引起事故后果断离职了

    前言 挺长时间没发文了,因为公司有一个紧急项目要赶进度,加班如吃饭喝水,久违的进入到码农的状态. 之所以抽空来发个文,是这个项目才刚上线,时间不长却因为一位新同事的代码引起了生产环境的事故,造成了一批 ...

  5. Redis环境搭建-Linux单机

    一.准备Linux 可以买云服务器,也可以用虚拟机,我用的是虚拟机Oracle VM VirtualBox 二.编译环境 1.检查linux下是否安装环境 yum list installed | g ...

  6. LGP6788题解

    太慢了!太慢了!我的替身 [The World] 是最强的替身! \(O(n^{\frac 2 3})\) 的解法!不清楚用 sbt 能不能更快一些,可能会吧.灵感来源于BZOJ4176,同时也可看到 ...

  7. 什么是SaaS?

    SaaS的定义 SaaS,是Software-as-a-Service的缩写名称,意思为软件即服务,即通过网络提供软件服务. SaaS平台供应商将应用软件统一部署在自己的服务器上,客户可以根据工作实际 ...

  8. 切换阿里巴巴开源镜像站镜像——Kali镜像

    参考链接: 阿里巴巴开源镜像站 镜像切换参考链接:阿里云Kali镜像源 安装Kali Linux系统参考链接:使用VMware虚拟机安装kali Linux 一.打开终端命令窗口 二.进入source ...

  9. ARM中断与架构知识 精简知识点

    目录 一.ARM系统的异常与中断 二.CPU模式与寄存器 1.ARM CPU模式 2.ARM CPU state,两种指令集 3.ARM CPU寄存器: 引申介绍一下存储空间中的数据存放 4.ARM三 ...

  10. 7月3日 Django 头像预览、用户上传文件操作、logging、debug_tool_bar

    1. 注册功能 1. 头像预览 //头像预览 $('#id_avatar').change(function () { console.log(this.files[0]) //找到选中的头像文件 v ...