You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

686 lines
17 KiB

2 years ago
<template>
<div class="wrap">
<div class="top">
<image :src="indexlogo" class="logo"></image>
<image :src="indextitle" class="title"></image>
<!-- <u-image :show-loading="false" :lazy-load="false" mode="scaleToFill" width="135rpx" height="100rpx"
:src="indexlogo"></u-image>
<u-image :show-loading="false" :lazy-load="false" mode="scaleToFill" width="514rpx" height="274rpx"
:src="indextitle"></u-image> -->
</div>
<div class="container" id="img-container">
<img ref="image" src="../../static/xtdk/map-map.png" alt="" @load="load">
<div class="area" :style="{ 'height': area.h +'px', 'width': area.w +'px' }">
<div class="pointer" v-for="(item, index) in pointers" :key="index"
:style="{ 'transform': `translate(calc(${area.w * item.x / 100}px - 50%),calc(${area.h * item.y / 100}px - 50%))` }"
@click="$u.throttle(() => toDetail(item))">
<!-- <div class="pointer__horn" :class="{ 'pointer__horn--active': item.has_answer > 0 }"
:style="{ 'transform': `translate(-3rpx, calc(-50% - 4rpx)) rotate(${item.d}deg)` }"></div> -->
<div class="box" :style="{ 'transform': transformBox(item.d) }">
<div class="box__image" :class="{ 'box--active': item.has_answer > 0 }">
<img :src="item.image ? item.image.url : ''" alt="">
</div>
<div class="box__text" :class="{ 'box__text--active': item.has_answer > 0 }"
:style="{ 'transform': (item.d > 100 || item.d < -100) ? 'translate(calc(-50% + 58rpx), 136rpx)' : '' }">
2 years ago
<image class="icons"
v-if="index>0"
:style="{'left':`-${iconArr[index]['width']/2+18}rpx`,'width':`${iconArr[index]['width']}rpx`,'height':`${iconArr[index]['height']}rpx`}"
:src="iconArr[index]['src']" alt="">
<!-- <u-image v-if="index>0" class="icons" :style="{'left':`-${iconArr[index]['width']/2+10}rpx`}" :src="iconArr[index]['src']" :width="iconArr[index]['width']" :height="iconArr[index]['height']" ></u-image> -->
2 years ago
{{ item.name }}</div>
<u-image class="pointer__flag"
2 years ago
v-if="item.has_answer > 0"
2 years ago
:width="92" :height="67"
:src="require('@/static/xtdk/map-flag.png')"></u-image>
</div>
<!-- v-if="item.has_answer > 0" -->
<!-- :style="{'transform': flagTranslate(item.d, item.name.length)}" -->
</div>
</div>
</div>
<transition name="progress-box" enter-active-class="fade-in" leave-to-class="fade-out">
<div class="progress" v-show="isShowProgress">
<div class="close">
<u-icon name="close-circle" :size="40" color="#555" @click="isShowProgress = false"></u-icon>
</div>
2 years ago
<div class="box" @click="$u.throttle(toCertificate(done !== pointers.length))">
2 years ago
<div class="box__line-progress">
<u-image class="box__line-progress--bkg" width="100%" mode="widthFix"
:src="require('@/static/xtdk/map-progress.png')"></u-image>
<u-line-progress :height="11" active-color="#b93736" :striped="true"
:percent="(done/pointers.length)*100" :striped-active="true">
<template #default>
<div></div>
<!-- <div class="box__line-progress--img">
<u-image mode="heightFix" :height="83"
:src="require('@/static/line-progress-img.png')"></u-image>
</div> -->
</template>
</u-line-progress>
</div>
<div class="box__text">
<span>已完成</span>
<span style="font-style: italic;padding-right: 4rpx;" class="box__text--red">{{done}}</span>
<span>家打卡</span>
<template v-if="done !== pointers.length">
<br><span>完成<span style="font-style: italic;padding-right: 4rpx;"
class="box__text--red">{{pointers.length}}</span>家即可获得</span>
<span class="box__text--red">荣誉证书</span>
</template>
<template v-else>
<br><span>生成我的</span>
2 years ago
<span class="box__text--red" @click="$u.throttle(toCertificate(false))"></span>
2 years ago
</template>
</div>
</div>
</div>
</transition>
<transition name="expand-progress-box" enter-active-class="fade-in" leave-to-class="fade-out">
<div class="progress expand-progress" v-show="!isShowProgress" @click="isShowProgress = true">
<u-icon name="arrow-left-double" color="#C52A34"></u-icon>
打卡进度
</div>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
indexlogo:require('../../static/xtdk/index-logo.png'),
2 years ago
indextitle:require('../../static/xtdk/index-title.png'),
iconArr:[{
src:'',
width:0,
height:0
},{
src:require('../../static/xtdk/map1.png'),
width:52,
height:68
},{
src:require('../../static/xtdk/map2.png'),
width:57,
height:65
},{
src:require('../../static/xtdk/map3.png'),
width:35,
height:85
},{
src:require('../../static/xtdk/map4.png'),
width:23,
height:102
},{
src:require('../../static/xtdk/map5.png'),
width:26,
height:83
},{
src:require('../../static/xtdk/map6.png'),
width:43,
height:59
},{
src:require('../../static/xtdk/map7.png'),
width:68,
height:54
},{
src:require('../../static/xtdk/map8.png'),
width:45,
height:82
}
],
signInfo:'',
2 years ago
isBkgLoad: false,
done: 0,
isShowProgress: true,
area: {
w: 100,
h: 200
},
pointers: [{
x: 37,
y: 34,
d: -30
},
{
x: 74,
y: 39,
d: 38
},
{
x: 43,
y: 72,
d: -170
},
{
x: 21,
y: 60,
d: -155
},
]
};
},
2 years ago
methods: {
async getPoster () {
const res = await this.$u.api.getPoster({
user_id: this.vuex_user.id,
type: 2
})
this.signInfo = res
},
async getPoster () {
const res = await this.$u.api.getPoster({
user_id: this.vuex_user.id,
type: 2
})
this.signInfo = res
},
async toCertificate(isgo) {
if(isgo){
return
}
await this.getPoster()
if (!this.signInfo?.upload) {
uni.navigateTo({
url: '/pages/sign/sign'
})
}else{
uni.navigateTo({
url: '/pages/certificate/certificate'
})
}
2 years ago
},
toDetail(item) {
this.$u.vuex('vuex_point_id', item.id)
uni.navigateTo({
url: `/pages/detail/detail?id=${item.id}`
})
},
load() {
this.isBkgLoad = true
this.area.w = this.$refs['image'].getBoundingClientRect().width
this.area.h = this.$refs['image'].getBoundingClientRect().height
this.scroll()
},
scroll() {
this.$nextTick(() => {
let element = document.getElementById("img-container"); // 获取需要滚动的元素
let scrollLeft = element.scrollWidth / 2 - element.offsetWidth / 2; // 计算横向滚动条滚动的位置
let scrollTop = element.scrollHeight / 2 - element.offsetHeight / 2; // 计算纵向滚动条滚动的位置
element.scrollLeft = scrollLeft; // 设置横向滚动条的位置
element.scrollTop = scrollTop; // 设置纵向滚动条的位置
})
},
async getPoints() {
function convertToEquivalentAngle(angle) {
if (angle > 180) {
return angle - 360;
} else if (angle < -180) {
return angle + 360;
} else {
return angle;
}
}
this.pointers = []
const res = await this.$u.api.getPoints()
this.done = res.point_answer_total || 0
this.pointers = res.points?.map((i, index) => {
return {
...i,
d: convertToEquivalentAngle((i.jiaodu && Number(i.jiaodu)) ? Number(i.jiaodu) : 0),
}
})
}
},
computed: {
transformBox() {
return function(deg) {
if (deg) {
if ((deg % 360) > -90 && (deg % 360) < 90) {
return `translate(calc(${Math.floor(Math.sin(Math.PI / 180 * deg) * 80)}rpx - 48rpx), calc(${-1 * Math.floor(Math.cos(Math.PI / 180 * deg) * 80)}rpx - 48rpx))`
} else {
return `translate(calc(${Math.floor(Math.sin(Math.PI / 180 * deg) * 80)}rpx - 48rpx), calc(${-1 * Math.floor(Math.cos(Math.PI / 180 * deg) * 80)}rpx - 48rpx))`
}
} else {
return 'translate(0, 0)'
}
}
},
translateText() {
return function(deg) {
if (deg) {
if ((deg % 360) > -90 && (deg % 360) < 90) {
return `translate(calc(${Math.floor(Math.sin(Math.PI / 180 * deg) * 152)}rpx - 50%), calc(${-Math.floor(Math.cos(Math.PI / 180 * deg) * 152)}rpx - 100%))`
} else {
return `translate(calc(${Math.floor(Math.sin(Math.PI / 180 * deg) * 152)}rpx - 50%), calc(${-Math.floor(Math.cos(Math.PI / 180 * deg) * 152)}rpx ))`
}
} else {
return 'translate(0, 0)'
}
}
},
flagTranslate() {
return function(deg, length) {
if (deg > -60 && deg < 60) {
return `translate(calc(${Math.floor(Math.sin(Math.PI / 180 * deg) * 152)}rpx),calc(-${Math.floor(Math.cos(Math.PI / 180 * deg) * 152)}rpx - 50% - ${Math.ceil(length / 8) * 22}rpx - 10rpx))`
} else {
return 'translate(0%, -34rpx)'
}
}
}
},
mounted() {
},
onLoad() {
this.getPoints()
},
onShow() {
if (this.isBkgLoad) {
this.scroll();
}
}
}
</script>
3 years ago
<style lang="scss">
2 years ago
.wrap{
background: url(../../static/xtdk/map-bg.png) no-repeat top left;
background-size: 100% 100%;
background-color:#fdd5d6;
height: 100vh;
width: 100vw;
}
.top {
width: 100%;
2 years ago
height: 380rpx;
2 years ago
background: transparent;
.logo{
2 years ago
width: 122rpx;
height: 90rpx;
2 years ago
position: absolute;
2 years ago
top: 50rpx;
2 years ago
left: 50%;
transform: translate(-50%, 0);
}
.title{
2 years ago
width: 360rpx;
height: 192rpx;
2 years ago
position: absolute;
2 years ago
top: 170rpx;
2 years ago
left: 50%;
transform: translate(-50%, 0);
}
}
.container {
// background: #FAEDCD;
2 years ago
height: calc(100vh - 380rpx);
// width: 100vw;
width: calc(100vw + 250rpx);
2 years ago
overflow: scroll;
2 years ago
position: relative;
margin-left:-250rpx;
2 years ago
&>img {
width: auto;
height: 100%;
object-fit: contain;
transition: all .2s;
padding: 20rpx 0;
//transform: translateX(-50%);
position: absolute;
top: 0;
left: 0;
}
& .area {
padding: 20rpx 0;
margin: 0 auto;
.pointer {
// width: 16rpx;
// height: 16rpx;
// border-radius: 100%;
// background: #fff;
transform-origin: center;
// border: 3rpx solid #C52A34;
display: inline-block;
position: relative;
&__flag {
//transform: translate(0%, -34rpx);
position: absolute;
top: -30rpx;
2 years ago
right: -10rpx;
2 years ago
}
&__horn {
width: 20rpx;
height: 26rpx;
clip-path: polygon(20% 0, 80% 0%, 50% 100%, 20% 0);
background: #67b8be;
filter: drop-shadow(2rpx 4rpx 2rpx #90D2CF);
transform-origin: 50% 100%;
position: absolute;
&--active {
background: #C52A34;
}
}
& .box {
transform-origin: 0 0;
text-align: center;
position: absolute;
&__text {
// min-width: 160rpx;
// max-width: 220rpx;
word-break: break-all;
background: #d2e9a3;
border-radius: 6rpx;
filter: drop-shadow(2rpx 4rpx 2rpx #90D2CF);
color: #8d4d12;
font-size: 22rpx;
zoom: .85;
text-align: center;
display: inline-block;
// transform: translate(calc(-50% + 58rpx), -100%);
transform: translate(0, -30%);
2 years ago
padding: 10rpx 8rpx;
position: relative;
2 years ago
// position: absolute;
// top: 0;
2 years ago
.icons{
max-height:102rpx;
max-width:68rpx;
position: absolute;
left: -25px;
bottom:0
// transform: translate(0,-50%);
}
2 years ago
&--active {
background: #b93736;
color: #fff;
2 years ago
}
2 years ago
}
&__image {
// width: 116rpx;
// height: 116rpx;
// border-radius: 100%;
box-sizing: border-box;
// border: 5rpx #67b8be solid;
display: flex;
justify-content: center;
align-items: center;
// filter: drop-shadow(2rpx 4rpx 4rpx #90D2CF);
overflow: hidden;
position: relative;
2 years ago
min-width:240rpx;
2 years ago
// max-width: 212rpx;
// width: 212rpx;
// height: 101rpx;
// max-height: 101rpx;
&>img {
// width: auto;
// height: auto;
max-width: 160rpx;
max-height:120rpx;
// border-radius: 100%;
object-fit: cover;
}
}
&--active {
border-color: #b93736;
}
// &--active::before {
// content: '已打卡';
// font-size: 20rpx;
// color: #fff;
// background: #b93736;
// border-radius: 30rpx;
// zoom: .8;
// padding: 10rpx 14rpx 5rpx 124rpx;
// z-index: 2;
// position: absolute;
// top: -1rpx;
// left: -96rpx;
// }
&--active::after {
background: #b93736;
}
}
}
//.pointer {
// width: 16rpx;
// height: 16rpx;
// border-radius: 100%;
// background: #fff;
// border: 3rpx solid #C52A34;
// display: inline-block;
//
// position: relative;
//
// & .text {
// background: #67b8be;
// border-radius: 6rpx;
// word-break: keep-all;
// filter: drop-shadow(2rpx 4rpx 2rpx #90D2CF);
// color: #C52A34;
// font-size: 20rpx;
// text-align: center;
// transform-origin: 50% 0;
//
// padding: 12rpx 10rpx;
// position: absolute;
//
// &--active {
// background: #b93736;
// color: #fff;
// }
// }
// & .box {
// width: 116rpx;
// height: 116rpx;
// border-radius: 100%;
// box-sizing: border-box;
// border: 5rpx #67b8be solid;
// display: flex;
// justify-content: center;
// align-items: center;
// filter: drop-shadow(2rpx 4rpx 2rpx #90D2CF);
// transform-origin: 50% calc(100% + 26rpx + 5rpx);
//
// position: absolute;
// top: calc(-116rpx - 26rpx);
// left: -50rpx;
//
// &--active {
// border-color: #b93736;
// }
// & > img {
// width: 106rpx;
// height: 106rpx;
// border-radius: 100%;
//
// }
// &::after {
// content: '';
// height: 26rpx;
// width: 22rpx;
// background: #67b8be;
// clip-path: polygon(0 0, 100% 0, 50% 100%,0 0);
//
// transform: translate(-50% , 100%);
// position: absolute;
// bottom: 0;
// left: 50%;
// }
// &--active::before {
// content: '已打卡';
// font-size: 20rpx;
// color: #fff;
// background: #b93736;
// border-radius: 30rpx;
// zoom: .8;
// clip-path: circle(84rpx at 84% 178%);
//
// padding: 6rpx 14rpx 5rpx 122rpx;
// z-index: 2;
// position: absolute;
// top: -1rpx;
// left: -96rpx;
// }
// &--active::after {
// background: #b93736;
// }
// }
//}
}
}
.expand-progress {
color: #D33838;
background: #67b8be;
word-break: break-word;
font-size: 20rpx;
width: 20rpx;
border-radius: 10rpx 0 0 10rpx;
filter: drop-shadow(4rpx 4rpx 4rpx #F08456) drop-shadow(4rpx 10rpx 8rpx #F6A996);
padding: 10rpx 18rpx;
}
.progress {
z-index: 999;
position: fixed;
right: 0;
bottom: 40rpx;
& .close {
transform: translateX(-100%);
position: absolute;
top: -2rpx;
left: 0;
}
& .box {
background: #67b8be;
border-radius: 30rpx 0 0 30rpx;
filter: drop-shadow(4rpx 4rpx 4rpx #F08456) drop-shadow(8rpx 10rpx 8rpx #F6A996);
padding: 20rpx 22rpx;
padding-top:90rpx;
::v-deep .u-progress {
overflow: visible !important;
}
::v-deep .u-active {
border-radius: 20rpx;
position: relative;
}
&__line-progress {
width: 282rpx;
height: 30rpx;
display: flex;
align-items: center;
position: relative;
&--bkg {
display: flex;
transform: translateY(calc(-100% - 7rpx));
position: absolute;
top: 50%;
left: 0;
}
&--img {
overflow: auto;
transform: translateX(50%);
position: absolute;
right: 0;
}
}
&__text {
text-align: center;
zoom: .95;
font-size: 16rpx;
font-weight: 400;
color: #666666;
&--red {
font-size: 30rpx;
color: #D33838;
font-weight: 600;
}
}
}
}
.fade-in {
animation: fade-in .8s cubic-bezier(0.39, 0.575, 0.565, 1) both;
}
@keyframes fade-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.fade-out {
animation: fade-out 0.6s ease-out both;
}
@keyframes fade-out {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
</style>