skip to Main Content

I need to calculate the exact location of a point to be drawn on an image. I noticed that there is some padding around the container in which the image is placed, as shown below:

The outer div with the padding

And this is the image of the div which holds the image:

The inner div which holds the image

So if we calculate the differences it will be:

  • left padding: 2560 – 2544 = 16
  • top padding: 509.15 – 493.15 = 16

I need to get the exact padding to calculate the right offset I need to use to correct the point location on the image, or preferably, to set this offset to 0.

Below is a sample code I used to produce this images:

Script:

<script lang="ts">
    const img =  `https://raw.githubusercontent.com/lieldvd/mturk/main/15545/frame_0.jpg`
    const leftPadding = 16;
    const topPadding = 8;
    const markLocation = (x: number, y: number) => {
        const mrkr = document.querySelector<HTMLElement>(".marker");
        console.log('marking')
        if (mrkr != null){
            mrkr.style.left = String(x) + '%';
            mrkr.style.top = String(y) + '%';
        }
    }

    function onClick(event: any){
        // Image container

        var videoContainer = document.getElementsByClassName("videoContainer")[0].getBoundingClientRect();
        const videoContainerWidth = videoContainer.width + leftPadding;
        const videoContainerHeight = videoContainer.height + topPadding;

        const clientX = event.clientX;
        const clientY = event.clientY;

        let clientXPct = 100 * clientX / videoContainerWidth;
        let clientYPct = 100 * clientY / videoContainerHeight;

        markLocation(clientXPct, clientYPct);
    }

</script>

Main:

    <div class="videoContainer">
        <h1><u>Training Guidelines</u></h1>
        <h1><u>Training Guidelines</u></h1>
        <h1><u>Training Guidelines</u></h1>
        <h2>Welcome to the "Contact Tagging" Training</h2>
        <!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
        <!-- svelte-ignore a11y-click-events-have-key-events -->
        <img 
            class="videoCanvas"
            src={img} 
            alt='Blank' 
            on:click|preventDefault={(e)=>onClick(e)}
        />
        <span class="marker"></span>
    </div>
</main>

Style:

<style>
    .mainContainer {
        padding-left: 0;
    }
    main {
        text-align: center;
        padding: 0em;
        max-width: 240px;
        margin: 0 auto;
    }
    @media (min-width: 640px) {
        main {
            max-width: none;
        }
    }   
    .videoContainer{
    /* This enables children to use position: absolute to be positioned using absolute coordinates relative to this element. */
        position: relative;

        margin: 0;
        padding-left: 0px;
        border: 1px solid black;
        width: 100%;
        height: 100%;
        box-sizing: border-box;
        -moz-box-sizing: border-box;
        -webkit-box-sizing: border-box;
    }
    .marker{
        
        /* Here we position this element relative to the .container element. */
        position: absolute;
        left: -50%; /* Update this using JS when the user clicks. */
        top: -50%; /* Update this using JS when the user clicks. */
        
        /* left and top indicates the position of the top left corner. 
        You probably want it to be centered at that position. 
        So translate (move it) 50% of it's size up and to the left. */
        transform: translate(-50%, -50%);
        
        /* Make it look like a circle. */
        width: 5px;
        aspect-ratio: 1;
        border-radius: 100%;
        background-color: red;
    }

</style>

2

Answers


  1. Chosen as BEST ANSWER

    Found a way to correct the point by accounting to the offset of the div that include the image and the image itself.

    The corected onClick function:

    function onClick(event: any){
        // Image container
        var videoContainer = document.getElementsByClassName("videoContainer")[0].getBoundingClientRect();
    
        const clientX = event.clientX;
        const clientY = event.clientY;
            
        // Video element
        var videoElement = document.getElementsByClassName("videoCanvas")[0].getBoundingClientRect();
        let imageTopLeftX = videoElement.left
        let imageTopLeftY = videoElement.top
           
        clickP.x = Math.floor(clientX - imageTopLeftX);
        clickP.y = Math.floor(clientY - imageTopLeftY);
            
        var leftPadding = (videoContainer.width - videoElement.width) / 2;
        var topPadding = (videoContainer.height - videoElement.height) / 2;
    
        var clientXPct: number = 100 * ((clickP.x + leftPadding) / videoContainer.width);
        var clientYPct: number = 100 * ((clickP.y + topPadding) / videoContainer.height);
            
        markLocation(clientXPct, clientYPct);
    
        pause()
    
    }
    

  2. The body tag basically has a margin of 8px.

    Usually, use reset css.
    Try it.

    Declaring after reset is applied first, so you can customize it.

    html, body { margin: 0; padding: 0; }
    body { margin-left: 20px; }
    <html>
      <body>
        Something
      </body>
    </html>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search