整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

巧用CSS3-Animation动画,实现小程序弹幕效果

近接到公司小程序项目首页迭代改版的工作,涉及到文章图文布局改版。主要是精选文章,在首页推广入口增加评论弹幕效果,后端弹幕数据是随文章列表接口一次性返回给前端,由前端来处理弹幕数据及相关弹幕交互效果。

随后,简单分析了一下后端接口的数据结构,以及查询了一些传统web端弹幕的js实现方式。

鉴于我们当前业务的后端弹幕数据非动态持续发送,而是固定的评论条目,前端处理也仅仅是把文章评论渲染成弹幕并循环滚动,于是我采用的解决方案是通过css3的Animation动画属性来实现。

下面是拆分出来的部分代码demo实现效果的动画演示效果。



左边的视频演示:有序弹幕(固定轨道式,弹幕数据划分为三条固定轨道进行滚动显示)

右边的视频演示:无序弹幕(每条弹幕的出现位置随机性);

如果视频无法播放的话,可以查看下方对比图:




当前代码逻辑比较适合一些展示型的前端交互效果,比如:资讯类栏目、社交属性图文栏目、推广类广告位等。

# 无序弹幕 wxml #

<view class='dmGroup' wx:for="{{ dmData }}" wx:key="{{ item.id }}" style="top:{{ item.top }}%; animation: dmAnimation {{item.time}}s linear {{ index*3 }}s infinite; ">
 <view class='dmItem'>
 <view class='dm'>
 <view class='avatarBox'>
 <image src='{{ item.sex == 0 ? avatarBoy : avatarGirl }}' class='avatar' mode='aspectFit'></image>
 <image src='{{ item.sex == 0 ? iconBoy : iconGirl }}' class='sex' mode='aspectFit'></image>
 </view>
 <text class='content'>{{ item.content }}</text>
 <image src='{{ iconGood }}' class='icon good' mode='aspectFill'></image>
 <text>{{ item.zanNumber }}</text>
 </view>
 </view>
</view>


# 无序弹幕 wxss #

@keyframes dmAnimation{
 from{ left: 100%; }
 to{ left: -100%; }
}


# 有序弹幕(轨道式) wxml #

<!-- top -->
<view class='dmGroup top' style="animation: dmAnimation2 35s linear infinite; ">
 <view class='dmItem' wx:for="{{ dmData }}" wx:if="{{ index < 6 }}" wx:key="{{ item.id }}">
 <view class='dm'>
 <view class='avatarBox'>
 <image src='{{ item.sex == 0 ? avatarBoy : avatarGirl }}' class='avatar' mode='aspectFit'></image>
 <image src='{{ item.sex == 0 ? iconBoy : iconGirl }}' class='sex' mode='aspectFit'></image>
 </view>
 <text class='content'>{{ item.content }}</text>
 <image src='{{ iconGood }}' class='icon good' mode='aspectFill'></image>
 <text>{{ item.zanNumber }}</text>
 </view>
 </view>
</view>
<!-- mid -->
<view class='dmGroup mid' style="animation: dmAnimation2 30s linear 1s infinite; ">
 <view class='dmItem' wx:for="{{ dmData }}" wx:if="{{ index > 5 && index < 10 }}" wx:key="{{ item.id }}">
 <view class='dm'>
 <view class='avatarBox'>
 <image src='{{ item.sex == 0 ? avatarBoy : avatarGirl }}' class='avatar' mode='aspectFit'></image>
 <image src='{{ item.sex == 0 ? iconBoy : iconGirl }}' class='sex' mode='aspectFit'></image>
 </view>
 <text class='content'>{{ item.content }}</text>
 <image src='{{ iconGood }}' class='icon good' mode='aspectFill'></image>
 <text>{{ item.zanNumber }}</text>
 </view>
 </view>
</view>
<!-- btm -->
<view class='dmGroup btm' style="animation: dmAnimation2 45s linear infinite; ">
 <view class='dmItem' wx:for="{{ dmData }}" wx:if="{{ index > 9 }}" wx:key="{{ item.id }}">
 <view class='dm'>
 <view class='avatarBox'>
 <image src='{{ item.sex == 0 ? avatarBoy : avatarGirl }}' class='avatar' mode='aspectFit'></image>
 <image src='{{ item.sex == 0 ? iconBoy : iconGirl }}' class='sex' mode='aspectFit'></image>
 </view>
 <text class='content'>{{ item.content }}</text>
 <image src='{{ iconGood }}' class='icon good' mode='aspectFill'></image>
 <text>{{ item.zanNumber }}</text>
 </view>
 </view>
</view>


# 有序弹幕 wxss #

@keyframes dmAnimation2{ 
 0% { transform: translateX(0); } 
 100% { transform: translateX(-130%); } 
}


# 查看线上项目弹幕效果 #


# 详细代码片段及详解,请私信哟#

轮事件:滚轮

滚动(卷动)事件:滚轮、拖拽滚动条、键盘方向键

<script type="text/javascript">
//滚轮事件:滚轮
//卷动事件:滚轮、拖拽滚动条、键盘↕键

//IE和Chrome
gunlun.onmousewheel = function(){
this.innerHTML += "IE和Chrome<br/>";
}
//Firefox
gunlun.addEventListener("DOMMouseScroll", function(){
this.innerHTML += "Firefox<br/>";
})
</script>

判断滚轮方向

<script type="text/javascript">
//滚轮事件:滚轮
//卷动事件:滚轮、拖拽滚动条、键盘↕键

//IE和Chrome
gunlun.onmousewheel = function(e){
var ev = e || window.event;
console.log(ev.wheelDelta);//判断滚轮方向的
//上120
//下-120

this.innerHTML += "IE和Chrome<br/>";
}
//Firefox
gunlun.addEventListener("DOMMouseScroll",function(e){
var ev = e || window.event;
console.log(ev.detail);//滚轮方向
//上-3
//下3
this.innerHTML += "Firefox<br/>";
})
</script>

兼容性封装

用JavaScript实现页面滑动到指定位置加载动画。

若页面滚动到class名为group-pic的元素的位置时开始加载


  1. $(document).ready(function(){
  2. var a,b,c;
  3. a = $(window).height(); //浏览器窗口高度
  4. var group = $(".group-pic");
  5. $(window).scroll(function(){
  6. b = $(this).scrollTop(); //页面滚动的高度
  7. c = group.offset().top; //元素距离文档(document)顶部的高度
  8. if(a+b>c){
  9. ...
  10. }else{
  11. ...
  12. }
  13. });
  14. });

原理: 1.获取浏览器窗口的高度;

2.获取页面滚动的高度;

3.获取页面距离文档(document)顶部的高度

offset().top具体指的是距哪里的高度呢?

一些获宽高度的属性:

网页可见区域宽: document.body.clientWidth;

网页可见区域高: document.body.clientHeight;

网页可见区域宽: document.body.offsetWidth (包括边线的宽);

网页可见区域高: document.body.offsetHeight (包括边线的宽);

网页正文全文宽: document.body.scrollWidth;

网页正文全文高: document.body.scrollHeight;

网页被卷去的高: document.body.scrollTop;

网页被卷去的左: document.body.scrollLeft;

网页正文部分上: window.screenTop;

网页正文部分左: window.screenLeft;

屏幕分辨率的高: window.screen.height;

屏幕分辨率的宽: window.screen.width;

屏幕可用工作区高度: window.screen.availHeight;

屏幕可用工作区宽度:window.screen.availWidth;

obj.offsetTop 指 obj 距离上方或上层控件的位置,整型,单位像素。

obj.offsetLeft 指 obj 距离左方或上层控件的位置,整型,单位像素。

obj.offsetWidth 指 obj 控件自身的宽度,整型,单位像素。

obj.offsetHeight 指 obj 控件自身的高度,整型,单位像素。

1.offsetTop : 当前对象到其上级层顶部的距离.

不能对其进行赋值.设置对象到页面顶部的距离请用style.top属性.

2.offsetLeft : 当前对象到其上级层左边的距离.

不能对其进行赋值.设置对象到页面左部的距离请用style.left属性.

3.offsetWidth : 当前对象的宽度.

与style.width属性的区别在于:如对象的宽度设定值为百分比宽度,则无论页面变大还是变小,style.width都返回此百分比,而offsetWidth则返回在不同页面中对象的宽度值而不是百分比值

4.offsetHeight : 与style.height属性的区别在于:如对象的宽度设定值为百分比高度,则无论页面变大还是变小,style.height都返回此百分比,而offsetHeight则返回在不同页面中对象的高度值而不是百分比值