Organizing objects within a canvas

When drawing two buttons on a canvas using rectangles and text overlaid, I encountered different results even though the same loop was used. One "button" had the text hidden behind the box while the other had the text displayed on top. I am curious about why this happened and how sorting works in canvas.

<body>
  <canvas id="canvas" width="320" height="512"
  style="position: absolute; left: 500px; top: 50px; z-index: 1;"></canvas>
<script>
var canvas = document.getElementById('canvas');
var context = canvas.getContext("2d");
canvas.style.backgroundColor = 'rgba(0, 0, 0, 0)';
context.clearRect(0, 0, 320, 16);
gameMenu();

function gameMenu(){
var buttons = [ {x: 210, y: 420, w: 80, h: 30, s: "Messages"},
              {x: 210, y: 470, w: 80, h: 30, s: "Pause"} ], i = 0, r;

    while(r = buttons[i++]) {
    context.rect(r.x, r.y, r.w, r.h);
    context.fillStyle = "rgb(26,26,26)";
    context.fill();

    context.fillStyle = 'White';
    context.font = "16px Tahoma";
    context.fillText(r.s, r.x + 18, r.y + 22);
    }
}
</script>
</body>

To see the issue in action, check out this JS Fiddle link: https://jsfiddle.net/oa84Lsxn/1/

Answer №1

Ensure that each time you start a new path operation (==each new .rect), you include context.beginPath. If this step is skipped, all previous .rects will be redrawn alongside the current .rect.

The problem lies in the fact that previous paths are being redrawn together with the new path. This results in the initial rect getting redrawn along with the subsequent rect, leading to the text of the first rect being overwritten by the second rect.

Below is a corrected version of your code with the addition of context.beginPath.

var canvas=document.getElementById("canvas");
var context = canvas.getContext("2d");
canvas.style.backgroundColor = 'rgba(0, 0, 0, 0)';
context.clearRect(0, 0, 320, 16);
gameMenu();

function gameMenu(){
// x,y changed to fit demo on StackSnipped window
var buttons = [ {x: 40, y: 20, w: 80, h: 30, s: "Messages"},
              {x: 40, y: 70, w: 80, h: 30, s: "Pause"} ], 
              i = 0, r;

    while(r = buttons[i++]) {
        context.beginPath();
        context.rect(r.x, r.y, r.w, r.h);
        context.fillStyle = "rgb(26,26,26)";
        context.fill();

        context.fillStyle = 'White';
        context.font = "16px Tahoma";
        context.fillText(r.s, r.x + 18, r.y + 22);
    }

}
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=300 height=300></canvas>

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

Validate the Start and Finish Date in a DatePicker without the need for a plugin

Utilizing Asp.Net MVC 4 in combination with JqueryUI. I have two textboxes that are equipped with datepickers. I am in need of validation where the start date can be equal to the finish date, but the finish date cannot be before the start date. Here is t ...

How to selectively display specific columns when outputting JSON to a dynamic HTML table?

I'm looking to output specific JSON data in an HTML table with JavaScript. The headers will remain the same, but the JSON content will vary. Currently, I have a working function that generates the entire table using JavaScript: <body> ...

What is the simplest method for fetching and parsing JSON data with jQuery and JavaScript?

I'm having trouble making this code snippet work. I can't seem to figure it out. The objective is to retrieve and parse a JSON object in the simplest and easiest way possible. Here's the code snippet. <!DOCTYPE html> <html> &l ...

Arrange by alphabetical order using a dropdown menu

I am stuck and need some help! I have a working Itemlist with Angular, but now I want to add sorting by a select-box. It should look something like this: preview Here is a Plunker example: https://embed.plnkr.co/JYF0u9jBbsfyIlraH3BJ/ <div id="ideaLis ...

Error: Invalid jQuery syntax, expression not recognized

There seems to be a syntax error with an unrecognised expression: #2015-11-30|1112|1 I'm trying to add a class to an anchor tag with the Id of '2015-11-30|1112|1', similar to how I've done it with another element that worked fine. How ...

Creating a typed JavaScript object using an object initializer - step by step guide

When creating an object using direct initialization and showing it in the console, the engine fails to assign it any type. This is not surprising, as the console considers displaying Object to be of little value. However, when a constructor function is use ...

The disappearance of the Request Body in the NuxtJS ServerMiddleware Express API

I've been working on my ExpressJS and NuxtJS skills lately. I've been trying to receive data from an axios POST request, but for some reason, the req.body and req.params always turn up empty. Below are the configurations and code snippets that I& ...

Steps to prevent submission of form until the maximum word count is reached

Currently, I am diving into the world of coding and have limited knowledge about JavaScript. As a result, I am facing some challenges and would greatly appreciate any guidance from the community. I am working on an input form and I want to disable the su ...

Displaying Database Content on Screen Instead of index.html in Node/Express

I'm currently working with Node.js, however, when I try to access my localhost all I see is the database data in JSON format instead of my index.html page. This issue doesn't happen when using localhost, so I'm not sure why it's not dis ...

using a synchronous fetch instead of synchronous ajax

Although synchronous calls are not recommended, I am in a situation where I need to make one in ajax. The device I am working with requires user action before I can receive a response from it. My current ajax() code has been functioning well so far. Howeve ...

Making JSON function in Internet Explorer

I'm encountering an issue retrieving data from a JSON feed specifically in Internet Explorer. Here's the problem. It functions correctly in Firefox, Chrome, and Safari, but fails to alert in IE: function perform_action(data){ alert(data); } ...

Tips for personalizing the export grid menu in angular-ui-grid?

My grid includes an external "Show Details" option that adds extra columns to the grid when clicked. https://i.sstatic.net/Fu2Qp.png The problem arises with the options for "Export all data" and "Export visible data," which can be confusing in this scena ...

A loop in JavaScript/TypeScript that runs precisely once every minute

Here is a snippet of my code: async run(minutesToRun: number): Promise<void> { await authenticate(); await this.stock.fillArray(); await subscribeToInstrument(this, this.orderBookId); await subscribeToOrderbook(this, this.orderBookId ...

Tips on automatically loading the map in satellite mode every time

My goal is to have my map consistently display in satellite view upon loading, but unfortunately, this code snippet doesn't seem to achieve that. I'm not sure if there's an error in the line of code. Below is the code I've been using: ...

What is the best way to programmatically transmit post data in a PHP script?

I am looking for a way to programmatically send post data to another page. In my database, I have two DateTime values that I need to compare. If one DateTime is greater than the other, I want to automatically send post data to another page. Here is a snip ...

What is the best way to incorporate Ajax into a Rails application?

Check out the Webpage Design I am currently working on a Todo List that includes various Todo Items. Each incomplete task has a button called "Mark Item as Done" next to it, which triggers the button_to method when clicked. I am facing challenges in imple ...

Adding colors dynamically upon page reload with javascript and jQuery

I have created an array of colors and am attempting to use colors.forEach inside the ready function to call addBox for each color in the array. My goal is to ensure that all the colors are added when the page is reloaded. Please let me know if you require ...

How to make Angular resolver and component share an injected service?

In my products list component, I have a table displaying various products. Since there is a considerable amount of data, I implemented a resolver to prevent the user from being directed to the page until all the data is loaded. The resolver currently utili ...

Exploring the world of JavaScript by dynamically retrieving all class functions

Is there a way to retrieve an array of all functions from a given class, including functions inherited from parent classes? For instance: class Foo extends Bar { funcA() {} } class Bar { funcB() {} } const instanceFoo = new Foo(); getClass ...

Can anyone explain the functionality of passport.initialize() in the context of Node.js and Express

I am currently working on implementing the passport module in my application. After reading some manuals, I found this: app.use(passport.initialize()); app.use(passport.session()); Can someone explain what app.use(passport.initialize()) does exactly? I ...