save
This commit is contained in:
parent
da1860cf87
commit
9ff3b92709
23
index.html
23
index.html
@ -9,6 +9,22 @@
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0,user-scalable=no"
|
||||
id="viewport"/>
|
||||
<title>Douyin</title>
|
||||
<script crossorigin="anonymous"
|
||||
integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ=="
|
||||
src="https://lib.baomitu.com/jquery/3.6.0/jquery.min.js"></script>
|
||||
<!-- <script crossorigin="anonymous"-->
|
||||
<!-- integrity="sha512-KkkY/3auRhaXDFzFMpwtZ+BrS8EBQ+GfiBxdJ9jGMi6Gg74/sYbq/IZpY593pkNjTmbeRfBwjpZo+7gcpH45Ww=="-->
|
||||
<!-- src="https://lib.baomitu.com/eruda/3.0.1/eruda.min.js"></script>-->
|
||||
<!-- <script>eruda.init();</script>-->
|
||||
<script>
|
||||
var _hmt = _hmt || [];
|
||||
(function () {
|
||||
var hm = document.createElement("script");
|
||||
hm.src = "https://hm.baidu.com/hm.js?6f910830f5a7d8b5f7e75d8d67458a7a";
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
</script>
|
||||
<style>
|
||||
::-webkit-scrollbar {
|
||||
display: none; /* Chrome Safari */
|
||||
@ -41,13 +57,6 @@
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script crossorigin="anonymous"
|
||||
integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ=="
|
||||
src="https://lib.baomitu.com/jquery/3.6.0/jquery.min.js"></script>
|
||||
<!-- <script crossorigin="anonymous"-->
|
||||
<!-- integrity="sha512-KkkY/3auRhaXDFzFMpwtZ+BrS8EBQ+GfiBxdJ9jGMi6Gg74/sYbq/IZpY593pkNjTmbeRfBwjpZo+7gcpH45Ww=="-->
|
||||
<!-- src="https://lib.baomitu.com/eruda/3.0.1/eruda.min.js"></script>-->
|
||||
<!-- <script>eruda.init();</script>-->
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
import {onMounted, reactive, ref, watch} from "vue";
|
||||
import {onMounted, onUnmounted, reactive, ref, watch} from "vue";
|
||||
import GM from '../../utils'
|
||||
import {
|
||||
getSlideDistance,
|
||||
@ -30,6 +30,7 @@ const props = defineProps({
|
||||
})
|
||||
const emit = defineEmits(['update:index'])
|
||||
|
||||
let ob = null
|
||||
const judgeValue = 20
|
||||
const wrapperEl = ref(null)
|
||||
const state = reactive({
|
||||
@ -57,6 +58,15 @@ watch(
|
||||
|
||||
onMounted(() => {
|
||||
slideInit(wrapperEl.value, state, SlideType.HORIZONTAL)
|
||||
|
||||
ob = new MutationObserver(() => {
|
||||
state.wrapper.childrenLength = wrapperEl.value.children.length
|
||||
});
|
||||
ob.observe(wrapperEl.value, {'childList': true,});
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
ob.disconnect()
|
||||
})
|
||||
|
||||
function touchStart(e) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import resource from "../assets/data/resource.js";
|
||||
import posts6 from "@/assets/data/posts6.json";
|
||||
import {cloneDeep} from '@/utils'
|
||||
import {_copy, cloneDeep} from '@/utils'
|
||||
import {BASE_URL} from "@/config";
|
||||
import {useBaseStore} from "@/store/pinia";
|
||||
import axiosInstance from "@/utils/request";
|
||||
|
||||
@ -39,11 +39,12 @@
|
||||
</template>
|
||||
</ScrollList>
|
||||
|
||||
<div class="shadow">
|
||||
<AlbumDetail v-if="state.d"
|
||||
:detail="state.current"
|
||||
@close="close"/>
|
||||
</div>
|
||||
<teleport to="body">
|
||||
<div class="shadow">
|
||||
<div class="wrap"></div>
|
||||
<AlbumDetail :detail="state.current" @close="close"/>
|
||||
</div>
|
||||
</teleport>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -97,20 +98,30 @@ watch(() => props.active, n => {
|
||||
function close() {
|
||||
let s = $('.shadow ')
|
||||
let domRect = rect.value
|
||||
// $('.cover-card').fadeIn()
|
||||
s.css('transition', 'all .3s')
|
||||
let t = '.3'
|
||||
s.css('transition', `all ${t}s`)
|
||||
s.css('top', domRect.top)
|
||||
s.css('left', domRect.left)
|
||||
s.css('width', domRect.width)
|
||||
s.css('height', domRect.height)
|
||||
$('.cover-card').css('transition', 'all .3s')
|
||||
$('.cover-card').css('opacity', '1')
|
||||
$('.cover-card').css('z-index', '1')
|
||||
|
||||
let a = $('.goods-detail')
|
||||
a.css('transition', `all ${t}s`)
|
||||
a.css('opacity', '0')
|
||||
a.css('width', '100vw')
|
||||
a.css('height', '100vh')
|
||||
a.css('transform', `scale(${domRect.sw},${domRect.sh})`)
|
||||
a.css('transform-origin', `0 0`)
|
||||
|
||||
let d = $('.shadow .wrap')
|
||||
d.css('transition', `all ${t}s`)
|
||||
d.css('opacity', '1')
|
||||
|
||||
// state.d = false
|
||||
setTimeout(() => {
|
||||
s.css('z-index', '-100')
|
||||
s.css('transition', 'all 0s')
|
||||
s.css('top', '-1000vh')
|
||||
s.css('top', '-200vh')
|
||||
}, 300)
|
||||
}
|
||||
|
||||
@ -126,43 +137,55 @@ function test(e, item) {
|
||||
item.note_card.interact_info.collect_count = Mock.Random.integer(60, 3000)
|
||||
item.note_card.interact_info.share_count = Mock.Random.integer(60, 3000)
|
||||
state.current = cloneDeep(item)
|
||||
console.log(state.current)
|
||||
// console.log(state.current)
|
||||
|
||||
state.d = true
|
||||
let domRect = e.currentTarget.getBoundingClientRect()
|
||||
console.log('e', domRect)
|
||||
// console.log('e', domRect)
|
||||
let s = $('.shadow ')
|
||||
|
||||
s.css('z-index', '1')
|
||||
s.css('transition', '0s')
|
||||
s.css('top', domRect.top)
|
||||
s.css('left', domRect.left)
|
||||
s.css('width', domRect.width)
|
||||
s.css('height', domRect.height)
|
||||
|
||||
let t = '.3'
|
||||
let d = $('.shadow .wrap')
|
||||
d.empty()
|
||||
d.show()
|
||||
d.append($(e.currentTarget).clone())
|
||||
d.css('transition', `all ${t}s`)
|
||||
d.css('opacity', '1')
|
||||
|
||||
let sw = domRect.width / baseStore.bodyWidth
|
||||
let sh = domRect.height / baseStore.bodyHeight
|
||||
console.log('sw', sw,sh)
|
||||
// s.css('width', domRect.width)
|
||||
// s.css('height', domRect.height)
|
||||
domRect.sw = sw
|
||||
domRect.sh = sh
|
||||
|
||||
s.css('width', '100vw')
|
||||
s.css('height', '100vh')
|
||||
s.css('transform', `scale(${sw},${sh})`)
|
||||
s.css('transform-origin', `0 0`)
|
||||
let $cover = $('.cover-card');
|
||||
// $cover.show()
|
||||
let a = $('.goods-detail')
|
||||
a.css('opacity', '0')
|
||||
a.css('width', '100vw')
|
||||
a.css('height', '100vh')
|
||||
a.css('transform', `scale(${domRect.sw},${domRect.sh})`)
|
||||
a.css('transform-origin', `0 0`)
|
||||
|
||||
rect.value = domRect
|
||||
|
||||
setTimeout(() => {
|
||||
// w.fadeOut()
|
||||
s.css('transition', 'all 5s')
|
||||
// $cover.css('transition', 'all 5s')
|
||||
// $cover.css('opacity', '0')
|
||||
// $cover.css('z-index', '-1')
|
||||
s.css('transition', `all ${t}s`)
|
||||
s.css('top', 0)
|
||||
s.css('left', 0)
|
||||
s.css('transform', `scale(1,1)`)
|
||||
s.css('transform-origin', `0 0`)
|
||||
s.css('width', '100vw')
|
||||
s.css('height', '100vh')
|
||||
|
||||
d.css('opacity', '0')
|
||||
d.css('z-index', '-1')
|
||||
|
||||
a.css('transition', `all ${t}s`)
|
||||
a.css('opacity', '1')
|
||||
a.css('transform', `scale(1,1)`)
|
||||
a.css('transform-origin', `0 0`)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@ -211,71 +234,75 @@ function test(e, item) {
|
||||
width: 96vw;
|
||||
}
|
||||
|
||||
.card {
|
||||
border-radius: 4rem;
|
||||
overflow: hidden;
|
||||
background: var(--main-bg);
|
||||
}
|
||||
|
||||
.poster {
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
//height: 33vh;
|
||||
}
|
||||
.card {
|
||||
border-radius: 4rem;
|
||||
overflow: hidden;
|
||||
background: var(--main-bg);
|
||||
|
||||
.bottom {
|
||||
color: gainsboro;
|
||||
padding: 10rem;
|
||||
|
||||
.title {
|
||||
font-size: 14rem;
|
||||
margin-bottom: 8rem;
|
||||
}
|
||||
|
||||
.b2 {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.user {
|
||||
display: flex;
|
||||
font-size: 12rem;
|
||||
|
||||
img {
|
||||
width: 15rem;
|
||||
border-radius: 50%;
|
||||
margin-right: 5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.star {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 3rem;
|
||||
|
||||
svg {
|
||||
font-size: 15rem;
|
||||
}
|
||||
|
||||
.num {
|
||||
font-size: 12rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.poster {
|
||||
display: block;
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
//height: 33vh;
|
||||
}
|
||||
|
||||
.shadow {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100vw;
|
||||
transition: all .3s;
|
||||
overflow: hidden;
|
||||
.bottom {
|
||||
color: gainsboro;
|
||||
padding: 10rem;
|
||||
|
||||
.wrap {
|
||||
position: absolute;
|
||||
z-index: 9999;
|
||||
.title {
|
||||
font-size: 14rem;
|
||||
margin-bottom: 8rem;
|
||||
}
|
||||
|
||||
.b2 {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.user {
|
||||
display: flex;
|
||||
font-size: 12rem;
|
||||
|
||||
img {
|
||||
width: 15rem;
|
||||
border-radius: 50%;
|
||||
margin-right: 5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.star {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 3rem;
|
||||
|
||||
svg {
|
||||
font-size: 15rem;
|
||||
}
|
||||
|
||||
.num {
|
||||
font-size: 12rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.shadow {
|
||||
background: var(--color-message);
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: -200vh;
|
||||
width: 100vw;
|
||||
transition: all .3s;
|
||||
overflow: hidden;
|
||||
|
||||
.wrap {
|
||||
position: absolute;
|
||||
z-index: 9999;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@ -1,64 +1,62 @@
|
||||
<template>
|
||||
<div class="goods-detail base-page1">
|
||||
<div class="goods-detail">
|
||||
<header>
|
||||
<Icon
|
||||
@click="$emit('close')"
|
||||
@click="close"
|
||||
icon="material-symbols-light:arrow-back-ios-new"/>
|
||||
<div class="option" @click="nav('/home/search')">
|
||||
<Icon icon="jam:search"/>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="slide-imgs"
|
||||
@click="$emit('close')"
|
||||
>
|
||||
<SlideHorizontal v-model:index="state.index">
|
||||
<SlideItem v-for="item in props.detail.note_card?.image_list">
|
||||
<img :src="_checkImgUrl(item.info_list?.[0]?.url)" alt="">
|
||||
</SlideItem>
|
||||
</SlideHorizontal>
|
||||
<div class="scroll" ref="scrollEl">
|
||||
<div class="slide-imgs">
|
||||
<SlideHorizontal v-model:index="state.index">
|
||||
<SlideItem v-for="item in props.detail.note_card?.image_list">
|
||||
<img :src="_checkImgUrl(item.info_list?.[0]?.url)" alt="">
|
||||
</SlideItem>
|
||||
</SlideHorizontal>
|
||||
|
||||
<div class="indicator-bar" v-if="props.detail.note_card?.image_list?.length > 1">
|
||||
<div class="indicator"
|
||||
:class="[i <= state.index+1 && 'active']"
|
||||
v-for="i in props.detail.note_card?.image_list?.length"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div class="shop">
|
||||
<header>
|
||||
<img class="avatar" :src="_checkImgUrl(props.detail.note_card?.user?.avatar)"/>
|
||||
<div class="right">
|
||||
<div class="name">{{ props.detail.note_card.user.nick_name }}</div>
|
||||
<div class="r" @click="$emit('close')">关注</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="desc">
|
||||
{{ props.detail.note_card?.display_title }}
|
||||
<div class="indicator-bar" v-if="props.detail.note_card?.image_list?.length > 1">
|
||||
<div class="indicator"
|
||||
:class="[i <= state.index+1 && 'active']"
|
||||
v-for="i in props.detail.note_card?.image_list?.length"></div>
|
||||
</div>
|
||||
<div class="date">{{ props.detail.note_card.createTime }}</div>
|
||||
</div>
|
||||
|
||||
<div class="card comments">
|
||||
<header>
|
||||
<span class="l">评论 {{ props.detail.note_card.comment_list.length }}</span>
|
||||
<div class="r">
|
||||
<span>查看全部</span>
|
||||
<Icon class="arrow" icon="mingcute:right-line"/>
|
||||
<div class="content">
|
||||
<div class="shop">
|
||||
<header>
|
||||
<img class="avatar" :src="_checkImgUrl(props.detail.note_card?.user?.avatar)"/>
|
||||
<div class="right">
|
||||
<div class="name">{{ props.detail.note_card.user.nick_name }}</div>
|
||||
<div class="r">关注</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="desc">
|
||||
{{ props.detail.note_card?.display_title }}
|
||||
</div>
|
||||
</header>
|
||||
<div class="comment"
|
||||
@click="$emit('close')"
|
||||
v-for="i in props.detail.note_card.comment_list.slice(0,2)">
|
||||
<img src="https://cdn.seovx.com/?mom=302" alt="" class="avatar">
|
||||
<span>
|
||||
<div class="date">{{ props.detail.note_card.createTime }}</div>
|
||||
</div>
|
||||
|
||||
<div class="card comments">
|
||||
<header>
|
||||
<span class="l">评论 {{ props.detail.note_card.comment_list.length }}</span>
|
||||
<div class="r">
|
||||
<span>查看全部</span>
|
||||
<Icon class="arrow" icon="mingcute:right-line"/>
|
||||
</div>
|
||||
</header>
|
||||
<div class="comment"
|
||||
v-for="i in props.detail.note_card.comment_list.slice(0,2)">
|
||||
<img src="https://cdn.seovx.com/?mom=302" alt="" class="avatar">
|
||||
<span>
|
||||
{{ i.name }}:{{ i.text }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="toolbar">
|
||||
<div class="input-wrap">
|
||||
说点什么...
|
||||
@ -82,41 +80,18 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cover-card"
|
||||
@click="$emit('close')"
|
||||
>
|
||||
<img class="poster" v-lazy="_checkImgUrl(props.detail.note_card?.cover?.url_default)"/>
|
||||
<div class="bottom">
|
||||
<div class="title">
|
||||
{{ props.detail.note_card?.display_title }}
|
||||
</div>
|
||||
<div class="b2">
|
||||
<div class="user">
|
||||
<img class="avatar" :src="_checkImgUrl(props.detail.note_card?.user?.avatar)"/>
|
||||
<div class="name">{{ props.detail.note_card?.user?.nickname }}</div>
|
||||
</div>
|
||||
<div class="star">
|
||||
<Icon icon="solar:heart-linear"/>
|
||||
<div class="num">{{ props.detail.note_card?.interact_info?.liked_count }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import SlideHorizontal from "@/components/slide/SlideHorizontal.vue";
|
||||
import SlideItem from "@/components/slide/SlideItem.vue";
|
||||
import {onMounted, reactive} from "vue";
|
||||
import {reactive, ref} from "vue";
|
||||
import {useNav} from "@/utils/hooks/useNav";
|
||||
import {Icon} from "@iconify/vue";
|
||||
import {useBaseStore} from "@/store/pinia";
|
||||
import {_checkImgUrl} from "@/utils";
|
||||
|
||||
const nav = useNav()
|
||||
const store = useBaseStore()
|
||||
|
||||
defineOptions({
|
||||
name: 'Album-Detail'
|
||||
@ -126,29 +101,27 @@ const props = defineProps({
|
||||
detail: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {
|
||||
"id": "",
|
||||
"note_card": {
|
||||
"interact_info": {},
|
||||
"cover": {},
|
||||
"image_list": [],
|
||||
"display_title": "",
|
||||
"user": {},
|
||||
comment_list: [],
|
||||
createTime: ''
|
||||
}
|
||||
}
|
||||
return {}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits({
|
||||
close: []
|
||||
})
|
||||
|
||||
const scrollEl = ref()
|
||||
const state = reactive({
|
||||
index: 0,
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
$('.cover-card').fadeOut()
|
||||
})
|
||||
function close() {
|
||||
emit('close')
|
||||
setTimeout(() => {
|
||||
state.index = 0
|
||||
scrollEl.value.scrollTop = 0
|
||||
}, 500)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
@ -162,9 +135,11 @@ onMounted(() => {
|
||||
@c: #a2a2a2;
|
||||
@c2: #c0c0c0;
|
||||
@red: rgb(248, 38, 74);
|
||||
position: relative;
|
||||
opacity: 0;
|
||||
|
||||
& > header {
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
@ -183,6 +158,11 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
.scroll {
|
||||
height: 100vh;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.slide-imgs {
|
||||
position: relative;
|
||||
height: 70vh;
|
||||
@ -377,62 +357,6 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cover-card {
|
||||
transition: all .3s;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
border-radius: 4rem;
|
||||
overflow: hidden;
|
||||
background: var(--main-bg);
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.bottom {
|
||||
color: gainsboro;
|
||||
padding: 10rem;
|
||||
|
||||
.title {
|
||||
font-size: 14rem;
|
||||
margin-bottom: 8rem;
|
||||
}
|
||||
|
||||
.b2 {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.user {
|
||||
display: flex;
|
||||
font-size: 12rem;
|
||||
|
||||
img {
|
||||
width: 15rem;
|
||||
border-radius: 50%;
|
||||
margin-right: 5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.star {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 3rem;
|
||||
|
||||
svg {
|
||||
font-size: 15rem;
|
||||
}
|
||||
|
||||
.num {
|
||||
font-size: 12rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@ -472,6 +472,10 @@ export function _sleep(duration) {
|
||||
})
|
||||
}
|
||||
|
||||
export function _copy(val) {
|
||||
return Utils.copy(val)
|
||||
}
|
||||
|
||||
export function cloneDeep(val) {
|
||||
return JSON.parse(JSON.stringify(val))
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user