Issue with mouseMove function not aligning correctly with object-fit:contain CSS property

My current code allows users to select a color from an image when hovering over the pixel with the mouse. However, I am encountering an issue where the colors do not map correctly when using object-fit: contain for the image. The script seems to be treating the image as if it is stretched to 100% width / 100% height and not considering the object-fit: contain style.

    <html>
    <head>
    <style>
    *,*:after,*:before{
      -webkit-box-sizing:border-box;
      -moz-box-sizing:border-box;
      box-sizing:border-box;
    }
    
    body{
      width:100%;
      height:100%;
      position:relative;
    }
    
    .thumbnail{
      position:relative;
      display: block;
      overflow:hidden;
      height:100%;
      width:100%;
    }
    
    .thumbnail img {
      display: block;
      cursor: crosshair;
      height: 100%;
      width: 100%;
      object-fit: contain;
    }
    
    #follow {
      position: absolute;
      width: 55px;
      height: 55px;
      border-radius:80%;
      z-index: 99 !important;
      border:2px solid black;
    }
    
    #cs{ 
      display:none;
    }
    
    #color{
      display:none;
    }
    
    }
    </style>
    </head>
    <body>
    <form id=color>
    <input id="hex" type="text"  value="hex">
    </form>
    
    <div class="preview" id="follow"></div>
    <div class="thumbnail">
    
    <img src='[BASE64 IMAGE GOES HERE]'/>       
          </div>
        
          <canvas id="cs"></canvas>
        <script>
        // preview follow mouse
        $(document).mousemove(function(e) {
          $("#follow").css({
            left: e.offsetX,
            top: e.offsetY
          });
        });
        
        // vars
        var img = _('.thumbnail img'),
            canvas = _('#cs'),
            preview = _('.preview'),x = '',y = '';
        
        // click function
        img.addEventListener('click', function(e){
          // chrome
          if(e.offsetX) {
            x = e.offsetX;
            y = e.offsetY; 
          }
          // firefox
          else if(e.layerX) {
            x = e.layerX;
            y = e.layerY;
          }
          useCanvas(canvas,img,function(){
            // get image data
            var p = canvas.getContext('2d')
            .getImageData(x, y, 1, 1).data;
            // show info
         
        color.innerHTML = '<textarea id="hex" type="text"  >'+rgbToHex(p[0],p[1],p[2])+'</textarea>';
        
          });
        },false);
        
        // preview function mousemove
        img.addEventListener('mousemove', function(e){
          // chrome
          if(e.offsetX) {
            x = e.offsetX;
            y = e.offsetY; 
          }
          // firefox
          else if(e.layerX) {
            x = e.layerX;
            y = e.layerY;
          }
          
          useCanvas(canvas,img,function(){
            
            // get image data
            var p = canvas.getContext('2d')
            .getImageData(x, y, 1, 1).data;
            // show preview color
            preview.style.background = rgbToHex(p[0],p[1],p[2]);
          });
        },false);
        
        
        // canvas function
        function useCanvas(el,image,callback){
          el.width = image.width; // img width
          el.height = image.height; // img height
          // draw image in canvas tag
          el.getContext('2d')
          .drawImage(image, 0, 0, image.width, image.height);
          return callback();
        }
        // short querySelector
        function _(el){
          return document.querySelector(el);
        };
        
        // convert rgba to hex 
        // http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
        function componentToHex(c) {
          var hex = c.toString(16);
          return hex.length == 1 ? "0" + hex : hex;
        }
        function rgbToHex(r, g, b) {
          return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
        }
        
        function findPos(obj) {
            var curleft = 0, curtop = 0;
            if (obj.offsetParent) {
                do {
                    curleft += obj.offsetLeft;
                    curtop += obj.offsetTop;
                } while (obj = obj.offsetParent);
                return { x: curleft, y: curtop };
            }
            return undefined;
        }
        </script>
        
        </body>
        </html>

Answer №1

A possible reason for this issue is that the code utilizes an unscaled canvas duplication of the image.

To resolve this, it is recommended to consistently display the image at a 100% scale rather than using fit. Enable the ability to pan across the image if necessary, allowing users to interact with any part of it. (Adjusting the mouse event's xy coordinates by subtracting the offset dimensions of the pan may be required.)

Another approach could involve detecting the resized scale and applying it as a multiplier when utilizing canvas, though this method may introduce inaccuracies due to rounding errors.

Additionally, consider preventing browsers from smoothing the displayed image in order to avoid rendering non-existent pixels: apply image-rendering: pixelated. More information can be found at https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering

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

How can I extract text from nested HTML elements with a <a href> tag using the Jericho library?

Here is a snippet of my HTML code: <div class="itm hasOverlay lastrow"> <a id="3:LE343SPABGLIANID" class="itm-link itm-drk trackingOnClick" title="League Sepatu Casual Geof S/L LO - Hitam/Biru" href="league-sepatu-casual-geof-sl-lo-hitambiru-6816 ...

Troubleshooting Jqgrid Keyboard Navigation Problem

Here is a link to the jsfiddle code snippet. Upon adding jQuery("#grid").jqGrid('sortableRows'); into my JavaScript code, I encountered an issue where keyboard navigation no longer worked after sorting rows Below is the JavaScript code snippet: ...

Can cucumber steps be executed conditionally within a single scenario?

I would like to streamline my testing process by using one feature file for both desktop and mobile tests. I am looking to run two separate tests, with one tagged as @mobile and the other as @desktop. By doing this, I can avoid creating a duplicate feature ...

Exploring the global document object within Next.js

We have been working on a project using nextjs and are facing an issue with changing the styling of a button upon click. Despite using document.getElementById, we are unable to change the styling no matter what we try. pages/index.js function Index() { ...

Get JSON data through AJAX using two different methods

Help needed: JSON request issue with XMLHttpRequest var xhr = new XMLHttpRequest(); function elenco_studenti() { var url = "/controller?action=student_list"; xhr.responseType = 'text'; xhr.open("GET", url, true); xhr.onreadystat ...

Enabling table row scrolling with keyboard navigation in React

Struggling to figure out how to make my table scroll while navigating through the rows using the onKeyDown event. It seems that the event isn't updating when using the keyboard, even though the highlighting of the selected row with selected is working ...

Plugin for creating a navigation bar with a jQuery and Outlook-inspired style

Our team is considering transitioning our asp.net forms application to MVC. Currently, we utilize outlook-style navigation with ASP controls such as listview and accordion, using code referenced here. Are there any jQuery/CSS controls available for MVC t ...

Chrome's keyup event restricts the use of arrow keys in text fields

Could you please test this on Google Chrome browser: jQuery('#tien_cong').keyup(function(e) { jQuery(this).val(jQuery(this).val().replace(".", ",")); var sum = 0; var tien_cong = jQuery('#tien_cong').val(); tien_cong = tien_ ...

Trouble arises when implementing personalized buttons on the Slick JS slider

Are you struggling to customize buttons for your Slick Slider JS? I am facing a similar issue with applying my own button styles to the slider. I am interested in using arrow icons instead of the default buttons. Here is the HTML code snippet: <secti ...

Method for extracting URL parameters while utilizing a hash within the URL

I've been exploring AJAX with hash in URL using prototypejs. Consider the following URL: http://example.com/#/example/104?v=0&d=a&rpp=10 print_r( $_GET ); // output: array() However, when I try this URL: http://example.com/example/104?v= ...

Struggling to synchronize animation timing between elements using jquery

When you navigate to an album (for example, Nature because I'm still working on the others) and select one of the images, they all gradually fade out while the selected image appears on the screen. What's actually happening is that the selected i ...

Displaying buttons within a component's onPress function will reveal the most recent information. Utilizing React-N

Currently, I am working on loading a component that contains an array from redux (for example, test). I have successfully created buttons with the correct titles, however, there seems to be an issue with the onPress function not displaying the expected v ...

Animations in Angular fail to operate within mat-tabs after switching back when custom components are being utilized

I am facing a similar issue as Olafvv with my angular 16 project. The problem occurs in a mat-tab-group where the :enter animations do not work when navigating away from a tab and then returning to it. However, in my case, the issue lies within a custom su ...

Having trouble configuring bcryptjs in a React.js project

I have been working on setting up a single registration page within a react component. However, I encountered an issue when trying to hash the password before sending the response to my back-end. I am puzzled as to why the code snippet below is not functi ...

Issue with conflicting trigger events for clicking and watching sequences in input text boxes and checkboxes within an AngularJS application

When creating a watch on Text box and Check box models to call a custom-defined function, I want to avoid calling the function during the initial loading of data. To achieve this, I am using a 'needwatch' flag inside the watch to determine when t ...

Issue with scroll down button functionality not functioning as expected

Is there a way to create a simple scroll down button that smoothly takes you to a specific section on the page? I've tried numerous buttons, jQuery, and JavaScript methods, but for some reason, it's not working as expected. The link is set up co ...

Receiving a "Undefined index" error while passing information to a PHP script via jQuery

I have extensively researched this issue, including reading numerous StackOverflow questions, but I am still unable to find a solution. My problem involves retrieving the 'id' attribute value of an HTML 'a' element with jQuery when the ...

managing nested JSON arrays in JavaScript

I have a straightforward task with handling a simple array that is divided into two parts: a group of vid_ids and a single element named page. Initially, I was iterating through the vid_id array using a for loop. However, upon adding the page element, I en ...

Monitoring changes to an array of objects in AngularJS within a Select tag using the ng-repeat directive

My goal is to monitor select tags using ng-repeat and disable the save button. My current setup includes: Initially, I will have three select boxes with values. The user must select at least one value from these boxes to enable the Save button. The u ...

Within jQuery lies the power to perform multiplication operations effortlessly

I'd like to accomplish this using jQuery: var menuItems = document.getElementsByTagName("li"); for (var k = 0; k < menuItems.length; k++) { if (menuItems[k].className == "menu") { var child = menuItems[k].firstChild; if ...