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.
369 lines
8.5 KiB
369 lines
8.5 KiB
<template>
|
|
<div style="background: #FAEDCD;">
|
|
<div class="top">
|
|
<u-image mode="scaleToFill" width="100%" height="100%" :src="require('@/static/map-title-bkg.png')"></u-image>
|
|
</div>
|
|
<div class="container">
|
|
<img ref="image"
|
|
src="static/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(index))">
|
|
<div class="box" :style="{ 'transform': `rotate(${item.d}deg)` }">
|
|
<img :style="{ 'transform': `rotate(${-item.d}deg)` }" :src="item.image.url" alt="">
|
|
|
|
</div>
|
|
|
|
<div class="text"
|
|
:style="{
|
|
'transform': translateText(item.d)
|
|
}">
|
|
{{ item.name }}
|
|
</div>
|
|
</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="25" color="#666666" @click="isShowProgress = false"></u-icon>
|
|
</div>
|
|
<div class="box">
|
|
<div class="box__line-progress">
|
|
<u-line-progress :height="11" active-color="#b93736" :striped="true" :percent="70" :striped-active="true">
|
|
<template #default>
|
|
<div class="box__line-progress--img">
|
|
<u-image mode="heightFix" :height="97" :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">{{pointers.length}}</span>
|
|
<span>家红色场馆打卡</span><br><span>即可获得</span>
|
|
<span class="box__text--red">荣誉证书</span>
|
|
</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 {
|
|
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: {
|
|
toDetail (id) {
|
|
uni.navigateTo({
|
|
url: `/pages/detail/detail?id=${id}`
|
|
})
|
|
},
|
|
|
|
load () {
|
|
this.area.w = this.$refs['image'].getBoundingClientRect().width
|
|
this.area.h = this.$refs['image'].getBoundingClientRect().height
|
|
},
|
|
|
|
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.baseFormIndex({
|
|
table_name: 'map_points',
|
|
with_relations: ['image']
|
|
})
|
|
this.pointers = res.data.map((i, index) => {
|
|
return {
|
|
name: i.name,
|
|
x: typeof i.x === 'string' ? Number(i.x) : 0,
|
|
y: typeof i.y === 'string' ? Number(i.y) : 0,
|
|
d: convertToEquivalentAngle(30 * index + 1),
|
|
image: i.image
|
|
}
|
|
})
|
|
}
|
|
|
|
},
|
|
computed: {
|
|
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)'
|
|
}
|
|
}
|
|
}
|
|
},
|
|
mounted() {
|
|
|
|
},
|
|
onShow() {
|
|
this.getPoints()
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.top {
|
|
width: 100%;
|
|
height: 247rpx;
|
|
background: transparent;
|
|
}
|
|
.container {
|
|
background: #FAEDCD;
|
|
height: calc(100vh - 247rpx);
|
|
width: 100vw;
|
|
overflow: scroll;
|
|
|
|
position: relative;
|
|
|
|
& > img {
|
|
width: auto;
|
|
height: 100%;
|
|
transition: all .2s;
|
|
|
|
padding: 20rpx 0;
|
|
transform: translateX(-50%);
|
|
position: absolute;
|
|
top: 0;
|
|
left: 50%;
|
|
}
|
|
& .area {
|
|
padding: 20rpx 0;
|
|
margin: 0 auto;
|
|
|
|
.pointer {
|
|
width: 16rpx;
|
|
height: 16rpx;
|
|
border-radius: 100%;
|
|
background: #fff;
|
|
border: 3rpx solid #C52A34;
|
|
display: inline-block;
|
|
|
|
position: relative;
|
|
|
|
& .text {
|
|
background: #F5D8AD;
|
|
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;
|
|
}
|
|
& .box {
|
|
width: 116rpx;
|
|
height: 116rpx;
|
|
border-radius: 100%;
|
|
box-sizing: border-box;
|
|
border: 5rpx #F5D8AD 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;
|
|
|
|
|
|
//&__text {
|
|
// background: #F5D8AD;
|
|
// border-radius: 6rpx;
|
|
// word-break: keep-all;
|
|
// filter: drop-shadow(2rpx 4rpx 2rpx #90D2CF);
|
|
// color: #C52A34;
|
|
// font-size: 20rpx;
|
|
// text-align: center;
|
|
//
|
|
//
|
|
// transform: translate(-50%, -100%);
|
|
// position: absolute;
|
|
// top: 0;
|
|
// left: 50%;
|
|
//}
|
|
& > img {
|
|
width: 106rpx;
|
|
height: 106rpx;
|
|
border-radius: 100%;
|
|
|
|
}
|
|
&::after {
|
|
content: '';
|
|
height: 26rpx;
|
|
width: 22rpx;
|
|
background: #F5D8AD;
|
|
clip-path: polygon(0 0, 100% 0, 50% 100%,0 0);
|
|
|
|
transform: translate(-50% , 100%);
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 50%;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
.expand-progress {
|
|
color: #D33838;
|
|
background: #F5D8AD;
|
|
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: #F5D8AD;
|
|
border-radius: 30rpx 0 0 30rpx;
|
|
filter: drop-shadow(4rpx 4rpx 4rpx #F08456) drop-shadow(8rpx 10rpx 8rpx #F6A996);
|
|
|
|
padding: 20rpx 22rpx;
|
|
|
|
::v-deep .u-progress {
|
|
overflow: visible !important;
|
|
}
|
|
::v-deep .u-active {
|
|
border-radius: 20rpx;
|
|
position: relative;
|
|
}
|
|
&__line-progress {
|
|
width: 282rpx;
|
|
height: 100rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
&--img {
|
|
overflow: auto;
|
|
|
|
transform: translateX(50%);
|
|
position: absolute;
|
|
right: 0;
|
|
}
|
|
}
|
|
|
|
&__text {
|
|
text-align: center;
|
|
zoom: .85;
|
|
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>
|