本文介绍: 现在很多app尤其是直播类、视频类甚至是社交类的,基本都是带有 “点赞功能“,其中有一部分app点赞功能甚至可以称为是 疯狂点赞,大量的爱心漂浮功能感觉非常有意思,忍不住尝试一下其实现~当然本文实现仅仅是demo级别的,下一篇我们再进一步优化本文先用CSS实现效果再说~

在这里插入图片描述

这是一个没有套路的前端博主,热衷各种前端向的骚操作,经常想到哪就写到哪,如果有感兴趣技术前端效果可以留言~博主看到后会去代替大家踩坑的~
主页: oliver尹的主页
格言: 跌倒了爬起来就好~

一. 前言

现在很多app尤其是直播类、视频类甚至是社交类的,基本都是带有 “点赞功能”,其中有一部分app点赞功能甚至可以被称为是 “疯狂点赞”,大量的爱心漂浮功能感觉非常有意思,忍不住尝试一下其实现~当然本文的实现仅仅是demo级别的,下一篇我们再进一步优化,本文先用CSS实现效果再说~
本文演示demo使用的UI组件库为:uView,它可以协助我们快速布局以及使用其一些组件,如对如何在uniapp安装uView存在疑惑请浏览博文:《《uni-app》npm详解及在uni-app中对npm的支持
耐心看完,或许所有收获~

二. 阅读对象难度

本文难度属于初级适合有对uni-app有一定了解的小伙伴通过本文你可以大致了解以下几个知识点

具体内容可以参考以下的思维导图:
在这里插入图片描述

三. 项目地址与最终效果

文本代码上传CSDN上的gitCode,有兴趣的小伙伴可以直接clone项目地址:https://gitcode.net/zy21131437/uni-app-study
本文最终实现效果图如下
在这里插入图片描述

四. 实现

4.1 简单布个局

由于我们只是为了探索实现点赞效果,因此template部分,也就是Html部分简单布局一下了,大致布局的示意图如下
在这里插入图片描述
具体代码如下

<template>
	<view class="study-container"&gt;
		<!-- 输入 -->
		<view class="study-bottom">
			<view class="input-container"><u--input class="input-style" placeholder="输入内容" border="surround"></u--input></view>

			<view class="likes-container" ref="likeContainer">
				<u-icon class="icon-style" color="#fc5531" name="heart-fill"></u-icon>
			</view>
		</view>
	</view>
</template>

简单的盒模型通过 view标签嵌套实现了简单布局最终实现的布局效果大致如下
在这里插入图片描述

其中这一段中最主要的是这一段代码

	<u-icon class="icon-style" color="#fc5531" name="heart-fill"></u-icon>

我们的目的是需要 实现点击后的大量带有上浮动画的爱心,那么这一段代码就是 必须包含点击事件用于触发点击事件绑定事件语法遵循vue语法

<u-icon class="icon-style" color="#fc5531" name="heart-fill" @click="createLikes"></u-icon>

<script>
export default {
	methods: {
		createLikes() {
      		console.log("触发点击")
		}
	}
};
</script>

4.2 实现上浮动

浮动画的核心利用的是CSS3的animate实现 的,先来个简单的上浮

.icon-animate-1 {
  animation: animate-1 1.5s ease-in-out;
}
@keyframes animate-1 {
  0% {
    top: 20px;
		opacity: 1;
  }
  100% {
    top: -140px;
		opacity: 0;
  }
}

解释一下这段代码,有一个类名 iconanimate-1这个类名中有一个 animation属性,它是隶属于CSS3中新增一个属性主要的作用执行动画这里执行一个名为 animate-1动画动画持续时间1.5s,动画的运动速度easeinout(动画以低速开始和结束

接着是 @keyframes animate-1定义一个动画,大致意思是开始的时候top值为20px,当动画结束时候top值为-140px,当定义完,把类名加到Icon组件上,它就会实现一个动画,动画大致是这样的效果
在这里插入图片描述
是不是有那么点意思了,既然单个动画实现了,那么接下来就是动态添加了,我们必须在 点击爱心的时候触发这个动态效果,而不是一加载页面就立刻触发

4.3 加入点击事件

接入上面的代码,我们在一开始的时候就为爱心的图标加入点击事件如下

<script>
export default {
	methods: {
		createLikes() {
      console.log("触发点击")
		}
	}
};
</script>

为了配合这段代码,我们 需要加入icon组件以及循环生成icon组件的变量加入组件后的代码如下

<view class="likes-container" ref="likeContainer">
  <u-icon v-for="(item, index) in likesData" :class="['icon-default', `${item.animate}`]" :name="item.name" :color="item.color" :key="item.id"></u-icon>

  <u-icon class="icon-style" color="#fc5531" name="heart-fill" @click="createLikes"></u-icon>
</view>
<script>
import _ from 'lodash';
export default {
	data() {
		return {
			likesData: []
		};
	},
	methods: {
		createLikes() {
      console.log("触发点击")
		}
	}
};
</script>

通过触发点击事件生成参数pushlikesData利用vuev-for指令循环生成DOM,当DOM被渲染出来之后,立刻触发CSS样式中的 animation动画,大致流程如下
在这里插入图片描述

第一步事件触发已经完成就是绑定在DOM上的点击事件,接着是 第二步创建配置参数
先说说配置参数作用,主要作用其实两个

两个参数需要 随机显示,因此在写配置函数之前要有一个 生成随机数函数

<script>
export default {
	methods: {
		randomNum(min, max) {
			return Math.floor(Math.random() * (max - min)) + min;
		},
    getLikeParams(){}
	}
};
</script>

这里简单的利用原生方法,实现了一个 随机数生成函数,之后利用随机数生成函数可以获得 随机的类名颜色

<script>
export default {
	methods: {
		randomNum(min, max) {
			return Math.floor(Math.random() * (max - min)) + min;
		},
    getLikeParams(){
      const classList = ['icon-animate-1'];
			const colorList = ['#fc5531', '#fcd030', '#00ff7f'];

			const className = classList[this.randomNum(0, classList.length)];
			const colorName = colorList[this.randomNum(0, colorList.length)];

			return {
				animate: className,
				color: colorName,
				name: 'heart-fill',
				id: `${new Date().getTime()}-likes`
			};
    }
	}
};
</script>

这样,每一次点击的时候,我们都可以得到一个 相对随机的参数配置
接着,我们需要 参数配置push进likesData数组v-for执行就会立刻执行循环生成DOM渲染页面

<script>
export default {
	methods: {
    createLikes() {
      const params = this.getLikeParams();
      // push参数
      this.likesData.push(params);
		},
		randomNum(min, max) {
			return Math.floor(Math.random() * (max - min)) + min;
		},
    getLikeParams(){
      const classList = ['icon-animate-1'];
			const colorList = ['#fc5531', '#fcd030', '#00ff7f'];

			const className = classList[this.randomNum(0, classList.length)];
			const colorName = colorList[this.randomNum(0, colorList.length)];

			return {
				animate: className,
				color: colorName,
				name: 'heart-fill',
				id: `${new Date().getTime()}-likes`
			};
    }
	}
};
</script>

试一下效果
在这里插入图片描述
效果还算不错,确实有点开始与目标效果相近了~

4.4 稍微优化一下

略微想一下,立刻发现 优化的点有三处

第一点优化
第一处优化就是对于执行完的动画需要及时的销毁,怎么实现呢?其实很简单,我们是push的方法将配置参数添加进数组然后v-for指令自动生成渲染了DOM,那么执行完了之后直接这个配置删除就完了,由于配置删除,v-for指令自然而言就会将对应的DOM

new Promise(reslove => {
  const params = this.getLikeParams();
  this.likesData.push(params);

  setTimeout(() => {
    reslove(params);
  }, 1200);
}).then(res => {
  this.likesData.shift();
});

通过Promise确保代码是同步执行的,执行完动画后直接使用 shift() 函数删除第一个配置即可,至于为什么要用Promise,那是因为其实可能一组动画类名,那么通过Promise我们可以精准控制添加类名的时机,算是方便扩展吧;
第二处优化
动态太少,那就加动画嘛,多定义几个动画,然后在随机生成class类名的时候把类名带上:

getLikeParams() {
  const classList = ['icon-animate-1', 'icon-animate-2', 'icon-animate-3', 'icon-animate-4', 'icon-animate-5'];
  const colorList = ['#fc5531', '#fcd030', '#00ff7f'];

  const className = classList[this.randomNum(0, classList.length)];
  const colorName = colorList[this.randomNum(0, colorList.length)];

  return {
    animate: className,
    color: colorName,
    name: 'heart-fill',
    id: `${new Date().getTime()}-likes`
  };
},

具体类名对应的动画这里就不放了,直接去代码里看即可,增加了类名动画后,再来看一下效果
在这里插入图片描述
看上去还不错,但还不够多,表现力还可以更强,但这一篇这里就算了,有兴趣的小伙伴可以自己加一下~
第三处优化
第三处优化主要是没有防抖处理,那么防抖我们可以直接借助lodash中的 throttle函数用法也非常简单,只需要包裹我们的函数即可

<script>
import _ from 'lodash';
export default {
	methods: {
		createLikes: _.throttle(function() {
			new Promise(reslove => {
				const params = this.getLikeParams();
				this.likesData.push(params);

				setTimeout(() => {
					reslove(params);
				}, 1200);
			}).then(res => {
				this.likesData.shift();
			});
		}, 50)
	}
};
</script>

通过设置后,在50毫秒内只能触发一次函数,这样就防止了那种疯狂触发的情况

五. 小结

本文主要分享了一下 通过CSS3的animation属性,实现了一个疯狂点赞的效果,可能有小伙伴问这种用法会有性能上的问题么,我个人感觉吧,由于动画是CSS3实现的其实性能没有多大影响,但要说这种做法是最合适嘛,那肯定不是,至少canvas实现的效果肯定比CSS3来的好~
一篇,我们封装一下,毕竟真实项目中我们不可能不考虑复用以及实现的问题然后动画也不够完美,下一步继续优化~

原文地址:https://blog.csdn.net/zy21131437/article/details/127125724

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_44426.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注