小程序canvas组件生成与保存海报

  • A+
所属分类:程序开发

在开发小程序的过程中使用到了canvas来生成海报,然后添加小程序的二维码就可以生成海报图了

生成图片如下:

小程序canvas组件生成与保存海报

代码如下,在这里我是用了uni-app框架进行的开发,如果你使用的是其他的框架或者原生需要进行相应替换

html模板

<template>
    <view>
        <view class="canvas-box" v-bind:style="{display:canvasShow?'block':'none'}">
            <canvas canvas-id="shareCanvas"></canvas>
            <icon type="cancel" size="32" color="#000" @click="closeShare" />
        </view>
        <view class="share-btn" @click="saveImageToPhoto">
            分享
        </view>
    </view>
</template>

js代码

export default {
    props: {
        imageArray: {
            type: Array,
            default: () => []
        }
    },
    data() {
        return {
            shareImageArr: [],
            savedImgUrl: '',
            canvasShow: false,
            ymd: '',
            week: '',
            initLoad: true
        };
    },
    methods: {
        closeShare() {
            this.canvasShow = false
        },
        saveImageToPhoto() {
            var that = this;
            //格式化时间
            that.getDateTime()
            //获取数组
            that.shareImageArr = that.assignArray(that.imageArray, 9)
            that.canvasShow = true
            if (that.initLoad) {
                that.getShareImage()
                setTimeout(function() {
                    that._canvasToTempFilePath()
                }, 800)
                that.initLoad = false
            }
            let reset = function() {
                setTimeout(function() {
                    if (that.savedImgUrl != "") {
                        that._saveImageToPhotosAlbum()
                    } else {
                        that.getShareImage()
                        setTimeout(function() {
                            that._canvasToTempFilePath()
                            reset()
                        }, 800)
                    }
                }, 1300)
            }
            reset()
        },
        _canvasToTempFilePath() {
            let that = this;
            uni.canvasToTempFilePath({
                x: 0,
                y: 0,
                width: 300,
                height: 534,
                destWidth: 900,
                destHeight: 1600,
                canvasId: 'shareCanvas',
                success: function(res) {
                    that.savedImgUrl = res.tempFilePath
                },
                fail: function(e) {
                    console.log("canvas save error")
                }
            }, that)
        },
        _saveImageToPhotosAlbum() {
            let that = this;
            uni.saveImageToPhotosAlbum({
                filePath: that.savedImgUrl,
                success: function() {
                    uni.showModal({
                        title: '保存图片成功',
                        content: '图片已经保存到相册,快去炫耀吧!',
                        showCancel: false,
                        success: function(res) {
                            that.canvasShow = false
                        },
                        fail: function(res) {},
                        complete: function(res) {},
                    });
                },
                fail: function(res) {
                    if (res.errMsg == "saveImageToPhotosAlbum:fail cancel") {
                        uni.showModal({
                            title: '保存图片失败',
                            content: '您已取消保存图片到相册!',
                            showCancel: false,
                            success: function(res) {
                                that.canvasShow = false
                            }
                        });
                    } else {
                        uni.showModal({
                            title: '提示',
                            content: '保存图片失败,您可以点击确定设置获取相册权限后再尝试保存!',
                            complete: function(res) {
                                if (res.confirm) {
                                    uni.openSetting({}) //打开小程序设置页面,可以设置权限
                                } else {
                                    uni.showModal({
                                        title: '保存图片失败',
                                        content: '您已取消保存图片到相册!',
                                        showCancel: false,
                                        success: function(res) {
                                            that.canvasShow = false
                                        }
                                    });
                                }
                            }
                        });
                    }
                }
            })
        },
        //分享海报图片
        getShareImage() {
            const wxGetImageInfo = this.promisify(uni.getImageInfo)
            Promise.all(
                this.shareImageArr.map(i => {
                    return wxGetImageInfo({
                        src: i
                    })
                })
            ).then(res => {
                const ctx = uni.createCanvasContext('shareCanvas', this)
                let w = 0
                let h = 0
                res.map(e => {
                    ctx.drawImage(e.path, w, h, this.dengbi(e).w, this.dengbi(e).h)
                    w = w + 100
                    if (w >= 300) {
                        h = h + 100
                        w = 0
                    }
                })
                //底部图层
                ctx.rect(0, 300, 300, 234)
                ctx.setFillStyle('rgba(255, 255, 255, 1)')
                ctx.fill()
                //图片遮罩
                ctx.rect(0, 0, 300, 300)
                ctx.setFillStyle('rgba(255, 255, 255, 0.5)')
                ctx.fill()

                ctx.setFillStyle('#000000')
                ctx.setFontSize(16)
                ctx.fillText(this.ymd, 10, 400)

                ctx.setFillStyle('#000000')
                ctx.setFontSize(16)
                ctx.fillText(this.week, 10, 430)

                ctx.setFillStyle('#333333')
                ctx.setFontSize(12)
                ctx.fillText("长按识别二维码,获取更多有趣图片", 70, 500)
                //二维码
                ctx.drawImage('../../static/codes.png', 190, 350, 100, 100)
                // ctx.stroke()//描边
                ctx.draw()
            })
        },
        //这是一个封装好的方法  
        promisify(api) {
            return (options, ...params) => {
                return new Promise((resolve, reject) => {
                    const extras = {
                        success: resolve,
                        fail: reject
                    }
                    api({ ...options,
                        ...extras
                    }, ...params)
                })
            }
        },
        //计算图片比例
        dengbi(e) {
            let h = 100 * e.height / e.width
            if (h < 100) {
                let w = 100 * e.width / e.height
                return {
                    h: 100,
                    w: w
                }
            } else {
                return {
                    h: h,
                    w: 100
                }
            }
        },
        //日期格式化
        getDateTime() {
            let d = new Date()
            let weekarr = ["日", "一", "二", "三", "四", "五", "六"]
            this.ymd = d.getFullYear() + "年" + (d.getMonth() + 1) + "月" + d.getDate() + "日"
            this.week = "星期" + weekarr[d.getDay()]
        },
        assignArray(data = [], _length = 9) {
            if (data.length == 0) {
                return new Int8Array(_length)
            } else
            if (data.length < _length && data.length > 0) {
                let arr = []
                while (arr.length < _length) {
                    data.map(e => {
                        arr.push(e)
                    })
                }
                return arr.slice(0, _length)
            } else
            if (data.length >= 9) {
                return data.slice(0, _length)
            }
        },
    },
}

scss样式

.share-btn {
    z-index: 10;
    position: fixed;
    bottom: 20px;
    right: 20px;
    height: 30px;
    width: 30px;
    border-radius: 50%;
    padding: 10px;
    box-shadow: inset 0px 0px 3px 5px #f7f379;
    background: #ffffff;
}

.canvas-box {
    z-index: 99;
    position: fixed;
    top: 0;
    height: 100vh;
    width: 100vw;
    background: rgba(0, 0, 0, 0.5);

    canvas {
        margin: 10px auto;
        width: 300px;
        height: 534px;
    }

    icon {
        display: block;
        text-align: center;
    }
}

如果对你有帮助就支持一下吧,( ̄▽ ̄)/

  • 公众号
  • 扫一扫
  • weinxin
  • 打赏
  • 扫一扫
  • weinxin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: