搜索

首页  >  问答  >  正文

javascript - 一个类环形旋转菜单实现?

设计图是这样的,点击其中一个元素,然后会按照那条白色的链子弧形移动
,像一个转盘一样,请问这样的话,怎么样实现比较简单快捷,求个思路。

-------补充-------
移动端的,其实这一块就算是一个整体了,只是线跟图标变化的话其实难度不大,但是需要的是图标也会跟着移动

迷茫迷茫2721 天前978

全部回复(6)我来回复

  • 伊谢尔伦

    伊谢尔伦2017-06-12 09:28:23

    图标不动 圆环转动 可行?

    回复
    0
  • PHP中文网

    PHP中文网2017-06-12 09:28:23

    整体 做一个超大的块, 视口 小, 点击的时候, 超大块 旋转就可以了。 这个超大块就是 圆环 和 小图标做成的一个整体 (或者 将 圆环和小图标做成两个整体, 两个块的宽高 和 圆环的设计直径 应该是一样的 , 这样 小图标的 大块 旋转的时候 才能无缝和 圆环衔接)

    回复
    0
  • 我想大声告诉你

    我想大声告诉你2017-06-12 09:28:23

    几个class将元素定位,存储class名在一个数组中,当点击一个元素,依次切换每个元素的class,要想要动画效果可以在每个class中添加transition

    这是一个大概思路,你可以试试。

    回复
    0
  • 巴扎黑

    巴扎黑2017-06-12 09:28:23

    我只能讨论一下。。。因为不确定,

    如果用那根链子要动---如果用css或者js动画,想起来那是一个很大的元素旋转。。。性能得试了才知道
    那就考虑用canvas画,那就麻烦了呀,我想法大环不动,计算环形中每个方块的位置和角度。。不知道有没有这方面的框架什么的,本身自身的canvas不熟悉,总之,很麻烦。

    然后是每个图标。。这个用css或者js都行。。关键是涉及事件呀。。canvas元素跟事件怎么联系我也没研究过。。。

    这只是一个菜鸟的想法。。看看其他人的

    回复
    0
  • typecho

    typecho2017-06-12 09:28:23

    思路:排列条目,计算偏移值(绝对中点,底部居中),点击条目获取索引对应的索引,索引比对偏移值,左侧逆时针,右侧顺时针,每次动画完成,重排图标顺序。

    需要注意:

    • 这个应该和无限循环滚动是一样的结构,需要 前中后 有三组原始数据,这样才能实现顺时针和逆时针都能补全。

    • 为了兼容性,建议动画仅作为一个过场使用,即点击条目时使用,动画完成动态调整条目的排序,并重绘列表,即每次动画都是一次数组排序操作;

    技术实现方案:

    • 用 css3 实现,难点在 css3 旋转动画;

    • 用 canvas 绘制,关键帧原理;

    • 用 svg 制作,原理和 canvas 类似,只是图形是矢量的;

    • 使用 mp4 视频,参考 https://www.apple.com/cn/mac-... ;

    • 使用关键帧动画,较为复杂;

    具体实现还是比较麻烦的,你可以搜索下相关的弧形排列插件、css3 动画等。个人觉得 canvas 和 svg 比较靠谱。抛砖引玉吧,具体的期待大神。

    回复
    0
  • 迷茫

    迷茫2017-06-12 09:28:23

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
    
            html,
            body,
            .wrap {
                width: 100%;
                height: 100%;
            }
    
            .wrap {
                position: fixed;
                top: 0;
                left: 0;
            }
    
            .annulus {
                position: absolute;
                top: -552px;
                left: 0;
                right: 0;
                margin: auto;
                width: 1000px;
                height: 1000px;
                border-radius: 50%;
                border: 1px solid #ccc;
            }
    
            .annulus__bg {
                position: absolute;
                top: 0;
                right: 0;
                left: 0;
                bottom: 0;
                margin: auto;
                border-radius: 50%;
                width: 100%;
                height: 100%;
                background: #fff url(YaoMing.jpg) center center no-repeat;
                border: 1px solid #ccc;
                transition: all 0.5s linear;
            }
    
            .annulus__item {
                position: absolute;
                top: 0;
                right: 0;
                left: 0;
                bottom: 0;
                margin: auto;
                width: 100px;
                height: 100px;
                border-radius: 50%;
                background: #fff url(YaoMing.jpg) center center / cover no-repeat;
                border: 1px solid #ccc;
                transition: all 0.5s linear;
            }
        </style>
        <script>
            onload = () => {
                var dataArr = [
                    "90|-90", "60|-60", "30|-30", "0|0", "-30|30", "-60|60", "-90|90"
                ], numArr = [
                    0, 1, 2, 3, 4, 5, 6
                ], lock = false;
                document.querySelectorAll(".annulus__item").forEach((v, i) => {
                    document.querySelector(".annulus__item--" + numArr[i]).style.transform =
                        "rotate(" + dataArr[i].split("|")[0] + "deg) translateY(500px) rotate(" + dataArr[i].split("|")[1] + "deg)";
                    v.addEventListener("click", function () {
                        if(lock) return false;
                        lock = true;
                        setTimeout(function() { lock = false; }, 500);
                        var content = numArr[3], target = /\d+$/.exec(this.className)[0];
                        if(+content + 1 == target || content - 6 == target) {
                            mainDeg += 30;
                            numArr.push(numArr.shift());
                            document.querySelector(".annulus__bg").style.transform = "rotate(" + mainDeg + "deg)";
                            document.querySelector(".annulus__item--" + numArr[6]).style.transition = "none";
                            setTimeout(() => { document.querySelector(".annulus__item--" + numArr[6]).style.transition = "all 0.5s linear"; }, 0);
                        } else if (content - 1 == target || content + 6 == target) {
                            mainDeg -= 30;
                            numArr.unshift(numArr.pop());
                            document.querySelector(".annulus__bg").style.transform = "rotate(" + mainDeg + "deg)";
                            document.querySelector(".annulus__item--" + numArr[0]).style.transition = "none";
                            setTimeout(() => { document.querySelector(".annulus__item--" + numArr[0]).style.transition = "all 0.5s linear"; }, 0);
                        }                    
                        for (var i = 0; i < 7; i++) {
                            document.querySelector(".annulus__item--" + numArr[i]).style.transform =
                                "rotate(" + dataArr[i].split("|")[0] + "deg) translateY(500px) rotate(" + dataArr[i].split("|")[1] + "deg)";
                        }
                    });
                });
                var mainDeg = 0;
                onkeydown = (event) => {
                    if (event.keyCode === 37) {
                        mainDeg += 30;
                        document.querySelector(".annulus__bg").style.transform = "rotate(" + mainDeg + "deg)";
                        numArr.push(numArr.shift());
                        document.querySelector(".annulus__item--" + numArr[6]).style.transition = "none";
                        setTimeout(() => { document.querySelector(".annulus__item--" + numArr[6]).style.transition = "all 0.5s linear"; }, 0);
                        for (var i = 0; i < 7; i++) {
                            document.querySelector(".annulus__item--" + numArr[i]).style.transform =
                                "rotate(" + dataArr[i].split("|")[0] + "deg) translateY(500px) rotate(" + dataArr[i].split("|")[1] + "deg)";
                        }
                    }
                    if (event.keyCode === 39) {
                        mainDeg -= 30;
                        document.querySelector(".annulus__bg").style.transform = "rotate(" + mainDeg + "deg)";
                        numArr.unshift(numArr.pop());
                        document.querySelector(".annulus__item--" + numArr[0]).style.transition = "none";
                        setTimeout(() => { document.querySelector(".annulus__item--" + numArr[0]).style.transition = "all 0.5s linear"; }, 0);
                        for (var i = 0; i < 7; i++) {
                            document.querySelector(".annulus__item--" + numArr[i]).style.transform =
                                "rotate(" + dataArr[i].split("|")[0] + "deg) translateY(500px) rotate(" + dataArr[i].split("|")[1] + "deg)";
                        }
                    }
                }
            }
        </script>
    </head>
    
    <body>
        <p class="wrap">
            <p class="annulus">
                <p class="annulus__bg"></p>
                <p class="annulus__item annulus__item--0"></p>
                <p class="annulus__item annulus__item--1"></p>
                <p class="annulus__item annulus__item--2"></p>
                <p class="annulus__item annulus__item--3"></p>
                <p class="annulus__item annulus__item--4"></p>
                <p class="annulus__item annulus__item--5"></p>
                <p class="annulus__item annulus__item--6"></p>
            </p>
        </p>
    </body>
    
    </html>

    上代码,把图片换一下就可以了
    很简陋,抛砖引玉用

    回复
    0
  • 取消回复