在项目中我们经常遇到上下滚动的特效,类似于抽奖摇号…网上的一些基本特效很满足我们的需求。
尝试了下手动写js,把他集成了一个vue文件如下
<template>
<div class="indexBox">
<button @click="addNum">增加</button>
<div id="animeBox">
</div>
</div>
</template>
<script>
export default {
data() {
return {
totalNum:0,
setting: {
speed : 1000,//动画速度
num : "", //初始化值
iniAnimate : true, //是否要初始化动画效果
symbol : '',//默认的分割符号,千,万,千万
dot : 0 //保留几位小数点
}
}
},
mounted() {
//初始化(默认为0)
var newArr = this.numToArr(this.totalNum);
var $dom = $('#animeBox').find(".mt-number-animate-dom");
if($dom.length < newArr.length){
$('#animeBox').html(this.setNumDom(this.numToArr(this.totalNum)));
}else{
$dom.each(function(index, el) {
$(this).attr("data-num",newArr[index]);
});
}
},
methods: {
addNum(){
this.totalNum += Math.floor(Math.random()*10 +1);
console.log('this.totalNum', this.totalNum);
var newArr = this.numToArr(this.totalNum);
var $dom = $('#animeBox').find(".mt-number-animate-dom");
if($dom.length < newArr.length){
$('#animeBox').html(this.setNumDom(this.numToArr(this.totalNum)));
}else{
$dom.each(function(index, el) {
$(this).attr("data-num",newArr[index]);
});
}
this.runAnimate($("#animeBox"))
},
animeTop(){
let childLen = $(".mt-number-animate-dom").children().length;
var spanHei = $('.mt-number-animate-dom').height()/ Number(childLen); //10为元素个数
var thisTop = -this.totalNum*spanHei;
var animeBox = anime({
targets: '.mt-number-animate-dom',
translateY: thisTop,
easing: 'easeInOutQuad'
});
},
//数字处理
numToArr(num){
num = parseFloat(num).toFixed(this.setting.dot);
if(typeof(num) == 'number'){
var arrStr = num.toString().split("");
}else{
var arrStr = num.split("");
}
console.log(arrStr);
return arrStr;
},
//设置DOM symbol:分割符号
setNumDom(arrStr){
var nHtml = '<div class="mt-number-animate-dom" data-num="{{num}}">\
<span class="mt-number-animate-span">0</span>\
<span class="mt-number-animate-span">1</span>\
<span class="mt-number-animate-span">2</span>\
<span class="mt-number-animate-span">3</span>\
<span class="mt-number-animate-span">4</span>\
<span class="mt-number-animate-span">5</span>\
<span class="mt-number-animate-span">6</span>\
<span class="mt-number-animate-span">7</span>\
<span class="mt-number-animate-span">8</span>\
<span class="mt-number-animate-span">9</span>\
<span class="mt-number-animate-span">.</span>\
</div>';
var shtml = '<div class="mt-number-animate">';
for(var i=0,len=arrStr.length; i<len; i++){
if(i != 0 && (len-i)%3 == 0 && this.setting.symbol != "" && arrStr[i]!="."){
shtml += '<div class="mt-number-animate-dot">'+this.setting.symbol+'</div>'+nHtml.replace("{{num}}",arrStr[i]);
}else{
shtml += nHtml.replace("{{num}}",arrStr[i]);
}
}
shtml += '</div>';
return shtml;
},
//执行动画
runAnimate($parent){
let that = this;
$parent.find(".mt-number-animate-dom").each(function() {
var num = $(this).attr("data-num");
num = (num=="."?10:num);
var spanHei = $(this).height()/11; //11为元素个数
var thisTop = -num*spanHei+"px";
if(thisTop != $(this).css("top")){
if(that.setting.iniAnimate){
//HTML5不支持
if(!window.applicationCache){
$(this).animate({
top : thisTop
}, that.setting.speed);
}else{
$(this).css({
'transform':'translateY('+thisTop+')',
'-ms-transform':'translateY('+thisTop+')', /* IE 9 */
'-moz-transform':'translateY('+thisTop+')', /* Firefox */
'-webkit-transform':'translateY('+thisTop+')', /* Safari 和 Chrome */
'-o-transform':'translateY('+thisTop+')',
'-ms-transition':that.setting.speed/1000+'s',
'-moz-transition':that.setting.speed/1000+'s',
'-webkit-transition':that.setting.speed/1000+'s',
'-o-transition':that.setting.speed/1000+'s',
'transition':that.setting.speed/1000+'s'
});
}
}else{
that.setting.iniAnimate = true;
$(this).css({
top : thisTop
});
}
}else if($(this).css("top") == '0px'){
$(this).css({
'transform': 'translateY(0px)',
'transition': 'all 1s ease 0s'
})
}
});
}
}
}
</script>
<style scope>
.indexBox{
width: 100%;
height: 800px;
}
#animeBox{
margin: 50px;
}
.mt-number-animate{
font-family: '微软雅黑';
line-height:40px;
height: 40px;/*设置数字显示高度*/;
font-size: 36px;/*设置数字大小*/
overflow: hidden;
display: inline-block;
position: relative;
}
.mt-number-animate .mt-number-animate-dot{
width: 15px;/*设置分割符宽度*/
line-height: 40px;
float: left;
text-align: center;
}
.mt-number-animate .mt-number-animate-dom{
width: 20px;/*设置单个数字宽度*/
text-align: center;
float: left;
position: relative;
top: 0;
}
.mt-number-animate .mt-number-animate-dom .mt-number-animate-span{
width: 100%;
float: left;
}
</style>
可以把这个vue文件跑起来,看下效果(可以根据自己的需求调节速度,更改样式)。