我想要实现的效果是在点击按钮时,一个由8个三角形组成的圆圈旋转。当它停止时,三角形在圆的顶部被选中。然后打开一个相对于所选段的花哨框覆盖(最后一部分还不起作用)。片段的选择顺序对用户来说是随机的,但它可以像我在CSS中所做的那样预先设置(目前:第3>第6>第1>第8>第2>第5>第7>第4)。
我已经创建了一个codepen来显示我目前在这方面的进展,你可以通过访问下面的链接看到,因为它很难解释。
http://codepen.io/moy/pen/DrbAL
点击"旋转"按钮,圆圈旋转3次(1080度)+额外的270度,所以第三个列表项位于div的顶部-这很好。
我的第一个问题是:在第二次点击按钮时,圆圈需要再次旋转3次,然后再旋转一点,以将下一个选定的列表项/段(6)定位在div的顶部,以此类推,用于每个剩余的项目。有没有一种方法可以做到这一点,而不必在圆已经旋转的量上增加1080 ?因此,该值始终是1080deg
+圆圈需要旋转的额外量,以将相关部分定位在div的顶部。否则,最后一项的值将是类似10000度的值!如果这是必须做的,我想我将不得不忍受它,把我的数学帽戴上。
第二个问题是:一旦圆完成旋转,我如何显示相关的花哨盒子覆盖?ID目前是每个覆盖的标题,但可以很容易地为overlay-1, overlay-2等,以匹配每次旋转后在纺轮上设置的spin-1, spin-2类。
谢谢,希望有人能帮忙!
我发现这个问题很有趣,因为我以前做过一个类似的项目,所以这是我的输入。首先,我建议你使用朱利安夏皮罗的速度插件为您的动画,这将给你一些以下优势:
- 更少更干净的代码没有杂乱(css和javascript)
- Javascript动画(有争议的)比CSS3动画快。更多
- 你不需要来回切换css类来实现你的动画(你不需要手动预设和计算多少度旋转在你的css规则)
有了速度,旋转你的轮子可以做得很简单:
$(".wheel").velocity({
rotateZ : "-" + {degree} + "deg" // "-" minus to spin counterclockwise, remove otherwise
});
velocity插件有一整套API选项,你可以在这里探索。当然,您需要一个算法来计算每个click
上degree
变量的新值。
现在,如果我理解正确的话,你有两个问题:
- 如何计算旋转到车轮的度数,并在下一个想要的位置停止。
- 如何确定选择的段(在车轮顶部)是什么,无论它是预设的还是随机选择的,然后启动相应的fancybox。
我将开始回答第二使用以下算法的问题:
_target = (_deg - (360 * parseInt(_deg / 360))) / 45;
其中_target
是所选片段的javascriptindex
,_deg
是我们从前一个位置旋转到当前位置的度数。
工作原理:
按照上面的例子,你的轮子的初始状态是第1段(商业意识),从那里你需要移动到第3段(团队工作),所以这意味着旋转轮子3次(1080度)+ 2个45度(90度)的部分=1170 degrees
旋转。
so,将该值应用于算法:
_target = (1170 - (360 * parseInt(1170 / 360))) / 45;
_target = (1170 - (360 * parseInt(3.25))) / 45;
_target = (1170 - (360 * 3)) / 45;
_target = (1170 - (1080)) / 45;
_target = (90) / 45;
_target = 2;
如果你认为在javascript中,一个组的第一个元素有index=0
,第二个是index=1
,第三个是index=2
,等等。_target = 2
实际上指向第三部分(团队工作)。无论你旋转了多少度,这个算法都有效。
那么启动fancybox很简单:
$(".fancybox").eq(_target).trigger("click");
上面的代码假设您已经在脚本的某个地方初始化了fancybox,例如
$(".fancybox").fancybox({ // API options });
现在,对于第一个我看到3种可能的算法,你可以在一个单独的函数中设置,在按钮click
之后调用:
返回一个模式顺序(每个click
前进3段),如1,4,7,2,5,8,3,6…然后循环。每个片段在循环前至少显示一次,因此:
function ordSequential() {
// order : 1,4,7,2,5,8,3,6 ... then loops
return _deg = _deg + (45*3) + 1080;
};
假设初始值为_deg = 0
。注意,您总是可以更改因子3
来更改模式。
有了旋转轮子的角度,我们可以使用velocity来:
- 重置所有段的不透明度为
1
- 旋转轮子
- 设置所选段的不透明度为
0.4
- 触发所选段对应的fanybox
完整代码
// sequential order
// advances 3 segments each click
var _target, _deg = 0;
function ordSequential() {
// order : 1,4,7,2,5,8,3,6 ... then loops
return _deg = _deg + (45*3) + 1080;
};
jQuery(document).ready(function ($) {
$(".skills-wheel .btn").on("click", function (e) {
// select algorithm sequential, random or preset :
ordSequential();
_target = (_deg - (360 * parseInt(_deg / 360))) / 45;
// start animation
// reset opacity of all segments to 1
$(".fancybox").parent("li").velocity({
opacity: 1
}, {
duration: 100,
complete: function () {
$(".wheel").velocity({
rotateZ: "-" + _deg + "deg"
}, {
duration: 3000,
complete: function (elements) {
// after spinning animation is completed, set opacity of target segment's parent
$(".fancybox").parent("li").eq(_target).velocity({
opacity: 0.4
}, {
duration: 100,
// after opacity is completed, fire targeted segment in fancybox
complete: function () {
$(".fancybox").eq(_target).trigger("click");
} // third animation completed
}); // nested velocity 2
} // second animation completed
}); // nested velocity 1
} // first animation completed
}); // velocity
return false;
}); // click
// initialize fancybox
$(".fancybox").fancybox({
maxWidth: "85%"
});
}); // ready
<<p>看到strong> JSFIDDLE注意在complete
回调函数
*编辑如果你正在使用Velocity的UI包,你可以使用
.RunSequence()
函数使嵌套动画序列更易于管理。参见更新后的JSFIDDLE使用此方法。请确保您使用的是最新版本的Velocity.js和UI pack (v1.1.0截至今天[2014年10月8日])http://cdnjs.com/libraries/velocity
预设:
返回一个预设的顺序,就像上面的例子
3rd> 6th> 1st> 8th> 2nd> 5th> 7th> 4th
代码基本相同,但算法稍微复杂一点。首先,我们需要预置数组中的顺序以及其他支持变量:
var presetPos = [3, 6, 1, 8, 2, 5, 7, 4],
presetInit = true,
spin_count = 0;
注意presetPos
数组包含实际的段号,而不是javascript的index
。还要注意使用的标志presetInit
,它告诉车轮是否处于初始状态(我们将在第一次旋转后将其切换为false
)
current
和next
段之间的差值(以度为单位),这样我们就知道轮子需要旋转多少度:
function ordPreset() {
// initial state?
if (presetInit) {
presetInit = false;
return _deg = _deg + ((presetPos[spin_count] - 1) * 45) + 1080;
} else {
var _current = presetPos[spin_count];
var _next = presetPos[spin_count > 6 ? 0 : spin_count + 1];
var _diff = _next - _current;
spin_count = spin_count > 6 ? 0 : ++spin_count;
return _deg = _deg + (_diff * 45) + 1080;
};
};
<<p>看到strong> JSFIDDLE 随机:返回0-7范围内的随机顺序。
随机算法非常简单。参考
function ordRandom() {
return _deg = _deg + ((Math.floor(Math.random() * (8 - 1 + 1)) + 0) * 45) + 1080;
};
然而,click
方法内部的逻辑要复杂一些。在理想情况下,所选择的段应该是完全随机的,但不要选择以前使用过的段。一旦所有的8
都被选中,这将是结束(按钮将停止旋转轮子)。
需要考虑以下几个因素:首先,我们需要一个数组来告诉我们哪些段从未被使用过。
var _index = [0,1,2,3,4,5,6,7];
注意这个数组是关于每个片段的index
的。
另外,我们需要一个标志让我们循环(使用while
)通过随机选择,直到我们找到一个从未使用过的index
。
var _repeatRandom = true;
然后,重要的是要使用.splice()
方法从数组中删除随机选择的index
,以确保我们不会再次使用它。
click事件的代码:
$(".skills-wheel .btn").on("click", function (e) {
// select algorithm sequential, random or preset :
// if random order, don't repeat the same
_repeatRandom = _index.length == 0 ? false : true;
// loop until find one that has never been used
while (_repeatRandom) {
ordRandom();
_target = (_deg - (360 * parseInt(_deg / 360))) / 45;
var _inArray = $.inArray(_target, _index);
if (_inArray > -1) {
// target is in the array
_repeatRandom = false; // break while loop
_index.splice(_inArray, 1); // remove segment from array so it won't be repeated
// start animation
// reset opacity of all segments to 1
$(".fancybox").parent("li").velocity({
opacity : 1
}, {
duration : 100,
complete : function () {
$(".wheel").velocity({
rotateZ : "-" + _deg + "deg"
}, {
// addtional settings and callback
duration : 3000,
complete : function (elements) {
// after spinning animation is completed, set opacity of target segment's parent
$(".fancybox").parent("li").eq(_target).velocity({
opacity : 0.4
}, {
duration : 100,
// after opacity is completed, fire targeted segment in fancybox
complete : function () {
$(".fancybox").eq(_target).trigger("click");
} // third animation completed
}); // nested velocity 2
} // second animation completed
}); // nested velocity 1
} // first animation completed
}); // velocity
}; // if
}; // while
return false;
}); // click
<<p>看到strong> JSFIDDLE 去年指出:
- 我删除了不必要的css选择器和
transform
效果(.wheel.spin-1
,.wheel.spin-2
,.wheel.spin-3
等) - 有许多设置(如
duration
的动画等),你可能想调整你的喜好和需要。