我们无论是移动端还是PC端都会遇到像滚动新闻的展示方式
演示.gif
自己做了一个组件,方便以后调用
下面是组件内部代码:
<template>
<transition name="fade">
<!--主要内容-->
<div class="noticebar" :style="{backgroundColor:data.backround}">
<div style="margin-left:5px"></div>
<img v-if="data.icon" :style="{height:data.iconSize?data.iconSize:'16px',width:data.iconSize?data.iconSize:'16px'}" :src=data.icon alt="">
<div style="margin-right:5px"></div>
<div ref="back" class="back">
<span ref="text" :style="{fontSize:data.size?data.size:'16px',color:data.color?data.color:'#f60'}" class="text">{{ data.text?data.text:'通知内容' }}</span>
</div>
</div>
</transition>
</template>
<script>
export default {
props: {
options: {
type: Object,
default() {
return {
text: '默认'
};
}
}
},
data() {
return {
speed: this.options.speed, // 速度(单位px/s)
backWidth: '', // 父级宽度
backHeight: '', // 父级高度
wordLength: '', // 文本长度
state: 1,
firstAnimationTime: '', // 状态一动画效果
secondAnimationTime: '', // 状态二动画效果
data: this.options
};
},
methods: {
// 获取数据
getData() {
let style = document.styleSheets[0];
let text = this.$refs.text;
let back = this.$refs.back;
this.backWidth = back.offsetWidth;
this.backHeight = back.offsetHeight;
text.style.lineHeight = this.backHeight + 'px';
this.wordLength = text.offsetWidth;
this.ComputationTime(); // 计算时间
style.insertRule(
`@keyframes firstAnimation {0% {left:0px;}100% {left:-${this.wordLength}px;}}`
);
style.insertRule(
`@keyframes secondAnimation {0% {left:${this.backWidth}px;}100% {left:-${this.wordLength}px;}}`
);
setTimeout(res => {
this.changeState();
}, this.data.delay);
},
// 用速度计算时间(想要保持速度一样,2种状态时间不同需算出)
ComputationTime() {
this.firstAnimationTime = this.wordLength / this.speed;
this.secondAnimationTime =
(this.wordLength + this.backWidth) / this.speed;
},
// 根据状态切换动画
changeState() {
let text = this.$refs.text;
if (this.state == 1) {
text.style.animation = `firstAnimation ${this.firstAnimationTime}s linear`;
this.state = 2;
} else {
text.style.animation = `secondAnimation ${this.secondAnimationTime}s linear infinite`;
}
},
Listener() {
let text = this.$refs.text;
console.log(text);
text.addEventListener(
'animationend',
res => {
this.changeState();
},
false
);
}
},
mounted() {
this.Listener();
setTimeout(res => {
this.getData();
}, 100);
}
};
</script>
<style lang="less" scoped>
.noticebar {
display: flex;
align-items: center;
height: 100%;
width: 100%;
background-color: #fff7cc;
.icon {
img {
height: 100%;
width: 100%;
}
}
.back {
overflow: hidden;
white-space: nowrap;
margin: 0 auto;
height: 100%;
width: 100%;
position: relative;
.text {
position: absolute;
display: inline-block;
padding: 2px 0;
}
}
}
</style>
父组件调用:
<template>
<transition name="fade">
<div class="wrap">
<div class="father">
<noticebar :options=options></noticebar>
</div>
</div>
</transition>
</template>
<script>
import noticebar from './noticebar';
export default {
components: {
noticebar
},
data() {
return {
// noticebar 组件的配置项
options: {
text:'日本网友momopoi家的柯基,表情管理经常崩坏,可以说是喜怒形于色的典范', // 通知内容
icon:'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=236296424,1105446647&fm=26&gp=0.jpg', // 左侧图标(不需要icon不传)
iconSize: '16px', // icon大小(正方形默认16px)
size: '16px', // 通知内容文字大小(默认16px)
color: '#1989fa', // 通知内容文字颜色(默认#f60)
backround: '#fff7cc', //背景颜色(默认#fff7cc)
delay: '1000', // 动画延迟时间(默认一秒后开始滚动,单位毫秒)
speed: '50' // 滚动速率默认50 (px/s)
}
};
}
};
</script>
<style lang="less" scoped>
.wrap {
.father {
margin: 150px auto;
height: 60px;
width: 100%;
img {
height: 100%;
width: 20px;
}
}
}
</style>
目前可供的配置项在option中,以后有什么好的建议请在评论留言,我会关注并且经常更新这个组件。
网友评论