弹幕系统聊天室
gateway介绍
-
GatewayWorker基于Workerman开发的一个项目框架,用于快速开发TCP长连接应用,例如app推送服务端、即时IM服务端、游戏服务端、物联网、智能家居等等
-
GatewayWorker使用经典的Gateway和Worker进程模型。Gateway进程负责维持客户端连接,并转发客户端的数据给BusinessWorker进程处理,BusinessWorker进程负责处理实际的业务逻辑(默认调用Events.php处理业务),并将结果推送给对应的客户端。Gateway服务和BusinessWorker服务可以分开部署在不同的服务器上,实现分布式集群。
-
GatewayWorker提供非常方便的API,可以全局广播数据、可以向某个群体广播数据、也可以向某个特定客户端推送数据。配合Workerman的定时器,也可以定时推送数据。
环境搭建
下载安装gateway
root@iZwz94dunl1qornhtnn4gpZ:/www/web/default# wget -c http://www.workerman.net/download/GatewayWorker.zip
root@iZwz94dunl1qornhtnn4gpZ:/www/web/default# unzip GatewayWorker.zip
root@iZwz94dunl1qornhtnn4gpZ:/www/web/default# cd GatewayWorker
协议以及地址
- 注意
ip:
1、如果写0.0.0.0代表监听本机所有网卡,也就是内网、外网、本机都可以访问到
2、如果是127.0.0.1,代表只能本机通过127.0.0.1访问,外网和内网都访问不到
3、如果是内网ip例如:192.168.10.11,代表只能通过192.168.10.11访问,也就是只能内网访问,本机127.0.0.1也访问不了(如果监听的ip不属于本机则会报错)
4、如果是外网ip例如110.110.110.110,代表只能通过外网ip 110.110.110.110访问,内网和本机127.0.0.1都访问不了(如果监听的ip不属于本机则会报错)
port:
端口不能大于65535,请确认端口没有被其它程序占用,否则启动会报错。如果端口小于1024,需要root权限运行GatewayWorker才能有权限监听,否则报错没有权限。
- 修改start_gateway.php文件配置协议地址
root@iZwz94dunl1qornhtnn4gpZ:/www/web/default/GatewayWorker# vim Applications/YourApp/start_gateway.php
文件内容
<?php
/**
* This file is part of workerman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
use \Workerman\Worker;
use \Workerman\WebServer;
use \GatewayWorker\Gateway;
use \GatewayWorker\BusinessWorker;
use \Workerman\Autoloader;
// 自动加载类
require_once __DIR__ . '/../../vendor/autoload.php';
$gateway = new Gateway("websocket://0.0.0.0:8081");
// gateway名称,status方便查看
$gateway->name = 'Lottery-2019';
// gateway进程数
$gateway->count = 4;
// 本机ip,分布式部署时使用内网ip
$gateway->lanIp = '127.0.0.1';
// 内部通讯起始端口,假如$gateway->count=4,起始端口为4000
// 则一般会使用4000 4001 4002 4003 4个端口作为内部通讯端口
$gateway->startPort = 2900;
$gateway->registerAddress = '127.0.0.1:1238';
// 当客户端连接上来时,设置连接的onWebSocketConnect,即在websocket握手时的回调
$gateway->onConnect = function($connection)
{
$connection->onWebSocketConnect = function($connection , $http_header)
{
var_dump($_GET, $_SERVER);
};
};
// 如果不是在根目录启动,则运行runAll方法
if(!defined('GLOBAL_START'))
{
Worker::runAll();
}
服务器消息处理
当客户端有信息发送过来时,聊天室需要立即处理信息并广播给当前连接了服务器的所有人
- 修改Events.php
<?php
/**
* This file is part of workerman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* 用于检测业务代码死循环或者长时间阻塞等问题
* 如果发现业务卡死,可以将下面declare打开(去掉//注释),并执行php start.php reload
* 然后观察一段时间workerman.log看是否有process_timeout异常
*/
//declare(ticks=1);
use \GatewayWorker\Lib\Gateway;
/**
* 主逻辑
* 主要是处理 onConnect onMessage onClose 三个方法
* onConnect 和 onClose 如果不需要可以不用实现并删除
*/
class Events
{
/**
* 当客户端连接时触发
* 如果业务不需此回调可以删除onConnect
*
* @param int $client_id 连接id
*/
// public static function onConnect($client_id)
// {
// // 向当前client_id发送数据
// Gateway::sendToClient($client_id, "Hello $client_id\r\n");
// // 向所有人发送
// Gateway::sendToAll("$client_id login\r\n");
// }
/**
* 当客户端发来消息时触发
* @param int $client_id 连接id
* @param mixed $message 具体消息
*/
public static function onMessage($client_id, $message)
{
// 向所有人发送 \n表示字符串结束
Gateway::sendToAll("$message\n");
}
/**
* 当用户断开连接时触发
* @param int $client_id 连接id
*/
public static function onClose($client_id)
{
// 向所有人发送
// GateWay::sendToAll("$client_id logout\r\n");
}
}
运行服务器
后台运行聊天室
root@iZwz94dunl1qornhtnn4gpZ:/www/web/default/GatewayWorker# php start.php start -d
建立移动端聊天室
下面代码重的静态资源我这里就先不提供了,各位看官自行修改一下就行了。
里面有一些代码涵盖了以前的红包系统等,看官可无视。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>翰文聊天室</title>
<meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=no">
<script type="text/javascript">
// 取消橡皮筋事件
// document.addEventListener('touchstart', function (e) {
// e.preventDefault();
// });
</script>
<style type="text/css">
html {
font-family:Helvetica;
font-size:62.5%;
color:#222; /**不建议使用纯黑,会显得呆板**/
background-image: url(__STATIC__/img/wechat_bg.png);
background-position: 0 0;
background-size: 100% 100%;
}
html,body {
margin:0;
padding:0;
height:100%;
width:100%;
}
::selection{
background-color: #b3d4fc; /*被选中的背景*/
text-shadow: none; /*被选中的阴影*/
}
/*设置无序列表的样式*/
ul {
margin: 0;
}
li {
list-style: none;
}
input {
tap-highlight-color:rgba(0,0,0,0);;
-webkit-tap-highlight-color:rgba(0,0,0,0);
}
</style>
<style type="text/css">
body {
position:relative;
}
/*聊天内容区*/
.cont-box {
width:100%;
height:90%;
position:absolute;
left:0;
top:0;
padding:0 2rem .5rem;
box-sizing: border-box;
font-size:1.6rem;
overflow-y: auto;
overflow-x: hidden;
}
#weChatBody {
height:auto;
}
.cont-box div {
/*border:1px solid blue;*/
margin-top:12px;
}
/*昵称*/
.cont-box div .nickname {
color: #fb6846;
}
/*内容*/
.cont-box div .content {
/*color: #fb6846;*/
}
/*聊天输入区域*/
.input-box {
position:fixed;
/*height:2rem;*/
width:100%;
left:0;
bottom:0;
border-top:1px solid #fcad9b;
border-bottom:1px solid #fcad9b;
}
.i-box {
padding:1rem;
display:flex;
display:-webkit-flex;
flex-direction:row;
justify-content: space-around;
align-items: center;
flex-wrap:nowrap;
background-color: rgba(255,255,255,.5);
}
.i-box .b-item {
height:2.8rem;
line-height: 2.8rem;
font-size:1.6rem;
position:relative;
overflow: hidden;
border:1px solid #fb6846;
}
.i-box .item1{
width:10%;
border-radius:5rem;
font-size:1.2rem;
text-align:center;
color:#fb6846;
}
.i-box .item2{
width:60%;
border-radius:10px;
padding:0 5px;
box-sizing: border-box;
}
.i-box .item3{
width:13%;
padding:0 5px;
height:2.8rem;
border-radius:5px;
text-align:center;
white-space:nowrap;
color:#fff;
background-color:#ddd;
border:1px solid #ddd;
}
/*输入框*/
.item-input {
overflow: hidden;
background-color:#fff;
border:none;
outline: none;
/*border:1px solid #eee;*/
white-space:nowrap;
tap-highlight-color:rgba(0,0,0,0);
-webkit-tap-highlight-color:rgba(0,0,0,0);
}
/*更换样式*/
.input-style {
height:0;
width:100%;
background-color:#fff;
display:flex;
overflow: hidden;
display:-webkit-flex;
flex-direction:row;
justify-content: space-around;
align-items: center;
flex-wrap:wrap;
transition:.2s;
-webkit-transition:.2s;
}
.s-item {
width:27%;
height:5rem;
position:relative;
}
.input-style .s-item:nth-of-type(1) {
background-color:#222;
}
.input-style .s-item:nth-of-type(2) {
background-color:#ff0002;
}
.input-style .s-item:nth-of-type(3) {
background-color:#fcff00;
}
.input-style .s-item:nth-of-type(4) {
background-color:#1eff00;
}
.input-style .s-item:nth-of-type(5) {
background-color:#096bff;
}
.input-style .s-item:nth-of-type(6) {
background-color:#ff00d5;
}
.input-style .active {
opacity:.7;
}
.input-style .active i {
position:absolute;
opacity:.7;
bottom:0;
right:0;
height:3rem;
width:3rem;
background-image: url(__STATIC__/img/style_choosed.png);
background-position: center center;
background-size: 100% 100%;
background-repeat: no-repeat;
}
/*红包*/
.redpack {
position:absolute;
width:100%;
height:100%;
left:0;
top:0;
display:flex;
display:-webkit-flex;
flex-direction:row;
justify-content: center;
align-items: center;
background-color: rgba(0,0,0,.8);
display:none;
z-index: 9999;
}
/*r-item == redpack-item*/
.r-item {
position:absolute;
top:-100%;
transition:.2s;
height:60%;
width:100%;
/* background-image: url(./img/redpack_boot.gif); */
/*background-image: url(./img/redpack_opened.png);*/
background-position: center center;
/* background-repeat: no-repeat; */
background-size: 100% 100%;
display:flex;
display:-webkit-flex;
flex-direction:column;
justify-content: center;
align-items: center;
}
/*领取到红包后,显示的文字*/
.r-item .info-item {
width:50%;
height:20%;
color:#fff;
font-size:3rem;
text-align:center;
/*border:1px solid yellow;*/
display:flex;
display:-webkit-flex;
flex-direction:row;
justify-content: center;
align-items: center;
display:none;
}
/*四条边界,用于关闭红包窗口*/
.r-side {
position:absolute;
/*border:1px solid yellow;*/
display:none;
}
.r-side1 {
height:25%;
width:100%;
left:0;
top:0;
}
.r-side2 {
height:25%;
width:100%;
left:0;
bottom:0;
}
.r-side3 {
height:100%;
width:15%;
left:0;
top:0;
}
.r-side4 {
height:100%;
width:15%;
right:0;
top:0;
}
</style>
</head>
<body>
<div class="cont-box">
<div id="weChatBody">
</div>
</div>
<div class="input-box">
<div class="i-box">
<div class="b-item item1" id="weChatStyle">样式</div>
<div class="b-item item2 item-input" id="weChatInput" contenteditable="true"></div>
<div class="b-item item3" id="sendMessage">发送</div>
</div>
<div class="input-style">
<div class="s-item active" data-color="#222"><i></i></div>
<div class="s-item" data-color="#ff0002"><i></i></div>
<div class="s-item" data-color="#fcff00"><i></i></div>
<div class="s-item" data-color="#1eff00"><i></i></div>
<div class="s-item" data-color="#096bff"><i></i></div>
<div class="s-item" data-color="#ff00d5"><i></i></div>
</div>
</div>
<!-- 红包 -->
<div class="redpack">
<div class="r-item">
<div class="info-item"></div>
<div class="info-item money-item"><p>¥2.00元</p></div>
</div>
<!-- 周围的四个可以点击使得红包消失的条 -->
<div class="r-side r-side1"></div>
<div class="r-side r-side2"></div>
<div class="r-side r-side3"></div>
<div class="r-side r-side4"></div>
</div>
<input type="hidden" name="nickname" id="nickNameVal" value="{$user.user_name}">
</body>
<script type="text/javascript">
// 工具函数
function gObj(obj){
return document.querySelector(obj);
}
function ajax(method, url, data, success)
{
var xhr = null;
try {
xhr = new XMLHttpRequest();
} catch (e) {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
if (method == 'get' && data) {
url += '?' + data;
}
xhr.open(method,url,true);
if (method == 'get') {
xhr.send();
} else {
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
xhr.send(data);
}
xhr.onload = function() {
success && success(xhr.responseText);
}
xhr.onerror = function(){
console.log('错误信息:' + xhr.status);
}
}
</script>
<!--<script src="/socket.io.js"></script>-->
<script type="text/javascript">
// 聊天框的高度oBox_h
// 输入框对象 oInput
// 用户昵称oNickname
// 所有颜色样式的对象aStyleColor
var oBox_h = gObj('.cont-box').offsetHeight;
var oInput = gObj('#weChatInput');
var oSendBtn = gObj('#sendMessage');
var oNickname = gObj('#nickNameVal').value;
var aStylecolor = document.querySelectorAll('.input-style div');
var oDatas = '';
var re = /^[\s\n]*?$/i; // 判断输入的内容是否为空格,回车,换行符
// var ren = /[\n]
var wStyleOff = false; // 样式开关wStyleOff, 默认false,为关闭状体
var nowColor = '#222'; // 存储当前的样式颜色
var aRedpack = document.querySelectorAll('.redpack .r-side'); // 获取所有
var aMoneyItem = document.querySelectorAll('.redpack .info-item'); // 获取所有
// 触发发送按钮
oSendBtn.addEventListener(
'touchstart', function(e){
if(oInput.innerText == ''){
// 先判断内容,如果无值,则点击无效,如果为空格和回车,则提示
return;
}
this.style.backgroundColor = '#f95833';
}, false);
oSendBtn.addEventListener(
'touchend', function(e){
// 先判断内容,如果无值,则点击无效,如果为空格和回车,则提示
if(oInput.innerText == ''){
return;
}
if(re.test(oInput.innerText)){
alert('输入内容必须为有效值');
return;
}
sendMessage();
}, false);
// 更换样式的按钮
gObj('#weChatStyle').addEventListener(
'touchend',function(){
if(!wStyleOff){
gObj('.input-style').style.height = '15rem';
this.style.borderColor = '#aaa';
this.style.color = '#aaa';
wStyleOff = true;
}else{
gObj('.input-style').style.height = '0';
this.style.borderColor = '#fb6846';
this.style.color = '#fb6846';
wStyleOff = false;
}
}, false);
// 选择颜色样式
for(var i=0; i<aStylecolor.length; i++){
aStylecolor[i].addEventListener(
'touchend', function(e){
for(var j=0; j<aStylecolor.length; j++){
aStylecolor[j].className = 's-item';
}
this.className = 's-item active';
nowColor = this.getAttribute('data-color');
},
false);
}
// 判断输入框的内容是否有值
oInput.addEventListener(
'input', function(e){
if(oInput.innerText.length != ''){
oSendBtn.style.backgroundColor = '#fb6846';
oSendBtn.style.borderColor = '#fb6846';
}else{
oSendBtn.style.backgroundColor = '#ddd';
oSendBtn.style.borderColor = '#ddd';
}
}, false);
// 点击聊天输入框
oInput.addEventListener(
'touchend', function(e){
gObj('.input-style').style.height = '0';
gObj('#weChatStyle').style.borderColor = '#fb6846';
gObj('#weChatStyle').style.color = '#fb6846';
wStyleOff = false;
}, false);
/*************************************************************************************************************************************************************************************************************************************************************************/
var ws = new WebSocket("ws://120.78.64.155:8081");
ws.onopen = function(e) {
console.log('已建立连接');
}
ws.onmessage = function(evt){
console.log('接收到服务器返回信息:'+evt.data);
var data = JSON.parse(evt.data);
var oDiv = document.createElement('div');
var oChatBody_h = gObj('#weChatBody').offsetHeight;
var message = data.text;
var color = data.color;
var nickname = data.nickname;
oDatas = '<span class="content" style="color:'+color+';">'+message+'</span>';
oDiv.innerHTML = '<b class="nickname" style="color:#fb6846;"><span>'+nickname+'</span>:</b>'+oDatas;
gObj('#weChatBody').appendChild(oDiv);
if(oChatBody_h > oBox_h){
gObj('.cont-box').scrollTop = oChatBody_h;
}else{
gObj('.cont-box').scrollTop = oBox_h;
}
}
// 发送聊天内容的函数
function sendMessage(){
// oDiv为创建的div对象
// oChatBody_h为聊天内容区的高度
// var oDiv = document.createElement('div');
// var oChatBody_h = gObj('#weChatBody').offsetHeight;
// oDatas = '<span class="content" style="color:'+nowColor+';">'+oInput.innerText+'</span>';
// oDiv.innerHTML = '<b class="nickname" style="color:#7590f3;"><span>'+oNickname+'</span>:</b>'+oDatas;
// gObj('#weChatBody').appendChild(oDiv);
// 去掉用户输入的回车,换行正则 /[\r\n]/g
// socket.emit('message', { text: oInput.innerText.replace(/[\r\n]/g, '') ,color: nowColor,nickname:oNickname});
var msg = oInput.innerText.replace(/[\r\n]/g, '');
var sendInfo = {
'text': msg,
'color': nowColor,
'nickname': oNickname,
};
sendInfo = JSON.stringify(sendInfo);
ws.send(sendInfo);
// 清空输入框,还原按钮样式
oInput.innerText = '';
oSendBtn.style.backgroundColor = '#ddd';
oSendBtn.style.borderColor = '#ddd';
// console.log(gObj('#weChatBody').offsetHeight);
// 关闭滚动窗口的自动上滚
// if(oChatBody_h > oBox_h){
// gObj('.cont-box').scrollTop = oChatBody_h;
// }else{
// gObj('.cont-box').scrollTop = oBox_h;
// }
}
/*************************************************************************************************************************************************************************************************************************************************************************/
</script>
</html>
弹幕系统
弹幕系统涵盖了公司的抽奖系统,有些css没有删除,请各位看官自行移除一下,当然不移除也不会有问题的。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>抽奖系统</title>
<style type="text/css">
html {
font-size:62.5%;
color:#222; /**不建议使用纯黑,会显得呆板**/
}
/*抽奖引导页面*/
body,html {
margin:0;
padding:0;
height:100%;
width:100%;
}
/*载入字体*/
@font-face {
font-family: gPrize-font01;
src:url(__STATIC__/css/font/gPrize-font01.ttf);
}
html {
font-family: gPrize-font01;
background-image: url(__STATIC__/img/boot_bg_static.png);
background-position: 0 0;
background-size: 100% 100%;
}
/*引导页面*/
.boot-page {
height:100%;
width:100%;
display:flex;
display:-webkit-flex;
flex-direction:column;
justify-content:center;
align-items: center;
/* background-color: #ffc3c3; */
position:absolute;
top:0;
left:0;
}
.boot-page .item {
height:150px;
text-align:center;
line-height: 170px;
color:#fff;
font-size:42px;
font-weight:bold;
text-shadow:5px 2px 6px #111;
position:relative;
}
.boot-page .item:nth-of-type(1){
width:auto;
}
.boot-page .item div {
float:left;
height:150px;
}
.boot-page .title{
width:auto;
margin-right:10px;
font-size:10rem;
}
/* .boot-page .btn{
width:150px;
background-image: url(./img/gift_btn.png);
background-size: 100% auto;
background-repeat: no-repeat;
background-position: center center;
} */
/*抽奖系统页面--内容页*/
.content-page {
height:100%;
width:100%;
display:flex;
display:-webkit-flex;
flex-direction:row;
justify-content:space-between;
align-items: stretch;
/* background-color: #1a1f39; */
background-image: url(__STATIC__/img/lottery_bg.png);
background-position: 0 0;
background-size: 100% 100%;
overflow: hidden;
position:absolute;
top:0;
left:0;
}
/* .main-item {
position:relative;
overflow-x:hidden;
} */
.main-item{
width:100%;
overflow:hidden;
}
.left-title {
position:relative;
height:auto;
border-bottom:1px solid #ddd;
}
.title-level {
height:60px;
line-height: 90px;
text-align:center;
font-size:25px;
}
.left-detail {
text-align:center;
padding:0 10px;
box-sizing: border-box;
}
.left-users {
position: relative;
box-sizing: border-box;
z-index: 88;
}
.left-users p {
padding: 9px 15px;
display:flex;
display:-webkit-flex;
flex-direction:row;
justify-content:center;
align-items: center;
}
.left-users p span {
display:inline-block;
}
.left-users .nickname {
text-indent:30px;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
}
/*左边右下角的猫*/
.left-right-bottom {
height:80px;
width:80px;
position:fixed;
z-index: 1;
right:82%;
bottom:0;
}
.left-right-bottom img {
height:100%;
width:100%;
}
/*公开透明抽奖区域*/
.main-item .wrap {
padding:4.5rem;
box-sizing: border-box;
width:100%;
height:100%;
position:relative;
display:flex;
display:-webkit-flex;
flex-direction:row;
align-items: center;
justify-content:space-around;
flex-wrap: wrap;
position:absolute;
left:0;
top:200%;
}
.main-item .wrap .title-name {
text-align:center;
}
.main-item .wrap .item {
position:relative;
/* background-color:rgba(255,255,255,.3); */
display:-webkit-flex;
flex-direction:row;
align-items: center;
justify-content:space-between;
text-align:center;
}
/*手机号码格式*/
.wrap .item div {
/*border:1px solid blue;*/
height:100%;
/*line-height: 5rem;
float:left;*/
/*手机好字体大小*/
font-size:2.7rem;
display:flex;
display:-webkit-flex;
flex-direction:row;
align-items: center;
justify-content:space-between;
color:yellow;
}
.wrap .item div p {
width:100%;
}
.wrap .item .first {
width:33%;
}
.wrap .item .center {
width:25%;
font-size:2rem;
}
.wrap .item .last {
width:42%;
}
/*41<=num<=50*/
.main-item .wrap-41-50 .item {
width:19.2%;
height:7.8%;
}
/*31<=num<=40*/
.main-item .wrap-31-40 .item {
width:19.2%;
height:9.8%;
}
/*21<=num<=30*/
.main-item .wrap-21-30 .item {
width:19.2%;
height:14%;
}
/*11<=num<=20*/
.main-item .wrap-11-20 .item {
width:23.8%;
height:15%;
}
.main-item .wrap-11-20 div {
font-size:3.3rem;
}
/*1<=num<=10*/
.main-item .wrap-3-10 .item {
width:30.8%;
height:20%;
}
.main-item .wrap-3-10 div {
font-size:5rem;
}
.main-item .wrap-3-10 {
justify-content:space-around;
}
.wrap-3-10 .item .first {
width:35%;
}
.wrap-3-10 .item .center {
width:21%;
}
.wrap-3-10 .item .last {
width:44%;
}
/*2<=num<=2*/
.main-item .wrap-1-2 .item {
width:42%;
height:25%;
}
.main-item .wrap-1-2 div p{
font-size:6.6rem;
}
.main-item .wrap-1-2 {
justify-content:space-around;
}
/*中间星号字体大小 ---- 放最后*/
.wrap .item .center {
font-size:2rem;
}
.wrap-1-2 .item .center {
font-size:4rem;
}
/*弹幕*/
.barrage {
position:absolute;
left:0;
top:0;
width:100%;
height:100%;
z-index: 99999;
overflow: hidden;
transform-style:preserve-3d;
-webkit-transform-style:preserve-3d;
}
.b-item {
position:absolute;
height:auto;
width:800px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding:1.3rem 1.5rem;
/* border-radius: 10rem; */
font-size:5rem;
/* background-color: rgba(0, 0, 0, .8); */
top:90%;
right:-900px;
color:#fff;
}
/* <!-- 左上角的二维码 --> */
.boot-page .qr-code {
width:15rem;
height:15rem;
background-image: url(__STATIC__/img/hanwen_year_qrcode.png);
background-position: center center;
background-size:100% 100%;
background-repeat:no-repeat;
position:relative;
}
.boot-page .qr-code p {
position:absolute;
font-size:1.9rem;
padding:0;
margin:0;
height:2rem;
line-height: 2rem;
width:100%;
left:0;
bottom:-2.2rem;
}
/* logo区域 */
.hanwen-logo {
position:absolute;
bottom:0;
left:0;
height:15rem;
width:15rem;
/* background-image: url(__STATIC__/img/hanwen_logo.png); */
background-position: center center;
background-size:100% 100%;
background-repeat:no-repeat;
}
/* 彩蛋表情包 */
#caidan {
height:300px;
width:300px;
position:absolute;
top:50%;
left:50%;
margin-top:-150px;
margin-left:-150px;
/* background-image: */
background-position: 0 0;
background-size: 100% 100%;
}
</style>
</head>
<body>
<!-- 弹幕 start-->
<div class="barrage">
<div class="b-item" style="display:none;"></div>
<!-- <div class="b-item"></div> -->
</div>
<!-- 弹幕 end-->
<div class="" id="caidan" style="position:absolute;z-index:999;">
</div>
</body>
<!-- 弹幕script -->
<script type="text/javascript">
// 工具函数
function gObj(obj){
return document.querySelector(obj);
}
function ajax(method, url, data, success)
{
var xhr = null;
try {
xhr = new XMLHttpRequest();
} catch (e) {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
if (method == 'get' && data) {
url += '?' + data;
}
xhr.open(method,url,true);
if (method == 'get') {
xhr.send();
} else {
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
xhr.send(data);
}
xhr.onload = function() {
success && success(xhr.responseText);
}
xhr.onerror = function(){
console.log('错误信息:' + xhr.status);
}
}
// var socket = io.connect('http://120.78.64.155:8081');
// 计时器,计算某个时间段内的弹幕数量
var ws = new WebSocket("ws://120.78.64.155:8081");
ws.onopen = function(e) {
// Check the protocol chosen by the server
console.log('已建立连接');
}
var tm = 1;
var topvlast = topv = 13;
ws.onmessage = function(evt){
console.log('接收到服务器返回信息:'+evt.data);
var data = JSON.parse(evt.data);
topv += 8
if(topv > 65){
topv = 21;
}
barrage(data, topv);
}
var timer_m_x = null;
function barrage(obj, topv){
var oDiv = document.createElement('div');
// 字幕wraper对象
var oBarrage = gObj('.barrage');
// var oDiv = gObj('.barrage .b-item');
oDiv.innerText = obj.nickname+':'+obj.text;
oDiv.className = 'b-item';
if(obj.color != '#222'){
oDiv.style.color = obj.color;
}
oDiv.x = 0;
oDiv.style.top = topv + '%';
setTimeout(function(){
oBarrage.appendChild(oDiv);
oDiv.timer = setInterval(function(){
oDiv.x -= 1;
oDiv.style.transform = 'translateX('+oDiv.x+'px)';
if(-oDiv.x > oBarrage.offsetWidth+900){
clearInterval(oDiv.timer);
oBarrage.removeChild(oDiv);
}
}, Math.random()*10);
}, Math.random()*1000);
}
</script>
</html>
网友评论