|
|
@@ -1,22 +1,15 @@
|
|
|
<script setup lang="ts">
|
|
|
+import type { LoadMoreState } from 'wot-design-uni/components/wd-loadmore/types'
|
|
|
import { StaticUrl } from '@/config'
|
|
|
+import router from '@/router'
|
|
|
|
|
|
+const props = defineProps<{ categoryList: Api.xsbCategories[] }>()
|
|
|
const { statusBarHeight, MenuButtonHeight } = storeToRefs(useSysStore())
|
|
|
-const classfiylist = ref([
|
|
|
- { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
|
|
|
- { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
|
|
|
- { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
|
|
|
- { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
|
|
|
- { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
|
|
|
- { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
|
|
|
- { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
|
|
|
- { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
|
|
|
- { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
|
|
|
- { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
|
|
|
-])
|
|
|
-const topNavActive = ref(0)
|
|
|
+const { topNavActive, leftActive } = storeToRefs(useSysXsbStore())
|
|
|
+const classfiylist = computed(() => props.categoryList)
|
|
|
const sortClassBtn = ref(1)
|
|
|
const show = ref(false)
|
|
|
+const showball = ref(false)
|
|
|
definePage({
|
|
|
name: 'xsb-classfiy',
|
|
|
islogin: false,
|
|
|
@@ -26,76 +19,111 @@ definePage({
|
|
|
disableScroll: true,
|
|
|
},
|
|
|
})
|
|
|
+const isTopLoading = ref(false)
|
|
|
+const basllObj = ref({
|
|
|
+ left: 0,
|
|
|
+ top: 0,
|
|
|
+ x: 0,
|
|
|
+ y: 0,
|
|
|
+})
|
|
|
+const x = computed(() => `${basllObj.value.x}px`)
|
|
|
+const y = computed(() => `${basllObj.value.y}px`)
|
|
|
+const left = computed(() => `${basllObj.value.left}px`)
|
|
|
+const top = computed(() => `${basllObj.value.top}px`)
|
|
|
+const productList = ref<Api.xsbCategoryProductList[]>([])
|
|
|
+const topScrollView = ref()
|
|
|
+const scrollTop = ref(0)
|
|
|
+const goodsLoading = ref<LoadMoreState>()
|
|
|
const navHeight = computed(() => {
|
|
|
return (`${Number(MenuButtonHeight.value) + Number(statusBarHeight.value)}px`)
|
|
|
})
|
|
|
-function handleTopNavChange(idx: number) {
|
|
|
- topNavActive.value = idx
|
|
|
+function handleTopNavChange(item: Api.xsbCategoriesChildren) {
|
|
|
+ topNavActive.value = item.code
|
|
|
+ leftActive.value = item.children[0].code
|
|
|
+ show.value = false
|
|
|
+ topScrollView.value = null
|
|
|
+ nextTick(() => {
|
|
|
+ topScrollView.value = item.code
|
|
|
+ })
|
|
|
+ getProductList()
|
|
|
}
|
|
|
function handleOpen() {
|
|
|
show.value = true
|
|
|
console.log(navHeight.value, '打开')
|
|
|
}
|
|
|
|
|
|
-const active = ref<number>(1)
|
|
|
-const scrollTop = ref<number>(0)
|
|
|
-const itemScrollTop = ref<number[]>([])
|
|
|
+const categories = computed(() => {
|
|
|
+ return classfiylist.value.find(it => it.code === topNavActive.value)?.children || []
|
|
|
+})
|
|
|
+const categoriesId = computed(() => {
|
|
|
+ return categories.value.find(it => it.code === leftActive.value)?.id
|
|
|
+})
|
|
|
|
|
|
-const subCategories = Array.from({ length: 24 }).fill({ title: '标题文字', label: '这是描述这是描述' }, 0, 24)
|
|
|
-const categories = ref([
|
|
|
- {
|
|
|
- label: '分类一',
|
|
|
- title: '标题一',
|
|
|
- items: subCategories,
|
|
|
- },
|
|
|
- {
|
|
|
- label: '分类二',
|
|
|
- title: '标题二',
|
|
|
- items: subCategories,
|
|
|
- },
|
|
|
- {
|
|
|
- label: '分类三',
|
|
|
- title: '标题三',
|
|
|
- items: subCategories.slice(0, 18),
|
|
|
- },
|
|
|
- {
|
|
|
- label: '分类四',
|
|
|
- title: '标题四',
|
|
|
- items: subCategories.slice(0, 21),
|
|
|
- },
|
|
|
- {
|
|
|
- label: '分类五',
|
|
|
- title: '标题五',
|
|
|
- items: subCategories,
|
|
|
- },
|
|
|
- {
|
|
|
- label: '分类六',
|
|
|
- title: '标题六',
|
|
|
- items: subCategories.slice(0, 18),
|
|
|
- },
|
|
|
- {
|
|
|
- label: '分类七',
|
|
|
- title: '标题七',
|
|
|
- items: subCategories,
|
|
|
- },
|
|
|
-])
|
|
|
+function handleChange({ value }: { value: string }) {
|
|
|
+ leftActive.value = value
|
|
|
+ getProductList()
|
|
|
+}
|
|
|
+async function getProductList() {
|
|
|
+ const res = await Apis.xsb.getCategoryProductList({
|
|
|
+ data: {
|
|
|
+ categoryId: Number(categoriesId.value),
|
|
|
+ shopId: 1,
|
|
|
+ },
|
|
|
+ })
|
|
|
+ productList.value = res
|
|
|
+ goodsLoading.value = 'finished'
|
|
|
+ isTopLoading.value = false
|
|
|
+}
|
|
|
|
|
|
-function handleChange({ value }) {
|
|
|
- active.value = value
|
|
|
- scrollTop.value = itemScrollTop.value[value]
|
|
|
+function handlScrollBottom() {
|
|
|
+ goodsLoading.value = 'loading'
|
|
|
+ const index = categories?.value.findIndex(it => it.code === leftActive.value)
|
|
|
+ if (index !== -1) {
|
|
|
+ handleChange({ value: categories.value[index + 1].code })
|
|
|
+ }
|
|
|
}
|
|
|
-function onScroll(e) {
|
|
|
- const { scrollTop } = e.detail
|
|
|
- const threshold = 50 // 下一个标题与顶部的距离
|
|
|
- if (scrollTop < threshold) {
|
|
|
- active.value = 0
|
|
|
+function handleSrollTop() {
|
|
|
+ isTopLoading.value = true
|
|
|
+ const index = categories?.value.findIndex(it => it.code === leftActive.value)
|
|
|
+ if (index !== -1) {
|
|
|
+ if (index === 0) {
|
|
|
+ nextTick(() => isTopLoading.value = false)
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ handleChange({ value: categories.value[index - 1].code })
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+function handleAddCart(event: WechatMiniprogram.TouchEvent, item: Api.xsbCategoryProductList) {
|
|
|
+ console.log(event.detail.x, item)
|
|
|
+ if (showball.value)
|
|
|
return
|
|
|
+ basllObj.value.left = event.detail.x
|
|
|
+ basllObj.value.top = event.detail.y
|
|
|
+ showball.value = true
|
|
|
+ setTimeout(() => {
|
|
|
+ showball.value = false
|
|
|
+ }, 500)
|
|
|
+}
|
|
|
+onMounted(() => {
|
|
|
+ if (leftActive.value) {
|
|
|
+ handleChange({ value: leftActive.value })
|
|
|
}
|
|
|
- const index = itemScrollTop.value.findIndex(top => top > scrollTop && top - scrollTop <= threshold)
|
|
|
- if (index > -1) {
|
|
|
- active.value = index
|
|
|
+ if (topNavActive.value) {
|
|
|
+ topScrollView.value = null
|
|
|
+ nextTick(() => {
|
|
|
+ topScrollView.value = topNavActive.value
|
|
|
+ })
|
|
|
}
|
|
|
-}
|
|
|
+ const query = uni.createSelectorQuery().in(getCurrentInstance())
|
|
|
+ query.select('.cart-box').boundingClientRect()
|
|
|
+ query.exec((res) => {
|
|
|
+ basllObj.value.y = res[0].top
|
|
|
+ uni.getSystemInfo().then((info) => {
|
|
|
+ basllObj.value.x = -(info.screenWidth - res[0].left - 15)
|
|
|
+ })
|
|
|
+ })
|
|
|
+})
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
@@ -106,11 +134,16 @@ function onScroll(e) {
|
|
|
>
|
|
|
<template #left>
|
|
|
<view class="flex items-center">
|
|
|
- <view class="h60rpx w-474rpx flex items-center justify-between border-2rpx border-[var(--them-color)] rounded-40rpx border-solid bg-white pr6rpx">
|
|
|
+ <view
|
|
|
+ class="h60rpx w-474rpx flex items-center justify-between border-2rpx border-[var(--them-color)] rounded-40rpx border-solid bg-white pr6rpx"
|
|
|
+ >
|
|
|
<view class="flex items-center pb14rpx pl24rpx pt16rpx">
|
|
|
<wd-icon name="search" size="14" color="#ccc" />
|
|
|
<view class="search ml12rpx h-full w-full overflow-hidden">
|
|
|
- <wd-notice-bar :text="['霸王茶姬', '牛奶', '洗衣机']" custom-class="notice-bar" color="#ccc" background-color="#fff" direction="vertical" />
|
|
|
+ <wd-notice-bar
|
|
|
+ :text="['霸王茶姬', '牛奶', '洗衣机']" custom-class="notice-bar" color="#ccc"
|
|
|
+ background-color="#fff" direction="vertical"
|
|
|
+ />
|
|
|
</view>
|
|
|
</view>
|
|
|
<view class="flex items-center pr28rpx">
|
|
|
@@ -127,40 +160,59 @@ function onScroll(e) {
|
|
|
class="h162rpx flex items-center justify-between bg-#F4FFD1 pl24rpx"
|
|
|
:style="{ paddingTop: `${(Number(statusBarHeight) || 44) + MenuButtonHeight + 12}px` }"
|
|
|
>
|
|
|
- <scroll-view scroll-x class="scrollx w-90% flex-shrink-0 whitespace-nowrap">
|
|
|
+ <scroll-view
|
|
|
+ scroll-x :scroll-into-view-offset="-150" scroll-with-animation enable-passive
|
|
|
+ class="scrollx w-90% flex-shrink-0 whitespace-nowrap" :scroll-into-view="`id${topScrollView}`"
|
|
|
+ >
|
|
|
<view class="flex items-end pb10rpx">
|
|
|
- <view v-for="item, idx in classfiylist" :key="idx" class="mr24rpx flex flex-col items-center justify-center" @click="handleTopNavChange(idx)">
|
|
|
+ <view
|
|
|
+ v-for="item in classfiylist" :id="`id${item.code}`" :key="item.code"
|
|
|
+ class="mr24rpx flex flex-col items-center justify-center" @click="handleTopNavChange(item)"
|
|
|
+ >
|
|
|
<image
|
|
|
:src="item.icon"
|
|
|
- :class="[topNavActive == idx ? 'overflow-hidden border-solid border-[var(--them-color)] border-2rpx rounded-26rpx h84rpx w-84rpx' : 'h72rpx w-72rpx']"
|
|
|
+ :class="[topNavActive == item.code ? 'overflow-hidden border-solid border-[var(--them-color)] border-2rpx rounded-26rpx h84rpx w-84rpx' : 'h72rpx w-72rpx']"
|
|
|
/>
|
|
|
- <view class="mt16rpx text-22rpx" :class="[topNavActive == idx ? 'bg-[var(--them-color)] rounded-18rpx px-8rpx py2rpx text-white text-24rpx' : '']">
|
|
|
- {{ item.title }}
|
|
|
+ <view
|
|
|
+ class="mt16rpx text-22rpx"
|
|
|
+ :class="[topNavActive == item.code ? 'bg-[var(--them-color)] rounded-18rpx px-8rpx py2rpx text-white text-24rpx' : '']"
|
|
|
+ >
|
|
|
+ {{ item.name }}
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</scroll-view>
|
|
|
- <view class="right-nav box-border h144rpx w64rpx flex flex-shrink-0 flex-col items-center justify-center px20rpx text-24rpx font-semibold" @click="handleOpen">
|
|
|
+ <view
|
|
|
+ class="right-nav box-border h144rpx w64rpx flex flex-shrink-0 flex-col items-center justify-center px20rpx text-24rpx font-semibold"
|
|
|
+ @click="handleOpen"
|
|
|
+ >
|
|
|
展开
|
|
|
- <image
|
|
|
- :src="`${StaticUrl}/xia.png`"
|
|
|
- class="mt20rpx h20rpx w20rpx"
|
|
|
- />
|
|
|
+ <image :src="`${StaticUrl}/xia.png`" class="mt20rpx h20rpx w20rpx" />
|
|
|
</view>
|
|
|
<wd-popup v-model="show" position="top" custom-style="border-radius:32rpx;">
|
|
|
- <view class="box-border bg-#F4FFD1 p24rpx" :style="{ paddingTop: `${(Number(statusBarHeight) || 44) + MenuButtonHeight + 12}px` }">
|
|
|
+ <view
|
|
|
+ class="box-border bg-#F4FFD1 p24rpx"
|
|
|
+ :style="{ paddingTop: `${(Number(statusBarHeight) || 44) + MenuButtonHeight + 12}px` }"
|
|
|
+ >
|
|
|
<view class="mb24rpx mt24rpx text-28rpx font-semibold">
|
|
|
全部一级分类
|
|
|
</view>
|
|
|
<view class="h400rpx overflow-y-scroll">
|
|
|
<view class="grid grid-cols-5 box-border gap-x-24rpx gap-y-24rpx">
|
|
|
- <view v-for="item, idx in classfiylist" :key="idx" class="box-border h150rpx w114rpx flex flex-col items-center justify-center" @click="handleTopNavChange(idx)">
|
|
|
+ <view
|
|
|
+ v-for="item in classfiylist" :key="item.code"
|
|
|
+ class="box-border h150rpx w114rpx flex flex-col items-center justify-center"
|
|
|
+ @click="handleTopNavChange(item)"
|
|
|
+ >
|
|
|
<image
|
|
|
:src="item.icon"
|
|
|
- :class="[topNavActive == idx ? 'overflow-hidden border-solid border-[var(--them-color)] border-2rpx rounded-26rpx h88rpx w-88rpx' : 'h76rpx w-76rpx']"
|
|
|
+ :class="[topNavActive == item.code ? 'overflow-hidden border-solid border-[var(--them-color)] border-2rpx rounded-26rpx h88rpx w-88rpx' : 'h76rpx w-76rpx']"
|
|
|
/>
|
|
|
- <view class="mt16rpx whitespace-nowrap text-nowrap text-22rpx" :class="[topNavActive == idx ? 'bg-[var(--them-color)] rounded-18rpx px-8rpx py2rpx text-white text-24rpx' : '']">
|
|
|
- {{ item.title }}
|
|
|
+ <view
|
|
|
+ class="mt16rpx whitespace-nowrap text-nowrap text-22rpx"
|
|
|
+ :class="[topNavActive == item.code ? 'bg-[var(--them-color)] rounded-18rpx px-8rpx py2rpx text-white text-24rpx' : '']"
|
|
|
+ >
|
|
|
+ {{ item.name }}
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -175,15 +227,16 @@ function onScroll(e) {
|
|
|
</wd-popup>
|
|
|
</view>
|
|
|
<view class="wraper">
|
|
|
- <wd-sidebar v-model="active" @change="handleChange">
|
|
|
- <wd-sidebar-item v-for="(item, index) in categories" :key="index" :value="index" :label="item.label" />
|
|
|
+ <wd-sidebar v-model="leftActive" @change="handleChange">
|
|
|
+ <wd-sidebar-item
|
|
|
+ v-for="(item) in categories" :key="item.code"
|
|
|
+ custom-style="font-size:28rpx; white-space: nowrap;text-overflow: ellipsis;overflow: hidden;"
|
|
|
+ :value="item.code" :label="item.name"
|
|
|
+ />
|
|
|
</wd-sidebar>
|
|
|
<view class="content">
|
|
|
<view class="p20rpx">
|
|
|
- <image
|
|
|
- :src="`${StaticUrl}/class.png`"
|
|
|
- class="h144rpx w-full"
|
|
|
- />
|
|
|
+ <image :src="`${StaticUrl}/class.png`" class="h144rpx w-full" />
|
|
|
<view class="my20rpx flex items-center justify-end rounded-16rpx bg-#F6F6F6 px20rpx py8rpx">
|
|
|
<view class="mr40rpx text-24rpx">
|
|
|
销量
|
|
|
@@ -191,28 +244,33 @@ function onScroll(e) {
|
|
|
<wd-sort-button v-model="sortClassBtn" :line="false" title="价格" />
|
|
|
</view>
|
|
|
</view>
|
|
|
- <scroll-view :style="{ height: `calc(100vh - ${navHeight} - 600rpx)` }" scroll-y scroll-with-animation :scroll-top="scrollTop" :throttle="false" @scroll="onScroll">
|
|
|
- <view class="p20rpx">
|
|
|
- <view v-for="item in 20" :key="item">
|
|
|
+ <scroll-view
|
|
|
+ :lower-threshold="10"
|
|
|
+ :refresher-triggered="isTopLoading" :scroll-top="scrollTop"
|
|
|
+ :style="{ height: `calc(100vh - ${navHeight} - 700rpx)` }" enable-passive scroll-y scroll-with-animation scroll-anchoring refresher-enabled :throttle="false"
|
|
|
+ @refresherrefresh="handleSrollTop" @scrolltolower="handlScrollBottom"
|
|
|
+ >
|
|
|
+ <view v-if="productList.length" class="p20rpx">
|
|
|
+ <view v-for="item in productList" :key="item.id" @click="router.push({ name: 'xsb-goods', params: { id: String(item.id) } })">
|
|
|
<view class="flex">
|
|
|
- <view class="mr20rpx h172rpx w172rpx flex-shrink-0 rounded-16rpx bg-#F6F6F6" />
|
|
|
- <view>
|
|
|
+ <view class="mr20rpx h172rpx w172rpx flex-shrink-0 overflow-hidden rounded-16rpx bg-#F6F6F6">
|
|
|
+ <image :src="item.pic" lazy-load class="h-full w-full" />
|
|
|
+ </view>
|
|
|
+ <view class="flex-1">
|
|
|
<view class="text-left text-28rpx font-semibold">
|
|
|
- <view v-for="i in 2" :key="i" class="mr5px inline-block">
|
|
|
+ <!-- <view v-for="i in 2" :key="i" class="mr5px inline-block">
|
|
|
<wd-tag type="primary">
|
|
|
新品{{ i }}
|
|
|
</wd-tag>
|
|
|
- </view>
|
|
|
- 海湾高盐特大白虾200g
|
|
|
+ </view> -->
|
|
|
+ {{ item.prodName }}
|
|
|
</view>
|
|
|
<view class="text-22rpx text-#AAAAAA">
|
|
|
<view class="mt10rpx flex items-center">
|
|
|
- <view>一年一季</view>
|
|
|
- <wd-divider vertical />
|
|
|
- <view>新鲜翠绿</view>
|
|
|
+ <view>{{ item.spec }}</view>
|
|
|
</view>
|
|
|
<view class="mt6rpx">
|
|
|
- 已售3.6万+
|
|
|
+ 已售 {{ item.soldNum }}+
|
|
|
</view>
|
|
|
</view>
|
|
|
<view class="flex items-center justify-between">
|
|
|
@@ -220,14 +278,11 @@ function onScroll(e) {
|
|
|
<text class="text-24rpx">
|
|
|
¥
|
|
|
</text> <text class="text-36rpx">
|
|
|
- 9.99
|
|
|
+ {{ item.channelProdPrice }}
|
|
|
</text>
|
|
|
</view>
|
|
|
- <view>
|
|
|
- <image
|
|
|
- :src="`${StaticUrl}/cart-yes.png`"
|
|
|
- class="h52rpx w52rpx"
|
|
|
- />
|
|
|
+ <view @click.stop="handleAddCart($event, item)">
|
|
|
+ <image :src="`${StaticUrl}/cart-yes.png`" class="h52rpx w52rpx" />
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -236,28 +291,88 @@ function onScroll(e) {
|
|
|
<wd-divider color="#F0F0F0" />
|
|
|
</view>
|
|
|
</view>
|
|
|
- <view class="h60rpx" />
|
|
|
+ <wd-loadmore :state="goodsLoading" />
|
|
|
</view>
|
|
|
+ <wd-status-tip v-else image="content" tip="暂无内容" />
|
|
|
</scroll-view>
|
|
|
</view>
|
|
|
</view>
|
|
|
+ <view
|
|
|
+ class="fixedShadow fixed bottom-60rpx left-0 z-99 box-border w-full flex items-center justify-between rounded-t-16rpx bg-white px24rpx pb60rpx pt10rpx"
|
|
|
+ >
|
|
|
+ <view class="ios w-full flex items-center justify-between">
|
|
|
+ <view class="flex items-center">
|
|
|
+ <image :src="`${StaticUrl}/cart-lanzi.png`" class="cart-box h100rpx w100rpx" />
|
|
|
+ </view>
|
|
|
+ <view class="flex items-center">
|
|
|
+ <view class="flex items-center font-semibold">
|
|
|
+ <view class="text-22rpx text-#222">
|
|
|
+ 总计:
|
|
|
+ </view>
|
|
|
+ <view class="flex items-baseline text-24rpx text-#FF4A39">
|
|
|
+ ¥
|
|
|
+ <text class="text-36rpx">
|
|
|
+ 8.9
|
|
|
+ </text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="ml20rpx w160rpx">
|
|
|
+ <wd-button block size="large">
|
|
|
+ 结算
|
|
|
+ </wd-button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view v-if="showball" class="ball">
|
|
|
+ <image :src="`${StaticUrl}/cart-yes.png`" class="cart-img h52rpx w52rpx" />
|
|
|
+ </view>
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
-.right-nav{
|
|
|
- background: linear-gradient( 180deg, #FAFFEC 0%, #F6FFDE 11%, #E7FFA5 100%);
|
|
|
- box-shadow: -10rpx 0rpx 12rpx 2rpx rgba(0,0,0,0.07);
|
|
|
+.right-nav {
|
|
|
+ background: linear-gradient(180deg, #FAFFEC 0%, #F6FFDE 11%, #E7FFA5 100%);
|
|
|
+ box-shadow: -10rpx 0rpx 12rpx 2rpx rgba(0, 0, 0, 0.07);
|
|
|
+}
|
|
|
+.fixedShadow{
|
|
|
+ box-shadow: 0rpx -6rpx 12rpx 2rpx rgba(0,0,0,0.05);
|
|
|
}
|
|
|
+
|
|
|
.wraper {
|
|
|
display: flex;
|
|
|
- height: calc(100vh - var(--window-top) - v-bind(navHeight) - 290rpx);
|
|
|
- height: calc(100vh - var(--window-top) - constant(safe-area-inset-bottom) - v-bind(navHeight) - 290rpx);
|
|
|
- height: calc(100vh - var(--window-top) - env(safe-area-inset-bottom) - v-bind(navHeight) - 290rpx);
|
|
|
+ height: calc(100vh - var(--window-top) - v-bind(navHeight) - 390rpx);
|
|
|
+ height: calc(100vh - var(--window-top) - constant(safe-area-inset-bottom) - v-bind(navHeight) - 390rpx);
|
|
|
+ height: calc(100vh - var(--window-top) - env(safe-area-inset-bottom) - v-bind(navHeight) - 390rpx);
|
|
|
}
|
|
|
|
|
|
.content {
|
|
|
flex: 1;
|
|
|
background: #fff;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+@keyframes moveX {
|
|
|
+ to {
|
|
|
+ transform: translateX(v-bind(x));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+@keyframes moveY {
|
|
|
+ to {
|
|
|
+ transform: translateY(v-bind(y));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.ball {
|
|
|
+ position: fixed;
|
|
|
+ z-index: 80;
|
|
|
+ left: v-bind(left);
|
|
|
+ top: v-bind(top);
|
|
|
+ animation: moveX .5s linear forwards;
|
|
|
+}
|
|
|
+
|
|
|
+.cart-img {
|
|
|
+ animation: moveY .5s cubic-bezier(1,-1.26,1,1) forwards;
|
|
|
}
|
|
|
</style>
|