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
686 lines
17 KiB
<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)' : '' }">
|
|
<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> -->
|
|
{{ item.name }}</div>
|
|
<u-image class="pointer__flag"
|
|
v-if="item.has_answer > 0"
|
|
: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>
|
|
<div class="box" @click="$u.throttle(toCertificate(done !== pointers.length))">
|
|
<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>
|
|
<span class="box__text--red" @click="$u.throttle(toCertificate(false))">荣誉证书</span>
|
|
</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'),
|
|
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:'',
|
|
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
|
|
},
|
|
]
|
|
};
|
|
},
|
|
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'
|
|
})
|
|
}
|
|
},
|
|
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>
|
|
|
|
<style lang="scss">
|
|
.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%;
|
|
height: 380rpx;
|
|
background: transparent;
|
|
.logo{
|
|
width: 122rpx;
|
|
height: 90rpx;
|
|
position: absolute;
|
|
top: 50rpx;
|
|
left: 50%;
|
|
transform: translate(-50%, 0);
|
|
}
|
|
.title{
|
|
width: 360rpx;
|
|
height: 192rpx;
|
|
position: absolute;
|
|
top: 170rpx;
|
|
left: 50%;
|
|
transform: translate(-50%, 0);
|
|
}
|
|
}
|
|
|
|
.container {
|
|
// background: #FAEDCD;
|
|
height: calc(100vh - 380rpx);
|
|
// width: 100vw;
|
|
width: calc(100vw + 250rpx);
|
|
overflow: scroll;
|
|
|
|
position: relative;
|
|
margin-left:-250rpx;
|
|
|
|
&>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;
|
|
right: -10rpx;
|
|
}
|
|
|
|
&__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%);
|
|
|
|
padding: 10rpx 8rpx;
|
|
position: relative;
|
|
// position: absolute;
|
|
// top: 0;
|
|
.icons{
|
|
max-height:102rpx;
|
|
max-width:68rpx;
|
|
position: absolute;
|
|
left: -25px;
|
|
bottom:0
|
|
// transform: translate(0,-50%);
|
|
}
|
|
&--active {
|
|
background: #b93736;
|
|
color: #fff;
|
|
}
|
|
|
|
}
|
|
|
|
&__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;
|
|
min-width:240rpx;
|
|
// 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> |