彈幕系統(tǒng)聊天室
gateway介紹
GatewayWorker基于Workerman開發(fā)的一個項目框架腿椎,用于快速開發(fā)TCP長連接應用优烧,例如app推送服務端、即時IM服務端庸娱、游戲服務端着绊、物聯(lián)網、智能家居等等
GatewayWorker使用經典的Gateway和Worker進程模型熟尉。Gateway進程負責維持客戶端連接归露,并轉發(fā)客戶端的數據給BusinessWorker進程處理,BusinessWorker進程負責處理實際的業(yè)務邏輯(默認調用Events.php處理業(yè)務)斤儿,并將結果推送給對應的客戶端剧包。Gateway服務和BusinessWorker服務可以分開部署在不同的服務器上,實現(xiàn)分布式集群往果。
GatewayWorker提供非常方便的API疆液,可以全局廣播數據、可以向某個群體廣播數據陕贮、也可以向某個特定客戶端推送數據堕油。配合Workerman的定時器,也可以定時推送數據肮之。
環(huán)境搭建
下載安裝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
協(xié)議以及地址
- 注意
ip:
1掉缺、如果寫0.0.0.0代表監(jiān)聽本機所有網卡,也就是內網戈擒、外網眶明、本機都可以訪問到
2、如果是127.0.0.1峦甩,代表只能本機通過127.0.0.1訪問赘来,外網和內網都訪問不到
3现喳、如果是內網ip例如:192.168.10.11,代表只能通過192.168.10.11訪問犬辰,也就是只能內網訪問嗦篱,本機127.0.0.1也訪問不了(如果監(jiān)聽的ip不屬于本機則會報錯)
4、如果是外網ip例如110.110.110.110幌缝,代表只能通過外網ip 110.110.110.110訪問灸促,內網和本機127.0.0.1都訪問不了(如果監(jiān)聽的ip不屬于本機則會報錯)
port:
端口不能大于65535,請確認端口沒有被其它程序占用涵卵,否則啟動會報錯浴栽。如果端口小于1024,需要root權限運行GatewayWorker才能有權限監(jiān)聽轿偎,否則報錯沒有權限典鸡。
- 修改start_gateway.php文件配置協(xié)議地址
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();
}
服務器消息處理
當客戶端有信息發(fā)送過來時仓蛆,聊天室需要立即處理信息并廣播給當前連接了服務器的所有人
- 修改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
*/
/**
* 用于檢測業(yè)務代碼死循環(huán)或者長時間阻塞等問題
* 如果發(fā)現(xiàn)業(yè)務卡死睁冬,可以將下面declare打開(去掉//注釋),并執(zhí)行php start.php reload
* 然后觀察一段時間workerman.log看是否有process_timeout異常
*/
//declare(ticks=1);
use \GatewayWorker\Lib\Gateway;
/**
* 主邏輯
* 主要是處理 onConnect onMessage onClose 三個方法
* onConnect 和 onClose 如果不需要可以不用實現(xiàn)并刪除
*/
class Events
{
/**
* 當客戶端連接時觸發(fā)
* 如果業(yè)務不需此回調可以刪除onConnect
*
* @param int $client_id 連接id
*/
// public static function onConnect($client_id)
// {
// // 向當前client_id發(fā)送數據
// Gateway::sendToClient($client_id, "Hello $client_id\r\n");
// // 向所有人發(fā)送
// Gateway::sendToAll("$client_id login\r\n");
// }
/**
* 當客戶端發(fā)來消息時觸發(fā)
* @param int $client_id 連接id
* @param mixed $message 具體消息
*/
public static function onMessage($client_id, $message)
{
// 向所有人發(fā)送 \n表示字符串結束
Gateway::sendToAll("$message\n");
}
/**
* 當用戶斷開連接時觸發(fā)
* @param int $client_id 連接id
*/
public static function onClose($client_id)
{
// 向所有人發(fā)送
// GateWay::sendToAll("$client_id logout\r\n");
}
}
運行服務器
后臺運行聊天室
root@iZwz94dunl1qornhtnn4gpZ:/www/web/default/GatewayWorker# php start.php start -d
建立移動端聊天室
下面代碼重的靜態(tài)資源我這里就先不提供了看疙,各位看官自行修改一下就行了豆拨。
里面有一些代碼涵蓋了以前的紅包系統(tǒng)等,看官可無視狼荞。
<!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;
}
/*聊天內容區(qū)*/
.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;*/
}
/*聊天輸入區(qū)域*/
.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">發(fā)送</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'); // 獲取所有
// 觸發(fā)發(fā)送按鈕
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;
}
}
// 發(fā)送聊天內容的函數
function sendMessage(){
// oDiv為創(chuàng)建的div對象
// oChatBody_h為聊天內容區(qū)的高度
// 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>
彈幕系統(tǒng)
彈幕系統(tǒng)涵蓋了公司的抽獎系統(tǒng)凛辣,有些css沒有刪除,請各位看官自行移除一下职烧,當然不移除也不會有問題的扁誓。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>抽獎系統(tǒng)</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;
} */
/*抽獎系統(tǒng)頁面--內容頁*/
.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%;
}
/*公開透明抽獎區(qū)域*/
.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區(qū)域 */
.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>