效果图

购物车主要是两张图,分别是盖子和篮子组成一个图,点击事件默认能获取页面点击X和Y
.vue
typescript
<template>
<view
v-for="ball in balls"
:key="ball.id"
class="ball"
:style="{
'--x': `${ball.x - 30}px`,
'--y': `${ball.y - 20}px`,
}" />
<view class="btn wxy-button flex-between">
<view class="flex">
<view class="btn-item">
<image class="btn-item-lid" :src="imgUrl('home/lid')"
:class="{'btn-item-lid-active': balls.length > 0}" />
<image class="btn-item-basket" :src="imgUrl('home/basket')" />
</view>
<wxy-text-price :num="2.5" :digit="2" />
</view>
<view class="wxy-btn flex-center btn-button bg-main round">
去结算
</view>
</view>
</template>
<script setup lang='ts'>
import { imgUrl } from '@/modules/tool'
import { watch, ref } from 'vue'
interface Ball {
id: number
x: number
y: number
}
const props = defineProps({
location: {
type: Object,
default: () => ({
x: 0,
y: 0,
}),
},
})
const balls = ref<Ball[]>([])
let ballId = 0
watch(() => props.location, (newLoc) => {
if (newLoc.x !== 0 || newLoc.y !== 0) {
const newBall: Ball = {
id: ++ballId,
x: newLoc.x,
y: newLoc.y,
}
balls.value.push(newBall)
setTimeout(() => {
const index = balls.value.findIndex((b) => b.id === newBall.id)
if (index > -1) {
balls.value.splice(index, 1)
}
}, 800)
}
})
</script>
<style lang='scss' scoped>
.ball {
position: absolute;
top: var(--y);
left: var(--x);
z-index: 3;
width: 48rpx;
height: 48rpx;
background-color: var(--main);
border-radius: 50%;
animation: fly-to-cart 1s cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
pointer-events: none;
will-change: transform;
}
@keyframes fly-to-cart {
to{
transform: translate(calc(30rpx - var(--x)), calc(100vh - 100rpx - var(--y))) scale(0.6);
}
}
.btn{
padding: 20rpx 30rpx calc(20rpx + (env(safe-area-inset-bottom) / 2));
&-button{
width: 280rpx;
height: 84rpx;
font-weight: 500;
}
&-item{
--size:166rpx;
--top:-30rpx;
width: 110rpx;
&-lid{
position: absolute;
top: var(--top);
left: 0;
z-index: 1;
width: var(--size);
height: var(--size);
backface-visibility: hidden;
transition: .4s ease-in-out;
will-change: transform;
}
&-lid-active{
transform: rotate(-60deg) translateY(-30rpx) translateX(20rpx);
}
&-basket{
position: absolute;
top: var(--top);
left: 0;
width: var(--size);
height: var(--size);
}
}
}
</style>
遇到问题可以看我主页加我Q,很少看博客,对你有帮助别忘记点赞收藏。