加入购物车动画

该文章介绍了如何在Uniapp中实现一个点击加入购物车的动画效果,通过模拟抛物线轨迹,使图片小球落入购物车,同时处理了获取图片和购物车位置的逻辑。
摘要由CSDN通过智能技术生成

找了很多个加入购物车动画都不行,看到了这个博主的可以,太赞了Uniapp实现加入购物车抛物线效果_uniapp 加入购物车抛物线动画-CSDN博客

因为我的功能和这位博主的不太一样,我的是点击加入购物车获取图片的位置而不是点击的位置,在这个基础上又以一样的方法获取了购物车的位置,做了下小修改,这样应该就不会有兼容问题了。

先上图:

加入过程:点击加入购物车,图片形成一个小球沿着轨迹(类似划线轨迹/抛物线)掉入购物车

界面:

<template>
    <view>
        <view v-for="(item,index) in itemList" class="flex position-relative"
            style="padding: 10rpx 0;border: 1rpx solid #CCCCCC;">
            <image class="img" :src="item.image" style="width: 160rpx;height: 160rpx;"></image>
            <view class="ml-30u">
                <view class="font-weight">{{item.title}}</view>
                <view class="">{{item.desc}}!</view>
            </view>
            <view @click="addShoppingCard(item,index)" class="position-absolute"
                style="padding: 10rpx 20rpx;border-radius: 50rpx;background-color: #d995d7;bottom: 20rpx;right: 30rpx;">
                加入购物车
            </view>
        </view>
        <!-- 购物车 -->
        <view class="cart" :class="shoppingCartAnimation? 'shoppingCartAnimations' : '' ">
            <block class="position-relative">
                <image src="../../static/cart.png" mode="" class="width-height-50 mt-10u"></image>
                <view class="badge">{{info}}</view>
            </block>
        </view>

        <!-- 小球动画 -->
        <view :animation="animationY" :style="'position:fixed;top:' + ballY + 'px;'" v-if="showBall">
            <view class="ball" :animation="animationX" :style="'position:fixed;left:' + ballX + 'px;'">
                <image class="ball" :src="addImg" mode=""></image>
            </view>
        </view>
    </view>
</template>

<script>
	export default {
		data() {
			return {
				itemList: [{
					title: '喵喵',
					desc: '可爱',
					image: '../../static/cat.jpg'
				}, {
					title: '咕噜',
					desc: '调皮',
					image: '../../static/cat2.png'
				}, {
					title: '猫猫',
					desc: '我的猫猫世界第一可爱',
					image: '../../static/cat3.jpg'
				}, {
					title: '喵喵',
					desc: '我的喵喵世界第一可爱',
					image: '../../static/cat.jpg'
				}, {
					title: '喵喵',
					desc: '我的喵喵世界第一可爱',
					image: '../../static/cat.jpg'
				}],
				imgListSum: [{
					showDel: false,
					delAnimation: false, // 删除动画
					sum: 0,
				}],
				shoppingCartAnimation: false, // 购物车动画
				showBall: false, // 小球是否显示
				animationY: '', // 动画Y
				animationX: '', // 动画X
				ballY: '', // 小球当前位置Y
				ballX: '', // 小球当前位置X
				cartX: null, //购物车位置X
				cartY: null, //购物车位置Y
				info: 0,
				addImg: ''
			}
		},
		onShow() {
			this.itemList.forEach(item => {
				let imgListSum = {
					showDel: false,
					delAnimation: false, // 删除动画
					sum: 0,
				}
				this.imgListSum.push(imgListSum)
			})

			this.$nextTick(() => {
				// 获取购物车位置
				const query = uni.createSelectorQuery().in(this);
				query.select('.cart').boundingClientRect(data => {
					console.log(data, 'data');
					this.cartX = data.left + 20
					this.cartY = data.top + 50
					console.log(this.cartX, this.cartY, '获取购物车位置');
				}).exec();
			})
		},
		methods: {
			// 删除购物车
			async delShoppingCard(index) {
				if (this.imgListSum[index].sum - 1 <= 0) {
					this.imgListSum[index].sum = this.imgListSum[index].sum - 1
					this.imgListSum[index].delAnimation = false
					this.setDelayTime(100).then(() => {
						this.imgListSum[index].showDel = false
					})
				} else {
					this.imgListSum[index].sum = this.imgListSum[index].sum - 1
				}
			},
			// 添加购物车
			addShoppingCard(item, ind) {
				this.addImg = item.image
				this.info++
				let imgX, imgY;
				this.$nextTick(function() {
					const query = uni.createSelectorQuery().in(this);
					query.selectAll('.img').boundingClientRect(data => {
						console.log(data, 'data');
						imgX = data[ind].left + 50
						imgY = data[ind].top + 50
						console.log(imgX, imgY, 'addCardAnimation');
						this.imgListSum[ind].sum = this.imgListSum[ind].sum + 1
						this.imgListSum[ind].delAnimation = true
						this.imgListSum[ind].showDel = true
						// x, y表示手指点击横纵坐标, 即小球的起始坐标
						let ballX = imgX,
							ballY = imgY
						this.createAnimation(ballX, ballY);
					}).exec();
				})
			},
			// 延迟执行
			setDelayTime(sec) {
				return new Promise((resolve, reject) => {
					setTimeout(() => {
						resolve()
					}, sec)
				});
			},
			// 创建动画
			createAnimation(ballX, ballY) {
				uni.getSystemInfo({
					success: async (e) => {
						// var bottomX = e.windowWidth; // 结束位置X
						// var bottomX = 50; // 结束位置X
						// var bottomY = e.windowHeight - 50; // 结束位置Y
						var bottomX = this.cartX; // 结束位置X
						var bottomY = this.cartY; // 结束位置Y
						var animationX = this.flyX(bottomX, ballX); // 创建小球水平动画
						var animationY = this.flyY(bottomY, ballY); // 创建小球垂直动画
						this.ballX = ballX; // 小球当前位置X
						this.ballY = ballY; // 小球当前位置Y
						this.showBall = true; // 显示小球

						this.setDelayTime(100).then(() => {
							this.animationX = animationX.export(); // 执行动画X
							this.animationY = animationY.export(); // 执行动画Y
							// 400ms延时, 即小球的抛物线时长
							return this.setDelayTime(400);
						}).then(() => {
							this.animationX = this.flyX(0, 0, 0).export(); // 执行动画X
							this.animationY = this.flyY(0, 0, 0).export(); // 执行动画Y
							this.showBall = false; // 隐藏小球
							this.shoppingCartAnimation = true // 购物车动画
							// 400ms延时, 即小球的抛物线时长
							return this.setDelayTime(700);
						}).then(() => {
							this.shoppingCartAnimation = false // 购物车动画
						})

					}
				})
			},
			// 水平动画
			flyX(bottomX, ballX, duration) {
				/**
				 * bottomX 结束位置
				 * ballX 开始位置
				 * duration 动画持续时间
				 */
				let animation = uni.createAnimation({
					duration: duration || 400,
					timingFunction: 'linear',
				})
				animation.translateX(bottomX - ballX).step(); // 动画效果
				return animation;
			},
			// 垂直动画
			flyY(bottomY, ballY, duration) {
				/**
				 * bottomY 结束位置
				 * ballY 开始位置
				 * duration 动画持续时间
				 */
				let animation = uni.createAnimation({
					duration: duration || 400,
					timingFunction: 'ease-in',
				})
				console.log(bottomY)
				animation.translateY(bottomY - ballY).step(); // 动画效果
				return animation;
			},
		}
	}
</script>

 

下面样式有购物车抖动动画哦哈哈哈

<style>
	@import url("../../commons/common.css");

	.cart {
		position: fixed;
		right: 50rpx;
		bottom: 250rpx;
		width: 70rpx;
		height: 70rpx;
		background-color: #fff;
		border: 1rpx solid #ebebeb;
		border-radius: 50%;
		text-align: center;
	}

	.badge {
		padding: 0 8rpx;
		font-size: 18rpx;
		border: .4rpx solid #DE1A1B;
		color: #DE1A1B;
		border-radius: 15rpx;
		position: absolute;
		top: -10rpx;
		right: -18rpx;
		background-color: #fff;
	}

	.flex {
		display: flex;
	}

	.ball {
		height: 40rpx;
		width: 40rpx;
		border-radius: 50rpx;
		position: fixed;
	}

	/* 下面都是购物车抖动 */
	.shoppingCartAnimations {
		animation: shoppingCartAnimation 1s;
	}

	@keyframes shoppingCartAnimation {
		0% {
			opacity: 0;
			transform: scale3d(.3, .3, .3)
		}

		20% {
			transform: scale3d(1.1, 1.1, 1.1)
		}

		40% {
			transform: scale3d(.9, .9, .9)
		}

		60% {
			opacity: 1;
			transform: scale3d(1.03, 1.03, 1.03)
		}

		80% {
			transform: scale3d(.97, .97, .97)
		}

		to {
			opacity: 1;
			transform: scaleX(1)
		}
	}

	/* 从右到左 */
	.delRightShoppingCardAnimations {
		animation: delRightShoppingCardAnimation .5s;
	}

	@keyframes delRightShoppingCardAnimation {
		from {
			transform: translateX(100rpx) rotate(900deg);
			animation-timing-function: linear;
		}

		to {
			transform: translateX(0rpx) rotate(0);

		}
	}

	/* 从左到右 */
	.delLeftShoppingCardAnimations {
		animation: delLeftShoppingCardAnimation .5s;
	}

	@keyframes delLeftShoppingCardAnimation {
		from {
			transform: translateX(0rpx) rotate(0);
		}

		to {
			transform: translateX(100rpx) rotate(900deg);
			animation-timing-function: linear;
		}
	}
</style>

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
本课程讲了Vue3+Vue2+Uni-app(uniapp)入门基础与实战,其中还重点讲解了ES6、TypeScript这些基础知识,实战由两大价值5000元的真实企业级项目组成,分别是仿京东电商网站和仿美团微信点餐小程序,同时两大项目代码全部赠送,还赠送前后端架构模板,工作中直接使用。VUE和uni-app是目前热门的前端框架,本课程教你如何快速学会VUE和uni-app并应用到实战,教你如何解决内存泄漏,常用UI库的使用,自己封装组件和插件,正式上线白屏问题,性能优化、解决iphoneX“刘海”兼容性问题、微信支付、微信授权登录,获取位置在地图上显示,获取用户所在的城市和街道信息,微信小程序发布审核等。对正在工作当中或打算学习VUE和uni-app高薪就业的你来说,那么这门课程便是你手中的葵花宝典。学习技巧:学习当中不要只看,一定要多敲代码,如果碰到某一个知识点不是很明白,不要钻牛角尖,千万不要因为一个点,放弃整个森林,接着往下学,硬着头皮开发项目。只要能亲自开发一个完整的项目,你会发现不明白的地方自然而然就明白了,项目做出来就真正的学会了。此vue和uni-app课程以面试和实战为基础进行讲解,每个知识点都会让你知道在实际项目开发中如何使用,学习后,可以开发大型项目,增强逻辑思维,至少让你拥有3年以上开发经验的实力!代码和ppt均可下载!免费提供《企业级完整实战项目接口文档》,绝对可用

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值