jQuery / JavaScript 충돌 감지
두 <div>
요소가 충돌 했는지 감지하는 방법 은 무엇입니까?
두 div는 서로 수직으로 이동하는 단순한 색상의 상자이므로 복잡한 모양이나 각도가 없습니다.
var overlaps = (function () {
function getPositions( elem ) {
var pos, width, height;
pos = $( elem ).position();
width = $( elem ).width();
height = $( elem ).height();
return [ [ pos.left, pos.left + width ], [ pos.top, pos.top + height ] ];
}
function comparePositions( p1, p2 ) {
var r1, r2;
r1 = p1[0] < p2[0] ? p1 : p2;
r2 = p1[0] < p2[0] ? p2 : p1;
return r1[1] > r2[0] || r1[0] === r2[0];
}
return function ( a, b ) {
var pos1 = getPositions( a ),
pos2 = getPositions( b );
return comparePositions( pos1[0], pos2[0] ) && comparePositions( pos1[1], pos2[1] );
};
})();
$(function () {
var area = $( '#area' )[0],
box = $( '#box0' )[0],
html;
html = $( area ).children().not( box ).map( function ( i ) {
return '<p>Red box + Box ' + ( i + 1 ) + ' = ' + overlaps( box, this ) + '</p>';
}).get().join( '' );
$( 'body' ).append( html );
});
body {
padding: 30px;
color: #444;
font-family: Arial, sans-serif;
}
h1 {
font-size: 24px;
margin-bottom: 20px;
}
#area {
border: 2px solid gray;
width: 500px;
height: 400px;
position: relative;
}
#area > div {
background-color: rgba(122, 122, 122, 0.3);
position: absolute;
text-align: center;
font-size: 50px;
width: 60px;
height: 60px;
}
#box0 {
background-color: rgba(255, 0, 0, 0.5) !important;
top: 150px;
left: 150px;
}
#box1 {
top: 260px;
left: 50px;
}
#box2 {
top: 110px;
left: 160px;
}
#box3 {
top: 200px;
left: 200px;
}
#box4 {
top: 50px;
left: 400px;
}
p {
margin: 5px 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<h1>Detect overlapping with JavaScript</h1>
<div id="area">
<div id="box0"></div>
<div id="box1">1</div>
<div id="box2">2</div>
<div id="box3">3</div>
<div id="box4">4</div>
</div>
일반적인 아이디어-상자의 오프셋과 치수를 확인하고 겹치는 지 확인합니다.
업데이트하려면 다음을 사용할 수 있습니다 setInterval
.
function detectOverlapping() {
// code that detects if the box overlaps with a moving box
setInterval(detectOverlapping, 25);
}
detectOverlapping();
또한 특정 예제에 대해 함수를 최적화 할 수 있습니다.
상자 치수가 고정되어 있기 때문에 (내 코드 에서처럼) 반복해서 읽을 필요가 없습니다. 페이지로드시 (변수로) 읽을 수 있으며 변수를 읽을 수 있습니다.
작은 상자의 가로 위치는 변경되지 않습니다 (사용자가 창 크기를 조정하지 않는 한). 자동차 상자의 수직 위치는 변경되지 않습니다. 따라서 이러한 값은 반복적으로 읽을 필요가 없지만 변수에 저장할 수도 있습니다.
작은 상자가 항상 모든 자동차 상자와 겹치는 지 테스트 할 필요가 없습니다. 수직 위치를 기반으로 상자가 현재 어느 차선에 있는지 파악하고 해당 차선에서 특정 자동차 상자 만 테스트 할 수 있습니다.
이것이 가장 쉬운 방법이라고 생각합니다 : http://plugins.jquery.com/project/collidable
다음은 독일어로 된 또 다른 것입니다. http://www.48design.de/news/2009/11/20/kollisionsabfrage-per-jquery-plugin-update-v11-8/
나는 그들을 시도 할 것입니다.
--최신 정보--
지금 당장은 그 일에 시간을 쓸 수 없지만, 당신 외에 아무도 대답하지 않으면 집에 돌아갈 때 할 수 있습니다.
setInterval(function(){
//First step would be to get the offset of item 1 and item 2
//Second would be to get the width of each
//Third would be to check if the offset+width ever overlaps
//the offset+width of the 2nd
//Fourth would be, if so, do X or set a class...
},10);
이것에 조금 늦었지만 비슷한 상황에 직면했을 때 시도한이 접근 방식을 사용할 수 있다고 생각합니다. 여기에서 장점은 추가 플러그인이나 스크립트가 없으며 성능에 굶주린 폴링을 도입 할 필요가 없다는 것입니다. 이 기술은 Jquery의 droppable이 제공해야하는 내장 메서드와 이벤트를 사용합니다.
좋습니다. 여기에 솔루션 기술이 있습니다. 두 개의 요소 (제 경우에는 이미지)가 있고 이들이 중첩되거나 감지되는 것을 원하지 않는 경우 두 요소를 드롭 가능하게 만들고 '수락'하도록 만드십시오. 서로:
$([div1, div2]).droppable(CONFIG_COLLISSION_PREVENTION_DROPPABLE);
'CONFIG_COLLISSION_PREVENTION_DROPPABLE'은 다음과 같습니다.
var originatingOffset = null;
CONFIG_COLLISSION_PREVENTION_DROPPABLE = {
tolerance: "touch",
activate : function (event, ui) {
// note the initial position/offset when drag starts
// will be usedful in drop handler to check if the move
// occurred and in cae overlap occurred, restore the original positions.
originatingOffset = ui.offset;
},
drop : function (event, ui) {
// If this callback gets invoked, the overlap has occurred.
// Use this method to either generate a custom event etc.
// Here, i used it to nullify the move and resetting the dragged element's
// position back to it's original position/offset
// (which was captured in the 'activate' handler)
$(ui.draggable).animate({
top: originatingOffset.top + "px",
left: originatingOffset.left + "px"
}, 300);
}
}
'activate'및 'drop'핸들러는 "droppable"플러그인의 'dropactivate'및 'drop'이벤트를 참조합니다.
여기서 핵심은 'drop'콜백입니다. 두 요소 중 하나가 겹치고 서로 위에 놓일 때마다 'drop'이 호출됩니다. 이것은 감지하고 조치를 취하는 곳이며, 사용자 정의 이벤트를 보내거나 다른 조치를 호출 할 수 있습니다 (여기서는 '활성화'콜백에서 캡처 된 드래그가 시작될 때 겹치는 요소의 위치를 초기 위치로 되돌 리도록 선택했습니다).
그게 다야. 폴링도, 플러그인도, 내장 이벤트 만 있습니다.
글쎄, 다른 최적화 / 확장이있을 수 있습니다. 이것은 단순히 내 머리에서 나온 첫 번째 샷이었습니다 :)
You can also use the 'dropover' and 'dropout' events to signal and create a visual feedback to the user that two elements are overlapping, while they may be still on the move.
var CLASS_INVALID = "invalid";
// .invalid { border: 1px solid red; }
...
$.extend(CONFIG_COLLISSION_PREVENTION_DROPPABLE, {
over : function (event, ui) {
// When an element is over another, it gets detected here;
// while it may still be moved.
// the draggable element becomes 'invalid' and so apply the class here
$(ui.draggable).addClass(CLASS_INVALID);
},
out : function(event, ui) {
// the element has exited the overlapped droppable now
// So element is valid now and so remove the invalid class from it
$(ui.draggable).removeClass(CLASS_INVALID);
}
});
Hope this helps!
EDIT: I have written a blog post on my website. Here a link to it. http://area36.nl/2014/12/creating-your-own-collision-detection-function-in-javascript/
Well I had the same problem but thanks to the answer of Oscar Godson I got a function that works. I used Jquery for easy coding and because i'm lazy ;p. I put the function in a other function that is fired every second so keep that in mind.
function collidesWith (element1, element2) {
var Element1 = {};
var Element2 = {};
Element1.top = $(element1).offset().top;
Element1.left = $(element1).offset().left;
Element1.right = Number($(element1).offset().left) + Number($(element1).width());
Element1.bottom = Number($(element1).offset().top) + Number($(element1).height());
Element2.top = $(element2).offset().top;
Element2.left = $(element2).offset().left;
Element2.right = Number($(element2).offset().left) + Number($(element2).width());
Element2.bottom = Number($(element2).offset().top) + Number($(element2).height());
if (Element1.right > Element2.left && Element1.left < Element2.right && Element1.top < Element2.bottom && Element1.bottom > Element2.top) {
// Do your stuff here
}
}
What it does is basically it gets all the values of element1
and then get all the values of element2
. Then with the help of some calculations it figures out all the values. Then in the if
statement it compares the square of element1
to the square of element2
. If the values of element1
are between the left, right, top and bottom values of element2
. If that is true the code in the bottom is executed.
I ran into this generalized issue myself, so (full disclosure) I made a plugin for it. For simple collision queries about static objects, try this:
http://sourceforge.net/projects/jquerycollision/
Which allows you to get a list of overlapping collision boxes (or none if there's no collision):
hits = $("#collider").collision(".obstacles");
Or to get a collision event during "dragging", use this:
http://sourceforge.net/apps/mediawiki/jquidragcollide/?source=navbar#collision
Which gives you a "collision" event to connect to. (Or a "protrusion" event, to see if a div escapes another div that currently contains it.)
$(draggable).bind(
"collision",
function(event,ui) {
...
}
);
If you are checking collisions during motion other than dragging, just call the original repeatedly, it's pretty quick. Note: the dragging one doesn't play nicely with resizing.
Post is old, May be it help someone...
function CheckDiv()
{
var ediv1 = document.getElementById('DIV1');
var ediv2 = document.getElementById('DIV2');
ediv1.top = $(ediv1).offset().top;
ediv1.left = $(ediv1).offset().left;
ediv1.right = Number($(ediv1).offset().left) + Number($(ediv1).width());
ediv1.bottom = Number($(ediv1).offset().top) + Number($(ediv1).height());
ediv2.top = $(ediv2).offset().top;
ediv2.left = $(ediv2).offset().left;
ediv2.right = Number($(ediv2).offset().left) + Number($(ediv2).width());
ediv2.bottom = Number($(ediv2).offset().top) + Number($(ediv2).height());
if (ediv1.right > ediv2.left && ediv1.left < ediv2.right && ediv1.top < ediv2.bottom && ediv1.bottom > ediv2.top)
{
alert("hi");
}
if (ediv1.left > ediv2.left && ediv1.top > ediv2.top && ediv1.right < ediv2.right && ediv1.bottom < ediv2.bottom)
{
alert("hello");
}
}
참고URL : https://stackoverflow.com/questions/4230029/jquery-javascript-collision-detection
'Development Tip' 카테고리의 다른 글
모듈 대 네임 스페이스-가져 오기 및 Typescript 필요 (0) | 2020.10.19 |
---|---|
C / C ++에서 서명 된 오버플로 감지 (0) | 2020.10.19 |
FROM의 하위 쿼리에는 별칭이 있어야합니다. (0) | 2020.10.19 |
const 생성자는 실제로 어떻게 작동합니까? (0) | 2020.10.19 |
두 개의 NULL 포인터를 빼는 동작이 정의되어 있습니까? (0) | 2020.10.18 |