本文介绍了多个元素循环移动 - 平滑过渡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 n 元素来创建圆形导航,方法是单击键盘的向左和向右箭头。我使用类具有特定的CSS3 rotate translate 值和一点javascript为了更改类所以。

I'm attempting to create a circular navigation with n elements navigable by clicking the keyboard's right and left arrows. I use classes with specific CSS3 rotate and translate values and a little bit of javascript in order to change the classes to do so.

我的问题是类之间的转换 / code>,在 360deg 30deg 之间转换,想要它。您可以查看明显的不必要的行为

My problem is that the transition between elements with classes four and five, the one that translates between 360deg and 30deg, which goes in the opposite direction than I want it to. You can see the obvious unwanted behavior here in this jsFiddle

.one    { transform: rotate(270deg) translate(200px); }
.two    { transform: rotate(300deg) translate(200px); }
.three  { transform: rotate(330deg) translate(200px); }
.four   { transform: rotate(360deg) translate(200px); }<-- Problematic transition
.five   { transform: rotate(30deg)  translate(200px); }<-- Problematic transition
.six    { transform: rotate(60deg)  translate(200px); }
.seven  { transform: rotate(90deg)  translate(200px); }
.eight  { transform: rotate(120deg) translate(200px); }
.nine   { transform: rotate(150deg) translate(200px); }
.ten    { transform: rotate(180deg) translate(200px); }
.eleven { transform: rotate(210deg) translate(200px); }
.twelve { transform: rotate(240deg) translate(200px); }

我想要一个CSS修复这个,但我也尝试了一个javascript可以找到。我在这个例子中只尝试使用左箭头。我的javascript方法是获取当前翻译的字符串形式的值,从其中剥离旋转度,并从它添加或减去30度取决于是否右或按下左箭头。这种方法的当前问题是它不给我一个值 element.style.webkitTransform (我使用Chrome),它只是空的某种原因。另外,我不想在javascript中的所有内容前缀,因此我想要一个CSS只是解决的原因

I would prefer a CSS fix for this, but I also attempted a javascript one which can be found here. I only attempted using the left arrow in this example. My approach with javascript is to obtain the current translated value in string form, strip the rotate degree from it, and add or subtract 30 degrees from it depending on whether or not the right or left arrow is pressed. The current problem with this approach is that it does not give me a value for element.style.webkitTransform (I'm using the Chrome), it's just empty for some reason. Also I'd prefer not to have to prefix everything in the javascript, thus the reason why I would like a CSS only fix

我尝试在javascript(未经测试,因为第一行由于某种原因不工作):

My attempt at the javascript (untested because the first line won't work for some reason):

var thisTransform = circleArray[i].style.webkitTransform;
if (thisTransform.indexOf("rotate(") >= 0) {
    var newDeg = parseInt(thisTransform.split("rotate(")[1].substring(thisTransform.indexOf("deg"))) - 30;
    circleArray[i].style.webkitTransform = "rotate(" + newDeg + "deg) translate(200px) !important;";
}

注意:我在我的项目中使用prefixfree.min.js来防止表单必须手动输入所有的浏览器前缀

Side note: I use prefixfree.min.js in my project to prevent form having to manually input all of the browser prefixes

有没有CSS只修复我的问题,我不知道?当尝试获取翻译时导致错误 value using javascript?

Is there a CSS only fix for my problem that I am unaware of? What is causing the error when attempting to obtain the translate value using javascript?

推荐答案

首先,让我说我认为最好的解决方案旋转基圆;我几乎可以肯定,结果会更好,更容易。

First of all, let me say that I think that probably the best solution would be just rotate the base circle; I am almost sure that the results would be better and easier.

但这只是一个并排的想法,让我们去你的问题。

But this is just an by side idea, let's go to the problem that you post.

我已经对你的问题做了工作,创建一个类,可以正确移动有问题的类。我的想法是提供一个动画,做运动确定:

I have done a workaroud to your problem creating a class that will move correctly the problematic classes. My idea is to provide an animation that does the movement ok:

.foura   { -webkit-transform: rotate(360deg) translate(200px);
    -webkit-animation: aclock .3s linear 1;
    transform: rotate(360deg) translate(200px);
    animation: aclock .3s linear 1;
    transition: none;
}
@keyframes aclock {
    0% {transform: rotate(30deg) translate(200px);}
   100% {transform: rotate(0deg) translate(200px);}
}

这个想法是从30度到360度的移动

The idea is that the movement from 30 deg to 360 deg, being done thru an animation, can be changed to go from 30 deg to 0 deg.

我为第五类提供另一个类似的类。

I provide another similar class for class five.

剩下的问题是,脚本必须将元素设置为四级或四级,这取决于旋转的感觉,五和五的相同。

The remaining problem is that the script must set the element to class four or foura depending on the rotation sense, and the same for five and fivea.

这导致了(有点混乱)脚本:

This lead to that (somewhat messy) script:

document.onkeydown = function (e) {
    e = e || window.event;
    switch(e.which || e.keyCode) {
        case 37:
            for (var i = 0, j = circleArray.length; i < j; i++) {
                var curClassList = circleArray[i].classList,
                    curClass = curClassList.toString().split(' ')[1];
                    baseClass = curClass;
                    if (baseClass == "fivea") {
                        baseClass = "five";
            }
                    if (baseClass  == "foura") {
                        baseClass  = "four";
            }

                if(circleClassArray.indexOf(baseClass) - 1 >= 0)
                {
                    var newClass = circleClassArray[circleClassArray.indexOf(baseClass) - 1];
                    if (newClass == "four") {
                        newClass = "foura";
            }
                    curClassList.add(newClass)
                    curClassList.remove(curClass);
                } else {
                    curClassList.add(circleClassArray[j - 1]);
                    curClassList.remove(curClass);
                }
            }
            break;
        case 39:
            for (var i = 0, j = circleArray.length; i < j; i++) {
                var curClassList = circleArray[i].classList,
                    curClass = curClassList.toString().split(' ')[1];
                    baseClass = curClass;
                    if (baseClass == "fivea") {
                        baseClass = "five";
            }
                    if (baseClass  == "foura") {
                        baseClass  = "four";
            }
                if(circleClassArray.indexOf(baseClass) + 1 < j)
                {
                    var newClass = circleClassArray[circleClassArray.indexOf(baseClass) + 1];
                    if (newClass == "five") {
                        newClass = "fivea";
            }
                    curClassList.add(newClass)
                    curClassList.remove(curClass);
                } else {
                    curClassList.add(circleClassArray[0]);
                    curClassList.remove(curClass);
                }
            }
            break;
    }
}

这是完整的CSS:

.circle-big {
    position: relative;
    height:500px;
    width:500px;
    background:red;
    border-radius: 50% 50%;
    margin: 10% 10%;
    border:5px solid black;
}
.circle-inner {
    border-radius: 50%;
    width: 300px;
    height: 300px;
    border: 5px solid white;
    background-color: black;
    display: block;
    position: absolute;
    overflow: hidden;
    top: 50%;
    left: 50%;
    margin-top:-155px;
    margin-left:-155px;
}
.circle {
    border-radius: 50%;
    width: 70px;
    height: 70px;
    background-color: white;
    display: block;
    position: absolute;
    overflow: hidden;
    top: 50%;
    left: 50%;
    margin-top:-35px;
    margin-left:-35px;
    transition: all .3s linear;
}
.one    { -webkit-transform: rotate(270deg) translate(200px);
          transform: rotate(270deg) translate(200px);
          background:blue; }
.two    { -webkit-transform: rotate(300deg) translate(200px);
          transform: rotate(300deg) translate(200px); }
.three  { -webkit-transform: rotate(330deg) translate(200px);
          transform: rotate(330deg) translate(200px);
}
.four   { -webkit-transform: rotate(360deg) translate(200px);
          transform: rotate(360deg) translate(200px);}
.foura   { -webkit-transform: rotate(360deg) translate(200px);
          -webkit-animation: aclock .3s linear 1;
          transform: rotate(360deg) translate(200px);
          animation: aclock .3s linear 1;
          transition: none;
}
.five   { -webkit-transform: rotate(30deg)  translate(200px);
          transform: rotate(30deg)  translate(200px);}
.fivea   { -webkit-transform: rotate(30deg)  translate(200px);
          -webkit-animation: clock .3s linear 1;
          transform: rotate(30deg)  translate(200px);
          animation: clock .3s linear 1;
          transition: none;
}
.six    { -webkit-transform: rotate(60deg)  translate(200px);
          transform: rotate(60deg)  translate(200px);}
.seven  { -webkit-transform: rotate(90deg)  translate(200px);
           transform: rotate(90deg)  translate(200px);}
.eight  { -webkit-transform: rotate(120deg) translate(200px);
          transform: rotate(120deg) translate(200px);}
.nine   { -webkit-transform: rotate(150deg) translate(200px);
          transform: rotate(150deg) translate(200px); }
.ten    { -webkit-transform: rotate(180deg) translate(200px);
          transform: rotate(180deg) translate(200px);}
.eleven { -webkit-transform: rotate(210deg) translate(200px);
          transform: rotate(210deg) translate(200px);}
.twelve { -webkit-transform: rotate(240deg) translate(200px);
          transform: rotate(240deg) translate(200px);}

@-webkit-keyframes clock {
    0% {-webkit-transform: rotate(0deg) translate(200px);}
  100% {-webkit-transform: rotate(30deg) translate(200px);}
}

@-webkit-keyframes aclock {
    0% {-webkit-transform: rotate(30deg) translate(200px);}
  100% {-webkit-transform: rotate(0deg) translate(200px);}
}

@keyframes clock {
    0% {transform: rotate(0deg) translate(200px);}
  100% {transform: rotate(30deg) translate(200px);}
}

@keyframes aclock {
    0% {transform: rotate(30deg) translate(200px);}
  100% {transform: rotate(0deg) translate(200px);}
}





按照我的第一个想法,我在脚本中添加了以下代码:

updated fiddle

Following my first idea, I have added the following code to the script:

   case 38:
    angle = angle + 30;
    var circleBig = document.getElementsByClassName("circle-big")[0];
    var style = "rotate(" + angle + "deg)";
    circleBig.style.webkitTransform = style;
    break;
case 40:
    angle = angle - 30;
    var circleBig = document.getElementsByClassName("circle-big")[0];
    var style = "rotate(" + angle + "deg)";
    circleBig.style.webkitTransform = style;
    break;

并添加到大圆圈。现在我认为它工作正常(上下箭头!)

And added also transition to the big circle. Now I think it works ok (on up and down arrow !)

保持内圈直立)我重新设计了大部分的小提琴。我修改了一个想法,我从Lea Verou看到,使旋转没有辅助div。它包括将变换设置为角度+平移+相对角度。这使得div去你想要的,未旋转。

For the new requirement (to keep the inner circles upright) I have redesigned most of the fiddle. I have adapted an idea that I saw from Lea Verou, to make the rotation without auxiliar divs. It consists in setting the transform to angle + translation + oposite angle. That makes the div go where you want, unrotated.

一旦决定这样做,脚本就必须修改内圈的样式,而不是基圆的样式。为了做到这一点,我已经存储在每个元素的特定元素的角度(在data-属性)。

Once decided to go this way, the script has to modified the styles of the inner circles, and not the style of the base circle. To do that easily, I have stored in every element the angle of that particular element (in a data- property).

生成的HTML类似:

<div class="circle-big">
    <div class="circle one" data-angle=270>1</div>
    <div class="circle two" data-angle=300>2</div>
    <div class="circle three" data-angle=330>3</div>
    <div class="circle four" data-angle=0>4</div>
    <div class="circle five" data-angle=30>5</div>
    <div class="circle six" data-angle=60>6</div>
    <div class="circle seven" data-angle=90>7</div>
    <div class="circle eight" data-angle=120>8</div>
    <div class="circle nine" data-angle=150>9</div>
    <div class="circle ten" data-angle=180>10</div>
    <div class="circle eleven" data-angle=210>11</div>
    <div class="circle twelve" data-angle=240>12</div>
    <div class="circle-inner"></div>
</div>

脚本是

var circleArray = document.getElementsByClassName("circle");
var angle = 0;

window.onload = chargearray;

function chargearray () {
    for (var i = 0, j = circleArray.length; i < j; i++) {
        var circle = circleArray[i];
        var circleAngle = parseInt (circle.dataset.angle);
        var totalAngle = angle + circleAngle
        var style = "rotate(" + totalAngle + "deg) translate(200px)";
        totalAngle = - totalAngle;
        style = style + " rotate(" + totalAngle + "deg)"
        circle.style.webkitTransform = style;
        circle.style.Transform = style;
    }
}

document.onkeydown = function (e) {
    e = e || window.event;
    switch(e.which || e.keyCode) {
        case 37:
            angle = angle + 30;
            chargearray ();
            break;
        case 39:
            angle = angle - 30;
            chargearray ();
            break;
    }
}

这篇关于多个元素循环移动 - 平滑过渡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 11:53