跑马灯,非常常用的功能,用于消息通知之类的。百度一搜都是使用<marquee></marquee>来完成。结果发现W3C上根本没有这个标签。原来是这个标签即将被删除。在前端不断革新的今天,怎么能用将废弃的标签呢。指不定哪天就没了,程序出了莫名的bug都不知道。所以我决定自己写一个跑马灯。
单独的css3动画完全可以实现一个跑马灯效果,但是,css写死了,那怎么组件化,让人人都可以用呢。所以想到使用js控制。第一个想到的就是定时器。通过定时器+transform:translateX()去减少px的值。只需要将定时器的时间设置为 16.6,即每秒刷新60次,让人看不到卡顿。轻松实现。
定时器存在一个致命问题,假如你做的页面还有其他动画也使用定时器,那完蛋,js是单线程,这种定时器会让组件移动开始出现卡顿。到后期可能直接卡死页面。
所以使用定时器的方案pass。
采用css3的动画的方式,这种方式利用纯css完成,为了不写死动画效果,使用js控制css,有一点all in js的感觉哈。下面上关键代码
runAnimationLR(){
this.render2.setAttribute(this.canvasBox.nativeElement,'style',`width: ${this.config['width']} `);
this.render2.setAttribute(this.marqueeBox.nativeElement,'style',!!this.config['animation']?
`animation: runAnimation ${this.config['animation']}; width: max-content`:
`animation: runAnimation ${this.config['duration']} ${this.config['timingFunction']} ${this.config['directionCount']}; width: max-content`);
let style = <CSSStyleSheet>document.styleSheets[0];
let start=this.canvasBox.nativeElement.getBoundingClientRect().width;
setTimeout(()=>{
let end = this.marqueeBox.nativeElement.getBoundingClientRect().width;
console.log(start,end)
style.insertRule(this.directionMap(this.config['direction'],start,end));
},0)
}
runAnimationDU(){
this.render2.setAttribute(this.canvasBox.nativeElement,'style',`height: ${this.config['height']};width: ${this.config['width']}`);
this.render2.setAttribute(this.marqueeBox.nativeElement,'style',!!this.config['animation']?
`animation: runAnimation ${this.config['animation']}; width: 100%`:
`animation: runAnimation ${this.config['duration']} ${this.config['timingFunction']} ${this.config['directionCount']}; width: 100%`);
let style = <CSSStyleSheet>document.styleSheets[0];
let start=this.canvasBox.nativeElement.getBoundingClientRect().height;
setTimeout(()=>{
let end = this.marqueeBox.nativeElement.getBoundingClientRect().height;
console.log(start,end)
style.insertRule(this.directionMap(this.config['direction'],start,end));
})
}
directionMap(dir:string,start:number,end:number):string{
if(dir==='right'){
return `@keyframes runAnimation
{
from {transform:translateX(${start}px);}
to {transform:translateX(${-end}px);}
}`
}
if(dir==='left'){
return `@keyframes runAnimation
{
from {transform:translateX(${-end}px);}
to {transform:translateX(${start}px);}
}`
}
if(dir==='down'){
return `@keyframes runAnimation
{
from {transform:translateY(${-end}px);}
to {transform:translateY(${start}px);}
}`
}
if(dir==='up'){
return `@keyframes runAnimation
{
from {transform:translateY(${-end}px);}
to {transform:translateY(${start}px);}
}`
}
}
关键代码如上,可以控制上下,左右变换。相对比较简单,完整代码放在github上,暂时还没上传,上传后附上地址。
原生的代码和上述类似,把获取dom的方式换成原生的即可。
希望对你有帮助。。。