dimanche 21 février 2021

Changing element position while window resize with overlap checking

I'm completely stuck.

I've got a container where I randomly creating a five span elements (dice) with overlap checking.

Here you can find container CSS:

&__dice {
    position: relative;
    height: 200px;
    background-color: rgb(3, 70, 3);

    @include mq(mobileLarge) {
        height: calc(100% - 37.5px);
    }
}

I'm using position: absolute for each span element to place them inside the board (container).

And here JS code:

  1. createDice
    createDice(die, positions, dieIndex) {
        const span = document.createElement("span");
        positions = this.addRandomPosition(positions);
        span.classList.add("dice-area__die", "fas", this.diceClasses[die]);
        span.style.left = positions[dieIndex].posX + "px";
        span.style.top = positions[dieIndex].posY + "px";
        span.setAttribute("data-die", dieIndex);
        span.setAttribute("data-choose", "noChoose");
        return span;
    }

die is die number which is changing to span element and position is empty array.

  1. addRandomPosition
    addRandomPosition(positions) {
        let posX = 0;
        let posY = 0;
        
        const maxBoardWidth = this.getBoardWidth();
        const maxBoardHeight = this.getBoardHeight();

        do {
            posX = Math.floor(Math.random() * (maxBoardWidth - this.dieSize));
            posY = Math.floor(Math.random() * (maxBoardHeight - this.dieSize));
        } while (this.checkOverlapping(posX, posY, positions));

        positions.push({ posX, posY });
        return positions;
    }
  1. chceckOverlapping

    checkOverlapping(pX, pY, positions) {
        for (let i = 0; i < positions.length; i++) {
            const newPosX = pX;
            const oldPosX = positions[i].posX;
            const rightNewPosX = pX + (this.dieSize + 5);
            const rightOldPosX = positions[i].posX + (this.dieSize + 5);
            const newPosY = pY;
            const oldPosY = positions[i].posY;
            const bottomNewPosY = pY + (this.dieSize + 5);
            const bottomOldPosY = positions[i].posY + (this.dieSize + 5);

            if (rightNewPosX < oldPosX || newPosX > rightOldPosX || newPosY > bottomOldPosY || bottomNewPosY < oldPosY) {
                continue;
            }
            return true;
        }
        return false;
    }

The problem is, that positions I've created are "permanent". When I resize the window, container width (and height in two breakpoints) are changing but my positions are still the same.

I've got two breakpoints when I'm changing whole container - (min-width: 1024px) and (min-width: 800px). In that breakpoints my container changing width and height (height is constant -> 400px and 200px for each breakpoint).

I tried to use matchMedia, addEventListener("resize") and addEventListener("change") for matchMedia inside createDice and addRandomPosition function, but I've always got an infinite loop.

So, my question is: How to change positions of those five span elements, when I resize the window but with overlap checking?

I don't want to change X and Y position every time I resize the window. That means:

  1. Change X position (if it's necessary, for example, when one die is near the board border), but here dice must stop changing X position when they found left board border + elements can't overlap themselves.
  2. Change X and Y position when window break the breakpoints.



Aucun commentaire:

Enregistrer un commentaire