新增海报生成页、H5端流程大致走通,差抽奖验证的逻辑,以及海报元素的对应关系

This commit is contained in:
Andy Leong 2024-01-19 20:22:31 +08:00
parent cac9a17d36
commit fc0d5fce8c
37 changed files with 654 additions and 101 deletions

View File

@ -26,8 +26,8 @@ service.interceptors.response.use(
(response) => {
return response.data || {};
}, (error) => {
Toast('网络繁忙')
console.log('请求错误:', error.message);
// Toast('网络繁忙')
// console.log('请求错误:', error.message);
return Promise.reject(error);
});

View File

@ -35,7 +35,7 @@ export function subAnswer(data, authorization) {
}
// 抽奖
export function draw(data, authorization) {
export function drawApi(data, authorization) {
return http.post("/h5/activity/draw",
data,
true,

Binary file not shown.

BIN
src/assets/font/fzcy.ttf Normal file

Binary file not shown.

BIN
src/assets/font/fzzy.ttf Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 845 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 834 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -4,7 +4,7 @@ import { addPoint, debounceTap } from '@/plugins'
import { Toast } from "vant";
import { Clipboard } from "v-clipboard";
import { useMainStore } from "@/store";
// import { drawApi } from '@/api'
import { drawApi } from '@/api'
//
@ -28,27 +28,34 @@ const drawFn = (event) => {
})
gsap.fromTo(e, { rotation: '-30' }, { rotation: '+30', repeat: -1, yoyo: true, ease: 'none', duration: 0.3 })
// const res = await drawApi({})
const res = await draw({},userStore.token)
if(res.code == 0){
// isDrawn
hasPrize.value = res.data.isDrawn == 1 ? true : false // true || false
if(res.data.isDrawn == 1){
hasPrize.value = true
}else{
try {
const res = await drawApi({}, userStore.token)
if (res.code == 0) {
// isDrawn
hasPrize.value = res.data.isDrawn == 1 ? true : false // true || false
// if (res.data.isDrawn == 1) {
// hasPrize.value = true
// } else {
// hasPrize.value = false
// }
} else {
hasPrize.value = false // true || false
}
}else{
hasPrize.value = false // true || false
} catch (e) {
console.log('有才有无');
hasPrize.value = false
}
showResult.value = true
console.log("showResult:", showResult.value);
Toast.clear()
gsap.from('.result-container', { duration: 0.5, scale: 0.7, autoAlpha: 0 })
gsap.killTweensOf('.draw-light,.draw')
userStore.updateDraw()
setTimeout(() => {
Toast.clear()
showResult.value = true
gsap.from('.result-container', { duration: 0.5, scale: 0.7, autoAlpha: 0 })
gsap.killTweensOf('.draw-light,.draw')
}, 1000)
// setTimeout(() => {
// hasPrize.value = false // true || false

View File

@ -1,9 +1,8 @@
<script setup>
import { Toast } from "vant";
import { Toast } from "vant";
import { debounceTap } from "@/plugins";
import gsap from "gsap";
import {draw} from '@/api'
import {useMainStore} from '@/store'
import { useMainStore } from '@/store'
const emit = defineEmits(["IndexPage"]);
const userStore = useMainStore()
@ -14,7 +13,7 @@ const start = (event) => {
gsap.to(".IndexPage", {
duration: 0.5,
autoAlpha: 0,
onComplete: () => {},
onComplete: () => { },
});
});
};
@ -26,6 +25,14 @@ const showMyPrize = (event) => {
});
};
const showRule = (event) => {
let e = event.target;
debounceTap(e, () => {
emit("IndexPage", { action: "showRule" });
});
};
const clockAni = () => {
gsap.to(".index-clock-h", {
duration: 12,
@ -64,18 +71,14 @@ onMounted(() => {
</div>
<div class="index-container">
<div class="index-title"></div>
<div class="index-rule-btn"></div>
<div class="index-prize-btn" @click="showMyPrize($event)"></div>
<div class="index-rule-btn" @click="showRule($event)"></div>
<div class="index-prize-btn" v-if="userStore.hasPrize" @click="showMyPrize($event)"></div>
<div class="index-start-btn" @click="start"></div>
<div class="index-agreement">
风险提示:本材料由平安理财有限责任公司(以下简称平安理财)制作并提供<span
class="b"
>本资料内容及观点仅供参考不构成对任何人的投资建议</span
>以上产品投资管理机构/管理人为平安理财代理销售机构不承担产品的投资兑付和风险管理的责任以上产品通过代理销售机构渠道销售的产品风险评级应当以代理销售机构最终披露的评级结果为准以上产品为非保本浮动收益理财产品具体以产品说明书或产品公告披露为准产品的业绩比较基准指管理人基于过往投资经验以及对产品存续期投资市场波动的预判而对本产品所设定的投资目标业绩比较基准不是预期收益率不代表产品的未来表现和实际收益不构成对产品收益的承诺<span
class="b"
>理财产品过往业绩不代表其未来表现不等于理财产品实际收益投资须谨慎过往业绩相关数据已经托管人核对</span
><span class="orange">理财非存款产品有风险投资须谨慎</span
>金融消费者不得利用金融产品和服务从事违法活动
class="b">本资料内容及观点仅供参考不构成对任何人的投资建议</span>以上产品投资管理机构/管理人为平安理财代理销售机构不承担产品的投资兑付和风险管理的责任以上产品通过代理销售机构渠道销售的产品风险评级应当以代理销售机构最终披露的评级结果为准以上产品为非保本浮动收益理财产品具体以产品说明书或产品公告披露为准产品的业绩比较基准指管理人基于过往投资经验以及对产品存续期投资市场波动的预判而对本产品所设定的投资目标业绩比较基准不是预期收益率不代表产品的未来表现和实际收益不构成对产品收益的承诺<span
class="b">理财产品过往业绩不代表其未来表现不等于理财产品实际收益投资须谨慎过往业绩相关数据已经托管人核对</span><span
class="orange">理财非存款产品有风险投资须谨慎</span>金融消费者不得利用金融产品和服务从事违法活动
</div>
</div>
</div>
@ -90,21 +93,26 @@ onMounted(() => {
@include pos(750px, 1624px, 0px, 50%);
transform: translateY(-50%);
@include bg_pos("index/bg.jpg");
.index-clock-box {
@include pos(125px, 125px, 213px, 700px);
@include bg_pos("load/clock-bg.png");
.index-clock-circle {
@include pos(13px, 13px, 57px, 55px);
@include bg_pos("load/clock-circle.png");
}
.index-clock-s {
@include pos(125px, 125px, 0px, 0px);
@include bg_pos("load/clock-second.png");
}
.index-clock-m {
@include pos(125px, 125px, 0px, 0px);
@include bg_pos("load/clock-minute.png");
}
.index-clock-h {
@include pos(125px, 125px, 0px, 0px);
@include bg_pos("load/clock-hour.png");
@ -147,9 +155,11 @@ onMounted(() => {
padding: 10px;
box-sizing: border-box;
border-radius: 10px;
.b {
font-weight: 700;
}
.orange {
color: #ea5404;
}

View File

@ -4,11 +4,14 @@ import { debounceTap } from "@/plugins";
import { useMainStore } from "@/store";
import { mbtiList } from "@/data";
import { posterCreate } from '@/plugins'
import { Toast } from "vant";
import { onBeforeMount } from "vue";
import { computed } from "vue";
//
const emit = defineEmits(["ResultPage"]);
const userStore = useMainStore();
let bgId = ref(1);
let bgId = ref(1); //id14
const bgPic = computed(() => {
return new URL(
`../assets/images/result/bg-${bgId.value}.jpg`,
@ -16,11 +19,20 @@ const bgPic = computed(() => {
).href;
});
const mbti = ref(userStore.MBTI);
//
const theme = reactive(['#d3473a', '#fb7700', '#4172d8', '#eb5c37'])
const mbti = ref(userStore.MBTI);
const mbtiObj = ref(mbtiList.find(item => item.type == mbti.value))
console.log("mbti", mbti.value);
onBeforeMount(() => {
// mbtiObj.value = mbtiList.find(item => item.type == mbti.value)
console.log('mbtiObj.value', mbtiObj.value);
})
const changBg = (event, number) => {
let e = event.target;
if (number == bgId.value) return;
@ -39,44 +51,146 @@ const createPoster = (event) => {
debounceTap(e, () => {
//
posterCreate(
{ width: 750, height: 1450 }, //
{ width: 750, height: 1500 }, //
//
[
//
{
src: new URL(`@/assets/images/result/bg-2.jpg`, import.meta.url).href,
pos: { w: 750, h: 1624, x: 0, y: 0 }
src: new URL('../assets/images/result/poster-bg-' + bgId.value + '.jpg', import.meta.url).href,
pos: { w: 750, h: 1500, x: 0, y: 0 }
},
//
{
src: mbtiObj.value.productPic,
pos: { w: 469, h: 102, x: 137, y: 911 }
},
],
//
[
// mbti title
{
content: mbtiObj.value.type + mbtiObj.value.job,
style: {
font: 'normal 80px HYYakuHei',
pos: { x: 70, y: 330 }
}
},
// mbti
{
content: mbtiObj.value.des[0],
style: {
font: 'normal 30px fzzy',
color: '#af6f49',
pos: { x: 70, y: 470 }
}
},
{
src: new URL(`@/assets/images/qa/question.png`, import.meta.url).href,
pos: { w: 250, h: 1624, x: 0, y: 0 }
content: mbtiObj.value.des[1],
style: {
font: 'normal 30px fzzy',
color: '#af6f49',
pos: { x: 70, y: 520 }
}
},
//
{
content: mbtiObj.value.blessings[0],
style: {
font: 'normal 50px fzcy',
pos: { x: 70, y: 650 }
}
},
{
src: new URL(`@/assets/images/qa/showResult-btn.png`, import.meta.url).href,
pos: { w: 250, h: 124, x: 0, y: 0 }
content: mbtiObj.value.blessings[1],
style: {
font: 'normal 50px fzcy',
pos: { x: 70, y: 725 }
}
},
]
//
{
content: mbtiObj.value.product,
style: {
font: 'normal 50px fzcy',
pos: { x: 70, y: 876 }
}
}
],
//
theme[bgId.value - 1]
)
}, 0.4)
}
const goDraw = (event) => {
let e = event.target
debounceTap(e, () => {
if (userStore.hasDraw) {
emit('ResultPage', { action: 'showDraw' })
} else {
Toast('暂无抽奖机会')
}
})
}
const goShare = (event) => {
let e = event.target
debounceTap(e, () => {
})
}
const hidePop = (event) => {
let e = event.target
debounceTap(e, () => {
gsap.to('.posterPop', { duration: 0.5, autoAlpha: 0 })
})
}
</script>
<template>
<div class="ResultPage">
<div class="ResultPage" @touchmove.prevent>
<div class="result-bg">
<img :src="bgPic" alt="" srcset="" />
</div>
<div class="result-container">
结果页:{{ mbti || "没结果" }}
<div class="bg-tab">
<div :class="{ active: bgId == item }" v-for="item in 4" class="li" @click="changBg($event, item)">
{{ item }}
<div :class="'page-theme-' + bgId">
<div class="mbti-title"><span>{{ mbtiObj.type }} {{ mbtiObj.job }}</span></div>
<div class="mbti-des-box">
<div class="des" v-for="item in mbtiObj.des">{{ item }}</div>
</div>
<div class="mbti-blessings-box">
<div class="blessings" v-for="item in mbtiObj.blessings">{{ item }}</div>
</div>
<div class="mbti-product">
<div class="product">{{ mbtiObj.product }}</div>
<div class="produc-img">
<img :src="mbtiObj.productPic" alt="" srcset="">
</div>
</div>
</div>
<div @click="createPoster($event)">生成海报</div>
<div style="width: 500px;height: 700px;">
<img class="pic" src="" alt="" srcset="">
<div class="theme-tab">
<div class="theme-select-tips"></div>
<div class="theme-list">
<div :class="{ active: bgId == item }" v-for="item in 4" @click="changBg($event, item)">
<div class="theme-li" :class="'theme-li-' + item"></div>
<div class="selected" v-show="bgId == item"></div>
</div>
</div>
<div class="create-btn" @click="createPoster($event)"></div>
</div>
<img id="poster" alt="" srcset="">
</div>
</div>
<!-- 海报弹窗 -->
<div class="posterPop" @touchmove.prevent>
<div class="cls-btn" @click="hidePop($event)"></div>
<div class="poster-box">
<img id="poster">
</div>
<div class="btn-box">
<div class="go-draw" @click="goDraw($event)"></div>
<div class="go-share" @click="goShare($event)"></div>
</div>
</div>
</template>
@ -88,7 +202,7 @@ const createPoster = (event) => {
background-color: azure;
.result-bg {
@include pos(750px, 100%, 0px, 50%);
@include pos(750px, 1624px, 0px, 50%);
transform: translateY(-50%);
pointer-events: none;
@ -98,25 +212,195 @@ const createPoster = (event) => {
}
.result-container {
@include pos(750px, 100%, 0px, 50%);
@include pos(750px, 1624px, 0px, 50%);
transform: translateY(-50%);
.bg-tab {
width: 90%;
.page-theme-1 {
color: #d3473a;
animation: color 1s;
}
.page-theme-2 {
color: #fb7700;
animation: color 1s;
}
.page-theme-3 {
color: #4172d8;
animation: color 1s;
}
.page-theme-4 {
color: #eb5c37;
animation: color 1s;
}
.mbti-title {
@include pos(480px, 120px, 90px, 418px);
font-size: 80px;
font-family: "HYYaKuHei";
text-align: center;
text-shadow: 3.109px 2.517px 4px rgba(215, 70, 56, 0.47);
text-stroke: 1px #ffffff;
-webkit-text-stroke: 1px #ffffff;
// -webkit-transform: matrix(2.63538838101382, -0.15627262233171, 0.15650043026188, 2.63155221026798, 0, 0);
font-weight: bolder;
transform: rotate(-4deg);
display: flex;
flex-direction: row;
span {}
}
.mbti-des-box {
@include pos(517px, 90px, 110px, 547px);
display: flex;
flex-direction: column;
justify-content: space-around;
font-family: 'fzzy';
.li {
@include box(80px, 80px);
background-color: aquamarine;
@include flexCen();
}
.active {
background: #bc0000;
.des {
color: #af6f49;
font-size: 30px;
transform: rotate(-4deg);
}
}
.mbti-blessings-box {
@include pos(500px, 140px, 130px, 720px);
display: flex;
flex-direction: column;
justify-content: space-between;
font-family: 'fzcy';
.blessings {
font-size: 50px;
transform: rotate(-4deg);
text-shadow: 0px -1px 0px rgba(255, 255, 255, 0.004);
}
}
.mbti-product {
@include pos(475px, 140px, 134px, 948px);
font-family: 'fzcy';
.product {
font-size: 45px;
transform: rotate(-3deg);
text-shadow: 0px -1px 0px rgba(255, 255, 255, 0.004);
}
.produc-img {
@include box(469px, 102px);
margin-left: 10px;
img {
width: 100%;
}
}
}
.theme-tab {
@include pos(487px, 240px, 161px, 1108px);
.theme-select-tips {
@include pos(250px, 21px, 118.5px, 0px);
@include bg_pos("result/select-tips.png");
}
.theme-list {
@include pos(483px, 116px, 2.5px, 36px);
display: flex;
flex-direction: row;
justify-content: space-around;
.active {
border-style: solid;
border-width: 8px;
border-color: rgb(255, 70, 76);
border-radius: 20px;
}
.theme-li {
@include box(97px, 98px);
position: relative;
}
.theme-li-1 {
@include bg_pos("result/theme-1.png");
}
.theme-li-2 {
@include bg_pos("result/theme-2.png");
}
.theme-li-3 {
@include bg_pos("result/theme-3.png");
}
.theme-li-4 {
@include bg_pos("result/theme-4.png");
}
.selected {
@include bg_pos("result/select-arrow.png");
@include pos(15px, 8px, 60px, 120px);
}
}
.create-btn {
@include pos(258px, 69px, 126px, 159px);
@include bg_pos("result/create-btn.png");
}
}
}
}
.posterPop {
@include fixed();
@include flexCen();
background-color: rgba($color: #000000, $alpha: 0.54);
visibility: hidden;
.cls-btn {
@include box(41px, 41px);
@include bg_pos("result/cls-btn.png");
}
.poster-box {
@include box(495px, 990px);
overflow: hidden;
border: 2px solid #dbbb90;
border-radius: 20px;
#poster {
@include box(100%, 100%);
}
}
.btn-box {
@include box(489px, 76px);
display: flex;
justify-content: space-between;
margin-top: 20px;
.go-draw {
@include box(226px, 76px);
@include bg_pos("result/go-draw-btn.png");
}
.go-share {
@include box(226px, 76px);
@include bg_pos("result/go-share-btn.png");
}
}
}
</style>

View File

@ -4,11 +4,58 @@ import { debounceTap } from '@/plugins'
//
const emit = defineEmits(["RulePage"]);
const hide = (event) => {
debounceTap(event.target, () => {
emit('RulePage', { action: 'hide' })
})
}
</script>
<template>
<div class="RulePage">
规则页面
<div class="rule-container">
<div class="content">
<div class="rule-content">
<div class="rule-text-area">
<div class="part">
<div>活动时间2024年2月5日2月8日</div>
<div>活动奖励0.5-8.88元微信红包</div>
</div>
<div class="part">
<div>活动攻略</div>
<div>1进入H5参加测测你的花式性格测试共设计12道题目全部选择完毕后即可获取测试结果即可参与抽奖活动</div>
<div>2活动期间不限制参与测试次数每人每日有1次抽奖机会</div>
</div>
<div class="part">
<div>领奖说明</div>
<div>1中奖后在中奖页面复制兑换码前往[平安理财服务号] 消息框发送兑换码即可领取奖品如关闭了中奖界面可在首页-[我的奖品] 内查看兑换码</div>
<div>2成功领奖后奖品将会在24小时内自动到账请耐心等候</div>
<div>3中奖人请在活动结束前进行兑换逾期视为弃权</div>
<div>其他</div>
<div>活动期间如遇到任何问题请在[平安理财服务号]后台咨询我们会在一个工作日内回复</div>
<div>说明</div>
<div>
1本活动由平安理财有限责任公司主办为保证活动的公平公正活动结束后主办方将对中奖用户信息进行核对用户若有下列任何一种行为或情况的主办方有权不经另行通知取消其参与活动以及获奖资格收回奖品权
</div>
<div>(1) 以任何机器人软件蜘蛛软件爬虫软件刷奖软件或其它任何自动方式不正当手段等参与本活动</div>
<div>(2) 同一用户(包含相同手机号相同收货信息相同移动设备号相同IP地址等) 单日内恶意切换微信账号参加活动扰乱正常抽奖秩序影响活动公平性的;</div>
<div>(3) 有任何违反法律法规诚实信用公序良俗公平公正平安理财平台规则等行为;</div>
<div>2平安理财保留调整暂停和终止本活动的权利并经公告后生效;</div>
</div>
<div class="part">
<div></div>
<div></div>
<div></div>
</div>
</div>
</div>
<div class="rule-cls-btn" @click="hide($event)"></div>
<div class="rule-arrow"></div>
</div>
<div class="rule-caidai"></div>
</div>
</div>
</template>
@ -17,5 +64,54 @@ const emit = defineEmits(["RulePage"]);
@include fixed();
@include flexCen();
background-color: rgba($color: #000000, $alpha: 0.7);
.rule-container {
position: relative;
@include box(492px, 712px);
.content {
.rule-content {
@include box(490px, 709px);
@include bg_pos('rule/rule-box.png');
position: relative;
.rule-text-area {
@include pos(405px, 523px, 41px, 101px);
// background-color: #000000;
overflow: hidden;
overflow-y: scroll;
.part {
font-family: 'fzcy';
color: #ac4d31;
font-size: 20px;
line-height: 30px;
margin-top: 30px;
text-align: justify;
padding: 0 10px;
}
}
}
.rule-arrow {
@include pos(38px, 23px, 224px, 641px);
@include bg_pos('rule/arrow.png');
}
.rule-cls-btn {
@include pos(48px, 48px, 441px, -76px);
@include bg_pos('rule/cls-btn.png');
}
}
.rule-caidai {
@include pos(135px, 185px, 357px, 557px);
@include bg_pos('rule/caidai.png');
pointer-events: none;
}
}
}
</style>

View File

@ -208,62 +208,99 @@ export const data = [
export const mbtiList = [
{
type: 'INTJ',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
job: '建筑师',
des: ['富有想象力和战略性的思想家,', '一切皆在计划之中'],
blessings: ['江南几度梅花发', '福瘦双全有钱花'],
product: '启航一年定开1号',
productPic: new URL('../assets/images/result/product-1.png', import.meta.url).href,
},
{
type: 'INTP',
spe: '富有创造力的发明家,对知识有着止不住的渴望',
job: '建筑师',
des: ['富有想象力和战略性的思想家,', '一切皆在计划之中'],
blessings: ['江南几度梅花发', '福瘦双全有钱花'],
product: '启航一年定开1号',
productPic: new URL('../assets/images/result/product-1.png', import.meta.url).href,
},
{
type: 'ENTJ',
spe: '大胆,富有想象力且',
job: '建筑师',
des: ['富有想象力和战略性的思想家,', '一切皆在计划之中'],
blessings: ['江南几度梅花发', '福瘦双全有钱花'],
product: '启航一年定开1号',
productPic: new URL('../assets/images/result/product-1.png', import.meta.url).href,
},
{
type: 'ENTP',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
job: '建筑师',
des: ['富有想象力和战略性的思想家,', '一切皆在计划之中'],
blessings: ['江南几度梅花发', '福瘦双全有钱花'],
product: '启航一年定开1号',
productPic: new URL('../assets/images/result/product-1.png', import.meta.url).href,
},
{
type: 'INFJ',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
job: '建筑师',
des: ['富有想象力和战略性的思想家,', '一切皆在计划之中'],
blessings: ['江南几度梅花发', '福瘦双全有钱花'],
product: '启航一年定开1号',
productPic: new URL('../assets/images/result/product-1.png', import.meta.url).href,
},
{
type: 'INFP',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
job: '建筑师',
des: ['富有想象力和战略性的思想家,', '一切皆在计划之中'],
blessings: ['江南几度梅花发', '福瘦双全有钱花'],
product: '启航一年定开1号',
productPic: new URL('../assets/images/result/product-1.png', import.meta.url).href,
},
{
type: 'ENFJ',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
job: '建筑师',
des: ['富有想象力和战略性的思想家,', '一切皆在计划之中'],
blessings: ['江南几度梅花发', '福瘦双全有钱花'],
product: '启航一年定开1号',
productPic: new URL('../assets/images/result/product-1.png', import.meta.url).href,
},
{
type: 'ENFP',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
job: '建筑师',
des: ['富有想象力和战略性的思想家,', '一切皆在计划之中'],
blessings: ['江南几度梅花发', '福瘦双全有钱花'],
product: '启航一年定开1号',
productPic: new URL('../assets/images/result/product-1.png', import.meta.url).href,
},
{
type: 'ISTJ',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
job: '建筑师',
des: ['富有想象力和战略性的思想家,', '一切皆在计划之中'],
blessings: ['江南几度梅花发', '福瘦双全有钱花'],
product: '启航一年定开1号',
productPic: new URL('../assets/images/result/product-1.png', import.meta.url).href,
},
{
type: 'ISFJ',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
job: '建筑师',
des: ['富有想象力和战略性的思想家,', '一切皆在计划之中'],
blessings: ['江南几度梅花发', '福瘦双全有钱花'],
product: '启航一年定开1号',
productPic: new URL('../assets/images/result/product-1.png', import.meta.url).href,
},
{
type: 'ESTJ',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
job: '建筑师',
des: ['富有想象力和战略性的思想家,', '一切皆在计划之中'],
blessings: ['江南几度梅花发', '福瘦双全有钱花'],
product: '启航一年定开1号',
productPic: new URL('../assets/images/result/product-1.png', import.meta.url).href,
},
{
type: 'ISTP',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
},
{
type: 'ISFP',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
},
{
type: 'ESTP',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
},
{
type: 'ESFP',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
job: '建筑师',
des: ['富有想象力和战略性的思想家,', '一切皆在计划之中'],
blessings: ['江南几度梅花发', '福瘦双全有钱花'],
product: '启航一年定开1号',
productPic: new URL('../assets/images/result/product-1.png', import.meta.url).href,
},
]

View File

@ -1,10 +1,11 @@
<template>
<div class="home" @touchmove.prevent>
<div class="home">
<Index v-if="showIndex" @IndexPage="indexFn"></Index>
<Question v-if="showQuestion" @QuestionPage="questionFn"></Question>
<Result v-if="showResult" @ResultPage="resultFn"></Result>
<MyPrize v-if="showMyPrize" @MyPrizePage="myPrizeFn"></MyPrize>
<Draw v-if="showDraw" @DrawPage="drawFn"></Draw>
<Rule v-if="showRule" @RulePage="ruleFn"></Rule>
<Loading v-if="showLoad" @LoadPage="loadFn"></Loading>
</div>
</template>
@ -17,6 +18,7 @@ import Question from "@/components/Question";
import MyPrize from "@/components/MyPrize";
import Draw from "@/components/Draw";
import Result from "@/components/Result";
import Rule from "@/components/Rule";
import { createBGM, getQueryString } from "@/plugins";
import { authorize, getUserInfo } from '@/api'
import { Toast } from "vant";
@ -43,6 +45,10 @@ const indexFn = (item) => {
if (item.action == "start") {
showQuestion.value = true;
}
if (item.action == "showRule") {
showRule.value = true;
}
};
const showQuestion = ref(false);
@ -76,6 +82,18 @@ const resultFn = (item) => {
if (item.action == "hide") {
showResult.value = false;
}
if (item.action == "showDraw") {
showDraw.value = true;
}
};
const showRule = ref(false);
const ruleFn = (item) => {
if (item.action == "hide") {
showRule.value = false;
}
};
onMounted(() => {

View File

@ -433,7 +433,7 @@ export function mostValue(arr) {
// 海报生成
export function posterCreate(option, imageArr) {
export function posterCreate(option, imageArr, textArr, theme) {
let posterUrl = ''
const { width, height } = option
Toast.loading({
@ -441,12 +441,13 @@ export function posterCreate(option, imageArr) {
duration: 0,
forbidClick: true
})
console.log('theme', theme);
let mycanvas = document.createElement('canvas') // 创建一个canvas画布元素
let ctx = mycanvas.getContext('2d')
mycanvas.width = width; //设置canvas的宽
mycanvas.height = height; //设置canvas的高
console.log('imgs:', imageArr);
//Promise对象加载资源
let loader_p = [];
imageArr.map((item) => {
@ -469,6 +470,39 @@ export function posterCreate(option, imageArr) {
ctx.drawImage(item, imageArr[index].pos.x, imageArr[index].pos.y, imageArr[index].pos.w, imageArr[index].pos.h); //原生canvas的绘制图片方法直接百度搜索 `js drawImage`查看方法的参数
})
// 画签文
ctx.rotate(-4 * (Math.PI / 180));
ctx.textAlign = 'start'; //type2
ctx.textBaseline = 'top'
textArr.map((item, index) => {
const { x, y } = textArr[index].style.pos
ctx.font = textArr[index].style.font; // normal bold
// title绘制描边
if (index == 0) {
ctx.lineWidth = 5
ctx.strokeStyle = 'white'
ctx.strokeText(textArr[index].content, x, y);
}
ctx.fillStyle = textArr[index].style.color ? textArr[index].style.color : theme; //原生canvas的绘制文字方法,属性类似css确定好文字颜色、粗细、字号、字体、对齐方式
ctx.fillText(textArr[index].content, x, y); //绘制文字
})
// let mbtiLogo = 'MBTI MBTI MBTI'
// let radius = 75
// var angleStep = ((3 / 4) * Math.PI) / mbtiLogo.length;
// for (var i = 0; i < mbtiLogo.length; i++) {
// var angle = i * angleStep + Math.PI / 250;
// var x = 375 + Math.cos(angle) * radius;
// var y = 775 + Math.sin(angle) * radius;
// ctx.font = 'normal 30px HYYakuHei';
// ctx.fillStyle = theme
// ctx.fillText(mbtiLogo[i], x, y);
// }
//海报绘制完 ,转成图片对象
return mycanvas.toDataURL('image/jpeg', 1);
})
@ -476,7 +510,11 @@ export function posterCreate(option, imageArr) {
//返回的图片地址就是最后海报的地址可以放在DOM显示
let posterImg = document.querySelector('#poster')
posterImg.src = baseURL
setTimeout(() => Toast.success({ message: '已成功' }), 500)
setTimeout(() => {
Toast.success({ message: '生成成功!' })
gsap.to('.posterPop', { duration: 0.5, autoAlpha: 1 })
}, 500)
})
return posterUrl

View File

@ -4,8 +4,10 @@ import { defineStore } from "pinia"
export const useMainStore = defineStore("counter", {
state: () => {
return {
hasDraw: true, //是否有抽奖机会
token: 'INFJ',
MBTI: '', //测试结果
MBTI: 'INTJ', //测试结果
hasPrize: true, //是否有奖品
prizeCode: 'DKS18', //兑换码
prizeMoney: '8.88', //金额
drawKey: '',
@ -27,6 +29,9 @@ export const useMainStore = defineStore("counter", {
},
updateDrawKey(key) {
this.drawKey = key
},
updateDraw(value) {
this.hasDraw = false
}
},
})

View File

@ -1,9 +1,67 @@
@charset "utf-8";
// @import url('@/assets/font/AlimamaShuHeiTi.ttf');
/*--------------------
默认设置
-------------------*/
* {
padding: 0;
margin: 0;
box-sizing: border-box;
-webkit-box-sizing: border-box;
// -webkit-user-select: none;
// -moz-user-select: none;
/*touch-action: none; */
// -webkit-transform: translate3d(0, 0, 0);
// -moz-transform: translate3d(0, 0, 0);
// -ms-transform: translate3d(0, 0, 0);
// transform: translate3d(0, 0, 0);
}
*:not(input, textarea) {
-webkit-user-select: none;
-moz-user-select: none;
//-webkit-touch-callout:none;
//user-select: none;
//-webkit-user-select: none;
}
html {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-tap-highlight: rgba(0, 0, 0, 0);
-webkit-text-size-adjust: none;
overflow: -moz-scrollbars-vertical;
width: 100%;
height: 100%;
font-size: 100px;
}
body {
position: relative;
width: 100%;
height: 100%;
margin: 0 auto;
font: normal 12px / auto "Helvetica Neue", Helvetica, "Micorsoft YaHei", Arial,
sans-serif;
/* -webkit-user-select: none;*/
}
@font-face {
font-family: 'alimama';
src: url(@/assets/font/AlimamaShuHeiTi.ttf) format('truetype');
font-family: "alimama";
src: url(@/assets/font/AlimamaShuHeiTi.ttf) format("truetype");
}
@font-face {
font-family: "HYYakuHei";
src: url(@/assets/font/HYYakuHei-85W.ttf) format("truetype");
}
@font-face {
font-family: "fzcy";
src: url(@/assets/font/fzcy.ttf) format("truetype");
}
@font-face {
font-family: "fzzy";
src: url(@/assets/font/fzzy.ttf) format("truetype");
}
* {