Vladimir Bykov 10 лет назад
Родитель
Сommit
5cda5bb3f1

+ 1 - 1
apps/web/priv/static/app/js/controller.js

@@ -37,7 +37,7 @@ function ControllerScope(scope) {
             ,   y_overlap = Math.max(0, Math.min(y12,y22) - Math.max(y11,y21))
             return {
                 square: x_overlap * y_overlap
-            ,   res : x_overlap * y_overlap > $el.width() * $el.height() * .25
+            ,   res : x_overlap * y_overlap > $el.width() * $el.height() * .4
             }   
         }
     }),

+ 9 - 1
apps/web/priv/static/app/js/okey/card.js

@@ -71,6 +71,12 @@ function CardScope(scope) {
             var pos = this.$el.position(), width = this.$el.width();
             return Math.round(pos.left + width / 2);
         },
+
+        centerY: function(){
+            var pos = this.$el.position(), height = this.$el.height();
+            return Math.round(pos.bottom + height / 2);
+        },
+
         toggle: function(e) {
             e.stopPropagation(), selStart && scope.deck.contains(this) ? this.nearSelectGroup() ? this.selected && !this.betweenSelected() ? this.uncheck() : this.check() : (Card.uncheckAll(), 
             this.check()) : ~Card.selected.indexOf(this) || Card.uncheckAll();
@@ -126,7 +132,9 @@ function CardScope(scope) {
         tile: function(){
             return [, scope.CARD_COLORS.indexOf(this.color), card.value]
         },
-        log: function() {}
+        log: function() {
+            console.log('%c'+this.value, 'color: '+this.color)
+        }
     });
 
     scope.Card = Card;

+ 206 - 45
apps/web/priv/static/app/js/okey/deck.js

@@ -9,6 +9,10 @@ function DeckScope(scope) {
         this.trfs = [ [], [] ];
         this.__super__.constructor.call(this),
         this.$dropPlace.droppable({ accept: this.place });
+        // this.move = $.debounce(this.move, 25)
+
+        this.restoredCards = [[], []]
+        this.selectedPos = {}
     }
 
     var padding = {
@@ -53,6 +57,45 @@ function DeckScope(scope) {
             });
         },
 
+        restoreCards: function(){
+            if(this.restoredCards && this.needRestore){
+                var trfs = this.trfs
+                for(var i = 0; i < 15; i++){
+                    for(var j = 0; j < 2; j++){
+                        var card = this.restoredCards[j][i]
+                        if(card && card != selected){
+                            card.$el.transform({
+                                from: [trfs[card.pos.y][card.pos.x].x, trfs[card.pos.y][card.pos.x].y].join(' '),
+                                to: [trfs[j][i].x, trfs[j][i].y].join(' ')
+                            })
+
+                            card.pos = {
+                                x: i,
+                                y: j
+                            }
+                        }
+                    }
+                }
+                this.needRestore = false
+                this.cards = this.restoredCards.map(function (row){ return row.concat() })
+                this.normalizeCards()
+            }
+        },
+
+        normalizeCards: function(){
+            for(var i = 0; i < 15; i++){
+                for(var j = 0; j < 2; j++){
+                    var card = this.cards[j][i]
+                    if(card){
+                        card.pos = {
+                            x: i,
+                            y: j
+                        }
+                    }
+                }
+            }
+        },
+
         render: function() {
             this.each(function(card, i, j) {
                 if (null != card) {
@@ -64,18 +107,28 @@ function DeckScope(scope) {
         },
 
         track: function(e) {
-            this.each(function(card, i, j) {
-                if (card && card.$el[0] != e.target && card.intersect($(e.target)).res && !card.$el.attr("animated") && scope.Card.selected.length < 2) {
-                    var shift = e.detail.x > card.centerX() ? i - 1 : i + 1
-                    shift = shift > 14 ? shift - 2 : shift
-                    shift = 0 > shift ? shift + 2 : shift
-                    this.move({ i: i, j: j}, {i: shift, j: j})
-                    moved = true
-                    prevX = e.detail.x
-                    prevY = e.detail.y
-                    return !1;
+
+            for(var i = 0; i < 15; i++){
+                for(var j = 0; j < 2; j++){
+                    var card = this.cards[j][i]
+                    if (card && card.$el[0] != e.target && card.intersect($(e.target)).res && !card.$el.attr("animated") && scope.Card.selected.length < 2) {
+                        var shift = e.detail.x > card.centerX() ? i - 1 : i + 1
+                        shift = shift > 14 ? shift - 2 : shift
+                        shift = 0 > shift ? shift + 2 : shift
+                        this.move({ i: i, j: j}, {i: shift, j: j})
+                        this.needRestore = true
+                        moved = true
+                        prevX = e.detail.x
+                        prevY = e.detail.y
+                        this.selectedPos = { x: i, y: j}
+                        return !1;
+                    }
                 }
-            });
+            }
+            var selectedPos = this.getSelectedPos()
+            if((this.selectedPos.x != selectedPos.x || this.selectedPos.y != selectedPos.y)){
+                this.restoreCards()
+            } 
         },
 
         move: function(fst, snd){
@@ -105,14 +158,37 @@ function DeckScope(scope) {
                             card = this.cards[fst.j][j]
                             if(card != selected){
 
-                                card.$el.transform({
-                                    from: [trfs[fst.j][j].x, trfs[fst.j][j].y].join(' '),
-                                    to: [trfs[fst.j][direction(j)].x, trfs[fst.j][direction(j)].y].join(' ')
-                                })
+                                var self = this
 
-                                if(selected){
-                                    selected.dragHandler.initTrf = [trfs[fst.j][j].x, trfs[fst.j][j].y]
-                                }
+                                ;(function (card, fst_j, j, dir_j){                                 
+                                    card.$el.transform({
+                                        from: [trfs[fst_j][j].x, trfs[fst_j][j].y].join(' '),
+                                        to: [trfs[fst_j][dir_j].x, trfs[fst_j][dir_j].y].join(' ')
+                                    })
+
+                                    // card.restoreCardHandler = function(){
+                                    //     var selectedPos = self.getSelectedPos()
+                                    //     if(!self.cards[fst_j][j] && (selectedPos.x != j || selectedPos.y != fst_j)){
+                                    //         console.log('restoreCard');
+                                    //         card.$el.transform({
+                                    //             to: [trfs[fst_j][j].x, trfs[fst_j][j].y].join(' '),
+                                    //             from: [trfs[fst_j][dir_j].x, trfs[fst_j][dir_j].y].join(' ')
+                                    //         })
+                                    //         ;(self.cards[fst_j][j] = card).pos = {x:j, y:fst_j}
+                                    //         self.cards[fst_j][dir_j] = null
+                                    //         card.restoreCardHandler = function(){}
+                                    //         var idx = self.restoredCards.indexOf(card)
+                                    //         if(~idx){
+                                    //             self.restoredCards.splice(idx, 1)
+                                    //         }
+                                    //     }
+                                    // }
+                                    // self.restoredCards.push(card)
+                                }(card, fst.j, j, direction(j)))
+
+                                // if(selected){
+                                //     selected.dragHandler.initTrf = [trfs[fst.j][j].x, trfs[fst.j][j].y]
+                                // }
 
                                 ;((this.cards[fst.j][j] = this.cards[fst.j][direction(j)]) || {}).pos = {x:j, y:fst.j}
                                 ;(this.cards[fst.j][direction(j)] = card).pos = {x:direction(j), y:fst.j}
@@ -122,40 +198,78 @@ function DeckScope(scope) {
                     }
                 }
             }
+            this.normalizeCards()
         },
 
         select: function(e) {
             selected = null, this.each(function(card) {
-                return card && card.$el[0] == e.target ? (selected = card, !1) : !0;
+                if(card && card.$el[0] == e.target){
+                    selected = card
+                    this.restoredCards = this.cards.map(function (row){ return row.concat() })
+                    return !1 
+                }
+                else {
+                    return !0
+                }
             });
         },
 
         place: function(target, x, y) {
             try{
-                var trfs = this.trfs, pos = this.$dropPlace.position(), width = this.$dropPlace.width(), height = this.$dropPlace.height(), placeWidth = Math.round(width / 15), placeHeight = Math.round(height / 2), truePosX = Math.floor((x - pos.left) / placeWidth), posY = Math.floor((y - pos.top) / placeHeight);
-                scope.Card.selected.sort(function(a, b) {
-                    return (a.pos.x > b.pos.x) - (b.pos.x > a.pos.x);
-                });
-                var dropResult, idx = scope.Card.selected.indexOf(target.owner), cards = scope.Card.selected.length ? scope.Card.selected.concat() : [ target.owner ];
-                if (cards.every(function(card, i) {
-                    return posX = truePosX + (i - idx) * (card != target.owner), null == this.cards[posY][posX] || this.cards[posY][posX] == card;
-                }, this)) for (var card, i = 0, l = cards.length; l > i; i++) card = cards[i], posX = truePosX + (i - idx) * (card != target.owner), 
-                (dropResult = null == this.cards[posY][posX] || this.cards[posY][posX] == selected) && (this.cards[posY][posX] != card && (null != card.pos.x && null != card.pos.y ? this.cards[card.pos.y][card.pos.x] = this.cards[card.pos.y][card.pos.x] == card ? null : this.cards[card.pos.y][card.pos.x] : (this.$el.trigger("take", {
-                    detail: {
-                        card: card
+                var trfs = this.trfs,
+                    pos = this.$dropPlace.position(),
+                    width = this.$dropPlace.width(),
+                    height = this.$dropPlace.height(),
+                    placeWidth = Math.round(width / 15),
+                    placeHeight = Math.round(height / 2),
+                    truePosX = Math.floor((x - pos.left) / placeWidth),
+                    posY = Math.floor((y - pos.top) / placeHeight)
+
+                scope.Card.selected.sort(function (a, b){
+                    return (a.pos.x > b.pos.x) - (b.pos.x > a.pos.x)
+                })
+
+                var idx = scope.Card.selected.indexOf(target.owner),
+                    cards = scope.Card.selected.length ? scope.Card.selected.concat() : [target.owner],
+                    dropResult
+
+                if(cards.every(function (card, i){
+                    posX = truePosX + (i - idx) * (card != target.owner)
+                    return this.cards[posY][posX] == null || this.cards[posY][posX] == card
+                }, this)){
+
+                    for(var i = 0, l = cards.length, card; i < l; i++){
+                        card = cards[i]
+                        posX = truePosX + (i - idx) * (card != target.owner)
+
+                        if(dropResult = (this.cards[posY][posX] == null || this.cards[posY][posX] == selected)){
+
+                            if(this.cards[posY][posX] != card){
+                                if(card.pos.x != null && card.pos.y != null){
+                                    this.cards[card.pos.y][card.pos.x] = this.cards[card.pos.y][card.pos.x] == card ? null : this.cards[card.pos.y][card.pos.x]
+                                }
+                                else {
+                                    this.$el.trigger('take', { detail: { card: card }})
+                                    this.justTaken = true
+                                }
+                                ;(this.cards[posY][posX] = card).pos = {x:posX,y:posY}
+                                this.normalizeCards()
+                                this.restoredCards = null
+                                selected = null
+                            }
+
+                            ;(function(card){
+                                card.$el.transform({
+                                    from: card.$el.attr('transform').slice(10,-1),
+                                    to: [trfs[posY][posX].x, trfs[posY][posX].y].join(' ')
+                                }).then(function(){
+                                    card.dragHandler.storeTrf()
+                                })
+                            }(card))
+                        }
                     }
-                }), this.justTaken = !0), (this.cards[posY][posX] = card).pos = {
-                    x: posX,
-                    y: posY
-                }), function(card) {
-                    card.$el.transform({
-                        from: card.$el.attr("transform").slice(10, -1),
-                        to: [ trfs[posY][posX].x, trfs[posY][posX].y ].join(" ")
-                    }).then(function() {
-                        card.dragHandler.storeTrf();
-                    });
-                }(card));
-                return dropResult;
+                }
+                return dropResult
             }
             catch(e){
                 return false
@@ -179,6 +293,7 @@ function DeckScope(scope) {
                             value: tile[2]
                         });
                         card.pos = {x:i, y:j};
+                        this.normalizeCards()
                         card.on('dragstart', this.select);
                         card.on('dragmove', this.track);
                         card.$el.doubletap(function() { scope.apiProvider.actionDiscard(card) });
@@ -219,9 +334,55 @@ function DeckScope(scope) {
             return result
         },
 
-        dir: function() {
-            for (var i = 0; 15 > i; i++) this.cards[0][i] && this.cards[0][i].log();
-            for (var i = 0; 15 > i; i++) this.cards[1][i] && this.cards[1][i].log();
+        getSelectedPos: function(){
+            if(selected){
+                var x = selected.centerX(),
+                    y = selected.centerY(),
+                    pos = this.$dropPlace.position(),
+                    width = this.$dropPlace.width(),
+                    height = this.$dropPlace.height(),
+                    placeWidth = Math.round(width / 15),
+                    placeHeight = Math.round(height / 2),
+                    posX = Math.floor((x - pos.left) / placeWidth),
+                    posY = Math.floor((y - pos.top) / placeHeight) - 1
+
+                console.log(posX, posY)
+                return {
+                    x: posX,
+                    y: posY
+                }
+            }
+            else {
+                return {
+                    x: -1,
+                    y: -1
+                }
+            }
+        },
+
+        dir: function(){
+            console.group('Cards')
+            console.group()
+            for(var i = 0; i < 15; i++){
+                if(this.cards[0][i]){
+                    this.cards[0][i].log()
+                }
+                else {
+                    console.log('%c■', 'color: #333')
+                }
+            }
+            console.groupEnd()
+            console.group()
+            for(var i = 0; i < 15; i++){
+                if(this.cards[1][i]){
+                    this.cards[1][i].log()
+                }
+                else {
+                    console.log('%c■', 'color: #333')
+                }
+            }
+            console.groupEnd()
+            console.groupEnd()
         }
     });
 

+ 63 - 0
apps/web/priv/static/app/js/selector.js

@@ -367,6 +367,69 @@ var $ = function(_undefind)
 
     $.rand = function(min, max) { return min + Math.floor(Math.random() * (max - min + 1)); },
 
+    $.throttle = function(func, wait, options) {
+        var context, args, result;
+        var timeout = null;
+        var previous = 0;
+        options || (options = {});
+        var later = function() {
+            previous = options.leading === false ? 0 : +new Date;
+            timeout = null;
+            result = func.apply(context, args);
+            context = args = null;
+        };
+        return function() {
+            var now = +new Date;
+            if (!previous && options.leading === false) previous = now;
+            var remaining = wait - (now - previous);
+            context = this;
+            args = arguments;
+            if (remaining <= 0) {
+                clearTimeout(timeout);
+                timeout = null;
+                previous = now;
+                result = func.apply(context, args);
+                context = args = null;
+            } else if (!timeout && options.trailing !== false) {
+                timeout = setTimeout(later, remaining);
+            }
+            return result;
+        };
+    },
+
+    $.debounce = function(func, wait, immediate) {
+        var timeout, args, context, timestamp, result;
+
+        var later = function() {
+            var last = +new Date - timestamp;
+            if (last < wait) {
+                timeout = setTimeout(later, wait - last);
+            } else {
+                timeout = null;
+                if (!immediate) {
+                    result = func.apply(context, args);
+                    context = args = null;
+                }
+            }
+        };
+
+        return function() {
+            context = this;
+            args = arguments;
+            timestamp = +new Date;
+            var callNow = immediate && !timeout;
+            if (!timeout) {
+                timeout = setTimeout(later, wait);
+            }
+            if (callNow) {
+                result = func.apply(context, args);
+                context = args = null;
+            }
+
+            return result;
+        };
+    },
+
     $;
 }();