UX hoàn hảo tam giác ma thuật của Amazon
Bài đăng này đã không được cập nhật trong 5 năm
Tam giác ma thuật của Amazon
Vậy là Amazon đã làm thế nào để vẫn đem lại UX hoàn hảo trong khi không có một tí delay nào ? Chúng ta không thấy Bootstrap bug, và tốc độ thì hẳn là tức thì. Câu trả lời là hình tam giác được đánh dấu dưới đây
Tôi vốn nghĩ tốc độ tức thì khi di chuyển con trỏ là điều không thể. Tất cả các menu đều cần một ít delay để thay đổi nội dung của submenu. Bạn có thể nhìn ví dụ dưới đây
Vùng màu xanh đậm được gọi là vùng "tam giác ma thuật" (chống chỉ định đối với các bạn có đầu óc đen tối mục đích của nó là giúp cho thao tác move chuột từ menu bên trái sang menu con bên phải được mượt mà hơn. Không bị dính vấn đề mất focus mà ẩn luôn cả cái menu, ví dụ:
Cách tạo ra tam giác ma thuật
JavaScript
var in_magic_triangle = false;
var in_magic_triangle = false;
var previous_X = 0;
var MAGIC_A, MAGIC_B, MAGIC_C;
area = function(A, B, C) {
return Math.abs(( A.x * (B.y - C.y) + B.x * (C.y - A.y) + C.x * (A.y - B.y) ) / 2);
}
pointInTriangle = function(D, A, B, C) {
var ABD = area(A, B, D);
var BDC = area(B, D, C);
var CAD = area(C, A, D);
var ABC = area(A, B, C);
if (ABC == (ABD + BDC + CAD)) {
return true;
}
return false;
}
$(document).ready(function(){
$('.menu-item a').on('mousemove', function(e){
if(!in_magic_triangle){
$(this).closest('.menu-item').addClass('active').siblings().removeClass('active');
MAGIC_A = {x:e.pageX,y: e.pageY};
MAGIC_B = {x:$(this).siblings('.sub-menu').offset().left,y: $(this).siblings('.sub-menu').offset().top};
MAGIC_C = {x: $(this).siblings('.sub-menu').offset().left, y:$(this).siblings('.sub-menu').offset().top + $(this).siblings('.sub-menu').outerHeight()};
console.log( MAGIC_A.y +','+MAGIC_A.x +' '+MAGIC_B.y +','+MAGIC_B.x +' '+MAGIC_C.y +','+MAGIC_C.x +' ');
$('#magic-triangle').attr('points', MAGIC_A.x +','+MAGIC_A.y +' '+MAGIC_B.x +','+MAGIC_B.y +' '+MAGIC_C.x +','+MAGIC_C.y +' ');
in_magic_triangle = true;
}else{
var D = {x: e.pageX, y: e.pageY};
if (e.pageX < previous_X || !pointInTriangle(D, MAGIC_A, MAGIC_B, MAGIC_C)){
in_magic_triangle = false;
}
previous_X = e.pageX;
}
})
})
HTMl
<script src="https://code.jquery.com/jquery-3.1.0.min.js" integrity="sha256-cCueBR6CsyA4/9szpPfrX3s49M9vUU5BgtiJj06wt/s=" crossorigin="anonymous"></script>
<svg>
<polygon id="magic-triangle" points="" style="fill:lime;stroke:purple;stroke-width:0" />
</svg>
<ul class="menu">
<li class="menu-item">
<a href="#">menu 1</a>
<ul class="sub-menu">
<li class="sub-menu-item">sub menu 1</li>
<li class="sub-menu-item">sub menu 1</li>
<li class="sub-menu-item">sub menu 1</li>
<li class="sub-menu-item">sub menu 1</li>
<li class="sub-menu-item">sub menu 1</li>
<li class="sub-menu-item">sub menu 1</li>
<li class="sub-menu-item">sub menu 1</li>
<li class="sub-menu-item">sub menu 1</li>
</ul>
</li>
<li class="menu-item">
<a href="#">menu 2</a>
<ul class="sub-menu">
<li class="sub-menu-item">sub menu 2</li>
<li class="sub-menu-item">sub menu 2</li>
<li class="sub-menu-item">sub menu 2</li>
<li class="sub-menu-item">sub menu 2</li>
<li class="sub-menu-item">sub menu 2</li>
<li class="sub-menu-item">sub menu 2</li>
<li class="sub-menu-item">sub menu 2</li>
</ul>
</li>
<li class="menu-item">
<a href="#">menu 3</a>
<ul class="sub-menu">
<li class="sub-menu-item">sub menu 3</li>
<li class="sub-menu-item">sub menu 3</li>
<li class="sub-menu-item">sub menu 3</li>
<li class="sub-menu-item">sub menu 3</li>
<li class="sub-menu-item">sub menu 3</li>
<li class="sub-menu-item">sub menu 3</li>
<li class="sub-menu-item">sub menu 3</li>
<li class="sub-menu-item">sub menu 3</li>
<li class="sub-menu-item">sub menu 3</li>
</ul>
</li>
<li class="menu-item">
<a href="#">menu 4</a>
<ul class="sub-menu">
<li class="sub-menu-item">sub menu 4</li>
<li class="sub-menu-item">sub menu 4</li>
<li class="sub-menu-item">sub menu 4</li>
<li class="sub-menu-item">sub menu 4</li>
<li class="sub-menu-item">sub menu 4</li>
<li class="sub-menu-item">sub menu 4</li>
<li class="sub-menu-item">sub menu 4</li>
<li class="sub-menu-item">sub menu 4</li>
<li class="sub-menu-item">sub menu 4</li>
</ul>
</li>
<li class="menu-item">
<a href="#">menu 5</a>
<ul class="sub-menu">
<li class="sub-menu-item">sub menu 5</li>
<li class="sub-menu-item">sub menu 5</li>
<li class="sub-menu-item">sub menu 5</li>
<li class="sub-menu-item">sub menu 5</li>
<li class="sub-menu-item">sub menu 5</li>
<li class="sub-menu-item">sub menu 5</li>
<li class="sub-menu-item">sub menu 5</li>
<li class="sub-menu-item">sub menu 5</li>
</ul>
</li>
<li class="menu-item">
<a href="#">menu 6</a>
<ul class="sub-menu">
<li class="sub-menu-item">sub menu 6</li>
<li class="sub-menu-item">sub menu 6</li>
<li class="sub-menu-item">sub menu 6</li>
<li class="sub-menu-item">sub menu 6</li>
<li class="sub-menu-item">sub menu 6</li>
<li class="sub-menu-item">sub menu 6</li>
<li class="sub-menu-item">sub menu 6</li>
<li class="sub-menu-item">sub menu 6</li>
</ul>
</li>
</ul>
CSS
ul.menu{
opacity: 0.8;
}
ul.sub-menu {
display: none;
background: #ccc;
margin-left: 200px;
position: absolute;
width: 400px;
top: 0;
padding: 0;
list-style: none;
box-sizing: border-box;
}
li.menu-item {
list-style: none;
height: 40px;
background: #eee;
width: 200px;
line-height: 40px;
padding: 0;
box-sizing: border-box;
}
body {
margin: 0;
padding: 20px;
font-family: verdana;
}
ul.menu {
padding: 0;
margin: 0;
position: relative;
}
a {
text-decoration: none;
color: inherit;
}
ul.sub-menu{
padding: 10px;
}
.menu-item.active ul.sub-menu {
display: block;
}
li.menu-item a {
margin: 0 10px;
display: block;
}
li.menu-item:hover {
background: #f9f5ec;
}
li.sub-menu-item:hover{
background: #eee;
padding: 0 10px;
}
svg {
height: 1000px;
width: 1000px;
position: absolute;
left: 0;
top: 0;
padding: 0;
margin: 0;
}
DEMO
Cám ơn các bạn đã đọc!
Tài liệu tham khảo :
https://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown
All rights reserved