Круговое вращающееся / увеличительное меню с jquery

Я пытаюсь сделать меню, которое содержит 5 пунктов / значков с выбранным в центре. При щелчке по левому или правому краю этого значка по центру меню поворачивается влево или вправо, оборачивается вокруг краев и перемещается в зависимости от того, какой элемент был ближе к краю, через противоположный. Нажав на центрированный элемент, вы попадете на связанный с ним URL-адрес.

Меню также должно увеличиваться аналогично док-станции OS X, за исключением того, что уровни увеличения устанавливаются на основе положения, а не наведения мыши.

Я сделал диаграмму, которую легче понять, чем мои разговоры.

http://img442.yfrog.com/img442/9321/navdiagram.png

Мне удалось собрать простую версию jQuery, в которой элементы меняются местами по мере необходимости, но не могу понять, как анимировать это движение, особенно обтекание вокруг краев, и изменять размер в зависимости от положения.

Наверное, мой код тоже не самый лучший:)

HTML выглядит следующим образом:

<div id="nav">
<div id="leftnav"></div>
<div id="rightnav"></div>
<div id="navblock1" class="navblock">
    one
</div>
<div id="navblock2" class="navblock">
    two
</div>
<div id="navblock3" class="navblock">
    three
</div>
<div id="navblock4" class="navblock">
    four
</div>
<div id="navblock5" class="navblock">
    five
</div>

И JS:

function rotateNav(direction) {
var change = (direction=='left')?(-1):(+1);
$('div.navblock').each(function() {
    oldPos = parseInt($(this).attr('id').substr(9));
    newPos = oldPos+change;
    if (newPos == 0)
        newPos = 5;
    else if (newPos == 6)
        newPos = 1;
    $(this).attr('id','navblock'+newPos);
});
}
$(document).ready(function(){
$("#leftnav").click(function() {
    rotateNav('right');
});
$("#rightnav").click(function() {
    rotateNav('left');
});

});

Все элементы.navblock абсолютно позиционированы. Элементы #leftnav и #rightnav также имеют более высокий z-индекс, поэтому плавают над элементами / значками.

Я посмотрел на различные плагины jQuery, но ни один из них не похож на то, что мне нужно.

3 ответа

Решение

Вместо смены id Атрибуты (которые вы действительно не должны делать в первую очередь), вы можете изменить классы CSS и использовать пользовательский интерфейс jQuery switchClass() метод анимации вращения.

Вы также должны сделать немного clone() чтобы он выглядел как край navblock S повернулся на другую сторону виджета и некоторые queue() / dequeue() для обработки нескольких кликов.

Рабочая Демо:

http://jsbin.com/ovemu (редактируется через http://jsbin.com/ovemu/edit)

Полный источник:

JavaScript

function rotateNav(direction) {
if (direction === 'left') {
  var change = 1;
  $('.navblock5').clone()
    .removeClass('navblock5')
    .addClass('navblock0')
    .appendTo('#nav');
}
else {
  var change = -1;
  $('.navblock1').clone()
    .removeClass('navblock1')
    .addClass('navblock6')
    .appendTo('#nav');
}

$('div.navblock').each(function() {
  var oldClassName = this.className.split(' ')[1],
    oldPos = parseInt(oldClassName.substr(8)),
    newPos = oldPos + change;

    $(this).switchClass(
      oldClassName,
      'navblock'+newPos,
      'fast', 
      function () { 
        var animated = $('.navblock:animated').length;
        if (newPos === 6 || newPos === 0) {
          $(this).remove(); 
        } 
        if (animated === 1) {
          $('#nav').dequeue();
        }
      }
    );
});
}

$(document).ready(function(){
$("#leftnav").click(function() {
  $('#nav').queue(function(){rotateNav('right');});
});
$("#rightnav").click(function() {
  $('#nav').queue(function(){rotateNav('left');});
});
});

CSS

#nav { 
  ширина: 580 пикселей; высота: 120 пикселей; 
  положение: относительное; слева: 150 пикселей; 
  переполнение: скрытое; 
}
.navblock { 
  высота: 100 пикселей; ширина: 100 пикселей; 
  положение: абсолютное; верх: 10 пикселей; z-индекс: 50;
  цвет фона: серый;
}.navblock0 {слева: -110 пикселей; }.navblock1 {слева: 10 пикселей; }
.navblock2 {слева: 120 пикселей; }
.navblock3 {слева: 230 пикселей; ширина: 120 пикселей; высота: 120 пикселей; top: 0;}
.navblock4 {слева: 360px; }
.navblock5 {слева: 470 пикселей; }
.navblock6 {слева: 590 пикселей; }

#leftnav, #rightnav { 
  положение: абсолютное; z-индекс: 100; высота: 120 пикселей; ширина: 228 пикселей;
}
#leftnav {left: 0; }
#rightnav {right: 0; }

/ * Раскомментируйте следующее, чтобы помочь отладке или увидеть внутреннюю работу */
/*
#nav { border: 1px solid green; переполнение: видимое; }

#leftnav, #rightnav {border: 1px solid blue; }
* /

HTML

<div id="nav">
<div id="leftnav"></div>
<div id="rightnav"></div>

<div class="navblock navblock1">one</div>
<div class="navblock navblock2">two</div>
<div class="navblock navblock3">three</div>
<div class="navblock navblock4">four</div>
<div class="navblock navblock5">five</div>

Вы, кажется, на правильном пути. Одна проблема заключается в том, что эта линия

oldPos = parseInt($(this).attr('id').substr(9));

Следует использовать 8 в подстре:

oldPos = parseInt($(this).attr('id').substr(8));

Вместо того, чтобы делать это самостоятельно и тратить время на правильную работу, я предлагаю вам использовать уже существующие решения. Здесь несколько указателей (я думаю, что многие другие можно найти с помощью Google

jQuery: Mac-подобная док-станция

Mac-подобная иконка док (v2)

Меню CSS CSS Dock

jQuery, имитирующий док OS X

Простой OSX-подобный док с jQuery

iconDock jQuery плагин

Другие вопросы по тегам