博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
html dom 转化成图片踩坑记(canvas toDataURL)
阅读量:6337 次
发布时间:2019-06-22

本文共 3725 字,大约阅读时间需要 12 分钟。

需求

在开发过程中遇到这么一个需求,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?!赶快换一个吧!!
let c = document.getElementById("canvas");let ctx = c.getContext("2d");

文本绘制

官方文档如图

图片描述

详细文档请参考

代码示例

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

图片绘制

官方文档如图

图片描述

详细文档请参考

注意事项

  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:....'; //这里是图片urlposterBg.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();  }

»

转载地址:http://iaaoa.baihongyu.com/

你可能感兴趣的文章
html img Src base64 图片显示
查看>>
[Spring学习笔记 7 ] Spring中的数据库支持 RowMapper,JdbcDaoSupport 和 事务处理Transaction...
查看>>
FFMPEG中关于ts流的时长估计的实现(转)
查看>>
Java第三次作业
查看>>
【HDOJ 3652】B-number
查看>>
android代码混淆笔记
查看>>
Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) C. String Reconstruction 并查集
查看>>
BMP文件的读取与显示
查看>>
Flash文字效果
查看>>
各种排序算法总结篇(高速/堆/希尔/归并)
查看>>
使用c#訪问Access数据库时,提示找不到可安装的 ISAM
查看>>
Highcharts X轴纵向显示
查看>>
windows 注册表讲解
查看>>
【算法】论平衡二叉树(AVL)的正确种植方法
查看>>
基于DDD的现代ASP.NET开发框架--ABP系列之1、ABP总体介绍
查看>>
react 从零开始搭建开发环境
查看>>
scala recursive value x$5 needs type
查看>>
ps -ef |grep 输出的具体含义
查看>>
markdown编辑
查看>>
ASCII 在线转换器
查看>>