Creating a Custom Container to perfectly Fit an Image

I am currently utilizing heatmap.js within Google Apps Script and I'm facing the challenge of resizing the heatmap canvas to match an image. Is there a way to modify the javascript or styling to achieve this functionality?

CODE: https://jsfiddle.net/nateomardavis/51h2guL9/

  • The wrapper is outlined in black.
  • The heatmap div has a blue border.
  • The canvas border is red.

Desired Functionality: The objective is to mark the heatmap on any part of the image. The wrapper, heatmap div, and canvas should all be sized proportionally to the image dimensions.

Current Behavior: Presently, I can only place markers within the confines of the blue/black borders. While my javascript resizes the canvas based on the image, it does not adjust to fit the heatmap boundaries.

Attempts Made: In the provided fiddle, you can observe my efforts to alter the sections that the javascript is resizing (lines 88-90). I also considered using the image as the background for the heatmap div, but the sizing was inaccurate, and I preferred the capability to save the heatmap and image together as one layer. Adjusting the image size (line 101) resulted in cutoffs beyond 55%.

The screenshot below serves purely for reference; the complete code is available in the fiddle. The usage of HTML encompasses everything due to its compatibility with Google Apps Script.

https://i.sstatic.net/JMy3m.png

 <!DOCTYPE html>
    <html>
  <head>
    <base target="_top">
    <script type="text/javascript" src="https://www.patrick-wied.at/static/heatmapjs/assets/js/heatmap.min.js"></script>
   <style>

   html, body {
     width:  100%;
     height: 100%;
  }

  html { 
    color: #333;
    font-family: sans-serif;
    font-size: 16pt;
    font-weight: 100;
    line-height: 1.5em;
  }

  .wrapper { 
    width: 100%; 
    height:100%; 
    background:rgba(0,0,0,.03); 
    border:3px solid black; 
  }

  .heatmap { 
    width:100%; 
    height:100%;
    background-position: top;
    background-repeat: no-repeat;
    background-size: contain;
    position: relative;
    border:3px solid blue; 
 }

 .canvas {
   border:3px solid red; 
 }

  </style>

  </head>

 <body>
   <button class="clear">Clear</button>
   <button onclick="printPage()" class="print-btn no-print" style="">Print</button>
   <p id="coords"></p>
    <div id="wrapper" class="wrapper"> <!-- black box on web app-->
      <div id="heatmap" class = "heatmap" style="position: relative;"> <!-- blue box on web app-->
      <canvas id="canvas" class="canvas"></canvas> <!-- red box on web app-->
    </div> 
  </div>


<script>



//CREATE HEATMAP
  window.onload = function() {
    var heatmapInstance = h337.create({
      container: document.querySelector('.heatmap'),
      gradient: {
        '.25': 'black',
        '.5': 'red',
        '.75': 'white'
      },
      radius: 20
    });

    document.querySelector('.wrapper').onclick = function(ev) {
      heatmapInstance.addData({
        x: ev.layerX,
        y: ev.layerY,
        value: 1
      });
    };

     document.querySelector('.clear').onclick = function() {
       //heatmapInstance._renderer._clear();
       heatmapInstance.setData({data:[]}); 
      };

//RESIZE CANVAS TO FIT IMAGE
  //http://jsfiddle.net/6ZsCz/1135/
  var canvas = document.getElementById('canvas');  //v1
  //var canvas = document.getElementById('heatmap'); //v2
  //var canvas = document.getElementById('wrapper');  //v3
    var ctx = canvas.getContext('2d');
      ctx.canvas.width  = window.innerWidth;
      ctx.canvas.height = window.innerHeight; 
    var imageObj = new Image();


  imageObj.onload = function() {
    canvas.width = imageObj.width; // version 2
    canvas.height = imageObj.height;  // version 2  
    ctx.drawImage(imageObj,0,0); // version 2
    //ctx.drawImage(imageObj, 0, 0, imageObj.width * 0.5, imageObj.height * 0.5); //version 1

  };
  imageObj.src = 'https://upload.wikimedia.org/wikipedia/commons/thumb/8/82/Soccer_Field_Transparant.svg/1200px-Soccer_Field_Transparant.svg.png';

 };


//MOUSE COORDINATES
//works inside heatmap
  function getCursorPosition(canvas, event) {
    const rect = canvas.getBoundingClientRect()
    const x = event.clientX - rect.left
    const y = event.clientY - rect.top
    var coor = "X coords: " + x + ", Y coords: " + y;
    document.getElementById("coords").innerHTML = coor;
  }

  const canvas = document.querySelector('.heatmap')
  canvas.addEventListener('mousedown', function(e) {
    getCursorPosition(canvas, e)
  })


  function printPage() {
    window.print();
  }

     </script>

  </body>

</html>

Answer №1

After experimenting with different methods, I finally cracked the code and found the solution: https://jsfiddle.net/nateomardavis/p1kwrhmv

  1. To achieve the desired effect, I utilized the img element and applied a background-image using CSS.
  2. Next, I adjusted the heatmap layer to relative positioning while setting the image layer to absolute, following the guidance provided HERE.
  3. Finally, I styled the image layer's CSS properties according to the method described HERE.

    .heatmap {
      background-size: contain;
      background-repeat: no-repeat;
      width: 100%;
      height: 300%; /*adjust if image exceeds screen size */
      position: relative;
    }
    
    .backgroundIMG {
      background-image: url('https://upload.wikimedia.org/wikipedia/commons/thumb/8/82/Soccer_Field_Transparant.svg/1200px-Soccer_Field_Transparant.svg.png');
      background-size: contain;
      background-repeat: no-repeat;
      position: absolute;
      width: 100%;
      height: 0;
      padding-top: 151.33%;
    }
    

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

Use Node and Express with JavaScript to store HTML form data in JSON format within a .json file

Just starting out with node and express. I am capturing user input from an HTML form and attempting to append or push it in a .json file. I tried using the jsonfile npm package but the data is not being stored in an array format in the JSON file. Here is ...

What is the best way to stack columns on small screens in a single row?

While utilizing the default bootstrap col classes, I noticed that when I reduce the grid to mobile size, the columns span the entire width of the row. This results in a long vertical list of items on mobile devices, even though there is sufficient space on ...

How to add an element to an array with a function in ExtJS

I am looking to add an element to the drawnShapes array within the draw() function and the getDrawnShapesCount() function should return the total number of shapes drawn The drawnShapes variable represents an array of shapes Ext.define('Shape', ...

The process of loading stylesheets and JavaScript is experiencing excessive delays

How can I improve website loading speed? <head> <title>NCI SwitchGears</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="boot ...

What is the reason that the CSS3 property name 'filter' is not recognized in Windows 8 applications?

I'm in the process of adapting my own codepen for a Windows 8 desktop app. Everything runs smoothly on Codepen, with the exception of some CSS adjustments from -webkit- to -ms-. However, I encountered an issue regarding this specific line in the CSS s ...

The setInterval function continues executing even after the page has been changed

I'm encountering an issue with my function where it continues to run even after the page has changed, resulting in an error. How can I go about stopping this behavior? Thank you! componentDidMount() { var current = 0; var slides = document.g ...

Creating a child div that is half the size of its parent

Is there a way for a child div to inherit half the width and half the height of its parent div without using specific values or viewport units? ...

I am experiencing difficulty in loading JS files within a Django template

I am encountering an issue with my Django project. While my static files for images and CSS are loading correctly, the JavaScript files are not. I have created a folder named "static" within my app with the following structure: static/js/my_app/, where my ...

What is the process for implementing filtered HTML attributes in a directive?

I’ve created a custom directive that generates a popup menu by extracting data from HTML content. The purpose is to transform a group of Bootstrap carousel-compatible elements into a structured list. However, each .item element contains an attribute with ...

Electron Developer: "An issue has occurred within the primary process - Callback function missing"

My Electron application runs smoothly when launched from the command line with npm start. However, I am now looking to distribute the application as user-friendly installers for Mac/Windows/Linux. To achieve this, I am utilizing Electron-Builder for packag ...

An issue arises with the Datatables destroy function

Utilizing datatables.js to generate a report table on my page with filters. However, when applying any of the filters, the data returned has varying column counts which prompts me to destroy and recreate the table. Unfortunately, an error message pops up ...

How about using AngularJS with JavaScript modules?

I have an old AngularJS app (using version 1.2) and I am trying to organize my code into JavaScript modules. However, I am struggling to figure out how to define the controller as a function within the module. In other words, I want to transition from: & ...

The issue with JSON and asynchronous JavaScript requests

I've been trying to work on this for hours, but I can't seem to figure it out by myself. For a project, I need to use JSON, and even though I was able to make it work, the data is not being returned to the correct JSP; instead, it's just di ...

Error message "TypeError: onClick is not a function" occurs when attempting to use a prop in a functional component

I am encountering issues while trying to utilize the onclick function as props. It shows an error message 'TypeError: onClick is not a function' when I click. What should I do? 7 | <Card 8 | onClick={() => onClick(dish ...

What causes inline-blocks to malfunction after a non-breaking space is inserted?

Here is some HTML code: <p id='one'>Hello World how are you.&nbsp;<span>Entrepreneur</span></p> <p>Hello World how are you.&nbsp;<span>Entrepreneur</span></p> Below is some CSS styling: ...

Seeking a template for a server-side programmer who lacks proficiency in CSS and design?

Hey there all you wise folks! So here's the deal - I'm a PHP/JavaScript wizard when it comes to logic and server-side stuff, but I really suck at design, CSS, and all things arty. Does anyone have any recommendations for a template or tool that ...

Encountered an error while trying to deploy Node.js on Heroku: TypeError - Unable to access property 'split' of null

Seeking insight into the following error message: My application is built on Node.js and uses Atlas as its database. However, when attempting to deploy it on Heroku, I encounter the following error in the logs: TypeError: Cannot read property 'spl ...

Transfer data as JSON from Flask to JavaScript

Having trouble sending data from Flask to JavaScript. I have the information from the database and added it to a dictionary. Now, I want to convert this data into a JSON object in JavaScript to display it on a map. Despite using JSON.parse in JavaScript, i ...

Struggling to make comparisons with numerical data from MongoDB in an ExpressJS route

I am currently developing a website using Node.js, EJS template, MongoDB, and Express. I am working on implementing search functionality on my page using forms, but I am encountering a small issue. The problem is related to a logical issue in the search f ...

I am experiencing a 404 error when attempting to import a local JS file in Angular

After creating a new project with "ng new xxx", all you need to do is add one line of code in index.html: <!doctype html> <html lang="en> <head> <meta charset="utf-8> <title>Bbb</title> <base href="/&g ...