最近在做一个项目,是在mobile网页上生成海报,海报中有用户圆形头像、图标、图片、文字等信息,相对来说也比较复杂的一个海报。

问题:

一、画圆形头像时就遇到了圆形头像时被切割。

问题描述:在用canvas画圆形头像时,向画布右侧移动时,右边半个圆被切割了。

原因:给头像的画布位置有限,移出了画布的区域自然就被切割了,一开始用的是fill()去填充,总是会被切割。

改之前的代码:

img.onload = function () {let width = 1.6 * textPx;let height = 1.6 * textPx;let min = Math.min(width, height)let circle = {x: Math.floor(min / 2),y: Math.floor(min / 2),r: Math.floor(min / 2)}ctx.fillStyle = ctx.createPattern(img, 'no-repeat')ctx.beginPath()//开始路径画圆,剪切处理console.log("r:=====", circle.r)ctx.moveTo(0, 0)ctx.arc(circle.x, circle.y, circle.r, 0, Math.PI * 2);//恢复状态ctx.fill();//用这段代码去画圆形头像总是被切割}

改之后的代码:

img.onload = function () {console.log("timeout doing 小主播头像")ctx.save()let width = 118;let height = 118;let min = Math.min(width, height)let circle = {x: Math.floor(min / 2),y: Math.floor(min / 2),r: Math.floor(min / 2)}ctx.fillStyle = ctx.createPattern(img, 'no-repeat')ctx.beginPath()//开始路径画圆,剪切处理ctx.arc(circle.x + 129, circle.y + 87, circle.r, 0, Math.PI * 2, false);ctx.clip()ctx.drawImage(img, 129, 87, 2 * circle.r, 2 * circle.r)//改成这种方式可以画圆形头像,且不被切割console.log("dataURL00000:===", canvas.toDataURL('image/jpg'))canvas2imgWrap.style.display = 'block'_this.dataImgSrc = canvas.toDataURL('image/png')if (clientWidth > 375) {dataImgWrap.style.marginLeft = 40 + 'px'}dataImgWrap.setAttribute('width', canvasWidth + 'px');dataImgWrap.setAttribute('height', canvasHeight + 'px');canvas2imgWrap.setAttribute('width', '100%');canvas2imgWrap.setAttribute('height', '100%');canvas.style.display = 'none'}

二、海报背景图总是会覆盖在文字上。

问题描述:因为图片加载需要时间,文字所需的时间比图片短,导致文字先画在了画布上,背景图后画,这就导致了背景图盖住了文字和其它的图片,导致只能看到部分绘画的图片。

解决方法是写了一个回调,在背景图画完之后再画其它的内容。因为其它内容需要覆盖在背景图片上。

代码如下:

createCanvas() {let _this = this;let canvas = document.getElementById("canvas_wrap")let dataImgWrap = document.getElementById("dataImgWrap")let canvas2imgWrap = document.getElementById("canvas2img")canvas.style.display = "block"let ctx = canvas.getContext("2d");let clientWidth = document.documentElement.clientWidth;let textPx = clientWidth * 180 / 750//根据设计图中的canvas画布的占比进行设置let canvasWidth = 375;let canvasHeight = 636console.log("canvasWidth:", canvasWidth, 'canvasHeight:===', canvasHeight)canvas.setAttribute('width', canvasWidth + 'px');canvas.setAttribute('height', canvasHeight + 'px');/* ctx.fillStyle = '#fff';ctx.fillRect(0, 0, canvasWidth, canvasHeight); *///canvas背景图function drawBg(callback) {let bgImg = new Image();bgImg.onload = function () {// resolve(bgImg)let bg = ctx.createPattern(bgImg, 'no-repeat');ctx.fillStyle = bg;ctx.fillRect(0, 0, canvasWidth, canvasHeight)console.log("timeout forward")}bgImg.src = canvasBg;setTimeout(function () {(callback && typeof (callback) === "function") && callback();}, 1500)console.log("timeout after")}drawBg(function () {console.log("timeout doing")let img = new Image();img.setAttribute('crossOrigin', 'anonymous');// img.src = _this.detailData.anchorHeadImg + '?' + (+new Date())img.src = localAvatar;  //为什么用本地图片后canvas背景图不显示???img.onload = function () {console.log("timeout doing 小主播头像")ctx.save()let width = 118;let height = 118;let min = Math.min(width, height)let circle = {x: Math.floor(min / 2),y: Math.floor(min / 2),r: Math.floor(min / 2)}ctx.fillStyle = ctx.createPattern(img, 'no-repeat')ctx.beginPath()//开始路径画圆,剪切处理console.log("r:=====", circle.r)ctx.arc(circle.x + 129, circle.y + 87, circle.r, 0, Math.PI * 2, false);ctx.clip()ctx.drawImage(img, 129, 87, 2 * circle.r, 2 * circle.r)/* ctx.fillStyle = "#fff"ctx.arc(circle.x + 110, circle.y + 90, circle.r + 10, 0, Math.PI * 2, false); */console.log("dataURL00000:===", canvas.toDataURL('image/jpg'))canvas2imgWrap.style.display = 'block'_this.dataImgSrc = canvas.toDataURL('image/png')if (clientWidth > 375) {dataImgWrap.style.marginLeft = 40 + 'px'// canvas2imgWrap.style.marginLeft = 7 + 'px'}dataImgWrap.setAttribute('width', canvasWidth + 'px');dataImgWrap.setAttribute('height', canvasHeight + 'px');canvas2imgWrap.setAttribute('width', '100%');canvas2imgWrap.setAttribute('height', '100%');canvas.style.display = 'none'}//作品数ctx.font = "bold 16px microsoft";ctx.fillStyle = "#333";ctx.fillText(_this.detailData.workCount + "个", 298, 40)ctx.font = "16px microsoft";ctx.fillStyle = "#666";ctx.fillText("作品数", 298, 65)ctx.font = "bold 16px microsoft";ctx.fillStyle = "#333";ctx.fillText(_this.detailData.workReadAmountCount, 298, 90)ctx.font = "16px microsoft";ctx.fillStyle = "#666";ctx.fillText("人气", 298, 115)// ctx.font = 0.4 * textPx;ctx.font = "bold 20px microsoft";ctx.fillStyle = "#333";ctx.fillText("小少年", 157, 250)//认证小主播let authImg = new Image();authImg.src = _this.detailData.anchorIsAuthed === 1 ? posterAuth : '';authImg.onload = function () {ctx.drawImage(authImg, 137, 260, 100, 24)console.log("timeout doing 认证小主播")}//小主播简介ctx.font = "12px microsoft"ctx.fillStyle = "#fff";// ctx.fillText(_this.detailData.anchorItdc, 165, 100)let t = "这里是小主播简介,这里是小主播。简介这里是小主播简介这里是,真的是这样的吗?哈哈哈哈!!小主播简介这里是小主播简介这里是小主播简介这里是小主播简介这里是小主播简介这里是小主播简介这里是小主播简介这里是小主播简介"// let t = _this.detailData.anchorItdc_this.drawText(ctx, t, 30, 330, 330)//二维码// console.log("url:=======", this.$nuxt.$route.path)let erweimaImg = new Image()erweimaImg.setAttribute('crossOrigin', 'anonymous');let erweima_URL = config.erweima_url + _this.$nuxt.$route.patherweimaImg.onload = function () {let erweimaPhoto = document.getElementById("canvasImg")ctx.drawImage(erweimaPhoto, 37, 505, 68, 68);// console.log("dataURL11111:===", canvas.toDataURL('image/png'))}console.log("erweimaurl:=======", erweima_URL)erweimaImg.src = erweima_URL + '?' + (+new Date())//小主播养成计划图片let titleImg = new Image();titleImg.src = posterTitle;titleImg.onload = function () {ctx.drawImage(titleImg, 125, 517, 170, 17)console.log("timeout doing 养成计划")}ctx.font = "14px microsoft";ctx.fillStyle = "#333";ctx.fillText("长按识别二维码", 125, 550)//中少网图片let logoImg = new Image();logoImg.src = posterLogo;logoImg.onload = function () {ctx.drawImage(logoImg, 97, 610, 180, 21)console.log("timeout doing 中少网logo")}})},drawText(context, t, x, y, w) {var chr = t.split("");var temp = "";var row = [];context.font = "14px microsoft";context.fillStyle = "#fff";context.textBaseline = "middle";for (var a = 0; a < chr.length; a++) {if (context.measureText(temp).width < w && context.measureText(temp + (chr[a])).width <= w) {temp += chr[a];}//context.measureText(text).width  测量文本text的宽度else {row.push(temp);temp = chr[a];}}row.push(temp);/* for (var b = 0; b < row.length; b++) {context.fillText(row[b], x, y + (b + 1) * 24);//字体20,间隔24。类似行高} */// 只显示2行,加...for (var b = 0; b < 4; b++) {var str = row[b];if (b == 3) {str = str.substring(0, str.length - 1) + '...';}context.fillText(str, x, y + (b + 1) * 24);}},

之所以没用promise,是因为本人的promise不是特别熟,看来必须把promise给学精了,加油!!!!

最终效果:

参考链接:

https://blog.csdn.net/u012011360/article/details/80169529

https://blog.csdn.net/fxss5201/article/details/79691923

https://www.cnblogs.com/padding1015/p/9717845.html

https://www.w3school.com.cn/tags/html_ref_canvas.asp

canvas画图及圆形的头像相关推荐

  1. 微信小程序使用canvas画图并保存到手机相册踩坑总结

    接到个项目做微信小程序的,需要将手机中的页面保存到手机相册中,效果图如下 首先想到的就是利用canvas画图然后在保存到相册,看起来很简单网上也有很多例子,但都不完整,很多网友分享的都在半吊子工程,只 ...

  2. HTML5 canvas画图

    HTML5 canvas画图 HTML5 <canvas> 标签用于绘制图像(通过脚本,通常是 JavaScript). 不过,<canvas> 元素本身并没有绘制能力(它仅仅 ...

  3. 今天的码农女孩做了关于svg画图和canvas画图 2022/1/18

    svg和canvas画图 svg和canvas区别: svg:不依赖分辨率,不能嵌入图片和文字,不能通过事件操作,但是可以通过css执行动画,矢量图形,放大缩小不失真,渲染能力强,适合做图标,地图,动 ...

  4. 可扩展面向对象的canvas画图程序

    面向对象的canvas画图程序 项目简介 整个项目分为两大部分 场景 场景负责canvas控制,事件监听,动画处理 精灵 精灵则指的是每一种可以绘制的canvas元素 Demo演示地址 Demo为最新 ...

  5. 微信小程序之canvas画图

    开题 前几天接到个需求,长按图片保存到相册,该图片上有用户头像和昵称以及对应的二维码:那这就不能直接当作图片来操作了,要先把整体图片画出来:我当时用的是canvas.效果图如下: canvas dra ...

  6. php绘图和canvas,html5 canvas画图实例用法汇总

    HTML5 canvas画图HTML5 标签用于绘制图像(通过脚本,通常是 JavaScript).不过, 元素本身并没有绘制能力(它仅仅是图形的容器) - 您必须使用脚本来完成实际的绘图任务.get ...

  7. html5 canvas 画图移动端出现锯齿毛边的解决方法

    html5 canvas 画图移动端出现锯齿毛边的解决方法 参考文章: (1)html5 canvas 画图移动端出现锯齿毛边的解决方法 (2)https://www.cnblogs.com/dear ...

  8. 小程序---canvas画图,生成分享图片,画图文字换行

    小程序目前只支持转发,不支持分享朋友圈,为了能实现分享,很多线上小程序通过生成分享图片,保存到相册来给用户增加分享的可能. 具体思路及简要代码如下: 一:canvas画图drawCanvas:func ...

  9. 解决canvas画图模糊的问题

    canvas 画图经常发现他是模糊的.解决这个问题主要从两个方面下手. 改变canvas渲染的像素 情况:画1像素的线条看起来模糊不清,好像更宽的样子. 解决方案 var ctx = canvas.g ...

  10. [转]html5 Canvas画图教程(1)—画图的基本常识

    今天看到一个讲Canvas的教程,很通俗移动,所以转载了下. 虽然大家都称Canvas为html5的新标签,看起来好像Canvas属于html语言的新知识,但其实Canvas画图是通过javascri ...

最新文章

  1. (转)小小的研究了一下linux下的”注册表“ gconf-editor
  2. Ubuntu实时监测系统性能工具
  3. const,readonly 这些你真的懂吗? 也许会被面试到哦。。。
  4. 遇java.lang.OutOfMemoryError: PermGen space之解决方案
  5. SQL数据库学习之路(五)
  6. 简单易懂的多线程(通过实现Runnable接口实现多线程)
  7. 计划学习研究模板引擎。学习stringtemplate先
  8. BZOJ 3910 并查集+线段树合并
  9. CSharpGL(36)通用的非托管数组排序方法
  10. 关于抢红包的_关于抢红包的话题800字作文
  11. ICIP2012 关于Saliency Map的文章
  12. 单片机读tf卡c语言程序,单片机读写U盘闪盘超精简C源程序
  13. 前端跨域请求get_解决前端跨域问题方案汇总
  14. JavaScript快速入门(三)——JavaScript语句
  15. linux 查看 shell进程,Linux之shell 和进程
  16. 微信小程序:全新圣诞节头像框制作生成微信小程序源码下载支持多模板
  17. NH7020固件网口分析与platoSDR固件对比
  18. python拟合线性函数_Python线性拟合实现函数与用法示例
  19. 20220721挨揍内容
  20. 误删注册表导致键盘不可用,NumLock一直亮着

热门文章

  1. 纯js前端导出Excel表格(Excel科学计数法问题)
  2. 简单的html练习:实现超好看唯美浪漫的文字边框卡片
  3. 基于PHP、MySql的宿舍管理系统
  4. python中while用法
  5. win7怎么把计算机图标下的箭头掉,win7系统桌面图标小箭头去掉的操作方法
  6. 【团队技术知识分享 一】技术分享规范指南
  7. 2021年中国原油产量、需求量及石油原油行业发展趋势分析[图]
  8. go php 框架,go框架 - Go语言中文网 - Golang中文社区
  9. 显示计算机程序的表格如何打开,如何设置打开excel表格的一个窗口显示多标签...
  10. CPU0704报错处理