<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>
【学习随记】cav
最新推荐文章于 2023-06-14 11:27:43 发布