Browse Source

implemented drag`n`drop by intersection square

Vladimir Bykov 10 years ago
parent
commit
8b2e61caa4

+ 19 - 3
apps/web/priv/static/app/js/controller.js

@@ -20,9 +20,25 @@ function ControllerScope(scope) {
         off: function(eventType, handler) { return this.$el.off(eventType, handler), this; },
         clientX: function(e) { return isIE ? e.pageX : document.createTouch ? e.changedTouches[0].clientX : e.clientX; },
         clientY: function(e) { return isIE ? e.pageY : document.createTouch ? e.changedTouches[0].clientY : e.clientY; },
-        intersect: function(x, y) {
-            var pos = this.$el.position();
-            return pos.top < y && pos.bottom > y && pos.left < x && pos.right > x;
+        intersect: function($el) {
+            // var pos = this.$el.position();
+            // return pos.top < y && pos.bottom > y && pos.left < x && pos.right > x;
+            var d0 = this.$el.position()
+            ,   d1 = $el.position()
+            ,   x11 = d0.left
+            ,   y11 = d0.top
+            ,   x12 = d0.left + this.$el.width()
+            ,   y12 = d0.top + this.$el.height()
+            ,   x21 = d1.left
+            ,   y21 = d1.top
+            ,   x22 = d1.left + $el.width()
+            ,   y22 = d1.top + $el.height()
+            ,   x_overlap = Math.max(0, Math.min(x12,x22) - Math.max(x11,x21))
+            ,   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
+            }   
         }
     }),
 

+ 14 - 3
apps/web/priv/static/app/js/dragndrop.js

@@ -101,15 +101,26 @@ function DragScope(scope) {
             // detect drop
             if(moved){
                 var dropList = scope.Droppable.list, 
+                    dropTargets =[],
+                    intersection,
                     droped
                 for(var i = 0, l = dropList.length, item; i < l; i++){
                     item = dropList[i]
-                    if(item.intersect(this.curX, this.curY)){
-                        droped = item.drop(this, this.curX, this.curY)
-                        break
+                    if((intersection = item.intersect(this.$el)).res){
+                        dropTargets.push({
+                            square: intersection.square,
+                            item: item
+                        })
                     }
                 }
 
+                dropTargets = dropTargets.sort(function(a,b){ 
+                    return (a.square < b.square) - (b.square < a.square) 
+                })
+                if(dropTargets.length){
+                    droped = dropTargets[0].item.drop(this, this.curX, this.curY)
+                }
+
                 // revert
                 if(!droped){
                     this.$el.transform({

+ 29 - 25
apps/web/priv/static/app/js/okey/deck.js

@@ -65,7 +65,7 @@ function DeckScope(scope) {
 
         track: function(e) {
             this.each(function(card, i, j) {
-                if (card && card.$el[0] != e.target && card.intersect(e.detail.x, e.detail.y) && !card.$el.attr("animated") && scope.Card.selected.length < 2) {
+                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
@@ -131,31 +131,35 @@ function DeckScope(scope) {
         },
 
         place: function(target, x, y) {
-
-            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
-                }
-            }), 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();
+            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);
                 });
-            }(card));
-            return dropResult;
+                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
+                    }
+                }), 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;
+            }
+            catch(e){
+                return false
+            }
         },
 
         remove: function(tile) {