Detecting the rectangular boundary of rotated elements on a dynamically generated canvas or SVG using JavaScript (TypeScript)

I've been struggling with a particular issue for some time now.

Currently, I'm developing a web application using TypeScript, React, and Google Maps. For the markers on the map, I aim to use custom images generated at runtime based on various parameters. These images consist of a circle and a triangle that indicates a direction at a specific angle with different colors. Examples of what the images should look like can be seen here: Image 1 and Image 2.

The number of these images can vary from 1 to 300 depending on user preferences. Additionally, the top of the triangle should start at the map coordinates. When multiple markers are in close proximity, they should appear similar to this image: Image 3.

I have managed to create and place the images on the map as intended. However, the problem arises when the images are too large and overlap when near each other. This results in the markers not being clickable until zoomed in, creating a situation like the one depicted here: Image 4.

My objective is to crop out the transparent areas so only the circle and triangle remain usable for the map. I have attempted two methods for this - one involving the canvas element and the other utilizing SVG elements. Both processes involve drawing the circle first, then the triangle, followed by rotation.

When working with SVGs, I was able to identify the bounding rectangle using getBBox() or getBoundingClientRect(). However, an issue arose when the images were not loaded into the DOM, resulting in no output from these methods until the SVG was added to the DOM. This approach proved inefficient as I would have to add every image to the DOM before processing it, adding it to the map, and finally removing it from the DOM.

With the canvas method, I found a function online that scans every pixel on the canvas, returning the objects within it. While effective, this process became sluggish with numerous elements present. Another failed attempt involved locating the rotated coordinates using a formula:

x1 = x * Math.cos(angle * Math.PI / 180) - y * Math.sin(angle * Math.PI / 180)
y1 = x * Math.sin(angle * Math.PI / 180) + y * Math.cos(angle * Math.PI / 180)

So, my question remains - what is the best approach to solving this dilemma?

Thank you for your assistance.

Here's the code snippet outlining the canvas and SVG drawing functions:

// Code for canvas icon creation
const drawMarkerIconCanvas = (
    angle?: number | null,
    arrowFillColor?: string,
    circleFillColor?: string,
    strokeColor?: string,
    scale?: number,
    text?: string,
    textColor?: string) => {
    
    // Function implementation goes here...
}

// Code for SVG icon creation
const drawMarkerIconSVG = (angle?: number | null,
                       arrowFillColor?: string,
                       circleFillColor?: string,
                       strokeColor?: string,
                       scale?: number,
                       text?: string,
                       textColor?: string) => {

    // Function implementation goes here...

}

Answer №1

After some trial and error, I managed to solve my issue by taking a different approach than originally planned. Instead of trying to find the bounds, I found success in a method that worked for my specific case. Initially, I was positioning images in the center of the canvas before scaling them. Then, I placed them on the map with an offset determined by the angle of rotation and canvas translation. I applied a formula to locate points after rotation, resulting in a function like the one below:

const getCoordinates = (x: number, y: number, angle: number, imgWidth: number, imgHeight: number) => {
    let x1, y1;

    x1 = x * Math.cos(angle * Math.PI / 180) - y * Math.sin(angle * Math.PI / 180)
    y1 = x * Math.sin(angle * Math.PI / 180) + y * Math.cos(angle * Math.PI / 180)

    return {
        x: x1+imgWidth/2, y: y1+imgHeight/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

What is the best way to retrieve the maximum date associated with a particular foreign key in SQL Server?

I'm currently developing a NodeJs application that involves a SQL Server database for storing data and running queries. However, I've encountered an issue with one specific query which I believe is due to my limited experience in SQL. The &apos ...

`Error importing react-markdown in Next.js 11.1 with TypeScript``

Having trouble with importing react-markdown in my next.js SSG project. When running npm run dev, I encounter an error that prevents me from proceeding to test in next export. I understand that react-markdown is an esm package, but I'm not sure how t ...

The dividers flicker in and out of view

I have a menu with 7 elements, where clicking on an element causes its content to appear by fading in. If another element is clicked, the current content fades out and the new content fades in. I've successfully implemented this concept for 3 of the 7 ...

Transferring data from ng-init to <script> in AngularJS

Take a look at this code snippet: <div ng-init="companyData"> <script type="text/javascript"> window.timeline = new TL.Timeline('timeline-embed', sampleJson); </script> </div> Is there a method to include company ...

Tips for changing the value of a TextField in React Material

I am faced with a challenge regarding a form that is populated with data from a specific country. This data is fetched from a GraphQL API using Apollo Client. By default, the data in the form is read-only. To make changes, the user needs to click on the e ...

Troubleshooting problems with background-image in CSS using Javascript

My latest project involves coding to assign background images to various classes using jQuery. The image files are named in a numerical order, such as 0bg.jpg, 1bg.jpg, 2bg.jpg, and so on. for (i=0; i < 8; i++) { $('.hpCarousel:eq('+i+' ...

Steps for transforming an array of file names into JSON format and including a specific key

I am in the process of creating a new website that will display all the files contained in a specific folder. However, I am facing an issue with converting an array of document names into JSON format. In order to achieve this, I understand that I need to ...

Removing a Firestore Document when the identifier is assigned to a unique name that is not predefined in any location

Presently, my database stores user information. The unique identifier for each document is the user's initial name upon registration, even though this name may have been changed at a later time without updating the document's name. My dilemma is ...

Customize the Address Bar with Google Extension

I recently developed a unique Chrome extension that modifies the appearance of the new tab page by incorporating my site's index.html. However, I am facing an issue where the address bar displays https://example.com/index.html/. Is there a way to have ...

Experiencing difficulties while attempting to organize an array?

// const first = data.groups_with_selected[7]; // const second = data.groups_with_selected[20]; // data.groups_with_selected.splice(2, 0, first, second); // data.groups_with_selected.splice(9, 1) // data.groups_with_selected ...

Creating a seamless integration between a multi-step form in React and React Router

I've been learning how to use React + ReactRouter in order to create a multi-step form. After getting the example working from this link: , I encountered an issue. The problem with the example is that it doesn't utilize ReactRouter, causing the ...

Trouble displaying events from resource in Angular UI calendar integration

I have encountered a perplexing issue with Angular UI Calendar. My goal is to fetch events from an API and display them on the calendar. Initially, the events load correctly when the page is first loaded. However, if I navigate to the next month and then r ...

Struggling to get Ajax to function on IE8 with dropdowns, while other browsers are working perfectly fine

My AJAX code functions properly in most browsers, however, it is not performing well in IE. While it successfully creates an XMLHTTPRequest object, the data retrieved from my PHP script is only returning an empty list! Check out my JavaScript code: < ...

Navigating nested routes in React Router: a comprehensive guide

I need help with integrating nested routes into my app. Can someone guide me on how to add nested routes? Here is the structure of my app: import { Route, Routes } from 'react-router-dom'; import routes, { RouteModel } from './router/routes ...

The interconnected layers of Callback Scope in AngularJS and the overarching rootScope concept

I've been working on an Angular controller to fetch records from a database and display them in a calendar. However, I'm facing an issue where the events array is returning empty. I tried using $rootScope.events as a workaround but encountered an ...

Update the text content in the specific span element when the class attribute matches the selected option in the

How can I dynamically update text inside a span based on matching classes and attributes without hardcoding them all? An ideal solution would involve a JavaScript function that searches for matches between span classes and select field options, updating t ...

Module output is "Undefined" when it is required

testing.js var something = require('./something'); var anotherThing = require('./anotherThing'); console.log(something()); console.log(anotherThing()); something.js module.exports = function() { console.log('Inside of someth ...

jQuery Ajax error 403 (unlike XMLHttpRequest)

Recently, I encountered an issue with two Ajax calls in my code. One of the calls was implemented using XMLHttpRequest and the other one using jQuery. Surprisingly, the first call completed successfully without any errors. However, the second call, which s ...

Safari is experiencing issues with the fill path of SVG icons, unlike Chrome where it is functioning properly

https://i.stack.imgur.com/XaKE4.jpgI'm having trouble with my SVG icons displaying correctly in Chrome but not in Safari. Does anyone have any tips or suggestions to fix this issue? Any help is appreciated. If anything is unclear about the problem, p ...

AngularJS Compile directive allows you to specify functions that you want to run in

Can someone assist me in understanding how to call an external function from a built-in compile directive? Here is a code example: http://plnkr.co/edit/bPDaxn3xleR8SmnEIrEf?p=preview This is the HTML: <!DOCTYPE html> <html ng-app="app"> ...