Creating unique random shapes within a larger shape on a canvas, as shown in the image

I have a parent rectangle and would like to add up to 10 or fewer rectangles on the right-hand side corner of the parent rectangle, as shown in the image below:

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

I attempted to write code to achieve this, but the alignment is off-center from the parent rectangle.

this.addPortsToTheTransponder(3);

addPortsToTheTransponder(noOfPortsToBeDrawn: number) {
    for (let i = 1; i <= noOfPortsToBeDrawn; i++) {
      this.createPorts(i, noOfPortsToBeDrawn);
    }
  }
  
createPorts(i: number, noOfPortsToBeDrawn: number): void {
    this.context.clearRect(0, 0, this.width, this.height);

    const length = this.sizeOfTransponder.height / noOfPortsToBeDrawn;
    const height = 10;
    const width = 10;

    const x = this.x + this.sizeOfTransponder.width;
    
    const y = this.y + i * length - length / 2;

    this.context.rect(
      x,
      y,
      height,
      width
      );
    this.context.stroke();
  }

How can I align the small rectangles so that they are always drawn from the center, regardless of the total number of small rectangles? You can view the code here.

Answer №1

To illustrate this concept, let's consider a scenario involving some simple math. Assume you have a large rectangle positioned at x=20, y=20 with a width of 200 and a height of 300.

Now, the goal is to create five smaller rectangles adjacent to the right side of the big rectangle.

In order to achieve this, you need to determine the maximum vertical space available for the five small rectangles, which would be equal to the height of the big rectangle (300). By dividing the height by 5, you get 60. To align the small rectangles with the top of the big rectangle, start drawing them every 60 pixels from the calculated starting point on the y-axis. However, to ensure that the small rectangles are centered, add half of the calculated spacing (30) and subtract half of the height of a small rectangle.

For instance, feel free to experiment with the variable numberOfRectangles in the code snippet below to observe how the small rectangles will always be centered alongside the big rectangle:

var bigRectangle = {
  x: 0,
  y: 0,
  width: 200,
  height: 400
};

var smallRectangle = {
  width: 20,
  height: 35
};
var numberOfRectangles = 6;

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
context.rect(bigRectangle.x, bigRectangle.y, bigRectangle.width, bigRectangle.height)
context.stroke();
for (var a = 0; a < numberOfRectangles; a++) {
  context.rect(bigRectangle.x + bigRectangle.width, bigRectangle.y + (bigRectangle.height / numberOfRectangles) * (a + .5) - smallRectangle.height / 2, smallRectangle.width, smallRectangle.height)
  context.stroke();
}
<canvas id="canvas" width=300 height=500></canvas>

The implementation may slightly differ based on the specific requirements of your code, particularly if your loop begins at 1.

 for (let i = 1; i <= noOfPortsToBeDrawn; i++) {

However, the main adjustment needed is changing how the height is factored into the calculation within the loop. Replace the following line:

const  y = this.y + i * length - length / 2;

with

const  y = this.y + length * (i - 0.5) - height/2;

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

Enclose Angular $resource requests that do not return POST data

Currently, I am working on enhancing my $resource requests by implementing a straightforward wrapper. The primary objective is to incorporate some logic before the request is actually sent. For guidance, I referred to an informative article authored by Nil ...

The array is present both before and after the res.json() call, however it appears empty in the response

When using Express to send a json response with res.json(), I am experiencing an issue where the value of records in the object sent via res.json() is empty. My code snippet looks like this: stats.activities(params).then(res => { processActivities ...

Issue encountered with dynamic ngStyle variable: ERROR Error: Unable to locate a supporting object 'ngStyleSmall'

I have defined two variables for ngstyle ngStyleSmall = { width: '150px !important', 'max-width': '150px', }; ngStylemedium = { width: '250px !important', 'max-width&apo ...

The JavaScript code runs first before retrieving any information from the server

When it comes to validating coupons on Stripe, the process needs to be done on the server side rather than the client side. I've tackled this by writing some code for validation, but I'm facing challenges with synchronizing the AJAX/JSON response ...

The regular expression should consist of just letters and a single dot

Currently, I am working on creating a regular expression that allows only letters and one dot. However, there is a specific rule to follow: the dot cannot be located at the beginning or end of the string. For example: abc.difference This is what I attem ...

Error in Angular Material: SassError - The CSS after "@include mat" is invalid. Expected 1 selector or at-rule, but found ".core();"

My Angular 11 project was running smoothly with Angular Material version 11 until I decided to update everything to Angular 12, including Material. However, after the update, the styles.scss file that comes with Material started throwing errors. The comple ...

Add a new variable to the data in a jQuery ajax request for each request with any updates

I've encountered an issue with the code below, which is meant to add additional data to any ajax request made by my app. It works fine when the page first loads, but because my application is single-page and ajax-based, I need the updated variable val ...

The performance of ternary operators in Typescript-based Reactjs fell short of my expectations

As a newcomer to TypeScript+ReactJS, I am facing an issue with the Ternary operator in my code. Here is the code snippet: import React, { SyntheticEvent,useRef,useState } from "react"; import Result from './Result'; //main application c ...

Preloading error alert message displayed during AJAX request

When I send an ajax request with a dropdown change, the loader div is shown using "before send". However, the issue is that the loader only displays for the first time, even though the ajax functionality works all the time. If you want to check this issue ...

Merge two JavaScript functions

I've been attempting to merge two if functions together but I keep encountering errors. Despite trying different methods, I have not been successful in combining them. My goal is to check if the body has a specific class and if it does, I want to unc ...

Combining Angular 2.0 within Angular 1.x: Elevating your module

Currently, I am attempting to incorporate an Angular 2.0 component within an Angular 1.x application (for experimentation and learning purposes). Upon further examination, I have observed that this can be achieved by referencing the Angular2 upgrade modul ...

Breaking down index.js into separate files in Ruby on Rails

I have this really massive index.js file, around 7000 lines long. I'm looking to break it up into separate files for easier editing purposes. It doesn't matter if Rails combines them back into one file later on, I just need some advice on how to ...

What sets apart using JQuery to run AJAX from using plain XMLHttpRequest for AJAX requests?

Can you explain the advantages and disadvantages of using JQuery versus XMLHttpRequest for running AJAX code? While I understand that JQuery is essentially a JavaScript library, there must be some key differences to consider. Please elaborate on this top ...

Exporting multiple sheets using Angular's ngx-export-as functionality

Currently utilizing ngx-export-as in my Angular project and I am looking to export an Excel file with multiple sheets. How can I achieve this export functionality? I have raised a concern regarding this on GitHub. ...

What are the steps for creating a custom repository with TypeORM (MongoDB) in NestJS?

One query that arises is regarding the @EntityRepository decorator becoming deprecated in typeorm@^0.3.6. What is now the recommended or TypeScript-friendly approach to creating a custom repository for an entity in NestJS? Previously, a custom repository w ...

Issue encountered with connecting to development server on Expo iOS simulator that is not present when using a browser

During the development of a chat application with React Native Expo, I encountered an issue when running "expo start" in my typical workflow. The error message displayed was "could not connect to development server." If anyone has experienced a similar pr ...

What is the reason for having two plugin declarations within the galleriffic.js file?

I am currently working on enhancing the functionality of galleriffic.js by implementing a feature that will update a <div> element with text content as images are being changed. However, I am facing some challenges understanding the code. What perpl ...

"The Ajax function for replacing a div upon change event is not functioning properly

I am having an issue with my select box using the onchange event, <select class="form-control" onchange="getval(this.value,'<?php echo $prd->pr_id;?>','ajax<?php echo $key?>','<?php echo $key ?>')"&g ...

Updating the value of the variable using ng-submit

My application displays Quantity: {{num}}. The default value is set to 3 in the scope. The objective is to click on: <form ng-submit="addContact()"> <input class="btn-primary" type="submit" value="Add Contact"> </form> and to up ...

What is the best way to add <li> to every element in an array?

I had a tough day today trying to figure out my code. My English isn't the best, so explaining my issue is hard. I decided to illustrate my problem in HTML and specify the kind of styling I need to achieve with JS. I also included an example using the ...