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

Centered iframe within a div

I am trying to center my iframe within a white box and need some assistance with this. I want the iframe to be in the middle of the white box rather than its current position at the moment. game1.html: <html> <head> <title>R ...

Overflow of Div Content

I need a way to showcase a collection of around 30 links in a horizontal layout without the links wrapping to a new line if they exceed the width of the parent container. A horizontal scroll should appear for users to navigate through the overflowing links ...

Unable to view cross domain cookies within the browser's development tools

I am currently working on a web application that has an Angular front end running on http://localhost:4200 and a NodeJs backend running on http://localhost:3000. When a user successfully logs in, a cookie is set from the backend containing a token. However ...

Dynamic content alongside a stationary sidebar that adjusts in width

Attempting to create a switchable sidebar (toggling between short and long form) using bootstrap, multiple examples, and online resources. The width of the sidebar changes when toggled, and I want the content to appear next to it regardless of its length. ...

React Native: Picker value remains static

I'm encountering an issue where the value of the picker does not change when I select a new value from it. This problem started occurring after I added the onValueChange function. If anyone has any insights or suggestions on how to resolve this, I wou ...

Modify picture properties when listbox is altered using jQuery

I need to set up a unique album gallery display where different folders are selected based on the item chosen in a selectbox. Below is the HTML code: <select name="album" id="album" onChange="changeimage();"> <option value="0" selected disab ...

Working with the visibility of a button using JavaScript

My goal is to toggle the visibility of a button using JavaScript. Initially, on page load, the button should be hidden. function hideButton(){ var x = document.getElementById('myDIV'); x.style.display = 'none'; } The visibilit ...

Conceal the button briefly when clicked

How can I disable a button on click for a few seconds, show an image during that time, and then hide the image and display the button again? HTML: <input type="submit" value="Submit" onclick="validate();" name="myButton" id="myButton"> <img st ...

Performing automatic submission of form data without needing to redirect or refresh the page using Javascript

I am trying to find a way to automatically submit form post data without the page redirecting, but I haven't had success with any of the examples I've found that involve jquery and ajax. Currently, my code redirects the page: <!DOCTYPE html& ...

Swap out the %20, which signifies a space in the iron router context

I am attempting to substitute the %20, which signifies a space in the URL, with a different character. Router.map(function () { this.route('promos', { path: '/:promo_name', waitOn: function(){ return Meteor.subscribe( ...

Sending a message through Discord.JS to a designated channel

Recently diving into Discord.JS, I am struggling to understand how to make my bot send a message to the General Chat when a new user joins. Many examples I've come across suggest using the following code: const channel = client.channels.cache.find(ch ...

Using the class attribute for Pagedown instead of the id keyword

I am utilizing Pagedown, which necessitates giving the id wmd-input to a textarea. This requirement is outlined in Markdown.Editor.js as follows: function PanelCollection(postfix) { this.buttonBar = doc.getElementById("wmd-button-bar" + postfix); ...

Encountering a problem within a Maven project during execution

Greetings, I am relatively new to maven and seeking some assistance. Recently, my Maven project has started displaying a 404 error on the browser when I attempt to run it. I initially created this Maven project using the webapp archetype and everything w ...

How to Style a Diamond Shape with Content Inside Using CSS

Can someone help me figure out how to create a diamond-shaped background in HTML? I want the diamond shape to contain text and images, similar to what's shown in this screenshot. The example image uses a background image of a diamond, but I'm loo ...

Tips for keeping the header section anchored to the top of the page

I am having trouble getting the menu bar and logo to stick at the top of my header section in the template. I have been trying different solutions, including using the sticky.js plugin for almost 4 days now but it's not working. I also have parallax e ...

Using an array to dynamically input latitude and longitude into a weather API call in PHP

I am currently working on a leaflet map project that showcases the top 10 cities in a selected country. The markers are added dynamically based on the coordinates provided in the $latLng array. For example, when Australia is chosen from the select field, t ...

Integration of Unlayer EmailEditor into React causes fatal errors in the application

I am attempting to integrate Unlayer into my React Application by using this guide: https://github.com/unlayer/react-email-editor. I have configured Webpack for this purpose. However, when I try to import EmailEditor in one of my modules: import React fr ...

Placing an absolutely positioned element on top of other elements

Currently, I am working on a frontendmentor website and encountering difficulty in positioning the shopping cart div above all the other elements. Initially, I attempted to use z-index for this purpose, but it seems that it does not work with elements havi ...

I am facing a dilemma with Expressjs when it comes to managing numerous users simultaneously

I'm grappling with a conceptual dilemma as I delve into the world of building an expressjs app. My goal is to create a system where each user, upon starting the app, has their own temporary folder for storing various files. Despite my lack of experien ...

Tips for embedding the <img> element inside the <a> element

I'm attempting to place an image within a hyperlink tag. Current code: <div class="Sample"> <a href="http://www.Sample.com"> <img src="http://www.Sample.com/Sloth.jpg"> </a> </div> I wish to add <img class= ...