小程序横向跑马灯效果(3种方式)

前端 2020-12-23 4229

1.方式1 js实现

看了一下别人的博客,自己写了一下,效果虽然实现了,但是有一个小bug,就是当滚动完成后,下一个动画会等待2秒左右才出现,暂时找不到原因!!!

思路:三个动画,第一个动画用于,将展示在内容区头部的文字滚动,第二个动画,将文字放置在内容区的尾部,第三个动画,将文字滚动起来。第二和第三个动画会被放置在定时器中重复运行。

  data: {
    animationData: {},
  },
  
sleep: function (num) { // copy的,睡眠,但是感觉不到作用
    var nowTime = new Date();
    var exitTime = nowTime.getTime() + num;
    while (true) {
      nowTime = new Date();
      if (nowTime.getTime() > exitTime)
        return;
    }
  },
  textScroll () {
    var animation = wx.createAnimation({ // 创建动画
      duration: 8000,
      timingFunction: 'linear',
    })
    this.animation = animation;
    // 根据屏幕大小换算文字长度
    const w = wx.getSystemInfoSync().windowWidth / 375 * 24 / 2;// 文字的长度
    var query = wx.createSelectorQuery();
    query.select('.msg-txt').boundingClientRect();
    query.exec((res) => {
      // 第一个动画
      this.msgTxtWidth = res[0].width;
      animation.translateX(-(59 * w - this.msgTxtWidth)).step()
      this.setData({
        animationData: animation.export()
      })
    })
    setInterval(() => {
      // 第二个动画
      // 将文字的头部置到容器的尾部
      console.log(this.msgTxtWidth)
      animation.translateX(this.msgTxtWidth).step({
        duration: 0
      }); // 创建动画,立刻执行
      this.setData({ // 执行
        animationData: animation.export()
      })
      this.sleep(5); // 延迟5微秒
      // 第三个动画
      animation.translateX(-(59 * w)).step({duration: 10000}); 
      this.setData({
        animationData: animation.export()
      })
    }, 10000);
  },

wxss

/*通知*/
.message{
  display:flex;
  align-items: center;
  width: 100%;
  padding: 20rpx 10rpx;
  border: 1rpx solid #E7EBEF;
  border-radius: 20rpx;
}
.msg-icon{
  display: flex;
  align-items: center;
  width: 15%;
}
.msg-icon-txt{
  margin-left: 10rpx;
  font-size: 24rpx;
  color: #FF5D38;
}
.msg-icon image{
  width: 40rpx;
  height: 40rpx;
}
.msg{ /*主体*/
  flex:1;
  overflow: hidden;
}
.msg-txt{
  font-size: 24rpx;
  color: #7B868C;
  white-space: nowrap;
}
.msg-more{
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-end;
  width: 5%;
}
.msg-more text{
  font-size: 24rpx;
  color: #BDC7C6;
}

第二种方式,使用css

参考:https://blog.csdn.net/hamelong/article/details/82657614

wxml
  <view class="marquee_container" style="--marqueeWidth--:-12em">
      <view class="marquee_text">一个人活着就是为了让更多的人更好的活着!</view>
  </view>
wxss
/*首页跑马灯效果*/
@keyframes around {
  from {
   margin-left: 100%;
  }
  to {
   /* var接受传入的变量 */
   margin-left: var(--marqueeWidth--);
  }
 }
 
.marquee_container{
  background-color: #fe4655;
  height: 50rpx;
  line-height: 44rpx;
  position: relative;
  width: 100%;
  margin-top:0rpx;
}
.marquee_container:hover{
  /* 不起作用 */
  animation-play-state: paused;
}
.marquee_text{
  color:#fff;
  font-size: 28rpx;
  display: inline-block;
  white-space: nowrap;
  animation-name: around;
  animation-duration: 10s;  /*过渡时间*/
  animation-iteration-count: infinite;
  animation-timing-function:linear;
}
/*首页跑马灯效果*/

效果展示:

更新方式3:

使用js,实现思路不同于方式1,这次使用绝对定位left

来个简版的:

data: {
  left:0,
  txt:"我是一段文字,你知道我意思",
  fontSize: 16,
},

onReady: function () {
    const screenWidth = wx.getSystemInfoSync().windowWidth; // 获取屏幕宽度
    let txtWidth = this.data.txt.length * this.fontSize; // 获取文字宽度
    let left = this.data.left; // 获取初始的left
    var clearInterval0 = setInterval(() => { // 设置定时器
      if (left !== -txtWidth){ // 当文字没有滚动到完全消失
        left = left - 1;
        this.setData({
          left
        })
      } else {
        left = screenWidth // 将文字的位置放置到尾部
        // clearInterval(clearInterval0)
      }
    }, 20);
},

// wxml +wxss
<view class="wrapper">
  <view>标题</view>
  <view>标题</view>
  <view class="txt" style="left:{{left}}px">{{txt}}</view>
</view>

.wrapper{
  position: relative;
  width: 100%;
}
.txt{
  font-size: 16px;
  position: absolute;
  left: 0;
  white-space: nowrap;
}

效果:

代码升级

Page({
  data: {
    text: '这是一条会滚动的文字滚来滚去的文字跑马灯,哈哈哈哈哈哈哈哈',
    marqueepace: 1, //滚动速度
    marqueedistance: 0, //初始滚动距离
    marqueedistance2: 0,
    marquee2copy_status: false,
    marquee2_margin: 60,
    size: 14,
    orientation: 'left', //滚动方向
    interval: 20 // 时间间隔
  },
  onShow: function () {
    // 页面显示
    var vm = this;
    var length = vm.data.text.length * vm.data.size; //文字长度
    var windowwidth = wx.getSystemInfoSync().windowWidth; // 屏幕宽度
    vm.setData({
      length: length,
      windowwidth: windowwidth,
      marquee2_margin: length < windowwidth ? windowwidth - length : vm.data.marquee2_margin //当文字长度小于屏幕长度时,需要增加补白
    });
    vm.run1(); // 水平一行字滚动完了再按照原来的方向滚动
    vm.run2(); // 第一个字消失后立即从右边出现
  },
  run1: function () {
    var vm = this;
    var interval = setInterval(function () {
      if (-vm.data.marqueedistance < vm.data.length) {
        vm.setData({
          marqueedistance: vm.data.marqueedistance - vm.data.marqueepace,
        });
      } else {
        
        clearInterval(interval);
        vm.setData({
          marqueedistance: vm.data.windowwidth
        });
        vm.run1();
      }
    }, vm.data.interval);
  },
  run2: function () {
    var vm = this;
    var interval = setInterval(function () {
      if (-vm.data.marqueedistance2 < vm.data.length) {
        // 如果文字滚动到出现marquee2_margin=30px的白边,就接着显示
        vm.setData({
          marqueedistance2: vm.data.marqueedistance2 - vm.data.marqueepace,
          marquee2copy_status: vm.data.length + vm.data.marqueedistance2 <= vm.data.windowwidth + vm.data.marquee2_margin,
        });
      } else {
        if (-vm.data.marqueedistance2 >= vm.data.marquee2_margin) { // 当第二条文字滚动到最左边时
          vm.setData({
            marqueedistance2: vm.data.marquee2_margin // 直接重新滚动
          });
          clearInterval(interval);
          vm.run2();
        } else {
          clearInterval(interval);
          vm.setData({
            marqueedistance2: -vm.data.windowwidth
          });
          vm.run2();
        }
      }
    }, vm.data.interval);
  }
})

wxml + wxss

<view>1 显示完后再显示</view>
<view class="example">
 <view class="marquee_box">
 <view class="marquee_text" style="{{orientation}}:{{marqueedistance}}px;font-size: {{size}}px;">
  {{text}}
 </view>
 </view>
</view>
<view>2 出现白边后即显示</view>
<view class="example">
 <view class="marquee_box">
 <view class="marquee_text" style="{{orientation}}:{{marqueedistance2}}px;font-size: {{size}}px;">
  <text>{{text}}</text>
  <text wx:if="{{marquee2copy_status}}" style="margin-left:{{marquee2_margin}}px;">{{text}}</text>
 </view>
 </view>
</view>


.example {
  display: block;
  width: 100%;
  height: 100rpx;
 }
  
 .marquee_box {
  width: 100%;
  position: relative;
 }
  
 .marquee_text {
  white-space: nowrap;
  position: absolute;
  top: 0;
 }

效果:

标签:前端

文章评论

评论列表

已有0条评论