小程序canvas組件生成與保存海報(bào)

在開(kāi)發(fā)小程序的過(guò)程中使用到了canvas來(lái)生成海報(bào)刽漂,然后添加小程序的二維碼就可以生成海報(bào)圖了

生成圖片如下:

0067gbbTly1g48mx4m3f3j30b70k40xt.jpg

代碼如下,在這里我是用了uni-app框架進(jìn)行的開(kāi)發(fā)涣楷,如果你使用的是其他的框架或者原生需要進(jìn)行相應(yīng)替換(原文)

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;
            //格式化時(shí)間
            that.getDateTime()
            //獲取數(shù)組
            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: '圖片已經(jīng)保存到相冊(cè)环肘,快去炫耀吧!',
                        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: '您已取消保存圖片到相冊(cè)揭璃!',
                            showCancel: false,
                            success: function(res) {
                                that.canvasShow = false
                            }
                        });
                    } else {
                        uni.showModal({
                            title: '提示',
                            content: '保存圖片失敗晚凿,您可以點(diǎn)擊確定設(shè)置獲取相冊(cè)權(quán)限后再嘗試保存!',
                            complete: function(res) {
                                if (res.confirm) {
                                    uni.openSetting({}) //打開(kāi)小程序設(shè)置頁(yè)面瘦馍,可以設(shè)置權(quán)限
                                } else {
                                    uni.showModal({
                                        title: '保存圖片失敗',
                                        content: '您已取消保存圖片到相冊(cè)歼秽!',
                                        showCancel: false,
                                        success: function(res) {
                                            that.canvasShow = false
                                        }
                                    });
                                }
                            }
                        });
                    }
                }
            })
        },
        //分享海報(bào)圖片
        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("長(zhǎng)按識(shí)別二維碼,獲取更多有趣圖片", 70, 500)
                //二維碼
                ctx.drawImage('../../static/codes.png', 190, 350, 100, 100)
                // ctx.stroke()//描邊
                ctx.draw()
            })
        },
        //這是一個(gè)封裝好的方法  
        promisify(api) {
            return (options, ...params) => {
                return new Promise((resolve, reject) => {
                    const extras = {
                        success: resolve,
                        fail: reject
                    }
                    api({ ...options,
                        ...extras
                    }, ...params)
                })
            }
        },
        //計(jì)算圖片比例
        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;
    }
}

如果對(duì)你有幫助就支持一下吧,( ̄▽ ̄)/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末情组,一起剝皮案震驚了整個(gè)濱河市燥筷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌院崇,老刑警劉巖肆氓,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異底瓣,居然都是意外死亡谢揪,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)键耕,“玉大人寺滚,你說(shuō)我怎么就攤上這事∏郏” “怎么了村视?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)酒奶。 經(jīng)常有香客問(wèn)我蚁孔,道長(zhǎng),這世上最難降的妖魔是什么惋嚎? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任杠氢,我火速辦了婚禮,結(jié)果婚禮上另伍,老公的妹妹穿的比我還像新娘鼻百。我一直安慰自己,他們只是感情好摆尝,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布温艇。 她就那樣靜靜地躺著,像睡著了一般堕汞。 火紅的嫁衣襯著肌膚如雪勺爱。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 48,970評(píng)論 1 284
  • 那天讯检,我揣著相機(jī)與錄音琐鲁,去河邊找鬼。 笑死人灼,一個(gè)胖子當(dāng)著我的面吹牛围段,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播投放,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼奈泪,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了跪呈?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤取逾,失蹤者是張志新(化名)和其女友劉穎耗绿,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體砾隅,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡误阻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片究反。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡寻定,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出精耐,到底是詐尸還是另有隱情狼速,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布卦停,位于F島的核電站向胡,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏惊完。R本人自食惡果不足惜僵芹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望小槐。 院中可真熱鬧拇派,春花似錦、人聲如沸凿跳。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)拄显。三九已至苟径,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間躬审,已是汗流浹背棘街。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留承边,地道東北人遭殉。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像博助,于是被迫代替她去往敵國(guó)和親险污。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容