Canvas connectives (HTML5)

I have successfully implemented a user interface, but I am experiencing lower FPS during certain moments. After conducting a performance test with Firefox, I have realized that these FPS drops occur when the browser re-calculates CSS.

The CSS recalculations are triggered by my modification of the "style" property to insert the CSS rule "cursor: pointer". I am doing this to change the cursor for specific links in my canvas. However, I am looking to optimize this feature to prevent any freezing issues. Do you have any suggestions on how I can achieve this optimization?

Here is a breakdown of my code: I add an event handler to the canvas for mousemove events. Each time the event is triggered, it checks the cursor coordinates. If the cursor is positioned over a link, it changes the cursor to "pointer" and sets a variable called hoverIndex to the position of the link in the array.

var sky = new Image();
var logotype = new Image();
var back_btn = new Image();
var next_btn = new Image();
var upgrades_btn = new Image();

var coin_five = new Image();
var coin_ten = new Image();
var coin_fifty = new Image();
var cash_hundred = new Image();

var currentArea = "main_menu";
var cvn, ctx;

var linkAreas = [];
var hoverIndex = -1;

var gameVersion = "1.2.2a";

var coinFiveReset = 1500;
var coinTenReset = 5000;
var coinFiftyReset = 10000;
var coinHundredReset = 10000;

var coinFiveRemaining = 1500;
var coinTenRemaining = -1;
var coinFiftyRemaining = -1;
var coinHundredRemaining = -1;

var playingInterval;

//{type: "five", x: 0, y: 0}
var coinsPlaying = [];

function initialization(){
    cvn = document.getElementById("kg_coinfactory");
    ctx = cvn.getContext("2d");

    cvn.addEventListener("mousemove", function(ev){
        var pos = getMousePosition(ev);
        for(var x = 0; x<linkAreas.length; x++)
            if(currentArea == linkAreas[x].area && pos.x >= linkAreas[x].x && pos.y >= linkAreas[x].y && pos.x <= linkAreas[x].x + linkAreas[x].width && pos.y <= linkAreas[x].y + linkAreas[x].height)
            {
                hoverIndex = x;
                cvn.style = "cursor: pointer";
                break;
            }
            else
            {
                cvn.style = "";
                hoverIndex = -1;
            }
    });

    cvn.addEventListener("mouseup", function(){
        if(hoverIndex != -1)
            linkAreas[hoverIndex].onClickFunc();
    });
}

function getMousePosition(ev){
    var rect = cvn.getBoundingClientRect();
    return {x: ev.clientX - rect.left, y: ev.clientY - rect.top};
}

function registerLink(x, y, text, area, ctx, onClickFunc)
{
    var s = ctx.measureText(text);
    linkAreas.push({x: x, y: y - 24, width: s.width, height: 24, area: area, onClickFunc: onClickFunc});
}

Answer №1

Is the drop in FPS really a cause for concern?

One solution could be to store the current cursor status and only change it if the cursor enters or leaves the hover areas.

Alternatively, if mouse events are not needed on the canvas under the hover areas, you could use position:absolute to place a DOM element over the canvas and have that element respond to hover and click events.

Another option is to hide the pointer when over the canvas and create custom pointers using drawImage.

For a more extreme approach, you could overlay a second canvas on top of the existing one and draw only the pointer on the second canvas. By setting pointer-events:none on the second canvas, mouse events will pass through to the underlying canvas.

Additionally, optimize your mouse position calculations for efficiency.

Instead of calling getBoundingClientRect for every mousemove event, save the rect.left and rect.top values once and use the saved offsetX and offsetY values. Recalculate the bounding box only when necessary, such as on window resize or scroll.

Minimize external function calls like getMousePosition for better performance. Calculate the mouse position directly inside your mouse event handler to reduce processing.

Finally, streamline your mouse event handler by indicating to the browser that the event does not need to bubble to other elements:

// inform the browser that we are handling this event
ev.preventDefault();
ev.stopPropagation();

An optimized mouse event handler could be structured like this:

cvn.addEventListener("mousemove", function(ev){    

    // inform the browser that we are handling this event
    ev.preventDefault();
    ev.stopPropagation();

    // calculate the mouse position directly within the handler
    // using cached offset values
    mouseX=parseInt(ev.clientX-offsetX);
    mouseY=parseInt(ev.clientY-offsetY);

    ... carry out necessary actions ...

}

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

"Skip the inbox clutter and access the compose page directly on Gmail, Yahoo, and

I was looking to create a unique hyperlink that would direct users to a compose page similar to Google Mail. Here is an example of what I tried: <li><a href="https://inbox.google.com/mail/?view=cm&fs=1&<a href="/cdn-cgi/l/email-protect ...

Use desktop images to set the background for mobile views in a React JSX environment

My custom Gutenberg block is built using React JSX, allowing users to input two hero images - one for Desktop and one for Mobile. Currently, if a user does not upload a mobile image, it displays a blank space. I am looking for a way to have the desktop ima ...

How to create a donut chart in Highcharts without an inner pie section?

I've been scouring the internet in search of a solution to create a basic donut chart using the Highcharts library. Most examples I come across show donut charts with both an inner pie and outer donut (see here). Is there a way to remove the inner pi ...

Encountering issues with integrating an external plugin with AngularJS code

For my app, I am attempting to incorporate intercom for monitoring user activity. It functions correctly when placed inside a script tag in index.html. However, I encounter an error when trying to use it in a .ts file as shown below: app/components/rocket/ ...

Local working fine but encountering issues on Openshift, specifically with syncing npm package versions across environments (local and global)

As I develop a forum using Angular that connects with Node/Mongo, there are numerous requests required to populate the page with necessary data. While everything functions flawlessly locally, once uploaded to Openshift, the site displays various bugs and f ...

Can search criteria be saved for later use?

I operate a classifieds website that allows users to search through ads. I am contemplating ways to save search criteria so that users can easily reuse them for future searches without having to input the same details over and over again. For instance, th ...

Passing data received from a node.js request (using https.get) to a separate JavaScript file

I'm new to posting here, so my explanation might not be very clear. I am working on a project using node.js to fetch data and pass it to another js file for use in an html file. The structure of my app folder is as follows: -App -node_modules -publi ...

adjustable canvas dimensions determined by chosen images

I would like to create a canvas image based on the selected image <canvas id="canvas" ></canvas> <input type="file" id="file-input"> Using JavaScript: $(function() { $('#file-input').change(function(e) { var file ...

Leveraging spread syntax and styling for array string interpolation in JavaScript

Imagine I have an array such as [1,2,3] and my goal is to insert its values into a string format like: the values are (?, ?, ?) Can anyone suggest a simple solution for this? I am aware of the spread operator ...[1,2,3], and it's feasible to conver ...

Vue.JS has issued a warning indicating that the `util._extend` API is no longer supported. To address this, developers are advised to utilize Object

During the execution of a call API request, the Vue.JS application encountered an error. The API is hosted at Okta, and the request is successful when using cURL in the CLI. Error Message (node:82171) [DEP0060] DeprecationWarning: The `util._extend` API i ...

Selecting a database design pattern for varying database types

After creating a class to manage interactions with my database, I realized that I need separate classes for two different modes: admin and client. class MyDatabase { connect() { /* ... */ } } So, I decided to create two new classes: class MyDatabaseAd ...

Export was not discovered, yet the names are still effective

There seems to be a slight issue that I can't quite figure out at the moment... In my Vue project, I have a file that exports keycodes in two different formats: one for constants (allCodes) and another for Vue (keyCodes): export default { allCodes ...

Implementing personalized SVG icons for list items

Here is some HTML code along with SCSS that I need help with: <div class="risk"> <ul> <li><span>Aggressive</span>Lorem ipsum dolor ...</li> <li><span>Growth</span>doloremque autem...</li ...

In JavaScript, the JSON Object only stored the final result from a loop

I am currently working on an HTML Site that features 4 inputRange sliders. My goal is to store all values from these sliders in a nested JSON Object when a user clicks on a button. However, I have encountered an issue where my JavaScript code only saves th ...

Should I increase the number of followers, or opt for an aggregated method to monitor them?

My system loads products using an infinite scroll, displaying 12 at a time. Sometimes, I may want to sort these products based on the number of followers they have. Here's how I keep track of the followers for each product: The follows are stored i ...

There seems to be an issue with configuring placeholders in Tailwind CSS

After deciding to switch to using only tailwind CSS, I noticed that on a particular page there were inputs with transitions but no icon on the inner left side. Adjusting the colors and position of the placeholder helped prevent collisions between the icon ...

Div flexes and compresses smaller than its content dimensions

Here's a link to the fiddle: check it out Take a look at a normal card below: https://i.sstatic.net/7Yqqv.png But when the browser window is resized, it shrinks to this: https://i.sstatic.net/1aexK.png This is the HTML structure: #product-list ...

Is there a way to retrieve time data from a different server through AJAX?

I am in need of obtaining time information from an online source, whether it be an NTP server, JSON time server, or simply an HTTP Header. The precision is not important to me, but the requirement is that I must get the time from an online source. Unfortun ...

Is it possible to arrange the final divs on top of the initial ones without any overlap between them?

I have a script for uploading files that displays all previously uploaded images in divs with the class "download". When I use a jQuery script to add more pictures, it puts them in divs with the class "upload". I want these new uploads to be displayed ab ...

Is there a way to implement this toolbar in Ionic Angular?

https://i.sstatic.net/sGd1o.png I am looking to replicate the toolbar shown in the image above using Ionic. As a beginner in Ionic development, I am finding it challenging to translate the design into code. I attempted to use a grid layout, but the varyin ...