Bootstrap

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.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>

;