使用H5 Canvas 在微信中合成海報(背景+logo+暱稱)

粗糙版,在微信裏可以掃描-可以保存圖片。

先上傳,具體優化等之後版本

效果如圖:

<template>
    <div class="share_model" v-on:click="showModel(false)" v-show="isShow" :style="mainStyle">
         <img :src="imgSrc" class="share_model_main_img"/>

                <div class="bg_box" id="bg_box">
                    <canvas id="bg_canvas" width="300" height="480"></canvas>
                </div>
                <div class="qrcode">
                    <canvas id="qr_canvas"></canvas>
                </div>
                <div class="logo">
                    <canvas id="logo_canvas"></canvas>
                </div>
    </div>

</template>

<script>
    import QRCode from 'qrcode';
    import {mapState} from "vuex";
    import {toast} from "../utils/public";

    export default {
        name: "ShareModel2",
        computed: {
            ...mapState({
                'constData': "constData",
                'headers':'headers',
                "nativeType": "nativeType",
                'mainStyle':'mainStyle'
            })
        },
        data() {
            return {
                isShow: false,
                qr_value: 'https:www.baidu.com',
                size: 100,
                imgSrc: '',
                logoSrc: "",
                defaultLogoSrc: "默認的logo",
                bgSrc: "此處背景圖",
                nickname: "",
                scale_number: window.devicePixelRatio,
            }
        },
        components: {},
        mounted() {

        },
        methods: {
            createQR() {
                let canvas = document.getElementById('qr_canvas');

                QRCode.toCanvas(canvas, this.qr_value, function (error) {
                    if (error) console.error(error)
                })
            },
            init() {
                let that = this;

                //定義參數
                let text_y = 60 * that.scale_number;
                let logo_y = 80 * that.scale_number;
                let qr_x = 40 * that.scale_number;
                let qr_y = 420 * that.scale_number;
                let qr_length = 40 * that.scale_number;
                let logo_r = 60 * that.scale_number;
                let scale =  1 / that.scale_number;
                //畫用戶logo
                let logo_canvas = document.getElementById("logo_canvas");
                let logo_draw = logo_canvas.getContext("2d");
                let logo_img = this.createImg(this.logoSrc);

                logo_img.onload = () => {
                    //獲取二維碼
                    let code_canvas = document.getElementById("qr_canvas");
                    let qr_img = this.convertCanvasToImage(code_canvas);

                    qr_img.width = qr_length;
                    qr_img.height = qr_length;

                    logo_draw.drawImage(logo_img, 0, 0, logo_img.width, logo_img.height);
                    //繪製背景
                    // let width = document.getElementById("bg_box").offsetWidth; //寬度
                    // let height = document.getElementById("bg_box").offsetHeight; // 高度
                    let width = 300 * that.scale_number;
                    let bg_canvas = document.getElementById("bg_canvas");
                    bg_canvas.width = 300 * that.scale_number;
                    bg_canvas.height = 480 * that.scale_number;
                    let bg_draw = bg_canvas.getContext("2d");

                    let bg_img = this.createImg(this.bgSrc);
                    bg_img.onload = () => {
                        //繪製背景圖
                        bg_draw.drawImage(bg_img, 0, 0, bg_canvas.width, bg_canvas.height);

                        //繪製文字
                        bg_draw.font = 20 * that.scale_number + "px Georgia";
                        bg_draw.fillStyle = "white";
                        bg_draw.textAlign = "center";
                        bg_draw.fillText(that.nickname, width / 2, text_y);

                        //繪製二維碼
                        bg_draw.drawImage(qr_img, qr_x, qr_y, qr_img.width, qr_img.height);
                        //繪製logo
                        bg_draw.arc(width / 2, logo_y +logo_r / 2, logo_r / 2, 0, 2 * Math.PI);
                        bg_draw.clip();

                        bg_draw.drawImage(logo_img, (width - logo_r) / 2, logo_y, logo_r, logo_r);
                        bg_draw.restore();
                        bg_draw.save();
                        
                        that.imgSrc = bg_canvas.toDataURL("image/png");

                        //隱藏canvas
                        bg_canvas.style.width = 0;
                        bg_canvas.style.height = 0;
                        code_canvas.style.width = 0;
                        code_canvas.style.height = 0;
                        logo_canvas.style.width = 0;
                        logo_canvas.style.height = 0;

                    }
                };
                logo_img.onerror = function () {
                    if (that.logoSrc !== that.defaultLogoSrc) {
                        that.logoSrc = that.defaultLogoSrc;
                        that.drawImageV1();
                    }
                }
            },
            createImg(url) {
                let img = new Image();
                img.setAttribute("crossOrigin", 'Anonymous');
                img.src = url;

                return img;
            },
            convertCanvasToImage(canvas) {
                let image = new Image();
                image.src = canvas.toDataURL("image/png");
                return image;
            }
        }
    }
</script>

<style scoped>

     .share_model_main_img {
        width: 3rem;
        height: 4.8rem;
    }
    #bg_canvas {
        transform: scale(0.5);
    }
</style>

3月6日更新:

因爲使用微信的logo,會遇到跨域的問題,測試的時候是本地,頭像會加載不出來,所以在logo_img.onerror(加載失敗) 的時候,將頭像地址換成默認無跨域的地址,正常加載海報。

微信跨域的問題請自行百度

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章