碰撞检测,交换位置

可拖动元素拖动到另外一个元素位置的时候,互相交换位置。

来源:最初是网上看到的一个拼图小游戏,具体网址不记得了,这块是单独扒出来的。

代码:

body,ul,li{margin:0;padding:0;}

ul{list-style: none;}

body{font:13px/1.5 Tahoma;}

#box{position:relative;width:435px;height:580px;margin:10px auto;padding: 10px 5px 10px 10px;border: 1px solid #ccc;}

#box li{float:left;width:80px;height:188px;overflow:hidden;background: #ccc;border: 1px solid #999;}

#box li.hig{width:78px;height:186px;overflow:hidden;border:2px dashed blue;}

 

<ul id="box"></ul>

 

  1 var zIndex = 1;

  2 window.onload = function() {

  3 

  4     var oBox = document.getElementById("box");

  5     var aLi = oBox.getElementsByTagName("li");

  6     var aPos = [];

  7     var aData = [];

  8     for (i = 0; i < 15; i++)aData.push(i+1);

  9 

 10 

 11     //插入结构

 12     var oFragment = document.createDocumentFragment();

 13     for (i = 0; i < aData.length; i++) {

 14         var oLi = document.createElement("li");

 15         oFragment.appendChild(oLi)

 16     }

 17     oBox.appendChild(oFragment);

 18 

 19     //布局转换

 20     for (i = 0; i < aLi.length; i++) {

 21         aLi[i].index = i;

 22         aLi[i].style.top = aLi[i].offsetTop + "px";

 23         aLi[i].style.left = aLi[i].offsetLeft + "px";

 24         aLi[i].style.margin = "0 5px 5px 0";

 25         aPos.push({

 26             "left": aLi[i].offsetLeft,

 27             "top": aLi[i].offsetTop

 28         })

 29     }

 30     for (i = 0; i < aLi.length; i++) {

 31         aLi[i].style.position = "absolute";        

 32         drag(aLi[i])

 33     }

 34 

 35     //拖拽函数

 36     function drag(obj, handle) {

 37         var handle = handle || obj;

 38         handle.style.cursor = "move";

 39         handle.onmousedown = function(event) {

 40             var event = event || window.event;

 41             var disX = event.clientX - this.offsetLeft;

 42             var disY = event.clientY - this.offsetTop;

 43             var oNear = null;

 44             obj.style.zIndex = zIndex++;

 45             document.onmousemove = function(event) {

 46                 var event = event || window.event;

 47                 var iL = event.clientX - disX;

 48                 var iT = event.clientY - disY;

 49                 var maxL = obj.parentNode.clientWidth - obj.offsetWidth;

 50                 var maxT = obj.parentNode.clientHeight - obj.offsetHeight;

 51 

 52                 iL < 0 && (iL = 0);

 53                 iT < 0 && (iT = 0);

 54                 iL > maxL && (iL = maxL);

 55                 iT > maxT && (iT = maxT);

 56                 obj.style.left = iL + "px";

 57                 obj.style.top = iT + "px";

 58 

 59                 for (i = 0; i < aLi.length; i++) aLi[i].className = "";

 60 

 61                 oNear = findNearest(obj);

 62 

 63                 oNear && (oNear.className = "hig");

 64 

 65                 return false

 66             };

 67             document.onmouseup = function() {

 68                 document.onmousemove = null;

 69                 document.onmouseup = null;

 70                 if (oNear) {

 71                     var tIndex = obj.index;

 72                     obj.index = oNear.index;

 73                     oNear.index = tIndex;

 74                     startMove(obj, aPos[obj.index]);

 75                     startMove(oNear, aPos[oNear.index], function() {

 76                         

 77                     });

 78                     oNear.className = "";

 79                 } else {

 80                     startMove(obj, aPos[obj.index])

 81                 }

 82                 handle.releaseCapture && handle.releaseCapture()

 83             };

 84             this.setCapture && this.setCapture();

 85             return false

 86         }

 87     }

 88 

 89     //找出相遇点中最近的元素

 90     function findNearest(obj) {

 91         var filterLi = [];

 92         var aDistance = [];

 93 

 94         for (i = 0; i < aLi.length; i++) aLi[i] != obj && (isButt(obj, aLi[i]) && (aDistance.push(getDistance(obj, aLi[i])), filterLi.push(aLi[i])));

 95 

 96         var minNum = Number.MAX_VALUE;

 97         var minLi = null;

 98 

 99         for (i = 0; i < aDistance.length; i++) aDistance[i] < minNum && (minNum = aDistance[i], minLi = filterLi[i]);

100 

101         return minLi

102     }

103 

104 

105 

106 };

107 //求两点之间的距离

108 function getDistance(obj1, obj2) {

109     var a = (obj1.offsetLeft + obj1.offsetWidth / 2) - (obj2.offsetLeft + obj2.offsetWidth / 2);

110     var b = (obj1.offsetTop + obj1.offsetHeight / 2) - (obj2.offsetTop + obj2.offsetHeight / 2);

111     return Math.sqrt(a * a + b * b)

112 }

113 

114 //碰撞检测

115 function isButt(obj1, obj2) {

116     var l1 = obj1.offsetLeft;

117     var t1 = obj1.offsetTop;

118     var r1 = obj1.offsetLeft + obj1.offsetWidth;

119     var b1 = obj1.offsetTop + obj1.offsetHeight;

120 

121     var l2 = obj2.offsetLeft;

122     var t2 = obj2.offsetTop;

123     var r2 = obj2.offsetLeft + obj2.offsetWidth;

124     var b2 = obj2.offsetTop + obj2.offsetHeight;

125 

126     return !(r1 < l2 || b1 < t2 || r2 < l1 || b2 < t1)

127 }

128 

129 //获取最终样式

130 function getStyle(obj, attr) {

131     return parseFloat(obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj, null)[attr])

132 }

133 

134 //运动框架

135 function startMove(obj, pos, onEnd) {

136     clearInterval(obj.timer);

137     obj.timer = setInterval(function() {

138         doMove(obj, pos, onEnd)

139     }, 30)

140 }

141 

142 function doMove(obj, pos, onEnd) {

143     var iCurL = getStyle(obj, "left");

144     var iCurT = getStyle(obj, "top");

145     var iSpeedL = (pos.left - iCurL) / 5;

146     var iSpeedT = (pos.top - iCurT) / 5;

147     iSpeedL = iSpeedL > 0 ? Math.ceil(iSpeedL) : Math.floor(iSpeedL);

148     iSpeedT = iSpeedT > 0 ? Math.ceil(iSpeedT) : Math.floor(iSpeedT);

149     if (pos.left == iCurL && pos.top == iCurT) {

150         clearInterval(obj.timer);

151         onEnd && onEnd()

152     } else {

153         obj.style.left = iCurL + iSpeedL + "px";

154         obj.style.top = iCurT + iSpeedT + "px";

155     }

156 }

 

预览图

碰撞检测,交换位置

 

你可能感兴趣的:(碰撞检测,交换位置)