Sketch a bounding box around an image displayed within a modal

I am a JavaScript beginner and currently working on a small code project that involves displaying an image inside a modal. I am attempting to draw a bounding box over the image.

Below is the code snippet I've used to try drawing the bounding box:

HTML: (modal code for displaying the image)

<div id="myModal" class="modal">

 <!-- The Close Button -->
 <span class="close">&times;</span>

 <!-- Modal Content (The Image) -->
 <div id="imagearea" class="imagearea">
 <img class="modal-content" id="img01">
 </div>

</div>

Javascript: (logic attempted for drawing the bounding box over the image)

 initDraw(document.getElementById('imgarea'));

function initDraw(imgarea) {
    var mouse = {
        x: 0,
        y: 0,
        startX: 0,
        startY: 0
    };
    function setMousePosition(e) {
        var ev = e || window.event; //Moz || IE
        if (ev.pageX) { //Moz
            mouse.x = ev.pageX + window.pageXOffset;
            mouse.y = ev.pageY + window.pageYOffset;
        } else if (ev.clientX) { //IE
            mouse.x = ev.clientX + document.body.scrollLeft;
            mouse.y = ev.clientY + document.body.scrollTop;
        }
    };

    var element = null;
    imgarea.onmousemove = function (e) {
        setMousePosition(e);
        if (element !== null) {
            element.style.width = Math.abs(mouse.x - mouse.startX) + 'px';
            element.style.height = Math.abs(mouse.y - mouse.startY) + 'px';
            element.style.left = (mouse.x - mouse.startX < 0) ? mouse.x + 'px' : mouse.startX + 'px';
            element.style.top = (mouse.y - mouse.startY < 0) ? mouse.y + 'px' : mouse.startY + 'px';
        }
    }

    imagearea.onmouseup = function (e) {
        if (element !== null) {
            element = null;
            imagearea.style.cursor = "default";
            console.log("finished.");
        } }
        imagearea.onmousedown = function (e) {
          if(element==null){
            console.log("started.");
            mouse.startX = mouse.x;
            mouse.startY = mouse.y;
            element = document.createElement('div');
            element.className = 'rectangle'
            element.style.left = mouse.x + 'px';
            element.style.top = mouse.y + 'px';
            imagearea.appendChild(element)
            imagearea.style.cursor = "crosshair";
            e.preventDefault();
          }
        }
      }

CSS: (for styling the bounding box)

 .rectangle {
      border: 10px solid red;
      position: absolute;
  }
  .imagearea {
     display: flex;
     flex-direction: column;
     float: left;
     width: 35%;
     max-width: 700px;
     position: relative;
    }
    #img01{
     position: absolute;
     }

The above code successfully displays the image in a modal, and when trying to draw the bounding box, the cursor changes to crosshair as intended. However, the issue I'm encountering is that the bounding box I draw over the image is not visible, even though the cursor changes. Any help or guidance would be greatly appreciated. Thank you!

Answer №1

There are a couple of issues.

  1. You cannot add child elements to an <img> tag.

  2. Your calculations rely on the viewport, while the CSS for borders is in relation to the image itself. There are several ways to address this, with one quick solution being to subtract the image's position from the mouse position, like so:

function adjustMousePosition(e) {
    // your mouse calculations

    const limits = e.currentTarget.getBoundingClientRect();

    mouse.x -= limits.left;
    mouse.y -= limits.top;
}

Additionally, remember to call adjustMousePosition() within your mousedown event handler.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the alternative method to clicking right in Selenium without utilizing JavaScript and fireEvent()?

I am trying to perform a right click on a context menu in a Selenium test. I attempted to use fireEvent but was unsuccessful as I am not familiar with JavaScript. Can anyone provide guidance on how to successfully execute a right click in Selenium? Thank ...

Using npm webpack-mix to execute a JavaScript function stored in a separate file

Currently, I am facing a challenge with accessing a function that is defined in the table.js file from within my index.html. Here is a snippet of the code: table.js let table; function set_table(table) { this.table = table; consol ...

The Node.js timestamp is later than the current date of the client

When storing data in MongoDB with the recording date, I utilize new Date() in Node.js and return that date with an AJAX response. To calculate the elapsed time from when the data was stored in MongoDB, I create a new date on the client-side. Then, I determ ...

What are the steps to transform my database object into the Material UI Table structure?

I have a MongoDB data array of objects stored in products. The material design format for creating data rows is as follows: const rows = [ createData('Rice', 305, 3.7, 67, 4.3), createData('Beans', 452, 25.0, 51, 4.9), createData ...

CSS Challenge: How to crop an image without using its parent container directly

I'm currently facing a complex CSS challenge that I can't seem to solve. I want to create an image controller (two-by-two layout on two lines) that can display: The top-left image in full size, The top-right with horizontal scrolling, The botto ...

Using Ruby instead of Javascript in lessc

My CSS is compiled in a node application using lessc. LESS was installed via NPM. When I check the current version of lessc --version it shows lessc 1.3.3 (LESS Compiler) [Ruby] 2.3.2 How can I change it to display lessc 1.3.0 (LESS Compiler) ...

What is the best way to validate email addresses in Vue.js using watchers?

watch: { email(value) { this.email = value; this.validateEmail(value); }, }, methods() { validateEmail() { // eslint-disable-next-line if (/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<> ...

Aligning a Material UI button to the far right of a row

I am struggling to align a React material-ui button to the right-most of the page and despite trying to use the justify="flex-end" attribute within the following code, it doesn't seem to be working: <Grid item justify="flex-end" ...

Ensure that both textarea and pre elements have equal dimensions and line wrapping behavior in Internet Explorer

I am in the process of implementing a dynamic textarea that resizes automatically, based on a technique discussed in this article: Alistapart: Expanding Textareas (2011). The idea is quite straightforward: by using a pre element to mirror the input in the ...

How come jQuery each is failing to iterate through all JSON items from two functions simultaneously with $.when?

After checking with the Chrome Network inspector, it appears that the json returns from both ajax functions are downloading completely. However, there seems to be an issue with the jQuery each function as it is only going through the first three items of t ...

Error encountered when attempting to load image from URL in domain

Why won't the image load on my domain? The image loads fine on other domains, but not mine Is there a problem with my domain? var textureLoader = new THREE.TextureLoader(); textureLoader.crossOrigin = ''; var map = textureLoader.load(&apos ...

Unable to save the session identifier from the response headers while utilizing sessions in react/frappe framework

I am attempting to retrieve the session id (sid) from the response headers in a unique scenario. My client application is situated on a local environment, while my API is hosted on an ERP Next server. Upon sending a login request from the React app, I am ...

Tips for optimizing SVG icon caching on an external CDN without encountering flash of missing icons

I've mastered the process of getting SVG icons to load on my website, but I am facing a challenge in meeting all the criteria listed below: Need to be able to use SVG icons in CSS Avoid any flash of missing icons (FOMI) Minimize the initial page siz ...

Opting for PHP over JSON in a jQuery live search code

Is it possible to modify my jQuery Google Instant style search script to pull content from a PHP script instead of using the BingAPI? Below is the current code being used: $(document).ready(function(){ $("#search").keyup(function(){ var searc ...

Updating state in React using the spread operator is not allowed

As a newcomer to React, I've been struggling with using the spread operator to push new elements into an array stored in the state. My aim is to create an array with a sequence of different numbers. Here's the code snippet that I've been wor ...

Variable in v-for loop is not properly declared

Currently, I am attempting to iterate through an array of objects retrieved from the backend and display these objects on the frontend. The Vue framework is throwing an error stating that "event" is not defined on the instance but referenced during render. ...

Creating a JavaScript regular expression for formatting time input without using any external plugin

As I work on implementing a time input mask with the meridian of am|pm without using an input mask plugin, I've encountered some challenges. The input should not allow the user to start with alphabets, but my current pattern, although it works, clears ...

Align container to the very edge of the browser window

I am having an issue with a div that extends to the edge of the browser, and I want to add content that is aligned to the center of the page within a container. I tried using Bootstrap by creating a row with col-md-6 filled with a background color, but whe ...

Repeating every other item in a list using ng-repeat in AngularJS

Using AngularJS version 1.5.3 In my view, I have a list of items that I want to display. After every two items, I would like to show a new div below the first one. <div class="col text-center" ng-repeat="event in weekDay.events"> &nbsp;& ...

Leveraging Angular and Firebase to integrate data with iframes for various platforms such as

Currently, I am in the process of creating an application using Angular and Firebase as the backend. I have a question regarding the data section - is it possible to include iframe code in this section and then connect it to my view using ng-bind-html? Th ...