---
theme: smartblue
这是我参与更文挑战的第26天,活动详情查看: 更文挑战 !
👽 概论
最高端的动画效果,往往由最朴素的方法实现,直接看效果。
ps: 此次组件开发使用vue实现。
👽 实现思路
老规矩,先说实现思路:每位数字所在的列都有竖排的0~9十个数字,需要展示几就通过动态控制css将其推到相应位置。
👽 基本布局
按照如上思路,首先我们来实现竖排数字的基本布局:
<!--
* @Author: 星始流年
* @Description:父组件
-->
<template>
<RollingNum :num="num"></RollingNum>
</template>
<script>
import RollingNum from "../../components/rollingNum/rollingNum.vue";
export default {
name: "Home",
components: {
RollingNum,
},
data() {
num: 270,
};
},
};
</script>
<!--
* @Author: 星始流年
* @Description:数字滚动组件
-->
<template>
<!-- 所有数字的整体容器 -->
<div
class="num-box"
:style="{ fontSize, height: fontSize, lineHeight: fontSize }"
>
<!-- 单个数字的容器 -->
<div
v-for="(item, i) in splitNum"
:key="i + 'l'"
ref="numEL"
class="num-item"
>
<!-- 所有备用数字的容器 -->
<div v-for="eachNum in 10" :key="eachNum" class="num">
{{ eachNum - 1 }}
</div>
</div>
</div>
</template>
<script>
export default {
props: {
num: {
type: Number,
default: 0,
},
fontSize: {
type: String,
default: "1rem",
},
},
computed: {
splitNum() {
const splitNum = this.num.toString().split("");
return splitNum;
},
},
};
</script>
<style lang="less" scoped>
@import "./rollingNum.less";
</style>
//rollingNum.less
.num-box {
border: 1px solid red;//border后期去掉
display: flex;
align-items: flex-start;
justify-content: flex-start;
}
具体的排列效果如下:
👽 调整数字
可以看到,虽然子组件接收到的数字为270,但布局的展示数字都是0,接下来我们通过利用transform属性来将调整数字使其正确展示:
<!--
* @Author: 星始流年
* @Description:数字滚动组件
-->
<script>
export default {
//···
data() {
return {
numEL: null,
};
},
mounted() {
this.numEL = this.$refs.numEL;//获取所有列数字的集合
this.adaptNum()
},
methods: {
//调整数字的方法
adaptNum() {
//遍历拆分后的数字[2,7,0]
this.splitNum.forEach((num, i) => {
//每个数字在Y方向上占10%,该位的数字是多少,就往上推多少个10%
this.numEL[i].style.transform = `translateY(-${10 * num}%)`;
});
},
},
}
</script>
👽 动态调整
这一阶段我们在父组件动态改变数字,然后在子组件进行监听,做出相应改变:
<!--
* @Author: 星始流年
* @Description:父组件
-->
export default {
//···
data() {
num: 270,
};
},
mounted() {
setInterval(() => {
this.num++;
}, 1000);
},
};
</script>
<!--
* @Author: 星始流年
* @Description:数字滚动组件
-->
<script>
export default {
//···
watch: {
num() {
//num改变时重新调整位置
this.adaptNum();
},
},
</script>
👽 动画添加
数字跳动很生硬,所以我们为其添加过渡效果:1.每位数字调整时遵循慢-快-慢的曲线,2. 位数越大的数字的滚动过程越长:
//rollingNum.less
.num-box {
display: flex;
align-items: flex-start;
justify-content: flex-start;
border-box:1px solid red;
overflow: hidden;//隐藏不必要的数字
.num-item {
transition-timing-function: cubic-bezier(0.93, 0.01, 0, 1);//定一条动画曲线
}
}
<!--
* @Author: 星始流年
* @Description:数字滚动组件
-->
<script>
export default {
//···
methods: {
//调整数字的方法
adaptNum() {
this.splitNum.forEach((num, i) => {
//每个数字在Y方向上占10%,该位的数字是多少,就往上推多少个10%
this.numEL[i].style.transform = `translateY(-${10 * num}%)`;
//位数越滚动过程越长
this.numEL[i].style.transitionDuration = `${
1 + (this.splitNum.length - i) * 0.3
}s`;
});
},
},
</script>
👽 结语
基本的实现就是这样,respect.