使用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(加载失败) 的时候,将头像地址换成默认无跨域的地址,正常加载海报。

微信跨域的问题请自行百度

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