页面绘制 canvas 并转换成图片实现长按保存
前言
基于 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 / 750console.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 并转换成图片实现长按保存相关推荐
- vue 签署文件两张图合并成一张图 h5页面转换成图片并长按保存在本地
在做让用户在页面签名并把当前页面保存为图片,附上完整代码 (直接复制代码,更改接口地址或删除接口逻辑可直接复用) **准备工作:安装 npm install vue-esign --save 全局 ...
- html页面转换成图片的三种方法——canvas、dom-to-image、html2canvas
html页面转换成图片的三种方法--canvas.dom-to-image.html2canvas canvas绘制网络图片报错(跨域) 使用canvas将html页面转成图片 dom-to-imag ...
- 使用的是html5的canvas将文字转换成图片
当前功能的运用场景是:用户需要传文件给他人,在用户选择文件之后需要显示一个文件图标和所选文件的名称. 当前代码部分是摘自网上,但是已经忘记在什么地方获取的,如有侵权联系小弟后自当删除. 注意:必须在h ...
- 使用html2canvas,将页面转换成图片的采坑记录(Web/Taro h5)
使用html2canvas将页面转换成图片的采坑记录 "html2canvas": "^1.4.1","@tarojs/taro": &qu ...
- html2canvas将html代码生成canvas转换成图片,并且保存到本地
html2canvas将html代码生成canvas转换成图片,并且保存到本地 html2canvas 将html转换成canvas展示 convertCanvasToImage 从canvas提取为 ...
- Android笔记:将布局转换成图片
如题,需求就是把xml里面的布局转换成图片,然后保存下来,大家觉得特别简单吧,去问过好多人,也查了查很多app都有这么一个功能,当用户完成了app的某个任务时,产品希望用户点击分享的时候,能动态绘制出 ...
- JavaScript实现React实现网页转换成图片截屏下载
最近有项目的需求需要把网站内HTML内容转换成图片保存下载,找了一圈发现一个不错的插件HTML-to-image,npm 包地址:Html-to-image NPM | npm.io,该插件的原理是: ...
- 微信小程序中base64转换成图片;uni-app小程序base64转图片;微信小程序base64文件转图片;微信小程序base64图片转图片
将微信小程序的图片转成base64 点击此链接看另一篇 以下是将后端返回的base64转成图片: 方法1:使用微信小程序自带方法 //把base64转换成图片getBase64ImageUrl: (b ...
- php+打开图片二进制文件,php接收二进制文件转换成图片
$GLOBALS['HTTP_RAW_POST_DATA'] 最近在做Flash在线裁剪图片 生成图片的东西. 通过Flash POST 图片的二进制数据给php,由php生成图片保存. 开始想到用$ ...
最新文章
- 设计模式(4)-序列生成器之单例模式
- 如何快速实现移动端短视频功能?
- apache日志记录格式LogFormat参数说明
- django第三天(路由基础和路由分配)
- 部署Dotnet Core应用到Kubernetes(一)
- Nmap命令:-sP和-sN的区别
- [深度学习] 深度可分离卷积
- 国内坐标转换常用投影EPSG
- 刘强东,一个农村孩子的自卑!
- HTML5期末大作业:仿悦世界游戏网站设计——仿悦世界游戏官网(6页) HTML+CSS+JavaScript web网页设计实例作业
- 花絮:用StyleGAN Encoder识别并重建国画和油画中的人脸
- node-red与西门子PLC通信
- 牛小刚的Spring自学笔记之IOC
- Transactional(事务)
- javascript实现无缝滚动
- 你是真的“C”——找单身狗~
- 从零玩转Node.js,助你打通前后端任督二脉
- BP神经网络的一些例子
- epic怎么添加本地游戏_Epic游戏商城本周免费游戏:无主之地 帅杰克合集
- 理解各种设计模式原则及区别丨浅谈Nginx中核心设计模式-责任链模式丨C++后端开发丨Linux服务器开发丨web服务器