如何优雅的使用canvas:通过li-canvas轻松实现绘制单图、多图、圆角图,绘制单行、多行、竖向文字,保存图片,下载图片等
Html5新增的canvas是个强大的功能, 估计大家平时都会用到,只是频率不高,偶尔用它合成图片,但是如果不进行封装的话,代码会很乱,所以对canvas常用的画图、绘制文字、保存功能进行了封装,目前还比较满意,能够快速完成canvas绘图任务,从容应对需求变更,只需进行简单配置更改即可。
先看一个简单的案例,假如要合成这张图片,其中背景图是一部分,有个标题,还有个简介,合成之后下载为图片
实现代码如下
... <script src="../dist/li-canvas.js"></script> //引入封装后的js文件 ... <canvas id="test" width="1563" height="1180"></canvas> ... <script> var canvas=new LiCanvas('test') //添加绘制图片任务 canvas.addDrawImageTask({ src:"http://www.***.com/bg.png",//图片的url地址 x:0,//绘制起始位置左上角的x坐标 y:0,//绘制起始位置左上角的y坐标 width:1563,//图片绘制宽度 height:1180,//图片绘制高度 borderRadius:0 //图片圆角半径 }) //添加绘制文字任务 canvas.addDrawTextTask(['【企服观察】美团上市后首份季报:B端成新增长点,出行业务仍拖累财报',{ text:"美团第三季度营业收入191亿元,同比增长97%;毛利总额46亿元,同比增长33.2%。", fontSize:48, color:'666666', fontWeight:500, }],{ x:110, y:496, width:1340, fontSize:54, fontWeight:'bolder', fontFamily:"PingFangSC-Regular,'Microsoft YaHei',SimSun,Arial,'Helvetica Neue',sans-serif", lineHeight:70, color:'#1a1a1a', marginBottom:40 }) //开始绘制 canvas.draw(()=>{ //绘制完成下载 canvas.saveToPng("test") }) </script>
怎么样,是不是很简单,绘制图片只需要指定图片的url和起始位置坐标、宽高即可,绘制文字则需要设置起始位置、字体大小、行高、段间距等即可,下载也很简单只需要一行代码。
有兴趣可以访问github:点击访问
npm安装
npm install --save li-canvas
下载js文件
通过github下载,然后调用即可
<script src="dist/li-canvas.js"></script>
使用li-canvas时需要先实例化对象,new LiCanvas(canvas_id,options),传入canvas的id,options选填,可以设置canvas背景和默认文字样式等
... <script src="../dist/li-canvas.js"></script> ... <canvas id="test" width="1563" height="1180"></canvas> ... <script> var canvas=new LiCanvas('test') </script> ...
option是一个对象,可以传入以下值
width、height:即canvas的宽高,也可以通过html设置canvas的宽高,<canvas width="1563" height="1180"></canvas>
backgroundColor:canvas的背景色,如:'red','#00ff00',实例化之后并不会立即绘制背景,而是添加到一个任务队列,所有绘制操作都在调用draw()方法时执行,后面介绍
backgroundImage:canvas背景图片的url地址
backgroundRepeat:canvas背景图片的平铺模式,可选值有四种"repeat | repeat-x | repeat-y | no-repeat",默认为repeat
fontStyle:默认的文字样式,也是一个对象,可选值如下
fontStyle:{ x:0, //文字起始位置左上角坐标x,默认0 y:0, //文字起始位置左上角坐标y,默认0 fontSize:14, //字体大小,默认14,单位px fontStyle:'normal', //可能的值,默认normal,可选的值:normal | italic | oblique fontWeight:'normal', //同css的font-weight 如normal bold 500 600 fontFamily:"PingFangSC-Regular", //字体 lineHeight:20, //行高 color:'black', //颜色,如"black",”#00ff00“,默认black marginBottom:10, //段落之间的间距,默认10,单位px textDirection:'horizontal', //文字方向,横排显示 或 竖排显示,默认横排 ”horizontal“,可选值horizontal | vertical rowDirection:'ltr', //段落方向,仅当textDirection为vertical时有效,当文字采取竖向排版时,指定段落是从左到右还是从右到做,默认"ltr",即left to right,可选值ltr | rtl },
绘制单张图片:
调用addDrawImageTask(image)添加一个绘图任务,其中参数image是一个对象,我们只需指明图片的url、绘制起始点坐标、绘制的宽高、圆角半径即可,可选参数为
src:图片的url地址
x:图片在canvas画布上的左上角x坐标
y:图片在canvas画布上的左上角y坐标
width:图片绘制宽度
height:图片绘制高度
borderRadius:图片圆角半径
调用addDrawImageTask(image)时,并没有立即绘制图片,而是添加了一个绘图任务,只有调用draw(callback)时,才执行绘图任务,绘图完成后调用callback回调函数
为什么这么做呢?因为图片绘制的时候需要先下载图片,这是个异步操作,所以先添加到任务列表,调用draw()的时候再按照任务添加顺序依次执行,任务全部执行完成后调用回调函数,回调函数中,我们一般获取图片数据或者保存下载图片
var bg={ src:document.getElementById('img').src, //src有两种:1.读取页面中的图片数据 2.http/https形式的url地址 x:0,//左上角的x坐标 y:0,//左上角的y坐标 width:1563,//图片绘制宽度 height:1180,//图片绘制高度 borderRadius:0 //图片圆角半径 } var canvas=new LiCanvas('test') canvas.addDrawImageTask(bg) //添加绘图任务,并没有立即进行绘图 canvas.draw(()=>{ console.log("绘制完成") })
绘制圆角或者圆形图片就非常简单了,我们只需要设置圆角半径borderRadius即可,如果图片宽高相等,borderRadius大于等于宽高的一半,不就是圆形图片了嘛
绘制多张图片
很简单多次调用addDrawImageTask(image)就可以实现多图绘制,也可以把image设置为一个数组
var imgs=[ { src:"http://*****.com/***.png", x:0, y:0, width:100, height:100, borderRadius:0 }, { src:"http://*****.com/***.png", x:0, y:0, width:100, height:100, borderRadius:0 } ] var canvas=new LiCanvas('test') canvas.addDrawImageTask(imgs) //直接传入一个数组也可以实现多图绘制 canvas.draw(()=>{ console.log("绘制完成") })
是不是so easy
绘制单段文字
调用addDrawTextTask(text,fontStyle)可以完成文字绘制,只需指明要绘制的文字和文字样式即可,超出fontStyle.width会自动进行换行,这里的fontStyle会覆盖初始化时的fontStyle
text:要绘制的文字
fontStyle:文字样式,是个对象,可选值同初始化时的fontStyle,即
//可设置的fontStyle { x:0, //文字起始位置左上角坐标x,默认0 y:0, //文字起始位置左上角坐标y,默认0 width: //文字一行的宽度,超出会自动进行换行 fontSize:14, //字体大小,默认14,单位px fontStyle:'normal', //可能的值,默认normal,可选的值:normal | italic | oblique fontWeight:'normal', //同css的font-weight 如normal bold 500 600 fontFamily:"PingFangSC-Regular", //字体 lineHeight:20, //行高 color:'black', //颜色,如"black",”#00ff00“,默认black marginBottom:10, //段落之间的间距,默认10,单位px textDirection:'horizontal', //文字方向,横排显示 或 竖排显示,默认横排 ”horizontal“,可选值horizontal | vertical rowDirection:'ltr', //段落方向,仅当textDirection为vertical时有效,当文字采取竖向排版时,指定段落是从左到右还是从右到做,默认"ltr",即left to right,可选值ltr | rtl }
var canvas=new LiCanvas('test') canvas.addDrawTextTask("要绘制的文字",{ x:110, y:496, width:1340, fontSize:54, fontWeight:'bolder', fontFamily:"PingFangSC-Regular,'Microsoft YaHei',SimSun,Arial,'Helvetica Neue',sans-serif", lineHeight:70, color:'#1a1a1a', marginBottom:40 }) canvas.draw(()=>{ console.log("绘制完成") })
绘制多段文字
像上面那样多调用几次即可,但是可能会略微繁琐,因为样式基本上都是一样的,而且有的文字是多行的,我们也不方便指明第二段的起始坐标
只需将text改为数组即可,可以共用fontStyle,而且后续的起始位置会根据行高和段间距自动计算
var canvas=new LiCanvas('test') canvas.addDrawTextTask(["要绘制的文字段落1","要绘制的文字段落2"],{ x:110, y:496, width:1340, fontSize:54, fontWeight:'bolder', fontFamily:"PingFangSC-Regular,'Microsoft YaHei',SimSun,Arial,'Helvetica Neue',sans-serif", lineHeight:70, color:'#1a1a1a', marginBottom:40 }) canvas.draw(()=>{ console.log("绘制完成") })
这样就能方便的绘制多段文字了,但是你可能又说,第二段我想要设置不同的文字大小,很简单,把文本改成一个对象即可,通过text属性指明文本内容,也可以指定其特有的fontStyle属性
var canvas=new LiCanvas('test') canvas.addDrawTextTask(["要绘制的文字段落1",{ text:"要绘制的段落文字2", fontSize:60 //...还可以添加更多fontStyle }],{ x:110, y:496, width:1340, }) canvas.draw(()=>{ console.log("绘制完成") })
可以看到绘制文字很灵活,支持各种不同的情况
上面调用addDrawImageTask、addDrawTextTask时,都是把绘图任务添加到任务队列,只有显示调用draw(callback)时才开始真正的绘制,绘制完成会调用回调函数callback,可以在callback中获取canvas的图片数据或者下载图片
将canvas下载成图片非常简单,支持三种
下载为png图片:saveToPng("文件名")
下载为jpeg图片:saveToJpeg("文件名")
下载为gif图片:saveToGif("文件名")
var bg={ src:"http://***.jpg", x:0, y:0, width:1563, height:1180, borderRadius:0 } var canvas=new LiCanvas('test') canvas.addDrawImageTask(bg) canvas.draw(()=>{ canvas.saveToPng("li-canvas") }) </script>
获取图片数据
有时候,我们并不想下载图片,比如在微信浏览器中,我们其实是希望用户长按图片保存,此时,我们希望canvas合成的图片数据,插入到img的src中
调用:getImageData()可以获取合成的图片数据
var bg={ src:"http://***.jpg", x:0, y:0, width:1563, height:1180, borderRadius:0 } var canvas=new LiCanvas('test') canvas.addDrawImageTask(bg) canvas.draw(()=>{ var imageData=canvas.getImageData() document.getElementById('img').src=imageData })
到这里就基本介绍完了,如果觉得还不错,可以访问github,有问题一起交流,如果能给我github点个赞,那就更感谢啦
github地址:https://github.com/501351981/li-canvas
点赞(2)