手把手教你用VUE封装一个文本滚动组件
作者:Sumu
一、引言
项目有文本滚动展示的需求,一开始使用marquee标签来实现需求,但是看一下MDN对该标签的描述:
这个标签已经不再推荐使用了,那就自己封装一个类似的组件来用。
二、实现思路
1.如何让文本滚动起来?
通过动画我们设置过渡transform:translateX(a) => transfrom:translateX(b)来实现向左或向右的滚动效果。transform:translateY(c) => transfrom:translateY(d)来实现向下或向上的滚动效果。
2.组件需要哪些配置?
(1)滚动的方向:上右下左
(2)滚动的速度:这里我以px/s作为单位
三、实现过程
1.html
2.css
最外层的div为滚动的可视区,里面的div为文本滚动区。可视区宽度高度均为100%使用时大小由外部容器决定,overflow设为hidden,防止文本滚动区滚动出可视区外仍可见。文本滚动区设置宽高都为fit-content使大小随内容自适应,内部设置插槽使用组件时插入滚动内容。
3.动画
动画应设置在文本滚动区上
需要上右下左四个方向滚动的动画,我们只需要定义上左两个方向,另外两个方向直接反转即可。先来想想向上滚动的动画怎么写,向上滚动的话文本滚动区的起点应设置在可视区外正下方,所以动画的起点应为 transform: translateY(可视区的高度),终点应设置在可视区外正上方应为transform: translateY(-100%)。
向上向左动画即为:
--text-scroll-height、--text-scroll-width两个css变量的值是可视区的高度和宽度,由于可视区的宽高不确定,所以需要通过js获取并设置这两个css变量。
注意: 动画样式不能加上scoped,否则不生效!
4.js
(1)组件配置
通过props传入组件配置
(2)计算得到滚动动画
scrollLength为一次动画的实际滚动的长度,time为一次动画的持续时间。我们可以算出scrollLength应为:可视区的宽或高加上文本滚动区的宽或高(根据滚动的方向来判断是宽还是高)。time应为 scrollLegnth / 组件配置的滚动速度。
(3)生命周期
在mounted里调用上面的方法初始化组件。在updated里同样调用该方法,当组件宽高改变或插槽内容变动重新计算动画样式。
三、完整代码
<template> <!-- 文本滚动 --> <div class="text-scroll" ref="textScroll"> <div class="content" ref="content" :style="scrollAnimation"> <!-- 默认插槽,插入滚动内容 --> <slot></slot> </div> </div> </template> <script> export default { name: "TextScroll", props: { /* 滚动方向 * value: up、down、left、right */ direction: { default: "up", type: String, }, //滚动速度 单位px/s speed: { default: 60, type: Number, }, }, data() { return { //滚动动画 scrollAnimation: {}, }; }, methods: { getScrollAnimation() { //获取文本滚动实际显示宽度高度,设为css变量,用于设置动画开始起始位置 let height = this.$refs.textScroll.offsetHeight; let width = this.$refs.textScroll.offsetWidth; this.$refs.content.style.setProperty( "--text-scroll-height", `${height}px` ); this.$refs.content.style.setProperty("--text-scroll-width", `${width}px`); //滚动长度、时间 let scrollLength, time; //根据滚动方向来设置不同的滚动动画 switch (this.direction) { case "up": scrollLength = this.$refs.content.offsetHeight + height; time = scrollLength / this.speed; this.scrollAnimation.animation = `up-scroll linear ${time}s infinite`; break; case "down": scrollLength = this.$refs.content.offsetHeight + height; time = scrollLength / this.speed; this.scrollAnimation.animation = `up-scroll linear ${time}s infinite reverse`; break; case "left": scrollLength = this.$refs.content.offsetWidth + width; time = scrollLength / this.speed; this.scrollAnimation.animation = `left-scroll linear ${time}s infinite`; break; case "right": scrollLength = this.$refs.content.offsetWidth + width; time = scrollLength / this.speed; this.scrollAnimation.animation = `left-scroll linear ${time}s infinite reverse`; break; } }, }, async mounted() { //设置文本滚动动画 this.getScrollAnimation(); }, updated() { //当插槽内容更新重新计算滚动动画 this.getScrollAnimation(); }, }; </script> <style scoped lang="scss"> .text-scroll { width: 100%; height: 100%; overflow: hidden; .content { height: fit-content; width: fit-content; } } </style> <style lang="scss"> .text-scroll { .content { @keyframes up-scroll { 0% { transform: translateY(var(--text-scroll-height)); } 100% { transform: translateY(-100%); } } @keyframes left-scroll { 0% { transform: translateX(var(--text-scroll-width)); } 100% { transform: translateX(-100%); } } } } </style>
总结
到此这篇关于用VUE封装一个文本滚动组件的文章就介绍到这了,更多相关VUE封装文本滚动组件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!