AlgoRythm
AlgoRythm

Reputation: 168

How to check if one element is in same position as another javascript

I am creating a thing that is kind of cool and basically, it's just drawing without the use of a canvas because I thought "What the hell, I'll play around with some JS". Right now my computer can handle around 4,000 different elements before becoming laggy and I can make that number larger if I could tell if there was a div under the new div I am creating, and then remove it.

How can I detect if there is already an element where the script is going to be creating a new element and remove the existing element without the use of external libraries?

<!DOCTYPE html>
<html>
<head>
    <title>Drawing thing</title>
</head>
<body onmousedown="setYes()" onmouseup="setNo()">

    <div id="appendThingsHere"></div>


<style>
.circle{
    height:50px;
    width:50px;
    background:blue;
    border-radius:50%;
    position:absolute;
    -moz-user-select:none;
    -webkit-user-select:none;
    user-select:none;
}
body{
    overflow:hidden;
}
#appendThingsHere{
    height:100%;
    width:100%;
    background:none;
    position:absolute;
    top:0;
    left:0;
}
</style>
<script>
var mouseDown = "no";
var elements = 0;

function setYes(){
    mouseDown = "yes";
}

function setNo(){
    mouseDown = "no";
}

document.body.onmousemove = function(e){

    if(mouseDown === "yes"){
        if(elements < 4000){

            var newCircle = document.createElement("div");
            newCircle.className = "circle";
            newCircle.style.top = e.clientY - 25 + 'px';
            newCircle.style.left = e.clientX - 25 + 'px';

            try{
                var elem = document.elementFromPoint(e.clientX - 25 + 'px', e.clientY - 25 + 'px');
                elem.parentElement.removeChild(elem);
                elements = elements - 1;
                alert("Got one!");
            }
            catch(err){

            }

            elements ++;

            document.getElementById('appendThingsHere').appendChild(newCircle);

        }
    }

}



</script>
</body>
</html>

http://jsbin.com/hocowa/edit?html,output

Upvotes: 0

Views: 2617

Answers (4)

Trey Huffine
Trey Huffine

Reputation: 242

The best option is to do all the logic in JavaScript and track using an array. Use the DOM only for display purposes and you should see an improvement.

Upvotes: 1

Nanang Mahdaen El-Agung
Nanang Mahdaen El-Agung

Reputation: 1434

If you want to ensure no new element with same position with the elements before, you can create Array to hold the drawn positions and draw new element only if the new position is not exist in the array. Example:

var mouseDown = "no";
var elements = 0;
var elmList = [];

function setYes() {
    mouseDown = "yes";
}

function setNo() {
    mouseDown = "no";
}

document.body.onmousemove = function (e) {
    if ( mouseDown === "yes" ) {
        if ( elements < 4000 ) {
            var offset = (e.clientY - 25) + 'x' + (e.clientX - 25);

            if ( elmList.indexOf(offset) < 0 ) {
                var newCircle = document.createElement("div");
                newCircle.className = "circle";
                newCircle.style.top = e.clientY - 25 + 'px';
                newCircle.style.left = e.clientX - 25 + 'px';

                elements++;

                elmList.push(offset);

                document.getElementById('appendThingsHere').appendChild(newCircle);
            }
        }
    }

}

Upvotes: 0

Juank
Juank

Reputation: 6196

Assuming this is an experiment to tinker with js... you could do this

On the handler where you draw each new div, keep track of the last one drawn

var previousCircle,
    yThreshold = 10,
    xThreshold = 10;
document.body.onmousemove = function(e){

    if(mouseDown === "yes"){
        if(elements < 4000){

        var ty = Math.abs(parseInt(previousCircle.style.top, 10) - e.clientY) < yThreshold;
        var tx = Math.abs(parseInt(previousCircle.style.left, 10) - e.clientX) < xThreshold;

         if (ty && tx){
               // if thresholds pass (new is far away enough from old) then draw a new one
               var newCircle = document.createElement("div");
               newCircle.className = "circle";
               newCircle.style.top = e.clientY - 25 + 'px';
               newCircle.style.left = e.clientX - 25 + 'px';
               previousCircle = newCircle;
         }

You basically decide to draw a new circle or not, based on the distance to the last circle drawn. You can tweak the "decision" with the threshold vars, the threshold condition ìf (ty || tx) or you could even calculate a vector magnitude (radius from center of each circle) to keep things geometrically correct: radius = sqrt( (newY - oldY)^2 + (newX - oldX)^2 ).

Granted, this only tracks drawings in sequence, not previous iterations. For that to work you would need to do collision checking on each draw cycle and that means iterating over all drawn divs and comparing their position to the position of the new circle. This is highly inefficient. You could speed up things a bit if you keep track of drawn circles in a index which avoids querying the DOM, only memory.

var drawnCircles = [];

for (var i in drawnCircles){
    if (Math.abs(drawnCircles[i].top - e.clientY) < yThreshold && //same for x){
        // draw your new circle
        var newCircle = document.createElement("div");
               newCircle.className = "circle";
               newCircle.style.top = e.clientY - 25 + 'px';
               newCircle.style.left = e.clientX - 25 + 'px';
        // and keep track of it
        drawnCircles.push({top: e.clientY, left: e.clientX});
    }
}

Upvotes: 1

sambomartin
sambomartin

Reputation: 6813

You could use document.elementFromPoint(x, y);

Don't think you'd be able to handle multiple elements in a single point though. May have to iterate whilst there is an element at point to either remove or ignore.

Upvotes: 2

Related Questions