前言

基于 uni-app 进行m端 app 开发的时候,碰上一个需求是将卡片弹窗生成图片,之前工作有用过 html2image 等插件,虽然简单便捷,但是经常会碰见一些奇奇怪怪的兼容性问题,因此此次需求采用手写 canvas 然后转成 base64 图片,杜绝一切 bug,直接无敌。

实现代码如下:

html:

页面添加一个 canvas 容器以及生成图片的 img 容器

<canvas canvas-id="myCanvas" id='cardCanvas'></canvas><image :src="base64" v-if="base64" class='cardImage' @longtap="saveImage()">
</image>

css:

没啥好说的,就是 canvas 和 img 的定位和宽高,隐藏 canvas,图片放置在页面中间

#cardCanvas {width: 654rpx;height: 400rpx;position: absolute;// top: -99999rpx;// left: -99999rpx;// z-index: 9999;
}.cardImage {width: 654rpx;height: 400rpx;// position: absolute;// top: 50%;// left: 50%;// transform: translate(-50%, -50%);top: 0;left: 0;
}

js:

data 里面为一些假数据和存放 base64 图片路径的变量(base64)

在 mounted 钩子中调用函数绘制 canvas

data() {return {showDiaCard: true,category: '服务类',amount: '10,200.00',cardNum: '0522 0522 0522 0522',base64: null}
},
mounted() {// 渲染 canvas this.renderCanvas();
},

methods 方法中共用到三个函数方法

渲染 canvas 函数

Tips: 因为是 m 端,所以考虑适配兼容问题,所有单位都乘以 w,w 为获取的设备宽度除以 750,以此达到类似于 rem, rpx 的适配兼容效果:

// canvas 单位换算为 rpx

const system = uni.getSystemInfoSync()
const w = system.windowWidth / 750

console.log(w)

// 渲染 canvas
renderCanvas() {let imgW, imgH;const query = uni.createSelectorQuery().in(this);// canvas 单位换算为 rpxconst system = uni.getSystemInfoSync()const w = system.windowWidth / 750console.log(w)// 获取canvasquery.select('#cardCanvas').boundingClientRect(data => {imgW = data.width;imgH = data.height;//绑定画布var ctx = uni.createCanvasContext('myCanvas');// 填充图片ctx.drawImage('https://doc.shoufusheji.com/img/temp/20221128/qlcu3_dia-card-bg.png', 0, 0,  imgW, imgH);// 画出 icon 图标ctx.drawImage('https://doc.shoufusheji.com/img/temp/20221205/siz7o_dia-card-icon.png', 32 * w, 48 * w, 40 * w, 40 * w);// 菜花卡类别ctx.font = "normal bold 34px PingFang SC-Bold"ctx.setFillStyle('#fff');ctx.setFontSize(34 * w);ctx.fillText('菜花卡-' + this.category, 88 * w, 80 * w);// 菜花卡金额ctx.font = "normal bold 48px Inter-Bold"ctx.setFillStyle('#fff');ctx.setFontSize(48 * w);ctx.fillText(this.amount, 32 * w, 224 * w);// 画出二维码this.drawRoundRect(ctx, 20 * w, 468 * w, 134 * w, 146 * w, 146 * w, "https://doc.shoufusheji.com/img/temp/20221128/loogd_dia-card-ewm.png")// 卡密ctx.font = "normal bold 28px Inter-Bold"ctx.setFillStyle('#fff');ctx.setFontSize(28 * w);ctx.fillText("卡密:" + this.cardNum, 32 * w, 374 * w);//输出到画布中ctx.draw();// 显示 loadinguni.showLoading({mask: true})// 不加延迟的话,base64有时候会赋予undefinedsetTimeout(() => {uni.canvasToTempFilePath({canvasId: 'myCanvas',success: (res) => {this.base64 = res.tempFilePath}})uni.hideLoading();}, 1200)}).exec();
},

保存 canvas 为 base64 图片函数

// 保存图片
saveImage() {uni.saveImageToPhotosAlbum({filePath: this.base64,success: (res) => {uni.showToast({title: '保存成功',})}})
},

因为二维码需要绘制圆角,所以加了个图片绘制圆角函数,在上面渲染 canvas 函数中有用到

// 二维码绘制圆角
/*** @param {Object} ctx: canvas实例* @param {Object} r: 圆弧的半径* @param {Object} x: 图片 x 轴坐标* @param {Object} y: 图片 y 轴坐标* @param {Object} w: 图片宽度* @param {Object} h: 图片高度* @param {Object} img: 图片路径*/
drawRoundRect(ctx, r, x, y, w, h, img) {ctx.save();if (w < 2 * r) r = w / 2;if (h < 2 * r) r = h / 2;ctx.beginPath();ctx.moveTo(x + r, y);ctx.arcTo(x + w, y, x + w, y + h, r);ctx.arcTo(x + w, y + h, x, y + h, r);ctx.arcTo(x, y + h, x, y, r);ctx.arcTo(x, y, x + w, y, r);ctx.closePath();ctx.clip();ctx.drawImage(img, x, y, w, h);ctx.restore(); // 返回上一状态
},

页面绘制 canvas 并转换成图片实现长按保存相关推荐

  1. vue 签署文件两张图合并成一张图 h5页面转换成图片并长按保存在本地

    在做让用户在页面签名并把当前页面保存为图片,附上完整代码 (直接复制代码,更改接口地址或删除接口逻辑可直接复用) **准备工作:安装   npm install vue-esign --save 全局 ...

  2. html页面转换成图片的三种方法——canvas、dom-to-image、html2canvas

    html页面转换成图片的三种方法--canvas.dom-to-image.html2canvas canvas绘制网络图片报错(跨域) 使用canvas将html页面转成图片 dom-to-imag ...

  3. 使用的是html5的canvas将文字转换成图片

    当前功能的运用场景是:用户需要传文件给他人,在用户选择文件之后需要显示一个文件图标和所选文件的名称. 当前代码部分是摘自网上,但是已经忘记在什么地方获取的,如有侵权联系小弟后自当删除. 注意:必须在h ...

  4. 使用html2canvas,将页面转换成图片的采坑记录(Web/Taro h5)

    使用html2canvas将页面转换成图片的采坑记录 "html2canvas": "^1.4.1","@tarojs/taro": &qu ...

  5. html2canvas将html代码生成canvas转换成图片,并且保存到本地

    html2canvas将html代码生成canvas转换成图片,并且保存到本地 html2canvas 将html转换成canvas展示 convertCanvasToImage 从canvas提取为 ...

  6. Android笔记:将布局转换成图片

    如题,需求就是把xml里面的布局转换成图片,然后保存下来,大家觉得特别简单吧,去问过好多人,也查了查很多app都有这么一个功能,当用户完成了app的某个任务时,产品希望用户点击分享的时候,能动态绘制出 ...

  7. JavaScript实现React实现网页转换成图片截屏下载

    最近有项目的需求需要把网站内HTML内容转换成图片保存下载,找了一圈发现一个不错的插件HTML-to-image,npm 包地址:Html-to-image NPM | npm.io,该插件的原理是: ...

  8. 微信小程序中base64转换成图片;uni-app小程序base64转图片;微信小程序base64文件转图片;微信小程序base64图片转图片

    将微信小程序的图片转成base64 点击此链接看另一篇 以下是将后端返回的base64转成图片: 方法1:使用微信小程序自带方法 //把base64转换成图片getBase64ImageUrl: (b ...

  9. php+打开图片二进制文件,php接收二进制文件转换成图片

    $GLOBALS['HTTP_RAW_POST_DATA'] 最近在做Flash在线裁剪图片 生成图片的东西. 通过Flash POST 图片的二进制数据给php,由php生成图片保存. 开始想到用$ ...

最新文章

  1. 设计模式(4)-序列生成器之单例模式
  2. 如何快速实现移动端短视频功能?
  3. apache日志记录格式LogFormat参数说明
  4. django第三天(路由基础和路由分配)
  5. 部署Dotnet Core应用到Kubernetes(一)
  6. Nmap命令:-sP和-sN的区别
  7. [深度学习] 深度可分离卷积
  8. 国内坐标转换常用投影EPSG
  9. 刘强东,一个农村孩子的自卑!
  10. HTML5期末大作业:仿悦世界游戏网站设计——仿悦世界游戏官网(6页) HTML+CSS+JavaScript web网页设计实例作业
  11. 花絮:用StyleGAN Encoder识别并重建国画和油画中的人脸
  12. node-red与西门子PLC通信
  13. 牛小刚的Spring自学笔记之IOC
  14. Transactional(事务)
  15. javascript实现无缝滚动
  16. 你是真的“C”——找单身狗~
  17. 从零玩转Node.js,助你打通前后端任督二脉
  18. BP神经网络的一些例子
  19. epic怎么添加本地游戏_Epic游戏商城本周免费游戏:无主之地 帅杰克合集
  20. 理解各种设计模式原则及区别丨浅谈Nginx中核心设计模式-责任链模式丨C++后端开发丨Linux服务器开发丨web服务器

热门文章

  1. 【Xshell】xshell本地指令以及常用命令大全
  2. Java设计模式(观察者模式)
  3. 台式计算机内存怎么查,怎么查询电脑内存的大小?怎样看?
  4. 最完整的php验证手机号码
  5. unity 制作 粒子 烟花
  6. 爬取寻梦环游记的评论生成词云
  7. Python的GUI界面
  8. 我的书架——一些关于书的拉杂胡说(转贴)
  9. nginx 反向代理报400错误
  10. 跑步戴哪款无线耳机好、跑步蓝牙耳机排名榜