使用 jquery 的圆形旋转/放大菜单

发布于 2024-08-14 18:40:48 字数 1693 浏览 7 评论 0原文

我正在尝试制作一个包含 5 个项目/图标的菜单,其中所选项目/图标位于中心。单击该居中图标的左侧或右侧,可向左或向右旋转菜单,环绕边缘并将最靠近边缘的项目移回到相对的项目中。单击居中的项目会将您带到其链接的 URL。

菜单也应该以类似于 OS X 扩展坞的方式放大,只不过放大级别是根据位置而不是鼠标悬停设置的。

我做了一个图表,比我的漫谈更容易理解。

替代文本
(来源:yfrog.com

我'我们设法拼凑出一个简单的 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-index,因此浮动在项目/图标上方。

我看过各种 jQuery 插件,但似乎没有一个能满足我的需要。

I'm trying to make a menu that contains 5 items/icons with the selected one being in the center. Clicking to the left or right of this centered icon, rotates the menu left or right, wrapping round the edges and moving whichever item was closest to the edge back in through the opposite one. Clicking on the centered item takes you to its linked URL.

The menu should also magnify in a way similar to the OS X dock except the magnification levels are set based on position not mouseover.

I've made a diagram which is easier to understand than my ramblings.

alt text
(source: yfrog.com)

I've managed to cobble together a simple jQuery version, where the items swap positions as needed, but can't figure out how to animate this movement, especially the wrap around the edges part, and change size based on position.

I'm guessing my code is probably not the best either :)

The HTML is as follows:

<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>

And the 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');
});

});

All the .navblock elements are absolutely positionned. The #leftnav and #rightnav elements also and they have a higher z-index so float above the items/icons.

I've looked at various jQuery plugins but none seem close to what I need.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

空城之時有危險 2024-08-21 18:40:48

您可以更改 CSS 类并使用 jQuery UI 的 switchClass() 方法来设置旋转动画,而不是更改 id 属性(您实际上不应该这样做)。

您还必须执行一些clone()操作,使其看起来像边缘navblock已旋转到小部件的另一侧,并且一些>queue()/dequeue()ing 处理多次点击。

工作演示:

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 { 
  width: 580px; height: 120px; 
  position: relative; left: 150px; 
  overflow: hidden; 
}

.navblock { 
  height: 100px; width: 100px; 
  position: absolute; top: 10px; z-index: 50;
  background-color: grey;
}
.navblock0 { left: -110px; }
.navblock1 { left: 10px; }
.navblock2 { left: 120px; }
.navblock3 { left: 230px; width: 120px; height: 120px; top: 0;}
.navblock4 { left: 360px; }
.navblock5 { left: 470px; }
.navblock6 { left: 590px; }

#leftnav, #rightnav { 
  position: absolute; z-index: 100; height: 120px; width: 228px;
}
#leftnav { left: 0; }
#rightnav { right: 0; }

/*Uncomment the following to help debug or see the inner workings */
/*
#nav { border: 1px solid green; overflow: visible; }
#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>

Instead of changing id attributes (which you really shouldn't do in the first place) you can change CSS classes and use jQuery UI's switchClass() method to animate the rotation.

You would also have to do a bit of clone()ing to make it look like the edge navblocks have rotated around to the other side of the widget and some queue()/dequeue()ing to handle multiple clicks.

Working Demo:

http://jsbin.com/ovemu (editable via http://jsbin.com/ovemu/edit)

Full Source:

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 { 
  width: 580px; height: 120px; 
  position: relative; left: 150px; 
  overflow: hidden; 
}

.navblock { 
  height: 100px; width: 100px; 
  position: absolute; top: 10px; z-index: 50;
  background-color: grey;
}
.navblock0 { left: -110px; }
.navblock1 { left: 10px; }
.navblock2 { left: 120px; }
.navblock3 { left: 230px; width: 120px; height: 120px; top: 0;}
.navblock4 { left: 360px; }
.navblock5 { left: 470px; }
.navblock6 { left: 590px; }

#leftnav, #rightnav { 
  position: absolute; z-index: 100; height: 120px; width: 228px;
}
#leftnav { left: 0; }
#rightnav { right: 0; }

/*Uncomment the following to help debug or see the inner workings */
/*
#nav { border: 1px solid green; overflow: visible; }
#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>
秋叶绚丽 2024-08-21 18:40:48

我建议您使用现有的解决方案,而不是自己执行此操作并浪费时间使其正常工作。这里有一些提示(我想可以通过使用谷歌找到更多提示

jQuery:类似Mac的Dock

类似 Mac 的图标底座 (v2)

MAC CSS Dock 菜单

jQuery 模仿 OS X 停靠栏

使用 jQuery 的类似 OSX 的简单底座

iconDock jQuery 插件

Instead of doing this yourself and wasting time on getting this to work properly I suggest you use existing solutions ones. Here a few pointers (I guess many more can be found by using google

jQuery: Mac-like Dock

Mac-like icon dock (v2)

MAC CSS Dock Menu

jQuery mimicking the OS X dock

Simple OSX-like dock with jQuery

iconDock jQuery Plugin

泪冰清 2024-08-21 18:40:48

你似乎走在正确的轨道上。一个问题是这一行

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

应该在子字符串中使用 8:

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

You seem to be on the right track. One issue is that this line

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

Should use 8 in the substr:

oldPos = parseInt($(this).attr('id').substr(8));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文