浏览代码

Merge branch 'websocket' of 121.43.114.153:/home/git/repositories/shopnc into websocket

stanley-king 7 年之前
父节点
当前提交
8755a5fafc

+ 340 - 0
data/resource/mobile/bargain/css/main.css

@@ -0,0 +1,340 @@
+* {
+    margin: 0;
+    padding: 0;
+}
+body {
+    color: #000000;
+    font: 26px PingFang SC;
+    line-height: 1;
+    background:#f13d5a;
+}
+img {
+    width: 100%;
+    height: 100%;
+    border: none;
+}
+a {
+    text-decoration: none;
+}
+ul,li {
+    list-style: none;
+}
+.maincontent {
+    position: absolute;
+    top: 0;
+    bottom: 80px;
+    left: 0;
+    width: 750px;
+    overflow-y: auto;
+    overflow-x: hidden;
+    -webkit-overflow-scrolling: touch;
+}
+.goods {
+    display: flex;
+    position: relative;
+}
+.goods:after {
+    content: '';
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    height: 1px;
+    width: 100%;
+    background: #eaeaea;
+}
+.content {
+    position: relative;
+    width: 700px;
+    margin: 0 auto 22px auto;
+    padding: 40px 0;
+    background: #fff;
+}
+.thumbnail {
+    width: 220px;
+    height: 220px;
+}
+.introduce {
+    width: 380px;
+    margin-left: 68px;
+}
+.introduce .goods_name {
+    line-height: 1.5;
+    margin-bottom: 20px;
+}
+.price_describe {
+    display: flex;
+    margin-bottom: 20px;
+}
+.price_describe > div {
+    flex: 1;
+}
+.current_price {
+    color: #fe4b57;
+    font-size: 33px;
+    white-space:nowrap;
+    display: block;
+}
+.original_price {
+    color: #bfc1c3;
+    font-size: 17px;
+    margin-left: 12px;
+    position: relative;
+}
+.original_price:after {
+    content: '';
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    height: 1px;
+    width: 120%;
+    margin-top: -1px;
+    margin-left: -60%;
+    background: #707070;
+}
+.rush_num {
+    text-align: right;
+}
+.rush_num span {
+    font-size: 18px;
+    color: #707070;
+    vertical-align: text-bottom;
+}
+.count_down {
+    font-size: 22px;
+    color: #707070;
+}
+.time_color {
+    color: #000000;
+}
+.bargain_handle {
+    text-align: center;
+    font-size: 35px;
+    color: #ffffff;
+    margin-top: 50px;
+    margin-bottom: 68px;
+}
+.bargain_btn {
+    display: inline-block;
+    height: 81px;
+    width: 252px;
+    color: #ffffff;
+    background: url("../images/bargain_btn.png") no-repeat;
+    background-size: 100% 100%;
+    line-height: 81px;
+    text-align: center;
+    margin-right: 60px;
+}
+.join_btn {
+    display: inline-block;
+    height: 81px;
+    width: 252px;
+    color: #ffffff;
+    background: url("../images/join_btn.png") no-repeat;
+    background-size: 100% 100%;
+    line-height: 81px;
+    text-align: center;
+}
+.avatar {
+    width: 56px;
+    height: 56px;
+    border-radius: 100px;
+    vertical-align: middle;
+    margin-right: 20px;
+}
+.bargain_users .title {
+    box-sizing: border-box;
+    font-size: 20px;
+    color: #b2b2b4;
+    padding-left: 84px;
+}
+.rules_box {
+    width: 700px;
+    margin: 0 auto;
+}
+.users_list {
+    position: relative;
+    top: 0;
+    padding-left: 50px;
+    margin-top: 20px;
+}
+.users_list li {
+    background: #ffffff;
+    height: 70px;
+    line-height: 70px;
+}
+.rules {
+    width: 700px;
+    height: 792px;
+}
+.hide {
+    display: none;
+}
+@-webkit-keyframes opacity_full {
+    from {
+        opacity: 0;
+    }
+    to {
+        opacity: 1;
+    }
+}
+@keyframes opacity_full {
+    from {
+        opacity: 0;
+    }
+    to {
+        opacity: 1;
+    }
+}
+@-webkit-keyframes scale {
+    0% {
+        -webkit-transform: scale(0);
+    }
+    50% {
+        -webkit-transform: scale(1.5);
+    }
+    100% {
+        -webkit-transform: scale(1);
+    }
+}
+@keyframes scale {
+    0% {
+        -webkit-transform: scale(0);
+    }
+    50% {
+        -webkit-transform: scale(1.5);
+    }
+    100% {
+        -webkit-transform: scale(1);
+    }
+}
+@keyframes stamp_scale {
+    0% {
+        -webkit-transform: scale(5);
+    }
+    100% {
+        -webkit-transform: scale(1);
+    }
+}
+@-webkit-keyframes stamp_scale {
+    0% {
+        -webkit-transform: scale(5);
+    }
+    100% {
+        -webkit-transform: scale(1);
+    }
+}
+.scale {
+    animation:scale .6s ease-out;
+    -webkit-animation:scale .6s ease-out;
+}
+.opacity_full {
+    -webkit-animation: opacity_full .3s forwards;
+}
+#frame {
+    position: fixed;
+    top: 50%;
+    left: 50%;
+    width: 400px;
+    height: 400px;
+    -webkit-transform: translate(-50%,-50%);
+}
+.slide_containe {
+    height: 232px;
+    overflow: hidden;
+}
+.stamp {
+    width: 300px;
+    height: 230px;
+    position: absolute;
+    right: 140px;
+    top: 30px;
+    z-index: 10;
+}
+.stamp_scale {
+    -webkit-animation: stamp_scale .3s;
+}
+.fixed_bottom {
+    height: 80px;
+    width: 750px;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    background: #ffffff;
+    z-index: 10;
+    -webkit-transform: translate3d(0,0,0);
+    display: flex;
+    -webkit-align-items: center;
+    align-items: center;
+}
+.fixed_bottom > div {
+    /*flex: 1;*/
+}
+.fixed_bottom > div {
+    text-align: center;
+}
+.send_input {
+    display: inline-block;
+    width: 410px;
+    border: 1px solid #7E7E7E;
+    border-radius: 10px;
+    outline: none;
+    font-size: 24px;
+    height: 60px;
+    line-height: 60px;
+    margin-left: 10px;
+    padding-left: 25px;
+}
+.send_msg {
+    border: 0;
+    font-size: 24px;
+    height: 60px;
+    width: 138px;
+    background: #f44056;
+    color: #fff;
+    border-radius: 10px;
+    margin: 0 8px;
+}
+.download_app {
+    border: 0;
+    font-size: 24px;
+    height: 60px;
+    width: 138px;
+    background: #f44056;
+    color: #fff;
+    border-radius: 10px;
+}
+.barrage {
+    background: rgba(255,255,255,0.6);
+    position: fixed;
+    right: -750px;
+    z-index: 10;
+    border-radius: 70px;
+    padding: 6px 65px 6px 11px;
+    white-space: nowrap;
+    font-size: 30px;
+    -webkit-animation: barrage_move 5s linear;
+}
+.barrage img {
+    display: inline-block;
+    margin-right: 33px;
+    width: 33px;
+    height: 33px;
+    border-radius: 50px;
+    vertical-align: middle;
+}
+.barrage .price {
+    color: #FF4E4E;
+}
+@-webkit-keyframes barrage_move {
+    from {
+        -webkit-transform: translateX(0);
+    }
+    to {
+        -webkit-transform: translateX(-1500px);
+    }
+}
+.main {
+    background: url("../images/bg.jpg") no-repeat;
+    padding-top: 383px;
+    box-sizing: border-box;
+}

二进制
data/resource/mobile/bargain/images/bargain_btn.png


二进制
data/resource/mobile/bargain/images/bg.jpg


二进制
data/resource/mobile/bargain/images/head_icon.png


二进制
data/resource/mobile/bargain/images/join_btn.png


二进制
data/resource/mobile/bargain/images/rules.png


二进制
data/resource/mobile/bargain/images/stamp.png


+ 106 - 0
data/resource/mobile/comm/animate.js

@@ -0,0 +1,106 @@
+// Zepto.js
+// (c) 2010-2016 Thomas Fuchs
+// Zepto.js may be freely distributed under the MIT license.
+;(function($, undefined){
+    var prefix = '', eventPrefix,
+        vendors = { Webkit: 'webkit', Moz: '', O: 'o' },
+        testEl = document.createElement('div'),
+        supportedTransforms = /^((translate|rotate|scale)(X|Y|Z|3d)?|matrix(3d)?|perspective|skew(X|Y)?)$/i,
+        transform,
+        transitionProperty, transitionDuration, transitionTiming, transitionDelay,
+        animationName, animationDuration, animationTiming, animationDelay,
+        cssReset = {}
+    function dasherize(str) { return str.replace(/([A-Z])/g, '-$1').toLowerCase() }
+    function normalizeEvent(name) { return eventPrefix ? eventPrefix + name : name.toLowerCase() }
+    if (testEl.style.transform === undefined) $.each(vendors, function(vendor, event){
+        if (testEl.style[vendor + 'TransitionProperty'] !== undefined) {
+            prefix = '-' + vendor.toLowerCase() + '-'
+            eventPrefix = event
+            return false
+        }
+    })
+    transform = prefix + 'transform'
+    cssReset[transitionProperty = prefix + 'transition-property'] =
+        cssReset[transitionDuration = prefix + 'transition-duration'] =
+            cssReset[transitionDelay = prefix + 'transition-delay'] =
+                cssReset[transitionTiming = prefix + 'transition-timing-function'] =
+                    cssReset[animationName = prefix + 'animation-name'] =
+                        cssReset[animationDuration = prefix + 'animation-duration'] =
+                            cssReset[animationDelay = prefix + 'animation-delay'] =
+                                cssReset[animationTiming = prefix + 'animation-timing-function'] = ''
+    $.fx = {
+        off: (eventPrefix === undefined && testEl.style.transitionProperty === undefined),
+        speeds: { _default: 400, fast: 200, slow: 600 },
+        cssPrefix: prefix,
+        transitionEnd: normalizeEvent('TransitionEnd'),
+        animationEnd: normalizeEvent('AnimationEnd')
+    }
+    $.fn.animate = function(properties, duration, ease, callback, delay){
+        if ($.isFunction(duration))
+            callback = duration, ease = undefined, duration = undefined
+        if ($.isFunction(ease))
+            callback = ease, ease = undefined
+        if ($.isPlainObject(duration))
+            ease = duration.easing, callback = duration.complete, delay = duration.delay, duration = duration.duration
+        if (duration) duration = (typeof duration == 'number' ? duration :
+                ($.fx.speeds[duration] || $.fx.speeds._default)) / 1000
+        if (delay) delay = parseFloat(delay) / 1000
+        return this.anim(properties, duration, ease, callback, delay)
+    }
+    $.fn.anim = function(properties, duration, ease, callback, delay){
+        var key, cssValues = {}, cssProperties, transforms = '',
+            that = this, wrappedCallback, endEvent = $.fx.transitionEnd,
+            fired = false
+        if (duration === undefined) duration = $.fx.speeds._default / 1000
+        if (delay === undefined) delay = 0
+        if ($.fx.off) duration = 0
+        if (typeof properties == 'string') {
+// keyframe animation
+            cssValues[animationName] = properties
+            cssValues[animationDuration] = duration + 's'
+            cssValues[animationDelay] = delay + 's'
+            cssValues[animationTiming] = (ease || 'linear')
+            endEvent = $.fx.animationEnd
+        } else {
+            cssProperties = []
+// CSS transitions
+            for (key in properties)
+                if (supportedTransforms.test(key)) transforms += key + '(' + properties[key] + ') '
+                else cssValues[key] = properties[key], cssProperties.push(dasherize(key))
+            if (transforms) cssValues[transform] = transforms, cssProperties.push(transform)
+            if (duration > 0 && typeof properties === 'object') {
+                cssValues[transitionProperty] = cssProperties.join(', ')
+                cssValues[transitionDuration] = duration + 's'
+                cssValues[transitionDelay] = delay + 's'
+                cssValues[transitionTiming] = (ease || 'linear')
+            }
+        }
+        wrappedCallback = function(event){
+            if (typeof event !== 'undefined') {
+                if (event.target !== event.currentTarget) return // makes sure the event didn't bubble from "below"
+                $(event.target).unbind(endEvent, wrappedCallback)
+            } else
+                $(this).unbind(endEvent, wrappedCallback) // triggered by setTimeout
+            fired = true
+            $(this).css(cssReset)
+            callback && callback.call(this)
+        }
+        if (duration > 0){
+            this.bind(endEvent, wrappedCallback)
+// transitionEnd is not always firing on older Android phones
+// so make sure it gets fired
+            setTimeout(function(){
+                if (fired) return
+                wrappedCallback.call(that)
+            }, ((duration + delay) * 1000) + 25)
+        }
+// trigger page reflow so new elements can animate
+        this.size() && this.get(0).clientLeft
+        this.css(cssValues)
+        if (duration <= 0) setTimeout(function() {
+            that.each(function(){ wrappedCallback.call(this) })
+        }, 0)
+        return this
+    }
+    testEl = null
+})(Zepto);

+ 270 - 0
mobile/templates/default/game/bargain.php

@@ -0,0 +1,270 @@
+<?php defined('InShopNC') or exit('Access Invalid!'); ?>
+
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>砍价团</title>
+    <meta name="viewport" content="width=750,user-scalable=no,target-densitydpi=device-dpi">
+    <meta name="format-detection" content="telephone=no">
+    <link rel="stylesheet" href="<?php echo RESOURCE_SITE_URL; ?>/mobile/bargain/css/main.css?<?php echo bonus_version(); ?>"/>
+</head>
+<body>
+
+<div class="maincontent">
+    <div class="main">
+        <div class="content">
+            <div class="goods">
+                <div class="thumbnail">
+                    <img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1515563446629&di=54394197eb40785021584b377f7c1c09&imgtype=0&src=http%3A%2F%2Fimgqn.koudaitong.com%2Fupload_files%2F2014%2F11%2F16%2FFlCgXx2oQYxENNLkllLxme4Oq2fI.jpg%2521580x580.jpg" alt="">
+                </div>
+                <div class="introduce">
+                    <p class="goods_name">泊美 | 菁盈粹系列植物活肤三件套 洁面水乳 礼物首选</p>
+                    <div class="price_describe">
+                        <div class="price_box">
+                            <span class="current_price" id="current_price">现价850</span><span class="original_price">原价1000</span>
+                        </div>
+                        <div class="rush_num">
+                            <span>已抢2030份</span>
+                        </div>
+                    </div>
+                    <div class="count_down">
+                        <p>剩: <span class="days time_color"></span> 天 <span class="hours time_color"></span>:<span class="minutes time_color"></span> :<span class="seconds time_color"></span> 结束</p>
+                    </div>
+                </div>
+                <img src="<?php echo RESOURCE_SITE_URL; ?>/mobile/bargain/images/stamp.png" id="stamp" class="stamp hide stamp_scale">
+            </div>
+            <div class="bargain_handle">
+                <span class="bargain_btn" id="bargain_btn">帮砍一刀</span>
+                <span class="join_btn" id="join_btn">我要参加</span
+            </div>
+            <div class="bargain_users">
+                <p class="title">看看小伙伴说了啥?</p>
+                <div class="slide_containe">
+                    <ul class="users_list" id="slide_list">
+                        <li><img class="avatar" src="http://img1.imgtn.bdimg.com/it/u=4026848961,760222886&fm=214&gp=0.jpg">小西1说:希望多砍点,加油!</li>
+                        <li><img class="avatar" src="http://img1.imgtn.bdimg.com/it/u=4026848961,760222886&fm=214&gp=0.jpg">小西2说:希望多砍点,加油!</li>
+                        <li><img class="avatar" src="http://img1.imgtn.bdimg.com/it/u=4026848961,760222886&fm=214&gp=0.jpg">小西3说:希望多砍点,加油!</li>
+                        <li><img class="avatar" src="http://img1.imgtn.bdimg.com/it/u=4026848961,760222886&fm=214&gp=0.jpg">小西4说:希望多砍点,加油!</li>
+                        <li><img class="avatar" src="http://img1.imgtn.bdimg.com/it/u=4026848961,760222886&fm=214&gp=0.jpg">小西5说:希望多砍点,加油!</li>
+                    </ul>
+                </div>
+            </div>
+        </div>
+        <div class="rules_box">
+            <img src="<?php echo RESOURCE_SITE_URL; ?>/mobile/bargain/images/rules.png" class="rules">
+        </div>
+    </div>
+</div>
+<div class="fixed_bottom" id="fixed_bottom">
+    <div>
+        <input type="text" placeholder="我想说几句" class="send_input" id="send_msg">
+    </div>
+    <div>
+        <button class="send_msg" id="send_btn">发送</button>
+    </div>
+    <div>
+        <button class="download_app" id="download_app">下载app</button>
+    </div>
+</div>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/mobile/shake/js/zepto.min.js"></script>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/mobile/comm/animate.js"></script>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/mobile/comm/websocket.js"></script>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/mobile/comm/new_bridge.js"></script>
+<script type="text/javascript">
+
+    //发送弹幕
+    var Barrage = function()
+    {
+        this.sendData = null;
+        this.barrage_html = '';
+        this.dataParse = function(data)
+        {
+            return {
+                posY :parseInt(Math.random() * (380 - 20) + 20),
+                avatar: data.get_from().avatar,
+                nickname : data.get_from().nickname,
+                msg:data.get_msg()
+            }
+        };
+        this.add = function(send_data){
+            this.sendData = this.dataParse(send_data);
+            return this;
+        };
+        this.send = function()
+        {
+            if(this.sendData)
+            {
+                if(this.sendData.msg > 0) {
+                    this.barrage_html = '<div class="barrage" style="top:'+this.sendData.posY+'%"><img src="'+this.sendData.avatar+'">'+this.sendData.nickname+'砍了<span class="price">'+this.sendData.msg+'元</span></div>';
+                }
+                $('body').append(this.barrage_html);
+                this.sendData = null;
+                this.barrage_html = '';
+                this.clear();
+                return this;
+            }
+            else {
+                console.log('没有弹幕可以发送');
+            }
+        };
+        this.clear = function()
+        {
+            $('.barrage').on('webkitAnimationEnd',function(){
+                $(this).remove();
+            });
+            return this;
+        };
+    };
+
+    var barrage = new Barrage();
+
+    var room    = <?php echo $output['room']; ?>;
+    var roomkey = "<?php echo $output['room_key']; ?>";
+    var addr    =  "<?php echo $output['addr']; ?>";
+
+    var room_msgs = {
+        room    : room,
+        roomkey :roomkey
+    };
+    var callbacks = {
+        onOpen:sOpen,
+        onError:sError,
+        onClose:sClose
+    };
+    var msg_handler = {
+        room_info:ret_join,
+        message:message
+    };
+    var websocket = new WebsocketConnect(addr,true,true,callbacks,room_msgs,msg_handler);
+
+    function sOpen(){
+    }
+    function sError(e){
+        alert('网络连接失败!请刷新重试');
+    }
+    function sClose(e){
+        console.log('网络连接关闭!');
+    }
+
+    function message(datas)
+    {
+        var jsonDatas = new websocket.Json_parse(datas);
+        var msg_type = datas.content.type;
+        var msg_from_userId = datas.content.from.userid;
+        try
+        {
+            if(msg_type == 'message') {
+                if(msg_from_userId !== websocket.getMeId) {
+                    barrage.add(jsonDatas).send();
+                }
+            }
+        }
+        catch (e) {
+            alert(e.message)
+        }
+    }
+
+    function ret_join(datas){
+        var jsonDatas = new websocket.Json_parse(datas);
+        websocket.setMeId(jsonDatas.content.me);
+    }
+
+
+    //倒计时
+    var over_time = (new Date(2018,0,14).getTime())/1000;
+
+    setInterval(function(){
+        var local_time = (new Date().getTime())/1000;
+        var count_down_time = (over_time - local_time).toFixed(0);
+        formatDuring(count_down_time);
+    },1000);
+
+    function formatDuring(mss) {
+        var days = parseInt( mss / 60 / 60 / 24, 10); //计算剩余的天数
+        var hours = parseInt(mss / 60 / 60 % 24, 10); //计算剩余的小时
+        var minutes = parseInt(mss / 60 % 60, 10);//计算剩余的分钟
+        var seconds = parseInt(mss % 60, 10);//计算剩余的秒数
+        if(days < 10) {
+            days = '0' + days;
+        }
+        if(hours < 10) {
+            hours = '0' + hours;
+        }
+        if(minutes < 10) {
+            minutes = '0' + minutes;
+        }
+        if(seconds < 10) {
+            seconds = '0' + seconds;
+        }
+        $('.days').text(days);
+        $('.hours').text(hours);
+        $('.minutes').text(minutes);
+        $('.seconds').text(seconds);
+    }
+
+
+    //消息滚动
+    setInterval(function(){
+        var $parent =  $('#slide_list');
+        var $first = $('#slide_list li').first();
+        var height = $first.height();
+        $first.animate({
+            marginTop: -height + 'px'
+        },'ease-out',function(){
+            $parent.append($first.css('marginTop',0));
+        })
+    },2000);
+
+
+    var random = function(){
+        return (Math.random()*10).toFixed(2);
+    };
+
+
+    document.querySelector('#bargain_btn').addEventListener('click',function(){
+        $('.stamp').removeClass('hide');
+        document.getElementById('stamp').addEventListener('webkitAnimationEnd',function(){
+            setTimeout(function(){
+                $('.stamp').addClass('hide');
+            },500);
+            setTimeout(function(){
+                var current_price = document.querySelector('#current_price').innerHTML;
+                var price = current_price.replace('现价',"");
+                document.querySelector('#current_price').innerHTML = "现价"+((price - random()).toFixed(2));
+                $('.current_price').addClass('scale');
+                document.getElementById('current_price').addEventListener('webkitAnimationEnd',function(){
+                    $('.current_price').removeClass('scale');
+                });
+            },500);
+        });
+    });
+
+    //发送信息
+    $('#send_btn').on('click',function(){
+        var sendMsg = $('#send_msg').val();
+        if(!sendMsg){return;}
+        websocket.send(sendMsg);
+        $('#send_msg').val('');
+    });
+
+    //判断用户设备下载app
+    var bridge = new Bridge();
+    function skip_download_app(){
+        if(bridge.isMobile.iOS()) {
+            window.location.href = 'itms-apps://itunes.apple.com/app/id945609424';
+        }
+        else if(bridge.isMobile.Android()) {
+            window.location.href = 'http://p.lrlz.com/hfive/android_down';
+        }
+    }
+    $('#download_app').on('click',function(){
+        skip_download_app();
+    });
+    $('#join_btn').on('click',function(){
+        skip_download_app();
+    });
+</script>
+</body>
+</html>
+