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

标签 jquery html5 css3 fancybox css-transitions

我想要达到的效果是点击一个按钮,一个由8个三角形组成的圆就会旋转。当它停止时,将选择圆顶部的三角形。然后打开相对于所选段的fancybox覆盖(最后一部分还不起作用)。段的选择顺序对用户来说是随机的,但它可以像我在CSS中所做的那样预先设置(当前:3>6>1>8>2>5>7>4)。
我已经创建了一个代码笔来显示我目前在这方面的进展,你可以通过访问下面的链接看到,因为这很难解释。

http://codepen.io/moy/pen/DrbAL

单击“旋转”按钮,圆圈旋转3次(1080度)+额外270度,因此第三个列表项位于div的顶部-这很好。
我的第一个问题是:在第二次单击按钮时,圆圈需要再次旋转3次,然后再稍微旋转一点,以将下一个选定的列表项/段(6)放置在div的顶部,依此类推。有没有一种方法可以做到这一点,而不必将1080添加到圆已经旋转的量上??因此该值总是1080deg+圆需要旋转的附加量,以将相关段定位在div的顶部。否则,最后一项的值将是10000度左右!如果必须这样做的话,我想我得忍受它,戴上数学帽子。
第二个问题是:一旦圆完成旋转,如何显示相关的fancybox覆盖?ID是当前每个覆盖的标题,但可以很容易地是overlay-1、overlay-2等,以匹配每次旋转后设置在旋转轮上的spin-1、spin-2的类。
谢谢,希望有人能帮忙!

最佳答案

我觉得这个问题很有趣,因为我以前做过一个类似的项目,所以这是我的输入。首先,我建议您在动画中使用Julian Shapiro的velocity插件,这将为您提供以下一些优点:
更少和更干净的代码,没有混乱(对于css和javascript)
Javascript动画比CSS3动画快(有争议)。阅读this了解更多
你不必来回切换css类来实现你的动画(你也不必手动设置和计算在css规则中旋转多少度)
有了速度,转动车轮可以简单地做到:

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

velocity插件有一整套API选项,您可以探索here。当然,您需要一个算法来计算每个degreeclick变量的新值。
现在,如果我理解正确,你有两个问题:
如何计算旋转到车轮的度数以及在下一个所需位置的止动块。
如何确定选定的段(在控制盘顶部)是什么,而不管它是预设的还是随机选择的,然后启动相应的fancybox。
我将使用以下算法开始回答第二个问题:
_target = (_deg - (360 * parseInt(_deg / 360))) / 45;

其中_target是所选段的javascriptindex,而_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;

如果您认为在javascript中,组的第一个元素有index=0,第二个元素是index=1,第三个元素是index=2,等等。_target = 2实际上指向第三个部分(团队工作)。不管你旋转了多少度,这个算法都能工作。
那么发射fancybox很简单:
$(".fancybox").eq(_target).trigger("click");

上面的代码假设您已经在脚本中的某个地方初始化了fancybox,比如
$(".fancybox").fancybox({ // API options });

现在,对于第一个问题,我看到了3种可能的算法,您可以在一个单独的函数中设置它们,以便在buttonclick之后调用:
相继的:
返回一个模式化顺序(每个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来更改模式。
因此,我们将旋转轮子的度数,我们可以使用速度来:
将所有分段的不透明度重置为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

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

The code is basically the same but the algorithm a little bit more complex. First we need to preset the order within an array along with other support variables:

var presetPos = [3, 6, 1, 8, 2, 5, 7, 4],
    presetInit = true,
    spin_count = 0;

注意presetPos数组包含实际的段号,而不是javascriptindex。还要注意标志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;
    };
};

JSFIDDLE
随机:
返回0-7范围内的随机顺序。
随机算法非常简单。参见this以供参考。
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;

然后,使用index方法从数组中移除随机选择的.splice()以确保不再使用它,这一点很重要。
单击事件的代码:
$(".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

JSFIDDLE
最后注释:
我删除了不必要的css选择器和transform效果(.wheel.spin-1.wheel.spin-2.wheel.spin-3,等等)
有许多设置(如动画的duration等),您可能需要根据自己的喜好和需要进行调整。

关于jquery - 旋转div onClick-在不同程度之间循环(命运之轮),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25806732/

相关文章:

css - flex 自动填充空间,不拉伸(stretch)

jquery - Hashbang 和逃脱的片段

jquery - 浏览器问题的多个打开选项卡的客户端脚本变量范围

javascript - 如果没有所需的值,则将文本框聚焦在焦点上

jquery - 如果页面高度动态变化,带 id 的链接不起作用

html - 如何使用CSS将更改应用于“选择”选项

javascript - 纯JavaScript文本 slider ,可更改php中文本的显示

javascript - html textarea的富文本编辑器替换

html - 图像 slider 过度滚动

css - Css3 div Angular 之一应向内