JavaScript Math Issues

  Kiến thức lập trình

So I’m building a ‘radar’ for a game. It consists of a background png and some JavaScript code that allows the user to click and drag to draw a line. Now the code is meant to display the ‘heading’ of the line. If anyone fancies aviation, you know that planes fly in headings like a compass. This radar is meant to do that, but for some reason the code that I used, when I drag the mouse perpendicularly upwards, the heading displays 180 when it should be 360/000 degrees (north), when I drag to the right the heading is 090, which is correct, when I drag downwards the heading is 360/000 when it should be 180 degrees (south), and when I drag the heading to the left the heading is correct. So it seems like the “compass” is flipped vertically. The range should be 360 degrees moving clockwise. Can anyone help? I’m pretty new to coding. The site is running on GitHub and has the necessary png, css and html files.

Here is the JavaScript code:

const radar = document.getElementById('radar');
let isDragging = false;
let startX, startY, line, headingText;

function removeExistingLineAndHeading() {
    if (line) {
        radar.removeChild(line);
        line = null;
    }
    if (headingText) {
        radar.removeChild(headingText);
        headingText = null;
    }
}


radar.addEventListener('dragstart', (e) => {
    e.preventDefault();
});

radar.addEventListener('mousedown', (e) => {
    removeExistingLineAndHeading();

    const rect = radar.getBoundingClientRect();
    startX = e.clientX - rect.left;
    startY = e.clientY - rect.top;
    isDragging = true;

    line = document.createElement('div');
    line.className = 'line';
    line.style.left = `${startX}px`;
    line.style.top = `${startY}px`;
    radar.appendChild(line);

    headingText = document.createElement('div');
    headingText.className = 'heading';
    radar.appendChild(headingText);
});

radar.addEventListener('mousemove', (e) => {
    if (!isDragging) return;

    const rect = radar.getBoundingClientRect();
    const currentX = e.clientX - rect.left;
    const currentY = e.clientY - rect.top;

    const deltaX = currentX - startX;
    const deltaY = currentY - startY;

    const length = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
    let angle = Math.atan2(deltaY, deltaX) * (180 / Math.PI);

    if (angle < 0) {
        angle += 360;
    }

    
    angle = (90 - angle + 360) % 360;

    line.style.width = `${length}px`;
    line.style.transform = `rotate(${angle}deg)`;

    
    displayHeadingText(angle, (startX + currentX) / 2, (startY + currentY) / 2);
});

radar.addEventListener('mouseup', () => {
    if (isDragging) {
        isDragging = false;
    }
});

radar.addEventListener('mouseleave', () => {
    if (isDragging) {
        isDragging = false;
        removeExistingLineAndHeading();
    }
});


function padNumber(number) {
    return number.toString().padStart(3, '0');
}


function displayHeadingText(angle, midX, midY) {
    if (!headingText) {
        headingText = document.createElement('div');
        headingText.className = 'heading';
        radar.appendChild(headingText);
    }

    headingText.textContent = `${padNumber(Math.round(angle))}°`;
    headingText.style.left = `${midX}px`;
    headingText.style.top = `${midY}px`;
}

Here’s the HTML code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ATC Radar</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div id="radar">
        <div id="map-container">
            <div class="map-background"></div>
            <img id="map" src="map.png" alt="Game Map">
        </div>
    </div>
    <script src="script.js"></script>
</body>
</html>

Here’s the CSS code:

body {
    margin: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    background-color: #f0f0f0;
}

#radar {
    position: relative;
}

#map-container {
    position: relative;
    overflow: hidden; 
}

#map {
    display: block;
    border: 2px solid black; 
    background-color: black; 
    position: relative;
    z-index: 1; 
}

.map-background {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: black;
    z-index: 0; 
}

.line {
    position: absolute;
    height: 4px;
    background-color: yellow; 
    transform-origin: top left;
    z-index: 2; 
}

.heading {
    position: absolute;
    background-color: white;
    padding: 2px 5px;
    border: 1px solid black;
    border-radius: 3px;
    transform: translate(-50%, -50%);
    z-index: 3; 
}

New contributor

p1anes is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Theme wordpress giá rẻ Theme wordpress giá rẻ Thiết kế website

LEAVE A COMMENT