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

news2024/12/29 8:49:40

在这里插入图片描述

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.title
                const goodsCover = this.selcetShareImgUrl // 分享商品图片 需要换成自己的产品图片
                const goodsTitle = this.goods.name // 商品名称
                const goodsPrice = '¥ '+this.goods.original_price
                const 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.canvasId
                const ctx        = uni.createCanvasContext(canvasId, this)
                const bgColor    = this.shareInfo.bgColor
                const title      = this.shareInfo.title
                const goodsCover = this.shareInfo.goodsCover
                const goodsTitle = this.shareInfo.goodsTitle
                const goodsPrice = this.shareInfo.goodsPrice
                const des1       = this.shareInfo.des1
                const des2       = this.shareInfo.des2
                const 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-WEIXIN
                            console.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.tempFilePath
                                    this.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 H5
                    uni.hideLoading()
                    var oA = document.createElement("a");
                    oA.download = ''; // 设置下载的文件名,默认是'下载'
                    oA.href = this.canvasImgPath;
                    document.body.appendChild(oA);
                    oA.click();
                    oA.remove(); // 下载之后把创建的元素删除
               // #endif
               
                // #ifdef MP-WEIXIN
                    console.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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1424441.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Vue】2-11、组件的生命周期

一、生命周期 & 声明周期函数 生命周期&#xff08;Life Cycle&#xff09;是值一个组件从 创建 -> 运行 -> 销毁 的整个阶段&#xff0c;强调的是一个时间段。 生命周期函数是由 Vue 框架提供的内置函数&#xff0c;会伴随着组件的生命周期&#xff0c;自动按次序…

【数据分享】1929-2023年全球站点的逐日最高气温数据(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff0c;其中又以气温指标最为常用&#xff01;说到气温数据&#xff0c;最详细的气温数据是具体到气象监测站点的气温数据&#xff01; 之前我们分享过1929-2023年全球气象站…

机器学习数学基础

机器学习基础 1、标量、向量、矩阵、张量2、概率函数、概率分布、概率密度、分布函数3、向量的线性相关性4、最大似然估计5、正态分布(高斯分布)6、向量的外积(叉积)7、向量的内积(点积)8、超平面(H)1、标量、向量、矩阵、张量 标量、向量、矩阵和张量是线性代数中不同…

周期承压下的徐工机械:收入持续负增长,大肆并购风险犹存

撰稿|行星 来源|贝多财经 工程机械行业的发展程度是衡量工业化水平的关键指标&#xff0c;亦是一直以来备受国家与市场关注的高成长板块。 在探索新发展增量的大军中&#xff0c;徐工机械&#xff08;SZ:000425&#xff09;活跃工程机械市场&#xff0c;寻求着利润与品质的最…

springboot140体育馆使用预约平台的设计与实现

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

草图导入3d之后渲染模型发光怎么回事?---模大狮模型网

在草图大师中&#xff0c;当导入3D模型之后发现模型发光通常是由于模型的材质属性或灯光设置所导致的。以下是一些可能的原因和解决方法&#xff1a; 材质属性设置&#xff1a;某些3D模型文件可能包含了发光材质属性&#xff0c;导致模型在草图大师中显示为发光状态。您可以尝试…

第四次项目(配置dns服务的正反向解析)

目录 实验要求 实验步骤 一、基础配置 1.1、服务端配置静态IP 1.2、客户端配置静态IP 二、配置dns服务的正向解析 2.1、服务端编辑主配置文件named.conf 2.2、服务端编辑主配置文件named.rfc1912.zones 2.3&#xff0c;服务端编辑数据配置文件&#xff0c;使用拷贝…

opencvb 十七 使用cmake配置opencv c++项目

1、cmake简介 1.1 cmake是什么 CMake是一个开源、跨平台的编译&#xff08;Build&#xff09;工具&#xff0c;是用来构建、测试和打包软件的。它能够用简单的语句来描述所有平台的编译过程。它能够输出各种各样的makefile或者project文件&#xff0c;能测试编译器所支持的C特…

【ASP.NET Core 基础知识】--Web API--创建和配置Web API(一)

一、简介 Web API&#xff08;Web Application Programming Interface&#xff09;的重要性在于其在现代软件开发中扮演着关键的角色。以下是一些关于Web API重要性的方面&#xff1a; 跨平台交互&#xff1a; Web API允许不同平台、不同技术栈的应用程序进行通信。无论是Web…

C#网络爬虫之TianyaCrawler实战经验分享

互联网时代的到来带来了大量的数据&#xff0c;而网络爬虫技术成为了获取这些数据的重要途径之一。如果你是一名C#开发者&#xff0c;那么你可能会对TianyaCrawler这个强大的网络爬虫框架感兴趣。本文将带你深入了解TianyaCrawler&#xff0c;分享它的技术概况、使用场景&#…

为什么光纤目前取代不了网线?

早上好&#xff0c;我的网工朋友。 在布线行业中&#xff0c;光纤与铜缆之间的较量已持续了十多年。 现如今随着云计算、5G等新型业务的不断涌现&#xff0c;数据中心规模不断的扩大&#xff0c;其架构与布线也越来越复杂。 但光纤的轻量化及逐渐降低的成本&#xff0c;使得…

Ubuntu Linux 下安装和卸载cmake 3.28.2版本

一、安装cmake 1.首先&#xff0c;先从cmake官网下载cmake-3.28.2-linux-x86_64.tar.gz 2.用FinalShell 等文件上传工具&#xff0c;将这个压缩包上传到 虚拟机的某个路径去&#xff08;自选&#xff09; 3. cd /usr/local/bin/&#xff0c;然后创建cmake文件夹&#xff0c;…

2024.2.1每日一题

LeetCode 今天看到一个评论挺有意思的&#xff0c;非常符合我现在的状况 简单题 – 稍加思索&#xff0c;嘴角上扬 中等题 – 认真对待&#xff0c;眉头一皱 困难题 – 绞尽脑汁&#xff0c;Ctrl cv 数字游戏 LCP 24. 数字游戏 - 力扣&#xff08;LeetCode&#xff09; 题目…

递归再认识----【详解】内含迷宫和八皇后问题

目录 一.递归&#xff1a; 1.1什么是递归&#xff1f; 1.2 递归示例&#xff1a; ①.打印问题&#xff1a; ②.阶乘问题&#xff1a; 1.3.递归需要遵守的规则&#xff1a; 二.迷宫问题&#xff1a; 说明&#xff1a; 代码详解&#xff1a; 三.八皇后问题&#xff1a; …

秋招面试—JS篇

2024 JavaScript面试题 1.new 操作符的工作原理 ①.创建一个新的空对象 ②.将这个对象的原型设置为函数的 prototype 对象 ③.让函数的this指向该对象&#xff0c;为函数添加属性和方法 ④.最后返回这个对象 2.什么是DOM&#xff0c;什么是BOM? DOM&#xff1a;文档对象…

回归预测 | Matlab实现CPO-GRU【24年新算法】冠豪猪优化门控循环单元多变量回归预测

回归预测 | Matlab实现CPO-GRU【24年新算法】冠豪猪优化门控循环单元多变量回归预测 目录 回归预测 | Matlab实现CPO-GRU【24年新算法】冠豪猪优化门控循环单元多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现CPO-GRU【24年新算法】冠豪猪优化…

BUUCTF-Real-[ThinkPHP]5-Rce

1、ThinkPHP检测工具 https://github.com/anx0ing/thinkphp_scan 漏洞检测 通过漏洞检测&#xff0c;我们发现存在rce漏洞&#xff01; 2、漏洞利用 ---- [!] Name: Thinkphp5 5.0.22/5.1.29 Remote Code Execution VulnerabilityScript: thinkphp5022_5129.pyUrl: http://n…

星际探险家

你是一个智能体,对于一切输入信息都是按照如下方式处理:输入信息:信息1 ,目的识别结果:有(没有就提取目的)提取信息1中目的相关有效信息,并设计和搜索达到完成目的的步骤和如何检测目的是否完成的步骤,执行步骤并达到目的,检测目标是否实现 实现则结束, 没有实现则检…

React18-模拟列表数据实现基础表格功能

文章目录 分页功能分页组件有两种接口参数分页类型用户列表参数类型 模拟列表数据分页触发方式实现目录 分页功能 分页组件有两种 table组件自带分页 <TableborderedrowKey"userId"rowSelection{{ type: checkbox }}pagination{{position: [bottomRight],pageSi…

如何下载52pojie、CSDN、简书、Myitmx、博客园的文章?(最新教程)

使用的油猴插件&#xff0c;具体怎么安装问一下度娘。 我用的火狐&#xff0c;点点点就行了&#xff0c;省事 先安装油猴拓展&#xff0c;启用一下 Tampermonkey – 下载 &#x1f98a; Firefox 扩展&#xff08;zh-CN&#xff09; 在安装插件 SaveToPDF 脚本安装后&#…