# Implement the Magic Triangle of Amazon

This week I joined a hardcore group, a research group whose goal is to gain an in-depth understanding of technology issues, and you may wish to consult the group's rule here . Each week the members will pick a topic and the weekend must have an article that summarizes what they learn about the topic.

This week I picked up the UI theme: **Amazon's Magic Triangulation techniques**

### **Magic triangle?**

If you hear this concept for the first time, you can read the article by a Vu Nhat Minh .

I summarize briefly:

The dark blue area is called the "magic triangle" (contraindicated for dark-minded people), its purpose is to help the mouse move from the left menu to the submenu on the right. smoother. There is no loss of focus, but the menu itself, for example:

### **Implement it like?**

Up to this point, there have been countless libraries supporting us to implement this function, but the purpose of this article is to delve and understand why people implement it, and how to implement it.

Here I will present two methods, one manual method and one more intensive method, which touches a bit of math ?

### **Manual method: Use SVG card**

This is the simplest solution, does not require any in-depth knowledge, and is also a "crude" way :))

1 2 3 4 | <div id = "menu-item"> <div class = "item"> Mouse on me </div> <div class = "content hover"> Come to me! </div> </div> |

For example, we have a menu like the image above, It is required that when dragging the **mouse on me area** , it will appear **Come to me in** accordance with the path of the magic triangle.

The solution is quite simple, it is to create an SVG tag to determine the movement area of the mouse, but if the cursor is on it, the menu will not be lost. That area will include a triangle connected from **Mouse on me** to **Come to me** and the whole region **Come to me** .

1 2 3 4 5 6 7 | <div id = "menu-item"> <div class = "item"> Mouse on me </div> <div class = "content hover"> Come to me! </div> <svg> <polygon id = "magic-triangle-menu-1" points = "75.25 150,0 400,0 400,200 150,200" style = "fill: lime; stroke: purple; stroke-width: 0" /> </svg> </div> |

We define the move area with an SVG tag as shown above, creating a polygon made up of points **(75:25)** , **(150: 0)** , **(400: 0)** , **(400: 200) )** , **(150: 200)** , these points are the peaks of the triangle and the top of the sub menu **Come to me** .

The rest of the work is probably guessed, which is to check if the mouse pointer is moving on this polygon area and show the menu.

The advantage of this way is that there is no need for cumbersome calculations, it can be "hard code" when creating a menu. The downside is that "hard code" and creating too many SVG tags on the site will affect performance and lead to the HTML structure not being nice, affecting this SEO …

### **Dynamic method: Check mouse coordinates when moving**

Similar to the above method, but in this way we do not need to create polygon manually anymore but will combine some operations to check the mouse coordinates are located in the polygon area. this or not.

We can get the mouse coordinates, we can also identify each vertex in the polygon to check (because there are specific sizes and coordinates of the menus).

So the problem here is: **How do I know if the cursor is in a polygon?**

The polygon is composed of a **triangle** and a **rectangle** :

So our problem here can be separated into 2 subproblems:

- Check a point in a triangle
- Check a point in a rectangle

Now that the problem has become quite easy, we only need to use the area method to check whether a point (here is the mouse coordinates) is in the triangle or rectangle.

**A point lies in a triangle**

For a point **D to** be in the triangle **ABC** , the area of the triangle **ABC** will equal the total area of the triangles **ADB** , **BDC** and **CDA** :

To calculate the area of a triangle when knowing its three vertices, we can use Shoelace's formula (thank you @TanDuong for correcting me here: D)

Looking at the mathematical expressions that seem to be afraid: v, then this is the code that expresses this formula:

1 2 3 | const area = function (A, B, C) { return Math.abs ((Ax * (By - Cy) + Bx * (Cy - Ay) + Cx * (Ay - By)) / 2); } |

And this is a function that tests a point in a triangle by calculating the total area of the three triangles mentioned above:

1 2 3 4 5 6 7 8 9 10 | const pointInTriangle = function (D, A, B, C) { let ABD = area (A, B, D); let BDC = area (B, D, C); let CAD = area (C, A, D); let ABC = area (A, B, C); if (ABC == (ABD + BDC + CAD)) { return true; } return false; } |

In addition to using the area method, there are many other methods, you can see this discussion thread to learn about the pros and cons of each type of method: http://stackoverflow.com/questions/2049582/how -to-determine-if-a-point-is-in-a-2d-triangle

### **A point lies in a rectangle**

Still by area method:

A point **E** will be in the rectangle **ABCD** if the total area of triangles **AEB** , **BEC** , **CED** and **DEA is** equal to the rectangular area **ABCD** .

And to calculate the area of each triangle, we have the formula as above, also calculate the area of **ABCD** rectangle, do we need to write the formula?

The code probably doesn't need to be written anymore :))

Like test cases triangle, rectangle, external method we investigated area there are many other methods, can refer here: http://math.stackexchange.com/questions/190111 / how-to-check-if-a-rectangle-a-rectangle

After checking whether the mouse cursor is in the triangle or rectangular area, it is not difficult to continue to edit the magic triangle effect nữa

Writer Huy Tran