UX hoàn hảo với tam giác ma thuật của Amazon

Cập nhật: Lượt xem: 123 [ Javascript ]

UX hoàn hảo với tam giác ma thuật của Amazon

UX hoàn hảo với tam giác ma thuật của Amazon

Tam giác ma thuật của Amazon

Amazon đã làm thế nào để đ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

amazone_menu

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:

menu_delayed

Vùng màu xanh đậm được gọi là vùng "tam giác ma thuật" 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ụ:

tam_giac

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: (Hover chuột vào menu để xem)

Nguồn: Viblo

Loading...