旋转div onClick - 循环不同程度(命运之轮)

use*_*440 2 jquery html5 css3 fancybox css-transitions

我试图实现的效果是点击一个按钮,一个由8个三角形组成的圆圈旋转.当它停止时,选择圆顶顶部的三角形.然后打开相对于所选段的fancybox覆盖(最后一部分尚未工作).选择段的顺序对用户来说是随机的,但可以像我在CSS中那样预设(当前:第3>第6>第1>第8>第2>第5>第7>第4).

我已经创建了一个codepen来显示我目前的进展,你可以通过访问下面的链接看到它很难解释.

http://codepen.io/moy/pen/DrbAL
Run Code Online (Sandbox Code Playgroud)

单击"旋转"按钮时,圆圈旋转3次(1080度)+另外270度,因此第3个列表项目位于div的顶部 - 这样可以正常工作.

我的第一个问题是:在第二次点击按钮时,圆圈需要再次旋转3次然后再多一点,将下一个选定的列表项/段(6)定位在div的顶部,依此类推其余的项目.有没有办法做到这一点,而不必添加1080到圆已经旋转的数量?因此,值始终为1080deg+圆圈需要旋转以将相关线段定位在div顶部的额外量.否则,最后一项的值将达到10000度!如果必须这样做,我想我将不得不忍受它,并得到我的数学帽子.

第二个问题是:一旦圆圈完成旋转,我该如何显示相关的fancybox叠加?ID目前是每个叠加的标题,但可以很容易地覆盖-1,叠加-2等,以匹配每次旋转后在旋转轮上设置的spin-1,spin-2的类别.

谢谢,希望有人能帮忙!

JFK*_*JFK 6

我发现这个问题很有意思,因为我前段时间做了一个类似的项目,所以这是我的意见.首先,我建议你使用Julian Shapiro的速度插件为你的动画,这将给你一些以下优点:

  • 没有混乱的更少和更清洁的代码(对于css和javascript)
  • Javascript动画(可论证)比CSS3动画更快.阅读本文了解更多
  • 您不必来回切换css类来实现动画(并且您不必手动预设和计算在css规则中旋转的度数)

通过速度,旋转您的车轮可以像下面这样简单:

$(".wheel").velocity({
    rotateZ : "-" + {degree} + "deg" // "-" minus to spin counterclockwise, remove otherwise
});
Run Code Online (Sandbox Code Playgroud)

速度插件拥有全套的,你可以探索API选择这里.当然,您需要一个算法来计算degree每个变量的新值click.

现在,如果我理解正确,你有两个问题:

  • 如何计算旋转到车轮的度数和在下一个想要的位置停止.
  • 无论是预设还是随机选择,如何确定选定的段(在车轮顶部),然后启动相应的fancybox.

我将开始用以下算法回答第二个问题:

_target = (_deg - (360 * parseInt(_deg / 360))) / 45;
Run Code Online (Sandbox Code Playgroud)

其中_targetindex所选片段的javascript 以及_deg我们将轮子从前一个位置旋转到当前位置的度数.

这个怎么运作 :

按照上面的例子,您的车轮的初始状态是1号段(商业意识),从那里您需要移动到3号(团队工作),所以这意味着将车轮旋转3次(1080度)+ 2更多的每段45度(90度)= 1170 degrees旋转.

所以,将该值应用于算法:

_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;
Run Code Online (Sandbox Code Playgroud)

如果你认为在javascript中组的第一个元素有index=0,第二个是index=1,第三个是index=2,等等_target = 2实际指向第三个段(Team Work).无论您旋转多少度,该算法都能正常工作.

然后发射fancybox很简单:

$(".fancybox").eq(_target).trigger("click");
Run Code Online (Sandbox Code Playgroud)

上面的代码假设您已经在脚本中的某处初始化了fancybox

$(".fancybox").fancybox({ // API options });
Run Code Online (Sandbox Code Playgroud)

现在,对于第一个问题,我看到3种可能的算法,您可以在单独的函数中设置以在按钮后调用click:

顺序:

返回一个图案化的顺序(每个前进3个段click),如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;
};
Run Code Online (Sandbox Code Playgroud)

它假定初始值为_deg = 0.请注意,您始终可以更改因子3以更改模式.

因此,我们将旋转车轮的度数,我们可以使用速度:

  • 将所有细分的不透明度重置为 1
  • 旋转车轮
  • 将所选片段的不透明度设置为 0.4
  • 触发所选片段的相应fancybox

完整的代码

// 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
Run Code Online (Sandbox Code Playgroud)

请参阅JSFIDDLE

注意在其complete回调中使用嵌套的*velocity函数

*编辑:如果您使用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;
Run Code Online (Sandbox Code Playgroud)

请注意,presetPos数组包含实际的段号而不是javascript index.还要注意标志的使用presetInit,它告诉车轮是否处于初始状态(我们将false在第一次旋转后将其切换到)

预设算法的调味料是计算阵列中currentnext段与段之间的差异(以度为单位),以便我们知道车轮需要旋转多少度:

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;
    };
};
Run Code Online (Sandbox Code Playgroud)

请参阅JSFIDDLE

随机:

返回0-7范围内的随机顺序.

随机算法非常简单.请参阅参考.

function ordRandom() {
    return _deg = _deg + ((Math.floor(Math.random() * (8 - 1 + 1)) + 0) * 45) + 1080;
};
Run Code Online (Sandbox Code Playgroud)

然而,click方法内部的逻辑有点复杂.在您理想的世界中,所选片段应该是完全随机的,但从不选择之前使用过的片段.一旦8选择了所有结束(按钮将停止旋转车轮).

有几个因素要考虑:首先,我们需要一个数组来说明从未使用过哪些段.

var _index = [0,1,2,3,4,5,6,7];
Run Code Online (Sandbox Code Playgroud)

请注意,此数组是关于index每个段的.

另外,我们需要一个标志,让我们循环(使用while)随机选择,直到找到一个index从未使用过的标志.

var _repeatRandom = true;
Run Code Online (Sandbox Code Playgroud)

然后,index使用该.splice()方法删除从数组中选择的随机数非常重要,以确保我们不会再次使用它.

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
Run Code Online (Sandbox Code Playgroud)

请参阅JSFIDDLE

最后的说明:

  • 我除去不必要CSS选择和transform效果(.wheel.spin-1,.wheel.spin-2,.wheel.spin-3等)
  • 有许多设置(如duration动画等),您可能需要根据自己的喜好和需求进行调整.