uniapp 使用canvas 画海报,有手粘贴即可用(拆成组件了,看后面)

1.直接使用
html部分
<view ="doposter">下载海报</view>
<canvas canvas-id="myCanvas" type='2d' style="width: 370px; height: 550px;opcity:0;position: fixed;z-index:-1;" id="myCanvas" />
js 部分
drawBackground() {const canvasId = 'myCanvas'const ctx = uni.createCanvasContext(canvasId, this)const title = this.titleconst goodsCover = this.selcetShareImgUrl // 分享商品图片 需要换成自己的产品图片const goodsTitle = this.goods.name // 商品名称const goodsPrice = '¥ '+this.goods.original_priceconst des1 = '① 长按识别二维码'const des2 = '② 查看商品详情'const qrcode = this.goods.share.code //二维码地址 需要换成自己的二维码// 绘制背景图ctx.setFillStyle('#fff')ctx.fillRect(0, 0, 370, 550)// 字体颜色ctx.setFontSize(17)ctx.setFillStyle('#111')ctx.fillText(title, 50, 39.9)ctx.fillText(title, 49.9, 40)ctx.fillText(title, 50,40)ctx.fillText(title, 50, 40.1)ctx.fillText(title, 50.1, 40.1)// 商品名称 且拦截页面文字长度let titleGoods = this.goods.name.split('').length <= 20 ? this.goods.name : this.goods.name.substring(0,18)+' ...'ctx.setFontSize(16)ctx.setFillStyle('#111')ctx.fillText(titleGoods , 30 , 420)// 商品价格ctx.setFontSize(18)ctx.setFillStyle('#f36d00')ctx.fillText(goodsPrice, 29.9, 450)ctx.fillText(goodsPrice, 30,450)ctx.fillText(goodsPrice, 30, 450.1)ctx.fillText(goodsPrice, 30.1, 450)// 二维码描述ctx.setFontSize(13)ctx.setFillStyle('#999')ctx.fillText(des1, 30, 490)ctx.setFontSize(13)ctx.setFillStyle('#999')ctx.fillText(des2, 30, 520)uni.downloadFile({url:goodsCover,success: (res) => {// 商品图片ctx.drawImage(res.tempFilePath, 30, 70, 310, 310)// 二维码ctx.drawImage(qrcode, 240, 420, 110, 110)ctx.draw(false, () => {uni.canvasToTempFilePath({canvasId: canvasId,success: (res) => {console.log('临时图片路径:', res.tempFilePath);uni.saveImageToPhotosAlbum({filePath: res.tempFilePath,success: () => {uni.hideLoading()uni.showModal({title: '提示',content: ' 图片保存成功',showCancel: false,confirmText: '知道了',confirmColor: '#f36d00',success: res => {uni.navigateBack()}})}})},fail: (error) => {console.error('转化图片失败:', error);}},this)});}})},async doposter() {uni.showLoading({title: '正在生成海报'});await this.drawBackground();},
2.拆分成组件方便使用组件
<template><view><canvas canvas-id="myCanvas" type='2d' style="width: 370px; height: 550px; opacity:0;position: fixed;z-index:-1;" id="myCanvas" /></view>
</template><script>export default {name:"shareQrcode",data() {return {canvasId:'myCanvas',canvasImgPath :''};},props:{shareInfo:{type:Object,default:() => {return{bgColor : '#fff',title : '看到这个第一眼就想分享给你',goodsCover : 'http://storage.zh.shangkelian.cn/images/2022/01/07/08e732962fc55a2a196f193c94c22cf9.png', // 换自己图片goodsTitle : '大菠萝大菠萝大菠萝蜜菠萝蜜大菠萝大菠萝大菠萝蜜菠萝蜜', // 商品名称goodsPrice : '¥ 123',des1 : '① 长按识别二维码',des2 : '② 查看商品详情',qrcode : require('@/static/ewm.png'), //二维码地址}}}},methods:{drawBackground() {const canvasId = this.canvasIdconst ctx = uni.createCanvasContext(canvasId, this)const bgColor = this.shareInfo.bgColorconst title = this.shareInfo.titleconst goodsCover = this.shareInfo.goodsCoverconst goodsTitle = this.shareInfo.goodsTitleconst goodsPrice = this.shareInfo.goodsPriceconst des1 = this.shareInfo.des1const des2 = this.shareInfo.des2const qrcode = this.shareInfo.qrcode// 绘制背景图ctx.setFillStyle(bgColor)ctx.fillRect(0, 0, 370, 550)// 字体颜色ctx.setFontSize(17)ctx.setFillStyle('#111')ctx.fillText(title, 50, 39.9)ctx.fillText(title, 49.9, 40)ctx.fillText(title, 50,40)ctx.fillText(title, 50, 40.1)ctx.fillText(title, 50.1, 40.1)// 商品名称let titleGoods = goodsTitle.split('').length <= 20 ? goodsTitle : goodsTitle.substring(0,18)+' ...'ctx.setFontSize(16)ctx.setFillStyle('#111')ctx.fillText(titleGoods , 30 , 420)// 商品价格ctx.setFontSize(18)ctx.setFillStyle('#f36d00')ctx.fillText(goodsPrice, 29.9, 450)ctx.fillText(goodsPrice, 30,450)ctx.fillText(goodsPrice, 30, 450.1)ctx.fillText(goodsPrice, 30.1, 450)// 二维码描述ctx.setFontSize(13)ctx.setFillStyle('#999')ctx.fillText(des1, 30, 490)ctx.setFontSize(13)ctx.setFillStyle('#999')ctx.fillText(des2, 30, 520)uni.downloadFile({url:goodsCover,success: (res) => {// 商品图片ctx.drawImage(res.tempFilePath, 30, 70, 310, 310)// 二维码ctx.drawImage(qrcode, 250, 440, 90, 90)// #ifdef MP-WEIXINconsole.log('...........downloadFile............')wx.showModal({title:'作者友情提示',content:'小程序端生成二维码功能暂未完善,作者会尽快完成的!',showCancel:false,confirmText:'我已知道',confirmColor:'green'})uni.hideLoading()// 保存海报 // uni.canvasToTempFilePath({// canvasId: canvasId,// success: (res) => {// console.log(res)// this.canvasImgPath = res.tempFilePath// // this.save()// },// fail: (error) => {// console.error('转化图片失败:', error)// }// },this)return// #endif// app 和 h5 调用这个方法ctx.draw(false, () => {uni.canvasToTempFilePath({canvasId: canvasId,success: (res) => {this.canvasImgPath = res.tempFilePaththis.save()},fail: (error) => {console.error('转化图片失败:', error)}},this)})}})},// 生成本地海报async doposter() {uni.showLoading({title: '正在生成海报'});await this.drawBackground()},// 获取权限( 只适用于小程序)saveAlbum(){wx.hideLoading()//获取权限保存相册uni.getSetting({//获取用户的当前设置success:(res)=> {console.log(res.authSetting['scope.writePhotosAlbum'])if(res.authSetting['scope.writePhotosAlbum']){//验证用户是否授权可以访问相册this.save();}else{uni.authorize({//如果没有授权,向用户发起请求scope: 'scope.writePhotosAlbum',success:()=> {this.save();},fail:()=>{uni.showToast({title:"请打开保存相册权限,再点击保存相册分享",icon:"none",duration:3000});setTimeout(()=>{uni.openSetting({//调起客户端小程序设置界面,让用户开启访问相册success:(res2)=> {// console.log(res2.authSetting)}});},3000);}})}},fail: (error) => {console.log(error)}})},// 保存海报save(){// #ifdef APP uni.saveImageToPhotosAlbum({filePath: this.canvasImgPath,success: () => {uni.hideLoading()uni.showModal({title: '提示',content: ' 图片保存成功',showCancel: false,confirmText: '知道了',confirmColor: '#f36d00',success: res => {uni.navigateBack()}})}})// #endif// #ifdef H5uni.hideLoading()var oA = document.createElement("a");oA.download = ''; // 设置下载的文件名,默认是'下载'oA.href = this.canvasImgPath;document.body.appendChild(oA);oA.click();oA.remove(); // 下载之后把创建的元素删除// #endif// #ifdef MP-WEIXINconsole.log('wx',this.canvasImgPath)// uni.saveImageToPhotosAlbum({// filePath: this.canvasImgPath,// success: () => {// uni.hideLoading()// uni.showModal({// title: '提示',// content: ' 图片保存成功',// showCancel: false,// confirmText: '知道了',// confirmColor: '#f36d00',// success: res => {// uni.navigateBack()// }// })// }// })// #endif}}}
</script><style></style>
父组件中引用
<template><view><shareQrcode ref="shareQrcode" :shareInfo="shareInfo"/><button type="primary" ="$refs.shareQrcode.doposter()">二维码生成图片</button> </view>
</template><script>import shareQrcode from '@/components/share-qrcode.vue'export default {data() {return {shareInfo:{// 背景色bgColor : '#fff',// 标题title : '看到他的第一时间就忍不住分享给你',// 商品图goodsCover : 'http://storage.zh.shangkelian.cn/images/2022/01/07/08e732962fc55a2a196f193c94c22cf9.png', // 商品名称goodsTitle : '大菠萝大菠萝大菠萝蜜菠萝蜜大菠萝大菠萝大菠萝蜜菠萝蜜', // 商品价格goodsPrice : '¥ 123', // 二维码描述des1 : '① 长按识别二维码', // 二维码描述des2 : '② 查看商品详情', //二维码地址qrcode : require('@/static/ewm.png'), }}},components:{shareQrcode},}
</script><style>
</style>相关文章:
uniapp 使用canvas 画海报,有手粘贴即可用(拆成组件了,看后面)
1.直接使用 html部分 <view click"doposter">下载海报</view> <canvas canvas-id"myCanvas" type2d style"width: 370px; height: 550px;opcity:0;position: fixed;z-index:-1;" id"myCanvas" />js 部分 drawBac…...
Amazon Bedrock 的微调和持续预训练功能允许用户使用私有数据定制模型
今天我很高兴地宣布,您现在可以在 Amazon Bedrock 中使用自己的数据,安全并私密地定制基础模型(FMs),按照您所在领域、企业和用例的特定要求构建应用程序。借助定制模型,您可以创建独特的用户体验ÿ…...
Pyecharts绘制多种炫酷气泡图
Pyecharts绘制多种炫酷气泡图 引言 数据可视化是数据分析中不可或缺的一环,而Pyecharts作为一款基于Echarts的Python图表库,提供了丰富的图表类型,其中气泡图是一种常用于展示三维数据的炫酷图表。本文将介绍如何使用Pyecharts绘制多种炫酷…...
C# 多线程(2)——线程同步
目录 1 线程不安全2 线程同步方式2.1 简单的阻塞方法2.2 锁2.2.1 Lock使用2.2.2 互斥体Mutex2.2.3 信号量Semaphore2.2.3 轻量级信号量SemaphoreSlim2.2.4 读写锁ReaderWriterLockSlim 2.3 信号同步2.3.1 AutoResetEvent2.3.1.1 AutoResetEvent实现双向信号 2.3.2 ManualResetE…...
Java设计模式【工厂模式】
Java设计模式【工厂模式】 前言 三种工厂模式:简单工厂模式、工厂方法模式、抽象工厂模式; 创建型设计模式封装对象的创建过程,将对象的创建和使用分离开,从而提高代码的可维护性和可扩展性 简单工厂模式 概述:将…...
AI智能分析+明厨亮灶智慧管理平台助力“舌尖上的安全”
春节是中国最重要的传统节日之一,在春节期间,人们聚餐需求激增,餐饮业也迎来了高峰期。在这个时期,餐饮企业需要更加注重食品安全和卫生质量,以保证消费者的健康和权益,明厨亮灶智慧管理成为了餐饮业中备受…...
【现代密码学基础】详解完美安全与香农定理
目录 一. 介绍 二. 完美安全的密钥与消息空间 三. 完美安全的密钥长度 四. 最优的完美安全方案 五. 香农定理 (1)理论分析 (2)严格的正向证明 (3)严格的反向证明 六. 小结 一. 介绍 一次一密方案…...
Python 将文本转换成语音播放 pyttsx3
Python 将文本转换成语音播放 pyttsx3 目录 Python 将文本转换成语音播放 pyttsx3 1. 安装 2. 使用 3. 封装 Pyttsx3 是一个 Python 库,它提供了文本到语音(Text-to-Speech,TTS)转换的功能。这个库允许 Python 程序通过调用本…...
FPGA高端项目:Xilinx Artix7系列FPGA 多路视频缩放拼接 工程解决方案 提供4套工程源码+技术支持
目录 1、前言版本更新说明给读者的一封信FPGA就业高端项目培训计划免责声明 2、相关方案推荐我这里已有的FPGA图像缩放方案我已有的FPGA视频拼接叠加融合方案本方案的Xilinx Kintex7系列FPGA上的ov5640版本本方案的Xilinx Kintex7系列FPGA上的HDMI版本 3、设计思路框架设计框图…...
开源模型应用落地-业务优化篇(三)
一、前言 假如您跟随我的脚步,学习到上一篇的内容,到这里,相信细心的您,已经发现了,在上一篇中遗留的问题。那就是IM服务过载的时候,如何进行水平扩容? 因为在每个IM服务中,我们用JV…...
基于SpringBoot+Vue实现的物流快递仓库管理系统
基于SpringBootVue实现的物流快递仓库管理系统 文章目录 基于SpringBootVue实现的物流快递仓库管理系统系统介绍技术选型成果展示账号地址及其他说明源码获取 系统介绍 系统演示 关注视频号【全栈小白】,观看演示视频 基于SpringBootVue实现的物流快递仓库管理系…...
编程笔记 html5cssjs 072 JavaScrip BigInt数据类型
编程笔记 html5&css&js 072 JavaScrip BigInt数据类型 一、BigInt 数据类型二、BigInt 的创建和使用三、BigInt 操作与方法三、示例小结 JavaScript BigInt 数据类型是一种内置的数据类型,用于表示大于 Number.MAX_SAFE_INTEGER(即2^53 - 1&…...
matlab simulink 步进电机控制
1、内容简介 略 41-可以交流、咨询、答疑 2、内容说明 电动执行器定位控制在生产生活中具有广泛的应用,在使用搭载步进电机的电动执行器进行定位控制的时候,定位系统的定位精度和响应波形,会随着负载质量的变化而变化,这是由电…...
使用阿里云的IDaaS实现知行之桥EDI系统的单点登录
,在开始测试之前,需要确定用哪个信息作为“登陆用户的ID字段”。 这个字段用来在完成SSO登陆之后,用哪个信息将阿里云IDaaS的用户和知行之桥EDI系统的用户做对应。这里我们使用了 phonenumber 这个自定义属性。需要在阿里云做如下配置&#x…...
基于微服务的高考志愿智能辅助决策系统(附源码)
目录 一.引言 1、编写目的 2、系统功能概述 二.功能分析 三.微服务模块 1、微服务用户相关模块 (1)用户注册 (2)用户登录 (3)用户信息管理 (4)用户操作 2、微服务文件云存…...
LeetCode —— 137. 只出现一次的数字 II
😶🌫️😶🌫️😶🌫️😶🌫️Take your time ! 😶🌫️😶🌫️😶🌫️😶🌫️…...
pnpm、npm、yarn 包管理工具
1、npm 关键词:软件包管理器、命令行工具、一个社区和一个平台 npm(Node Package Manager)是一个用于Node.js环境的软件包管理器。它是一个命令行工具,用于安装、升级、删除和管理JavaScript软件包。npm最初是随同Node.js一起发布…...
微服务知识
1、概念 大型单体应用拆分成多个独立部署运行的微服务(解决并发问题) 2、特点 3、技术栈 4、微服务带来的问题 5、微服务的注册中心 服务注册与发现:微服务实例在启动时会向注册中心注册自己的信息…...
如何在微信搭建私域流量池?
A: ①给客户打标签 添加标签,多维度构建用户画像,精准发送消息。 ②群发信息 选择自定义时间,上传内容 (支持文字,图片) ,一键群发 。 ③建立专属素材库 将常用的话术、图片与文件录入至素材库,员工可随…...
MySQL原理(三)锁定机制(1)综述
一、介绍: 1、锁的本质 业务场景中存在共享资源,多个进程或线程需要竞争获取并处理共享资源,为了保证公平、可靠、结果正确等业务逻辑,要把并发执行的问题变为串行,串行时引入第三方锁当成谁有权限来操作共享资源的判…...
AI答案优化效果可以靠哪些第三方数据验证?
先给结论:AI答案优化效果要做三层交叉验证AI 答案优化、GEO 服务的效果,不应只听服务商自述,也不适合只靠单张 AI 回答截图判断。更稳妥的做法,是用三层数据交叉验证:AI回答层数据:看品牌是否被提及、位置是…...
告别手动配IP!用STM32CubeMX快速实现LwIP DHCP客户端,连接路由器即插即用
告别手动配IP!用STM32CubeMX快速实现LwIP DHCP客户端 每次为嵌入式设备配置静态IP都像在玩一场"猜谜游戏"——子网掩码输错一位、网关地址填错,整个网络就瘫痪了。更糟的是,当设备需要部署到不同网络环境时,还得重新烧…...
29.新生活轨道
七月中旬,北京的夏天进入最炙热的阶段。阳光白晃晃地炙烤着大地,空气滚烫,连风吹在脸上都带着一股干燥的灼烧感。行道树上的知了叫得声嘶力竭,仿佛要用尽最后一丝力气,对抗这无休止的炎热。陈远的生活,也像…...
突破距离限制,抗扰稳连|三格电子 Profibus-DP 转光纤模块,工业通信优选
在冶金、矿山、化工、大型制造等工业场景中,Profibus-DP 总线常面临传输距离不足、电磁干扰强、信号易中断三大难题,严重影响生产设备联动与数据传输稳定性。三格电子MS-F155-P (Y) Profibus-DP 转光纤点对点模块,专为解决工业长距离、强干扰…...
5步完成黑苹果配置:OpCore Simplify终极简化指南 [特殊字符]
5步完成黑苹果配置:OpCore Simplify终极简化指南 🚀 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 还在为复杂的OpenCore配置…...
从接入到稳定使用Taotoken服务的整体流程与可靠性观察
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 从接入到稳定使用Taotoken服务的整体流程与可靠性观察 1. 引言 对于需要调用多种大模型能力的开发者而言,找到一个统一…...
边缘计算是5G应用的核心平台 , 产业空间广阔
5G引入三大应用场景,eMBB(高速移动通信)、mMTC(大规模机器通信)、URLLC(低时延高可靠),为克服传输网的性能瓶颈,边缘计算成为5G网络的核心网络技术之一。为进一步拓展运营…...
机器学习优化地形图:凹凸函数如何决定模型收敛
1. 项目概述:为什么凹函数与凸函数是机器学习的“底层操作系统” 你有没有遇到过训练模型时损失曲线反复震荡、优化器在某个值附近打转、调参像开盲盒,怎么改学习率都收不到预期效果?我带过十几支算法团队,几乎每支队伍在模型收敛…...
终极HsMod炉石传说模改插件:如何用开源技术重塑你的游戏体验
终极HsMod炉石传说模改插件:如何用开源技术重塑你的游戏体验 【免费下载链接】HsMod Hearthstone Modification Based on BepInEx 项目地址: https://gitcode.com/GitHub_Trending/hs/HsMod 在炉石传说的世界里,每个玩家都渴望更流畅、更个性化的…...
C166架构中idaata变量存储类别变更的解析与优化
1. 问题现象与背景解析最近在Keil C166开发环境中遇到了一个有趣的编译警告,代码看起来非常简单:void main(void) {int i;int j;int idata asdf; // 触发警告的变量声明i 100;j 1000;asdf i j; }编译时会出现如下警告:*** WARNING 189 I…...
