This commit is contained in:
zyronon 2023-02-13 01:14:26 +08:00
parent 37f3b211a6
commit 16d5cfa089
5 changed files with 179 additions and 94 deletions

View File

@ -1,5 +1,7 @@
<template> <template>
<div class="button" :class="class1" @click.capture.stop="check"> <div class="button" :class="class1"
:style="{'border-radius':radius+'rem'}"
@click.capture.stop="check">
<img v-show="loading" src="../assets/img/icon/loading-white.png" alt=""> <img v-show="loading" src="../assets/img/icon/loading-white.png" alt="">
<slot name="prefix"></slot> <slot name="prefix"></slot>
<slot v-if="showText"></slot> <slot v-if="showText"></slot>
@ -44,6 +46,10 @@ export default {
default: 'normal' default: 'normal'
//small //small
}, },
radius: {
type: String,
default: '3',
}
}, },
data() { data() {
return {} return {}
@ -84,7 +90,6 @@ export default {
color: white; color: white;
height: 40rem; height: 40rem;
line-height: 40rem; line-height: 40rem;
border-radius: 8rem;
//width: 100%; //width: 100%;
font-size: 14rem; font-size: 14rem;
display: flex; display: flex;

View File

@ -1,13 +1,42 @@
<template> <template>
<div id="UserPanel"> <div id="UserPanel"
@scroll="scroll"
ref="page">
<div ref="float" class="float" :class="state.floatFixed?'fixed':''">
<div class="left" @click="back">
<img class="back" src="@/assets/img/icon/next.svg" alt="">
<transition name="fade">
<div class="float-user" v-if="state.floatFixed">
<img v-lazy="Utils.$imgPreview(state.localAuthor.avatar)" class="avatar"/>
<img v-if="!state.localAuthor.is_follow" src="@/assets/img/icon/add-light.png" alt="" class="add">
<span @click="followButton">{{ state.localAuthor.is_follow ? '私信' : '关注' }}</span>
</div>
</transition>
</div>
<div class="right">
<transition name="fade">
<div class="request" v-if="!state.floatFixed && state.localAuthor.is_follow">
<img @click="$nav('/me/request-update')" src="@/assets/img/icon/me/finger-right.png" alt="">
<span>求更新</span>
</div>
</transition>
<img class="menu" src="@/assets/img/icon/search-light.png" alt="">
<img class="menu" src="@/assets/img/icon/more.svg" alt="" @click.stop="$emit('showFollowSetting')">
</div>
</div>
<div class="main" <div class="main"
ref="scroll" ref="main"
@touchstart="touchStart($event)" @touchstart="touchStart"
@touchmove="touchMove($event)" @touchmove="touchMove"
@touchend="touchEnd($event)"> @touchend="touchEnd">
<header ref="header" <!-- src="@/assets/img/header-bg.png" -->
:style='{backgroundImage: `url(${state.localAuthor.cover})`}' <header>
@click="state.previewImg = state.localAuthor.cover"> <img
ref="cover"
:src="state.localAuthor.cover"
@click="state.previewImg = state.localAuthor.cover"
alt=""
class="cover">
<div class="avatar-wrapper"> <div class="avatar-wrapper">
<img v-lazy="Utils.$imgPreview(state.localAuthor.avatar)" class="avatar" <img v-lazy="Utils.$imgPreview(state.localAuthor.avatar)" class="avatar"
@click="state.previewImg = state.localAuthor.avatar"> @click="state.previewImg = state.localAuthor.avatar">
@ -99,7 +128,7 @@
</div> </div>
<div class="option" <div class="option"
:class="state.isShowRecommend?'option-recommend':''" :class="state.isShowRecommend?'option-recommend':''"
@click="state.toggleRecommend"> @click="state.isShowRecommend = !state.isShowRecommend">
<img v-if="state.loadings.showRecommend" class="loading" src="@/assets/img/icon/loading-gray.png" <img v-if="state.loadings.showRecommend" class="loading" src="@/assets/img/icon/loading-gray.png"
alt=""> alt="">
<img v-else class="arrow" src="@/assets/img/icon/arrow-up-white.png" alt=""> <img v-else class="arrow" src="@/assets/img/icon/arrow-up-white.png" alt="">
@ -108,25 +137,18 @@
<div class="recommend" :class="{hidden:!state.isShowRecommend}"> <div class="recommend" :class="{hidden:!state.isShowRecommend}">
<div class="title"> <div class="title">
<div class="left"> <span>你可能感兴趣</span>
<span>你可能感兴趣</span> <img src="@/assets/img/icon/about-gray.png">
<img src="@/assets/img/icon/about-gray.png">
</div>
<div class="right" @click="$nav('/people/find-acquaintance')">
<span>查看更多</span>
<back direction="right"></back>
</div>
</div> </div>
<div class="friends" <div class="friends"
@touchstart="friendsTouchStart" @touchmove="stop">
@touchend="friendsTouchEnd">
<div class="friend" v-for="item in friends.all"> <div class="friend" v-for="item in friends.all">
<img :style="item.select?'opacity: .5;':''" class="avatar" :src="$imgPreview(item.avatar)" alt=""> <img :style="item.select?'opacity: .5;':''" class="avatar" :src="$imgPreview(item.avatar)" alt="">
<span class="name">{{ item.name }}</span> <span class="name">{{ item.name }}</span>
<span class="tips">可能感兴趣的人</span> <span class="tips">可能感兴趣的人</span>
<b-button type="primary">关注</b-button> <b-button type="primary">关注</b-button>
<div class="close"> <div class="close">
<back img="close" scale=".6"></back> <dy-back img="close" scale=".6"></dy-back>
</div> </div>
</div> </div>
<div class="more" @click="$nav('/people/find-acquaintance')"> <div class="more" @click="$nav('/people/find-acquaintance')">
@ -137,11 +159,10 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<div class="total"> <div class="total" ref="total">
作品 62 作品 62
<img class="arrow" src="@/assets/img/icon/arrow-up-white.png" alt=""> <img class="arrow" src="@/assets/img/icon/arrow-up-white.png" alt="">
</div>
</div> </div>
<div class="videos"> <div class="videos">
<Posters v-if="state.videos.my.total !== -1" :list="state.videos.my.list"></Posters> <Posters v-if="state.videos.my.total !== -1" :list="state.videos.my.list"></Posters>
@ -151,7 +172,7 @@
</template> </template>
<script setup> <script setup>
import {onMounted, reactive} from "vue"; import {computed, onMounted, reactive, ref} from "vue";
import Utils from "@/utils"; import Utils from "@/utils";
import {useNav} from "@/utils/hooks/useNav"; import {useNav} from "@/utils/hooks/useNav";
import {useStore} from "vuex"; import {useStore} from "vuex";
@ -171,10 +192,13 @@ const props = defineProps({
} }
}) })
const friends = () => store.friends const friends = computed(() => store.state.friends)
const main = ref(null)
const page = ref(null)
const cover = ref(null)
const total = ref(null)
const state = reactive({ const state = reactive({
isShowRecommend: false,// isShowRecommend: false,//
isLoadRecommendFriends: false,//friends.all
previewImg: '', previewImg: '',
contentIndex: 0, contentIndex: 0,
baseActiveIndex: 0, baseActiveIndex: 0,
@ -236,7 +260,15 @@ const state = reactive({
acceleration: 1.2, acceleration: 1.2,
sprint: 15, sprint: 15,
canScroll: true, canScroll: true,
localAuthor: resource.videos[0].author localAuthor: resource.videos[0].author,
start: {x: 0, y: 0, time: 0},
move: {x: 0, y: 0},
isTop: false,
coverHeight: 240,
//
canMoveMaxHeight: document.body.clientHeight / 4,
//Cover
isAutoScaleCover: false
}) })
onMounted(() => { onMounted(() => {
@ -244,19 +276,66 @@ onMounted(() => {
state.videos.my.total = resource.my.length state.videos.my.total = resource.my.length
}) })
function friendsTouchStart() { function stop(e){
e.stopPropagation()
}
function followButton() {
} }
function friendsTouchEnd() { function back() {
} }
function touchStart() { function scroll(e) {
// console.log('scroll', page.value.scrollTop)
let scrollTop = page.value.scrollTop
let totalY = total.value.getBoundingClientRect().y
state.floatFixed = totalY <= 46
let isTop = scrollTop === 0
if (isTop && state.isAutoScaleCover) {
cover.value.style.transition = 'all .1s'
cover.value.style.height = `calc(${state.coverHeight}rem + ${state.canMoveMaxHeight}px)`
setTimeout(() => {
cover.value.style.transition = 'all .4s'
cover.value.style.height = `calc(${state.coverHeight}rem)`
state.isAutoScaleCover = false
}, 200)
}
} }
function touchMove() { function touchStart(e) {
state.start.x = e.touches[0].pageX
state.start.y = e.touches[0].pageY
state.start.time = Date.now()
state.isTop = page.value.scrollTop === 0
if (state.isTop) {
cover.value.style.transition = 'none'
}
console.log('touchStart', page.value.scrollTop)
} }
function touchEnd() { function touchMove(e) {
state.move.x = e.touches[0].pageX - state.start.x
state.move.y = e.touches[0].pageY - state.start.y
let isNext = state.move.y < 0
// console.log('touchMove', page.value.scrollTop)
//todo
if (state.isTop && !isNext && (document.body.clientHeight / 4 > state.move.y)) {
// if (state.isTop && !isNext) {
let scrollHeight = state.move.y
cover.value.style.height = `calc(${state.coverHeight}rem + ${scrollHeight}px)`
}
}
function touchEnd(e) {
if (state.isTop) {
state.isTop = false
cover.value.style.transition = 'all .3s'
cover.value.style.height = `calc(${state.coverHeight}rem)`
}
let endTime = Date.now()
state.isAutoScaleCover = (endTime - state.start.time) < 100
console.log('touchEnd')
} }
</script> </script>
@ -285,6 +364,7 @@ function touchEnd() {
background: @main-bg; background: @main-bg;
height: 100%; height: 100%;
width: 100%; width: 100%;
overflow: auto;
font-size: 14rem; font-size: 14rem;
.preview-img { .preview-img {
@ -461,17 +541,17 @@ function touchEnd() {
} }
header { header {
color: white;
height: 240rem;
background-image: url('@/assets/img/header-bg.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
box-sizing: border-box;
position: relative; position: relative;
color: white;
.cover {
height: 240rem;
object-fit: cover;
width: 100vw;
//transition: height .3s;
}
.avatar-wrapper { .avatar-wrapper {
width: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
box-sizing: border-box; box-sizing: border-box;
@ -526,7 +606,7 @@ function touchEnd() {
position: relative; position: relative;
z-index: 1; z-index: 1;
background: @main-bg; background: @main-bg;
padding: 0 20rem 15rem 20rem; padding: 0 20rem;
border-radius: 10rem 10rem 0 0; border-radius: 10rem 10rem 0 0;
margin-top: -20rem; margin-top: -20rem;
@ -625,6 +705,7 @@ function touchEnd() {
.my-buttons { .my-buttons {
margin-top: 20rem; margin-top: 20rem;
margin-bottom: 20rem;
overflow: hidden; overflow: hidden;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
@ -698,7 +779,6 @@ function touchEnd() {
} }
} }
.option { .option {
position: relative; position: relative;
width: @width; width: @width;
@ -745,39 +825,28 @@ function touchEnd() {
.recommend { .recommend {
transition: all .3s ease; transition: all .3s ease;
height: 220rem; height: 230rem;
overflow: hidden; overflow: hidden;
margin-bottom: 20rem;
&.hidden { &.hidden {
height: 0; height: 0;
} }
.title { .title {
padding: 0 20rem 0 20rem;
font-size: 12rem; font-size: 12rem;
color: @second-text-color; color: @second-text-color;
display: flex; display: flex;
justify-content: space-between; align-items: center;
.left {
display: flex;
align-items: center;
}
img { img {
margin-left: 3rem; margin-left: 3rem;
width: 13rem; width: 13rem;
height: 13rem; height: 13rem;
} }
.right {
display: flex;
align-items: center;
}
} }
.friends { .friends {
padding-left: 20rem;
margin-top: 10rem; margin-top: 10rem;
display: flex; display: flex;
overflow-x: scroll; overflow-x: scroll;
@ -837,19 +906,24 @@ function touchEnd() {
} }
} }
} }
}
.total { .total {
color: white; background: @main-bg;
display: flex; color: white;
align-items: center; display: flex;
margin-top: 20rem; align-items: center;
padding: 15rem 20rem;
padding-top: 0rem;
position: sticky;
top: 46rem;
z-index: 2;
img { img {
transform: rotate(180deg); transform: rotate(180deg);
margin-left: 5rem; margin-left: 5rem;
width: 12rem; width: 12rem;
height: 12rem; height: 12rem;
}
} }
} }
@ -871,12 +945,6 @@ function touchEnd() {
background: transparent; background: transparent;
transition: all .2s; transition: all .2s;
.center {
left: 50%;
transform: translateX(-50%);
position: absolute;
color: white;
}
&.fixed { &.fixed {
background: @main-bg; background: @main-bg;
@ -887,30 +955,41 @@ function touchEnd() {
} }
.left { .left {
img { display: flex;
align-items: center;
.back {
transform: rotate(180deg); transform: rotate(180deg);
border-radius: 50%; border-radius: 50%;
background: rgba(82, 80, 80, 0.5); background: rgba(82, 80, 80, 0.5);
padding: 6rem; padding: 6rem;
width: 18rem; width: 18rem;
} }
}
.follow-btn { .float-user {
color: white; display: inline-flex;
position: absolute; margin-left: 32rem;
font-size: 12rem; color: white;
padding: 3rem 12rem; font-size: 12rem;
border-radius: 2rem; align-items: center;
right: 60rem; background: @second-btn-color-tran;
background: @primary-btn-color; height: 22rem;
border-radius: 40rem;
padding: 1rem 10rem 1rem 1rem;
&.followed { .add {
background: @second-btn-color; width: 12rem;
margin-right: 2rem;
}
.avatar {
width: 20rem;
border-radius: 50%;
margin-right: 5rem;
}
} }
} }
.right { .right {
display: flex; display: flex;
color: white; color: white;

View File

@ -103,7 +103,7 @@
</SlideItem> </SlideItem>
<SlideItem class=" gray"> <SlideItem class=" gray">
<!-- <div class="big" v-for="i in 100">主页</div>--> <!-- <div class="big" v-for="i in 100">主页</div>-->
<Uploader <UserPanel
ref="uploader" ref="uploader"
:isOnThisPage="state.baseIndex === 1" :isOnThisPage="state.baseIndex === 1"
:author="state.recommendVideos[state.itemIndex]?.author" :author="state.recommendVideos[state.itemIndex]?.author"
@ -202,6 +202,7 @@ import FollowSetting2 from "@/pages/home/components/FollowSetting2";
import Dom from "../../utils/dom"; import Dom from "../../utils/dom";
import ShareToFriend from "@/pages/home/components/ShareToFriend"; import ShareToFriend from "@/pages/home/components/ShareToFriend";
import resource from "@/assets/data/resource"; import resource from "@/assets/data/resource";
import UserPanel from "@/components/UserPanel.vue";
const nav = useNav() const nav = useNav()

View File

@ -3,8 +3,8 @@
<!-- <SlideUser></SlideUser>--> <!-- <SlideUser></SlideUser>-->
<!-- <SlideImgs></SlideImgs>--> <!-- <SlideImgs></SlideImgs>-->
<!-- <TestSwiperJs></TestSwiperJs>--> <!-- <TestSwiperJs></TestSwiperJs>-->
<!-- <slideHooks></slideHooks>--> <slideHooks/>
<UserPanel/> <!-- <UserPanel/>-->
<!-- <div class="body">--> <!-- <div class="body">-->
<!-- <div class="wrapper">--> <!-- <div class="wrapper">-->

View File

@ -31,7 +31,7 @@ export default {
Footer, Footer,
Mask, Mask,
NoMore, NoMore,
Back, 'dy-back': Back,
Loading, Loading,
'b-button': BaseButton 'b-button': BaseButton
}, },