用react的ReactCSSTransitionGroup插件实现简单的弹幕动画
1,开始的思路
公司想做直播方面的项目,并想加入弹幕的功能,直播的页面已经作为一个组件放在了用react+redux写好的一个网站项目上。
所以技术老大让我研究下如何用react实现弹幕的功能。下面我就简单说下我的react弹幕折腾之路。
一开始其实是两手空空,作为一个php的初级开发人员,我对前端技术掌握的很少,远不到熟练的程度。所以,我得从头学习如何用js+css实现弹幕,然后再将弹幕移植到react项目上去,这是我一开始的思路。
2,中间的折腾
我百度了下“js 弹幕”,发现大部分都是用jquery的animate()函数和css配合来实现的,比如这个HTML+CSS+jQuery实现弹幕技术,有些则是jquery配合css的animation来实现。
我学习了下用jquery的animate()函数配合css来实现弹幕的方法,然后就尝试将这个方法引入到react项目中去。但我在这个地方费了好多时间都没有进展,最终我放弃了将jquery引入react的想法。技术老大提醒我,可以找找react动画的解决方法。
于是百度、google,在sgemenfault和知乎上有不少问答,给出了三个解决方向:
1,用react官方提供的动画插件(ReactCSSTransitionGroup)可以实现基本和简单的动画
2,引入专业的第三方的动画库
3,用第三方的react动画插件
第1种方法,简单、直接,需要对react的动画插件有所了解,第2种方法需要非常熟悉第三方库的用法,像我这种前端的半吊子还是算了:),第3种方法,我也没考虑。
总之,我选择了第1种。我大致看了下react官方的tutorial和docs,然后就开始动手了。
3,初现曙光
按照react官网上给的TodoList例子,我写出了我的第1个react动画(没有用到redux),
实现的基本功能就是在一个输入框中输入文字,然后enter发送文字,文字从一个div的右侧走到左侧,最后消失。先把代码贴出来:
import React from 'react';
import ReactCSSTransitionGroup from 'react-addons-css-transition-group'; class App extends React.Component {
constructor(props) {
super(props);
this.state = {
word: '',
value: '',
index: 0,
top: 0,
};
this.returnWord = this.returnWord.bind(this);
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
} componentDidMount() {
// 监听回车事件
document.onkeydown = (event) => {
if (event.keyCode === 13) {
document.getElementById('sendBullet').click = null;
}
};
} handleSubmit(event) {
event.preventDefault();
this.setState({ value: '' });
} handleChange(event) {
this.setState({ value: event.target.value });
} returnWord() {
const word = this.myTextInput;
const index = this.state.index;
const top = this.state.top;
if (word === this.state.value) {
this.setState({ word, index: index + 1 });
}
if (top <= 435) {
this.setState({ top: top + 75 });
} else if (top > 435) {
this.setState({ top: 0 });
}
} render() {
const item = (
<div
className="bullet"
key={this.state.index}
style={{ top: `${this.state.top}px`, color: `#${((1 << 24) * Math.random() | 0).toString(16)}` }}
>
{this.state.word}
</div>
); return (
<div>
<form onSubmit={this.handleSubmit}>
<input
type="text"
ref={
(ref) => {
if (ref !== null && ref.value.trim() !== '') {
this.myTextInput = ref.value;
}
}
}
value={this.state.value}
onChange={this.handleChange}
/>
<button id="sendBullet" onClick={this.returnWord}>发送弹幕</button>
<div
style={{
position: 'relative',
width: '1200px',
height: '500px',
margin: 'auto',
background: 'rgba(255, 0, 0, 0.1)',
overflow: 'hidden',
}}
>
<ReactCSSTransitionGroup
transitionName={{
enter: 'bullet-enter',
}}
transitionEnterTimeout={5000}
transitionLeave={false}
>
{item}
</ReactCSSTransitionGroup>
</div>
</form>
</div>
);
}
} export default App;
可以看到我这里引入了ReactCSSTransitionGroup,它是react提供的一个动画插件,可以实现基本、简单的css动画和渐变功能,它需要单独安装,具体的安装方法可以百度或google。
下面来说下比较关键的地方:
1,代码第51~59行,定义要动的弹幕文字组件。 render方法中定义了一个item,这个item就是弹幕中要动起来的弹幕文字组件。要注意:item中的key属性是必须要给定的,哪怕你只有单独的1个item也要指定key,
这样React才能决定哪个item该如何动作,这也是react官方文档中所强调的。我定义了自增的index作为state来管理item的key,这样每个item都有一个唯一的key。
2,代码第87~95行,ReactCSSTransitionGroup配置。需要注意的是,一定要将要操纵的动画元素完全包含到ReactCSSTransitionGroup中去,然后就是根据动画需要设置要做的动画过程。我只要入场动画(有字幕出现时就开始动画)就可以了。
所以设置入场动画时间transitionEnterTimeout={5000}。另外,出场动画不需要可以设置为false: transitionLeave={false},不能忽略这个属性,不然会报错。transitionName中可以设置动画过程的css样式名称,设置规则可参考官网。
3,下面是我的入场动画css样式,也是要注意的第3点
.bullet {
opacity: 0.01;
}
.bullet-enter {
opacity:;
position: absolute;
left: 1100px;
}
.bullet-enter.bullet-enter-active {
opacity: .5;
position: absolute;
left: -100px;
transition: all 5000ms ease-in;
}
.bullet-enter对应入场动画开始时的item样式,.bullet-enter.bullet-enter-active对应入场动画结束时的item样式,可以看到用到了css的transition,这也是实现动画的关键。
以上3点比较关键,其余的问题就是如何产生item的问题,这个暂时先不写了。
4,将弹幕作为一个组件整合到react+redux项目中
其实只要实现了弹幕动画,整合也就容易了,下面先把弹幕组件的代码贴出来。
import React, { Component, PropTypes } from 'react';
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
class BulletScreen extends Component {
render() {
const item = (
<div
className="bullet"
key={this.props.index}
style={{
top: `${this.props.top}vh`,
color: 'rgb(255, 255, 255)',
whiteSpace: 'nowrap',
fontSize: '3vh',
}}
>
{this.props.word}
</div>
);
return (
<div
id="bullt-screen"
style={{
position: 'relative',
width: 'auto',
height: '46vh',
overflow: 'hidden',
margin: '-50vh auto auto auto',
background: 'rgba(0, 255, 0, 0.01)',
}}
>
<ReactCSSTransitionGroup
transitionName={{
enter: 'bullet-enter',
}}
transitionEnterTimeout={5000}
transitionLeave={false}
>
{item}
</ReactCSSTransitionGroup>
</div>
);
}
}
BulletScreen.propTypes = {
word: PropTypes.string,
index: PropTypes.number,
top: PropTypes.number,
};
export default BulletScreen;
到时在视频播放的页面中引入这个组件就可以了。
这个项目目前是我司的开源项目,感兴趣的朋友可以去github上看下: wecan-tv-frontend
参考资料:
HTML+CSS+jQuery实现弹幕技术
Animation Add-Ons
用react的ReactCSSTransitionGroup插件实现简单的弹幕动画的更多相关文章
- Xcode7使用插件的简单方法&&以及怎样下载到更早版本的Xcode
Xcode7自2015年9上架以来也有段时间了, 使用Xcode7以及Xcode7.1\Xcode7.2的小伙伴会发现像VVDocumenter-Xcode\KSImageNamed-Xcode\HO ...
- 移动端全屏滑动的小插件,简单,轻便,好用,只有3k swiper,myswiper,page,stage
https://github.com/donglegend/mySwiper mySwiper 移动端全屏滑动的小插件,简单,轻便,好用,只有3k 下载 直接下载 bower install mySw ...
- 数据统计表插件,highcharts插件的简单应用
highcharts插件的简单应用,非常全能好用的一个数据统计表插件. $(function () { $('#container').highcharts({ chart:{ type:" ...
- ASP.NET MVC5 插件机制中插件的简单实现
Autofac 依赖注入 ASP.NET MVC5 插件机制中插件的简单实现 一.前言 由于项目业务复杂,创建了多个插件并把他们放在了不同的项目中,项目使用AutoFac做的IOC:但是主项目可以注入 ...
- Atom编辑器之加快React开发的插件汇总
汇总下比较实用的atom插件[偏react开发的]-- 博主发现这个还是比较全面的! atom-react-autocomplete–项目内,组件名及状态的自动补全 autocomplete-js- ...
- swiper插件的简单使用,实现图片轮播
移动端和p c端经常会遇到写轮播图的情况,这里只是简单的说一下swiper插件的简单用法(移动端为例). <!DOCTYPE html> <html lang="en&qu ...
- VUE图片懒加载-vue lazyload插件的简单上手使用(优化版本)
在用VUE做项目开发的过程中,首页用到了懒加载的方法,查找了一些方法,觉得官网写得太复杂,有一篇博客不错(https://www.cnblogs.com/xyyt/p/7650539.html),但是 ...
- nice-validator表单验证插件的简单使用
前言 前端表单校验是过滤无效数据.假数据.有毒数据的第一步,是数据安全的第一道关卡,虽然我们不能100%相信客户端提交的数据(真正的校验还得在服务端进行),但设置前端表单校验也是至关重要的,自己写逻辑 ...
- VUE图片剪辑插件 React图片剪辑插件
React图片剪辑插件: https://github.com/roadmanfong/react-cropper React图片剪辑插件: https://github.com/xyxiao001/ ...
随机推荐
- LINQ 的使用
[转]链接:cnblogs.com/liqingwen/p/5832322.html LINQ 简介 语言集成查询 (LINQ) 是 Visual Studio 2008 和 .NET Framewo ...
- mysql 命令行还原备份数据库
通常数据库还原备份可以通过navicat等数据库管理工具进行,只需要简单的导出导入就行了,但遇到有索引外键的数据库,数据库管理工具运行.sql文件会报错,这时候可以尝试命令行导入,亲测可以成功 MyS ...
- ArcGIS10的附件功能
转自 积思园 http://blog.csdn.net/linghe301/article/details/6386176 老是忘记怎么使用这个ArcGIS10的附件功能,这次就做个记录吧. 在项目应 ...
- IE7中使用Jquery动态操作name问题
问题:IE7中无法使用Jquery动态操作页面元素的name属性. 在项目中有出现问题,某些客户的机器偶尔会有,后台取不到前台的数据值. 然开发和测试环境总是不能重现问题.坑爹之处就在于此,不能重现就 ...
- 浅谈WEB跨域的实现(前端向)
同源策略/SOP(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS.CSFR等攻击(可以参考我的这篇文章). SOP要求 ...
- JavaScript状态机程序逻辑编辑器
制作背景 之前做Win8 Metro动态加载内容框架的时候,由于采用了XAML+JavaScript的方法,程序复杂的执行逻辑是由JavaScript控制的,而页面一多,流程一复杂,制作起来就非常麻烦 ...
- gulp使用小结(一)
这篇文章不会介绍 gulp 的起源.发展:不会去一个个讲解 gulp API:也不想出现大段大段的 gulpfile.js 代码:更木有帮你分析 gulp 实现原理,只有一些我自己对 gulp 的使用 ...
- GitHub的使用记录
前言: 该贴为笔者在使用GItHub中的一些使用注意,及Git的基本命令,会一直记录笔者在使用GitHub中可能产生的错误及解决方法(会一直更新中),待一些Git初使用者参考,如果有说明不详细或不对的 ...
- salesforce 零基础学习(四十五)Approval Lock & UnLock相关注意事项
我们都知道,当一条记录进入审批流程以后会自动加锁,apex提供Approval类的lock和unlock方法可以让我们使用代码对记录进行加锁和解锁. 项目中遇到一个需求,需要当某种情况下对记录进行先解 ...
- Java Math 取整的方式
1.Math.floor floor,英文原意:地板. Math.floor 函数是求一个浮点数的地板,就是 向下 求一个最接近它的整数,它的值肯定会小于或等于这个浮点数. 2.Math.ceil c ...