1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
| <html>
<head>
<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript" src="scriptaculous/scriptaculous.js"></script>
<script type="text/javascript">
/**
* @description :
* Deux objets 1 et 2 se superposent-ils ?
* @params
* aPos position de l'element 1
* aDim dimension de l'element 1
* bPos positon de l'element 2
* bDim dimension de l'element 2
*/
function intersect(aPos, aDim, bPos, bDim) {
// On créé un range sur la largeur de l'objet 2
var rbW = $R(bPos.left, bPos.left + bDim.width);
// On créé un range sur la hauteur de l'objet 2
var rbH = $R(bPos.top, bPos.top + bDim.height);
// Calcul des coordonnées A,B,C,D du rectangle représentant l'élément 1
var A = {x: aPos.left, y: aPos.top};
var B = {x: aPos.left + aDim.width, y: aPos.top};
var C = {x: aPos.left + aDim.width, y: aPos.top + aDim.height};
var D = {x: aPos.left, y: aPos.top + aDim.height};
// Si A est dans les 2 range, lors A est dans l'element 2
if(rbW.include(A.x) && rbH.include(A.y)) {return true;}
// Si B est dans les 2 range, lors B est dans l'element 2
if(rbW.include(B.x) && rbH.include(B.y)) {return true;}
// Si C est dans les 2 range, lors C est dans l'element 2
if(rbW.include(C.x) && rbH.include(C.y)) {return true;}
// Si D est dans les 2 range, lors D est dans l'element 2
if(rbW.include(D.x) && rbH.include(D.y)) {return true;}
// pas trop sur de moi... cas ou les éléments se superposent mais pas leurs coins...
if(A.x <= rbW.start && B.x >= rbW.end && (rbH.include(A.y) || rbH.include(B.y) || rbH.include(C.y) || rbH.include(D.y) || (A.y <= rbH.start && D.y >= rbH.end))) {
return true;
}
if(A.y <= rbH.start && D.y >= rbH.end && (rbW.include(A.x) || rbW.include(B.x) || rbW.include(C.x) || rbW.include(D.x) || (A.x <= rbW.start && B.x >= rbW.end))) {
return true;
}
if(D.x <= rbW.start && C.x >= rbW.end && (rbH.include(A.y) || rbH.include(B.y) || rbH.include(C.y) || rbH.include(D.y) || (B.y <= rbH.start && C.y >= rbH.end))) {
return true;
}
if(B.y <= rbH.start && C.y >= rbH.end && (rbW.include(A.x) || rbW.include(B.x) || rbW.include(C.x) || rbW.include(D.x) || (D.x <= rbW.start && C.x >= rbW.end))) {
return true;
}
}
// cache des dernieres "bonnes coordonnées"
var lastGood = {};
Event.observe(window, "load", function(e) {
// on fait un reverse avant de faire un absolutize pour ne pas que les draggable soient les uns sur les autres
$$(".draggable").reverse().invoke("absolutize");
// pour chaque draggabke
$$(".draggable").each( function(shape) {
// on initialise lastGood avec leur positions actuelles
lastGood[shape.identify()] = shape.positionedOffset();
// on construit le draggable
new Draggable(shape, {
// avec la fonction snap
snap:function(x, y, drag) {
// on recupere l'element
var object = drag.element;
// on recupere les dimensions de l'element
var objDim = object.getDimensions();
var objPos = {left:x, top:y};
// pour chaque element de classe draggable
var draggables = $$(".draggable");
for(var i=0;i<draggables.length;i++) {
var other = draggables[i];
// si ce n'est pas l'objet draggé
if(object.identify() != other.identify()) {
// on recupere la position et les dimensions
var otherPos = other.positionedOffset();
var otherDim = other.getDimensions();
// si les objets s'intersectent
if(intersect(objPos, objDim, otherPos, otherDim)) {
// on renvoie la derniere bonne position
return lastGood[object.identify()] ;
}
}
}
// on stocke la position comme etant la derniere bonne
lastGood[object.identify()] = [x, y];
// on renvoie les coordonnées proposées
return [x, y];
},
// passage par la méthode revert
revert:function(object){
var failure = false;
// on recupere position et dimension
var objPos = object.positionedOffset();
var objDim = object.getDimensions();
var draggables = $$(".draggable");
// pour chaque autre draggable
for(var i=0;i<draggables.length;i++) {
var other = draggables[i];
if(object.identify() != other.identify()) {
// on recupere les positions / dimensions d'un autre draggable
var otherPos = other.positionedOffset();
var otherDim = other.getDimensions();
// si intersection, on est en failure
if(intersect(objPos, objDim, otherPos, otherDim)) {
failure = true;
break;
}
}
}
return failure;
}});
} );
});
</script>
<style type="text/css">
.draggable {
float:left;
}
.shape1 {
width:100px;
height:30px;
background-color:green;
}
.shape2 {
width:50px;
height:100px;
background-color:orange;
}
.shape3 {
width:60px;
height:30px;
background-color:blue;
}
.shape4 {
width:120px;
height:50px;
background-color:yellow;
}
.shape5 {
width:80px;
height:80px;
background-color:red;
}
</style>
</head>
<body>
<div id="zone" style="width:800px;height:400px;border:1px solid black;overflow:hidden;position:absolute;">
<div class="draggable shape1">
</div>
<div class="draggable shape1">
</div>
<div class="draggable shape2">
</div>
<div class="draggable shape3">
</div>
<div class="draggable shape4">
</div>
<div class="draggable shape5">
</div>
</div>
</body>
</html> |
Partager