CSS实现文字跑马灯效果
在完成一个任务的时候,要求在表格中固定宽度的其中一个item
文字过长需要滚动显示,然后经过多次效果的尝试,实现代码如下所示:
- 它需要一个外层包围盒,设置定宽、文字不换行以及超过隐藏
- 子元素为一个
p
标签,设置width: fit-content;
使盒子背景宽度随文字宽度而进行自适应,并设置一个自定义属性text
(可自定义) - 给
p
标签添加伪元素::after
,设置content: attr(text);
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>* {margin:0;padding: 0;}.container {/* 最外层盒子,需要三个属性:定宽、文字不换行、超过隐藏 */width: 500px;white-space: nowrap;overflow: hidden;font-size: 20px;color: #65b4ae;}.container_words {position: relative;/* 盒子背景宽度将随文字宽度而进行自适应 */width: fit-content;/* 添加动画 */animation: move 4s linear infinite;/* 让前面的几个文字有一个初始的距离,达到更好的呈现效果 */padding-left: 20px;}.container_words::after {position: absolute; right: -100%;content: attr(text);}@keyframes move {0% {transform: translateX(0);}100% {transform: translateX(-100%);}}</style>
</head>
<body><div class="container"><p class="container_words" text="文字文字文字文字文字">文字文字文字文字文字</p></div>
</body>
</html>
效果如下:
那么,我们试着将其封装,以便在多处使用:
- 首先,我们需要计算这段文字的宽度。通过扩展String原型方法
getWidth
/*** 获取文本px宽度* @param font{String}: 字体样式* @return {Number} 文本宽度**/
String.prototype.getWidth = function (font: string) {// re-use canvas object for better performanceconst canvas =String.prototype.getWidth.canvas ||(String.prototype.getWidth.canvas = document.createElement('canvas')),context = canvas.getContext('2d');font && (context.font = font);const metrics = context.measureText(this);return metrics.width;
};
- 其次,我们设想哪些参数是需要可配置的。
属性 | 是否必须 | 类型 | 默认值 | 描述 |
---|---|---|---|---|
width | 是 | Number | - | 元素DOM的最大宽度,超过此宽度将滚动 |
text | 是 | String | - | 文本内容 |
font | 是 | String | - | 这个是用来计算传入的文本的真实宽度,对比最大宽度看是否需要滚动。示例:21px SourceHanSansCN-Normal |
classNames | 否 | String | 空 | 元素class类名,需要设置其他的样式 |
speed | 否 | Number | 20 | 滚动速度,单位s |
paddingLeft | 否 | Number | 20 | paddingLeft,需要滚动的元素的初始paddingLeft,为了防止初次滚动而看不见前面几个字 |
那么,封装的组件完整代码如下:
<template><divv-if="text.getWidth(font) > width":class="['horse', classNames]":style="{width: width + 'px','--speed': speed,}"><p:text="text"class="horse_words":style="{paddingLeft: paddingLeft + 'px',}">{{ text }}</p></div><divv-else:style="{width: width + 'px',}":class="classNames">{{ text }}</div>
</template><script lang="ts">
export default {name: 'HorseRaceLamp',props: {// 元素DOM的最大宽度,超过此宽度将滚动width: {type: Number,required: true,},// 文本内容text: {type: String,required: true,},// 文本字体、大小等 示例:'21px SourceHanSansCN-Normal'font: {type: String,required: true,},// 元素class类名,需要设置其他的样式classNames: {type: String,default: '',},// 滚动速度,单位sspeed: {type: Number,default: 20,},// paddingLeft,需要滚动的元素的初始paddingLeft,为了防止初次滚动而看不见前面几个字paddingLeft: {type: Number,default: 20,},},
};
</script><style lang="scss" scoped>
.horse {white-space: nowrap;overflow: hidden;&_words {position: relative;width: fit-content;animation: move calc(var(--speed) * 1s) linear infinite;&::after {position: absolute;right: -100%;content: attr(text);}}
}
@keyframes move {0% {transform: translateX(0);}100% {transform: translateX(-100%);}
}
</style>
使用方式:
<HorseRaceLampfont="20px SourceHanSansCN-Normal":width="115"text="今日累计收费金额今日累计收费金额今日累计收费金额"
/>