does a pixel coverage collision based on where we started, returning the node that has the most coverage that is >50% mid line
(node: GridStackNode, o: GridStackMoveOpts, collides: GridStackNode[])
| 205 | |
| 206 | /** does a pixel coverage collision based on where we started, returning the node that has the most coverage that is >50% mid line */ |
| 207 | protected directionCollideCoverage(node: GridStackNode, o: GridStackMoveOpts, collides: GridStackNode[]): GridStackNode | undefined { |
| 208 | if (!o.rect || !node._rect) return; |
| 209 | const r0 = node._rect; // where started |
| 210 | const r = {...o.rect}; // where we are |
| 211 | |
| 212 | // update dragged rect to show where it's coming from (above or below, etc...) |
| 213 | if (r.y > r0.y) { |
| 214 | r.h += r.y - r0.y; |
| 215 | r.y = r0.y; |
| 216 | } else { |
| 217 | r.h += r0.y - r.y; |
| 218 | } |
| 219 | if (r.x > r0.x) { |
| 220 | r.w += r.x - r0.x; |
| 221 | r.x = r0.x; |
| 222 | } else { |
| 223 | r.w += r0.x - r.x; |
| 224 | } |
| 225 | |
| 226 | let collide: GridStackNode; |
| 227 | let overMax = 0.5; // need >50% |
| 228 | for (let n of collides) { |
| 229 | if (n.locked || !n._rect) { |
| 230 | break; |
| 231 | } |
| 232 | const r2 = n._rect; // overlapping target |
| 233 | let yOver = Number.MAX_VALUE, xOver = Number.MAX_VALUE; |
| 234 | // depending on which side we started from, compute the overlap % of coverage |
| 235 | // (ex: from above/below we only compute the max horizontal line coverage) |
| 236 | if (r0.y < r2.y) { // from above |
| 237 | yOver = ((r.y + r.h) - r2.y) / r2.h; |
| 238 | } else if (r0.y + r0.h > r2.y + r2.h) { // from below |
| 239 | yOver = ((r2.y + r2.h) - r.y) / r2.h; |
| 240 | } |
| 241 | if (r0.x < r2.x) { // from the left |
| 242 | xOver = ((r.x + r.w) - r2.x) / r2.w; |
| 243 | } else if (r0.x + r0.w > r2.x + r2.w) { // from the right |
| 244 | xOver = ((r2.x + r2.w) - r.x) / r2.w; |
| 245 | } |
| 246 | const over = Math.min(xOver, yOver); |
| 247 | if (over > overMax) { |
| 248 | overMax = over; |
| 249 | collide = n; |
| 250 | } |
| 251 | } |
| 252 | o.collide = collide; // save it so we don't have to find it again |
| 253 | return collide; |
| 254 | } |
| 255 | |
| 256 | /** does a pixel coverage returning the node that has the most coverage by area */ |
| 257 | /* |