【学习随记】cav

<template>
    <div class="poster" id="poster">

        <!-- loading -->
        <div class="loadingWrap" v-if="loadingState">
            <div class="loadingArea">
                <img src="../assets/imgs/loading.gif" alt="loading">
            </div>
        </div>

        <!-- 页面 html -->
        <div class="bgWrap"></div>
        
        <!-- canvas 绘制好的海报图片 在页面显示 -->
        <img class="showPoster" id="posterBox">
        
    </div>    
</template>
<script>

import logo_bank_01 from '../assets/imgs/street/logo_bank_01.png';  // 左上角 logo
import logo_bank_02 from '../assets/imgs/street/logo_bank_02.png';  // 底部中间 logo
import logo_txt from '../assets/imgs/street/logo_txt.png';  // 右上角 文字
import poster_bg from '../assets/imgs/street/poster_bg.jpg';    // 大背景
import poster_head from '../assets/imgs/street/h03.png';    // 头像 图片
import qr_stg from '../assets/imgs/street/qr_stg.jpg';
import qr_prd from '../assets/imgs/street/qr_prd.jpg';
import qr_txt from '../assets/imgs/street/qr_txt.png';
import title_img from '../assets/imgs/street/title_img.png';
import icon_prize from '../assets/imgs/street/icon_prize.jpg';

import head_01 from '../assets/imgs/street/head_01.jpg';
import head_02 from '../assets/imgs/street/head_02.jpg';
import head_03 from '../assets/imgs/street/head_03.jpg';
import head_04 from '../assets/imgs/street/head_04.jpg';

export default {
    data(){
        return {
            loadingState: false,    // loading 状态
            headimg: sessionStorage.getItem('headimgBase64'), // 头像图片 base64
            
            poster_bg: poster_bg,   // 大背景
            imgList: [
                [ logo_bank_01, 66, 53, 280, 46 ],   // 左上角 logo
                [ logo_txt, 1350, 57, 200, 20 ], // // 右上角 文字
                [ logo_bank_02, 750, 700, 124, 24 ], // 底部中间 logo
                [ qr_stg, 40, 577, 129, 129 ],  // 二维码 图片
                [ qr_txt, 186, 618, 170, 88 ],    // 二维码 侧边文字
                [ title_img, 576, 135, 494, 238 ],    // 标题图片
                // [ poster_head, 644, 366, 62, 62 ],   // 头像 图片
                // [ sessionStorage.getItem('headimgBase64'), 644, 366, 62, 62 ],   // 头像 图片
            ],
            icon_prize: icon_prize, // 礼盒 icon_prize, 1378, 550, 154, 158

            deHeadimg: [ head_01, head_02, head_03, head_04 ],
            
            userMsg: {},    // 用户信息
            prizeMsg: {},   // 用户中奖信息

            prizeIcon: {},  // 页面和生成海报的中奖文案
            prizeList: [    // 所有中奖奖项的文案列表
                {
                    type: 'LTA',
                    title: '奖项一',
                    desc: '国贸大厦',
                    num: '订餐券'
                },
                {
                    type: 'LTB',
                    title: '奖项一',
                    desc: '大酒店',
                    num: '餐饮券'
                },
                {
                    type: 'LTC',
                    title: '奖项一',
                    desc: '小礼品',
                    num: '一份'
                },
                {
                    type: 'LTD',
                    title: '谢谢参与!'
                },
            ],


        }
    },
    methods: {
        // nickName 
        // clibName(nickname){
        //     console.log("nickname.length: ", nickname.length)
        //     if (nickname.length >= 9){
        //         nickname = nickname.substr(0,10) + "...";
        //         return nickname;
        //     }else{
        //         return nickname;
        //     }
        // },
        
        // 生成海报
        Poster(){
            // console.log("原生js canvas 开始画海报 satrt");
            let that = this;
            that.loadingState = true;   // loading 开启

            let c = document.createElement('canvas');
            let width = 1624;
            let height = 750;
            c.width = width;
            c.height = height;
            const ctx = c.getContext("2d");

            // 填充背景色
            ctx.fillStyle = "pink";
            ctx.fillRect(0, 0, width, height);


            // 绘制 大背景
            let bg = new Image();
            bg.src = that.poster_bg;  // 背景图片
            // bg.setAttribute("crossOrigin", "anonymous");
            bg.onload = ()=>{
                ctx.drawImage(bg, 0, 0, c.width, c.height);              

                that.lineRoundRect(ctx, 36, 573, 137, 137, 3, 4, '#d381bc'); // 绘制 二维码圆角边框矩形
                
                // that.lineRoundRect(ctx, 642, 364, 66, 66, 33, 2, '#fa55dc'); // 绘制 头像圆形边框
                
                for(let i = 0; i < that.imgList.length; i++){
                    // console.log(that.imgList[i]);
                    that.drawElement(ctx, that.imgList[i]);
                }

                // 绘制头像
                let head = new Image();
                head.src = sessionStorage.getItem('headimgBase64') // that.headimg;  // logo图片
                head.onload = ()=>{
                    ctx.save();
                    let qrX = 644;
                    let qrY = 366;
                    let qrW = 62;
                    ctx.beginPath();
                    ctx.arc(qrX + qrW / 2, qrY + qrW / 2, qrW / 2, 0, Math.PI * 2, false);
                    ctx.strokeStyle = "#fa55dc";
                    ctx.lineWidth = 2;
                    ctx.stroke();
                    ctx.closePath();
                    ctx.clip();
                    ctx.drawImage(head, qrX, qrY, qrW, qrW);
                    ctx.restore();
                }

                ctx.save()
                ctx.font = "24px PingFangSC";
                ctx.fillStyle = "#f07dda";
                ctx.fillText("巴拉巴拉的:" + that.userMsg.nickname, 713, 448); // 绘制 昵称
                // ctx.font = "24px PingFangSC";
                // ctx.fillStyle = "#f07dda";
                ctx.fillText("巴拉小魔仙:" + that.prizeMsg.landmarkName, 713, 486); // 绘制 地标
                ctx.restore()
                
                // 绘制 券号码
                let cell_x_num = 1125;   // 首个格子x轴位置
                for(let i = 1; i <= 11; i++ ){
                    ctx.save()
                    that.fillRoundRect(ctx, cell_x_num, 100, 34, 33, 0, '#fff', 1, '#bf74aa');
                    // console.log("that.prizeMsg.postCode[i]", that.prizeMsg.postCode[i-1])
                    ctx.font = "24px PingFangSC";
                    ctx.fillStyle = "#f07dda";
                    // ctx.fillText(that.prizeMsg.postCode[i-1], cell_x_num + 9, 125);  // 券号遍历从下标0开始;每个数字之间的距离比格子之间的距离增加 9px

                    ctx.textAlign = 'center';
                    ctx.fillStyle = "#000";
                    ctx.fillText(that.prizeMsg.postCode[i-1], cell_x_num + 17, 125); // 每个格子的对齐中线x轴 递增 17px
                    cell_x_num += 39;    // 每个格子在x轴上距离 递增 39px
                    ctx.restore()
                }

                let prize_icon = new Image();
                prize_icon.src = that.icon_prize;
                prize_icon.onload = ()=>{
                    ctx.save();
                    ctx.drawImage(prize_icon, 1378, 550, 154, 158);

                    let iconTxt = {
                        title: that.prizeIcon.title,
                        desc: that.prizeIcon.desc,
                        num: that.prizeIcon.num
                    };
                    ctx.textAlign = 'center';   // 文字水平对齐基线,基于fillText传入的x轴的值
                    ctx.font = `${ that.prizeIcon.type == 'LTD' ? 24 : 27}px PingFangSC`;
                    ctx.fillStyle = "#f07dda";
                    ctx.fillText(iconTxt.title, 1457, that.prizeIcon.type == 'LTD' ? 650 : 626);
                    if(that.prizeIcon.type != 'LTD'){
                        ctx.font = `${ that.prizeIcon.type == 'LTA' ? 19 : 22}px PingFangSC`;
                        ctx.fillText(iconTxt.desc, 1457, 660);
                        ctx.font = `${ that.prizeIcon.type == 'LTA' ? 17 : 22}px PingFangSC`;
                        ctx.fillText(iconTxt.num, 1457, 692);
                    }
                    ctx.restore();
                }

            }
            
            setTimeout(()=>{ // 延迟1s设置img地址,防止canvas未完成绘制,页面空白或图片不完整
                that.loadingState = false; // loading 关闭
                posterBox.src = c.toDataURL(); // 设置页面图片地址
            }, 1000);
            that.setImgSize(); // 设置图片的宽高
            // console.log("原生js canvas 开始画海报 end");
        },


        // 设置 旋转rotate(90deg)之后图片img标签的宽高
        setImgSize(){
            let width = document.documentElement.clientWidth,
                height = document.documentElement.clientHeight,
                img = document.getElementById("posterBox");
                img.style.width = height + 'px';
                // img.style.height = width + 'px';
                // console.log("width: ", width, ' <<>> height: ', height);
        },


        /** 绘制 图片元素
        * @param ctx: canvas对象
        * @param arrList: 图片信息arr
        * @param arrList[0]:img 绘制的图片
        * @param arrList[1]: x x轴坐标
        * @param arrList[2]: y y轴坐标
        * @param arrList[3]: w 宽度
        * @param arrList[4]: h 高度
        **/
        drawElement(ctx, arrList){
            let el = new Image();
            el.src = arrList[0];
            el.onload = ()=>{
                ctx.save();
                ctx.drawImage(el, arrList[1], arrList[2], arrList[3], arrList[4]);
                ctx.restore();
            }
        },
 
        /**绘制--不填充--颜色的圆角矩形(带边框)
        * @param ctx: canvas对象
        * @param x: x轴坐标
        * @param y: y轴坐标
        * @param w: 宽度
        * @param h: 高度
        * @param round: 圆角半径
        * @param lineWidth: 线条宽度
        * @param lineColor: 线条颜色
        **/
        lineRoundRect(ctx, x, y, w, h, round, lineWidth, lineColor) {
            //圆的直径必然要小于矩形的宽高
            if (2 * round > w || 2 * round > h) { return false; }
            ctx.save();
            ctx.translate(x, y);
            //绘制圆角矩形的各个边
            this.drawRoundLine(ctx, w, h, round);
            ctx.lineWidth = lineWidth || 2; // 默认:2px
            ctx.strokeStyle = lineColor || "#000";  // 线条颜色 默认:黑色
            ctx.stroke();
            ctx.restore();
        },

        /**绘制--填充--颜色的圆角矩形(带边框)
        * @param ctx: canvas对象
        * @param x: x轴坐标
        * @param y: y轴坐标
        * @param w: 宽度
        * @param h: 高度
        * @param round: 圆角半径
        * @param innerColor: 填充颜色
        * @param lineWidth: 线条宽度
        * @param lineColor: 线条颜色
        **/
        fillRoundRect(ctx, x, y, w, h, round, innerColor, lineWidth, lineColor) {
            //圆的直径必然要小于矩形的宽高
            if (2 * round > w || 2 * round > h) { return false; }

            ctx.save();
            ctx.translate(x, y);
            //绘制圆角矩形的各个边
            this.drawRoundLine(ctx, w, h, round);
            ctx.fillStyle = innerColor || "#000"; //填充颜色 默认值:黑色
            ctx.fill();

            ctx.lineWidth = lineWidth || 2; // 默认:2px
            ctx.strokeStyle = lineColor || "#000";  // 线条颜色 默认:黑色
            ctx.stroke();

            ctx.restore();
        },

        // 绘制圆角矩形各边线
        drawRoundLine(ctx, w, h, round) {
            ctx.beginPath(0);
            // 从右下角顺时针绘制,弧度从0到1/2PI
            ctx.arc(w - round, h - round, round, 0, Math.PI / 2);
            ctx.lineTo(round, h);   // 矩形下线

            // 左下角圆弧,弧度从1/2PI到PI
            ctx.arc(round, h - round, round, Math.PI / 2, Math.PI);
            ctx.lineTo(0, round);   // 矩形左线

            // 左上角圆弧,弧度从PI到3/2PI
            ctx.arc(round, round, round, Math.PI, Math.PI * 3 / 2);
            ctx.lineTo(w - round, 0);   // 矩形上线

            // 右上角圆弧
            ctx.arc(w - round, round, round, Math.PI * 3 / 2, Math.PI * 2);
            ctx.lineTo(w, h - round);   // 矩形右线
            ctx.closePath();
        },


        // 将图片url转换为base64
        getBase64(userMsg){
            let that = this;
            console.log('getBase64- -userMsg', userMsg);
            window.URL = window.URL || window.webkitURL;
            let xhr = new XMLHttpRequest();
            xhr.open("get", userMsg.headimg, true);
            xhr.responseType = "blob";
            xhr.onload = function(){
                if(this.status == 200){
                    let blob = this.response;
                    console.log('blob', blob);
                    let oFileReader = new FileReader();
                    oFileReader.onloadend = function(e){
                        let base64 = e.target.result;
                        sessionStorage.setItem('headimgBase64', base64);
                        console.log('base64', base64);

                        let formMsg = new FormData();
                        formMsg.append('headimg', that.dataURLtoBlob(base64))
                        formMsg.append('nickname', userMsg.nickname)
                        formMsg.append('openid', userMsg.openid)
                        formMsg.append('sex', userMsg.sex)
                        for(let val of formMsg.values() ){
                            console.log('formdata', val);
                        }

                        that.getData();

                    }   
                    oFileReader.readAsDataURL(blob);
                }
            }
            xhr.send();
        },
        // 将base64转换为blob
        dataURLtoBlob(dataurl){
            var arr = dataurl.split(','),
                mime = arr[0].match(/:(.*?);/)[1],
                bstr = atob(arr[1]),
                n = bstr.length,
                u8arr = new Uint8Array(n);
            while (n--){
                u8arr[n] = bstr.charCodeAt(n);
            }
            return new Blob([u8arr], { type: mime});
        },

        // 获取 信息
        getData(){
            let that = this;
            // 获取用户信息
            let userMsg = sessionStorage.getItem('userMsg');
            userMsg = JSON.parse(userMsg);
            // console.log('userMsg.sex___111', typeof userMsg.sex);
            userMsg['sex'] = String(userMsg.sex); // 性别 由数字转换为字符串
            // console.log('userMsg.sex___222', typeof userMsg.sex);
            

            // 处理昵称字符串  AlanZuo
            // userMsg.nickname = '到好0j0s'

            // console.log('userMsg', userMsg);
            // that.userMsg.nickname = that.splitName(userMsg.nickname);
            that.userMsg = userMsg;
            // console.log('that.userMsg', that.userMsg);

            that.userMsg.nickname = that.splitName(userMsg.nickname);
            // console.log("666", that.splitName(userMsg.nickname))
            // console.log("888", that.userMsg['nickname'])

            // 获取中奖信息
            let prizeData = sessionStorage.getItem('prizeData');
            prizeData = JSON.parse(prizeData);
            // console.log('prizeData', prizeData);

            // 处理 中奖类型 与 data 中定义的对应项
            // 用于显示页面的文案 及生产海报的文案
            for(let i = 0, len = that.prizeList.length; i < len; i++){
                if(prizeData.lotteryCode == that.prizeList[i].type){
                    // console.log('that.prizeList[i]', that.prizeList[i]);
                    that.prizeIcon = that.prizeList[i];
                }
            }

            // prizeData['landmarkName'] = '平安金融中心'
            if (prizeData.landmarkName.length > 3){
                prizeData['landmarkName'] = prizeData['landmarkName'].substr(0,3) + "...";
                // console.log('landmarkName', prizeData.landmarkName);
            }else{
                prizeData['landmarkName'] = prizeData.landmarkName
            }
            that.prizeMsg = prizeData;
            // console.log('that.prizeMsg', that.prizeMsg);

            // 生产海报
            that.Poster();
        },


        // 获取空头像
        testEmptyHead(){
            let that = this;
            // 获取用户信息
            let userMsg = sessionStorage.getItem('userMsg');
            userMsg = JSON.parse(userMsg);
            userMsg['sex'] = String(userMsg.sex); // 性别 由数字转换为字符串
            
            
            if(userMsg.headimg){
                console.log('YY userMsg.headimg',userMsg.headimg)
                // 调用 getBase64
                this.getBase64(userMsg);
            }else{
                console.log('NNNN userMsg.headimg',userMsg.headimg)

                let randomWoman = that.random(0,1);  // 随机数 0-1
                let randomMan = that.random(2,3);  // 随机数 2-3

                if(userMsg.sex == '1' || userMsg.sex == ''){
                    userMsg.headimg = that.deHeadimg[randomMan]
                }else{
                    userMsg.headimg = that.deHeadimg[randomWoman]
                }

                console.log('userMsg', userMsg)
                this.getBase64(userMsg);

            }


            
        },

        // 头像为空时
        noHead(){
            let randomMan = this.random(0,1);  // 随机数 0-1
            let randomWoman = this.random(2,3);  // 随机数 2-3
            console.log('randomMan', randomMan)
            console.log('randomWoman', randomWoman)
        },
        random(lower, upper) {
            return Math.floor(Math.random() * (upper - lower+1)) + lower;
        },

        // 处理字符
        splitName(str){
            let reg = /[^\x00-\xff]/;   // 匹配双字节字符
            let dbcsNum = 0;  // 双字节字符个数
            let name;
            for(let i = 0 ; i < 4; i++){    // 检查字符串前四位字符
                if(reg.test(str[i])){   // 每检查到双字节字符,计一次数
                    dbcsNum++;
                }
            }
            if(dbcsNum == 0 && str.length <= 6 ){  // 无双字节字符,6个字符以下
                // console.log("无双字节字符,长度  <= 6 :", str);
                return str;
            }
            else if(dbcsNum == 0 && str.length > 6){   // 无双字节字符,6个字符以上
                name = str.substr(0,5) + "...";
                // console.log("无双字节字符,长度 > 6 :", name);
                return name;
            }
            else if(dbcsNum > 0){  // 前四位字符中带有双字节字符
                if(dbcsNum <= 3 && str.length < 5){ // 双字节字符个数<=3,5个字符以下
                    // console.log("1-双字节字符 <= 3,长度 <= 5 :", str);
                    return str;
                }
                else if(dbcsNum > 3 && str.length >= 5){    // 双字节字符个数>3,5个字符以上
                    name = str.substr(0,3) + "...";
                    // console.log("2-双字节字符 <= 3,长度 > 5 :", name);
                    return name;
                }
                else{
                    name = str.substr(0,4) + "...";
                    // console.log("3-双字节字符 其他 :", name);
                    return name;
                }
            }
        },


    },
    mounted(){
        console.log("hello  Poster");

        // 模拟 设置用户信息
        let userMsg = {
            desc: '本条数据用于测试',
            // headimg: 'http://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTIea3CJE1vqbydFpMTs2vLAWuU2rR7fykicevuLWjGQeicVgYQABUPWgicmVXPDlnIr5my0IT4c96qZg/132',
            headimg: '',
            nickname: 'Dasigdf',
            openid: 'orMfExIDwXbqd_-IFPoB3IgJDn4c',
            sex: 1
        }
        sessionStorage.setItem('userMsg', JSON.stringify(userMsg));
        

        // 模拟数据 设置缓存
        let prizeData = {
            headimgurl: 'http://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTIea3CJE1vqbydFpMTs2vLAWuU2rR7fykicevuLWjGQeicVgYQABUPWgicmVXPDlnIr5my0IT4c96qZg/132',
            landmarkId: '18',
            landmarkName: '南山大剧院',
            lotteryCode: 'LTA',
            lotteryName: '你好哈hello哈哈哈',
            postCode: 'P1P2P3P4P50'
        };
        sessionStorage.setItem('prizeData', JSON.stringify(prizeData));


        // 
        this.testEmptyHead()
        

        // this.noHead()

        
    }
}
</script>
<style type="text/css" scoped>

.poster{
    position: relative;
    /* width: 100%; */
    /* min-height: 100vh; */
    background: pink;
}
/* 页面 */
.bgWrap{
    width: 100%;
    height: 100vh;
    background: url('../assets/imgs/poster_bg.png') no-repeat 0 center;
    background-size: 100%;
}

/* loading start */
.loadingWrap{
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 90;
}
.loadingArea{
    position: absolute;
    top: 50%;
    left: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 1.5rem;
    height: 1.5rem;
    background: rgba(0,0,0,.5);
    border-radius: .1rem;
    transform: translate(-50%, -50%);
}
.loadingArea img{
    width: 0.6rem;
    height: 0.6rem;
}
/* loading end */


/* 绘制好的图片,定位在最上层,铺满全屏并设置一个透明度长按保存 */
.showPoster{
    position: absolute;
    top: 0;
    left: 0;
    z-index: 5;
    /* width: 100%;
    height: 100%;
    opacity: .01; */

    /* top: 0%;
    left: -60%; */

    top: 50%;
    left: 50%;
    transform:  translate(-50%, -50%) rotate(90deg);

}


</style>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值