赞
踩
每次点击添加按钮时,往该按钮上方添加一个悬浮元素,通过位移动画将元素移到目标位置。
1. 为每个点击元素设置不同的class,才能通过uni.createSelectorQuery来获取每个元素的节点信息;
2. 添加一个与点击元素一模一样的动画元素;
3. 获取点击元素的节点信息将动画元素放置到点击元素上方;
4. 计算动画元素到目标位置的距离,获得xy坐标执行位移动画;
5. 等待每个动画元素执行动画完毕后移除该元素。
- <template>
- <view>
- <!-- 商品列表 -->
- <view v-for="item in goodsList" :key="item.id">
- <view :class="[`add-cart-${item.id}`]" @click="addToCart(item)">加购</view>
- </view>
- <!-- 动画元素列表 -->
- <view
- v-for="item in anims" :key="item.key"
- style="position: fixed; transition: transform 0.5s linear;"
- :style="{
- top: `${item.top}px`,
- left: `${item.left}px`,
- transform: `translate(${item.x}px, ${item.y}px)`,
- }"
- >
- 加购
- </view>
- </view>
- </template>
-
- <script setup lang="ts">
- import { ref } from 'vue';
- import uniqueId from 'lodash-es/uniqueId';
-
- const sys = uni.getSystemInfoSync();
- const anims = ref<any[]>([]);
- const goodsList = ref([{ id: 1 }, { id: 2 }, { id: 3 }])
-
- function addToCart(item) {
- // 添加动画元素
- const key = uniqueId();
- anims.value.push({
- key,
- id: item.id,
- left: 0,
- top: 0,
- y: 0,
- x: 0,
- });
- // 获取点击元素的节点信息
- uni.createSelectorQuery().select(`.add-cart-${item.id}`)
- .boundingClientRect((e: any) => {
- // 初始化起始位置
- anims.value.some((citem) => {
- if (citem.key === key) {
- citem.top = e.top;
- citem.left = e.left;
- return true;
- }
- return false;
- });
- nextTick(() => {
- // 设置目标位置
- anims.value.some((citem) => {
- if (citem.key === key) {
- citem.y = sys.windowHeight - citem.top - 50;
- citem.x = -sys.windowWidth * 0.30;
- setTimeout(() => { // 等待动画执行完毕移除元素
- anims.value.splice(anims.value.findIndex((v: any) => v.key === key), 1);
- }, 500);
- return true;
- }
- return false;
- });
- });
- }).exec();
- }
-
- </script>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。