提问者:小点点

如何使窗口轮播菜单动画化?


我已经四处寻找了很多关于如何做不同的carousels,但我正在努力找到一个资源来教我它实际做什么,而不是仅仅向我扔代码。 把时间浪费在误导性的视频上,你必须在最后下载他们的特殊脚本! :-(

我想首先在vanilla JS/CSS中理解它,然后朝着理解PUG/SCSS的方向努力。

我有以下几点:

null

.MenuContainer {
    position: relative;
    width: 300px;
    height: 175px;
    background-color: black;
    border-radius: 10px;
}

.Imagebox {
    height: 150px;
    margin-top: 15px;
    margin-bottom: 27px;
    bottom: -17px;
    width: 260px;
    margin-left: 20px;
    margin-right: 15px;
    background-color: lavender;
    align-self: center;
    position: absolute;
    border-radius: 5px;
}

.ListReel {
    position: inherit;
    height: 120px;
    background-color: white;
    width: 217px;
    bottom: 8px;
    margin-left: 20px;
    display: flex;
    flex-direction: row;
    overflow-x: hidden;
    justify-content: space-evenly;
}

.fa-chevron-left {
    position: inherit;
    left: 30px;
    bottom: 93px;
    font-size: 1.5em;
}

.fa-chevron-right {
    position: inherit;
    left: 236px;
    bottom: 93px;
    font-size: 1.5em;
}

.MenuItem {
    position: inherit;
    height: 85px;
    width: 85px;
    top: 1px;
    position: inherit;
    border-color: lawngreen;
    border-style: solid;
    border-width: 1px;
    display: table-row;
}
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
    <script src="https://kit.fontawesome.com/a427ef628d.js" crossorigin="anonymous"></script>
    <script src="../Scripts/JQuery"></script>
    <script src="../Scripts/jquery-ui.min.js"></script>
    <link rel="stylesheet" href="../Scripts/jquery-ui.min.css">
    <link rel="stylesheet" href="Test.css">
    <title>TESTING</title>
</head>

<body>
    <h1>Hello!</h1>
    <div class="MenuContainer">
        <h5 style="text-align: center; margin-top: 5px; color: white;">Select Item</h5>
        <div class="Imagebox"></div>
        <ul class=ListReel>
            <li class="MenuItem"></li>
            <li class="MenuItem"></li>
            <li class="MenuItem"></li>
            <li class="MenuItem"></li>
            <li class="MenuItem"></li>
            <li class="MenuItem"></li>
        </ul>
        <i class="fas fa-chevron-left"></i>
        <i class="fas fa-chevron-right"></i>
    </div>
</body>
</html>

null

我试着走我自己的路,但我完全被困住了--我设想绿色的盒子将需要均匀地间隔,并且在一个直线上,落在盒子外面的物品将不是可见的,卷轴将循环物品“旋转木马”风格。

我尝试了很多东西到目前为止,我甚至不能似乎能够灵活的我的容器/绿色的盒子跨越,更不用说使动画开始!

有没有人有任何提示或资源或代码想法可以给我指明正确的方向? 最好是解释清楚的教程? 求你了?

非常感谢


共2个答案

匿名用户

让我们从思考旋转木马应该做什么开始。 它应该从查看容器的侧面滚动新的图像/项目,对吗?

这意味着我们希望我们的轮播项目是轮播容器的全宽,所以项目填充容器,其余的留在外面。 现在,我们不希望在轮播之外看到其他轮播项目,为此,我们可以在轮播容器上使用overflow:hidded。 这个CSS声明意味着隐藏所有不适合轮播容器的内容。

另一个关键的事情是布局旋转木马项目挨着彼此,这样当我们移动他们,他们从侧面出现。

当然,有多种方法可以实现这一点,但下面是我要做的。

<div class="carousel">
    <div id="carousel-item-wrapper">
        <div style="background-color: red" class="carousel-item"></div>
        <div style="background-color: blue" class="carousel-item"></div>
        <div style="background-color: yellow" class="carousel-item"></div>
    </div>
</div>

我们有一个容器用于carousel(class:carousel)和其中的项(class carousel-item)。 这里我还添加了一个“carousel-item-wrapper”元素。 它的工作是包含所有的旋转木马项目,所以我们可以只是滑动这个坏男孩周围和显示的旋转木马项目将改变。

现在来看看这个MF的CSS。

.carousel {
    width: 600px;
    height: 200px;
    border: 3px solid #333;

    overflow: hidden;
}

#carousel-item-wrapper {
    display: flex;
    flex-direction: row;

    position: relative;
    left: 0;

    transition: left 0.5s;
}

.carousel-item {
    display: inline-block;
    min-width: 600px;
    height: 200px;
}

让我们从.carousel.carousel-item开始。

我们根据需要为轮播容器设置已定义的宽度高度属性。 我们希望将相同的宽度和高度应用于轮播项目,以便它们填充轮播窗口。 我们还想在.carousel容器上设置前面提到的overflow:hidding,这样其他项在不需要显示时就不会显示。

现在我已经用min-width设置了轮播项目的宽度:600px。 原因是我们有项目的carousel-item-wrapper使用了flexbox布局display:flex。 如果这些项目没有设置min-width属性,flexbox将收缩所有这些项目,直到它们都并排适合轮播容器。 我们不想那样!

现在我们开始讨论神秘的#carousel-item-wrapper元素。 首先,它具有水平布局所需的flex属性:display:flex实际使用flexbox和flex-direction:row(这实际上是默认的。。。) 它告诉flexbox对齐紧挨着的项。

然后,我将包装器元素的位置设置为relative,这意味着如果没有设置其他设置(left,right,top,bottom),则元素将位于它自然要去的位置。 相对定位的理由是,然后我们可以更改left(或right)值来移动轮播项目的长水平列表,以便我们所需的元素将与.carousel元素(也就是“显示窗口”)对齐。

最后,它具有transition:left0.5s,它告诉浏览器,每当left属性被更改(通常是通过JS)时,浏览器将动画化该值的更改。 也就是说,如果我们首先有left:0px并将其更改为left:-600px(将轮播滑过一个项目,因为我的轮播宽度为600px),则更改将被动画化(0.5s指的是您希望它花费的时间)

现在我们已经设置了所有的HTML和CSS,如果您更改#carousel-item-wrapperleft属性,它将移动并动画旋转木马。

我们唯一需要的就是创建一些JS来移动它。 我选择了一个按钮,只移动旋转木马一个项目。

我本来不打算解释JS的,但是看到这个答案太长了,我可能也会这么做。

function moveCarousel() {
    const carouselWrapper = document.getElementById("carousel-item-wrapper");
    let left = carouselWrapper.style.left.slice(0, -2);
    left = (left - 600) % 1800;

    carouselWrapper.style.left = left + 'px';
}

首先,我们用document.getElementById获取对包装器元素的引用。 我们可以使用这个来读取元素上left属性的当前值并更改它。 carouselwrapper.style.leftleft属性和slice(0,-2)的值,您可以自己读取它,但是这里它只是从值中去掉了“px”(因为left的值是一个px的字符串。接下来我们要从这个值中减去carousel宽度(这样项目就可以正确地向上滑动)。我还使用了模运算符,它只是余数除法。这意味着一旦我减去太多,它就会绕过去。现在唯一剩下的就是将这个新值

总而言之,这个实现看起来有点像这样:(编辑:我把height更改为100px,而不是200px,以使它适合运行代码片段窗口)

null

function moveCarousel() {
            const carouselWrapper = document.getElementById("carousel-item-wrapper");
            let left = carouselWrapper.style.left.slice(0, -2);
            left = (left - 600) % 1800;

            carouselWrapper.style.left = left + 'px';
        }
.carousel {
    width: 600px;
    height: 100px;
    border: 3px solid #333;

    overflow: hidden;
}

#carousel-item-wrapper {
    display: flex;
    flex-direction: row;

    position: relative;
    left: 0;

    transition: left 0.5s;
}

.carousel-item {
    display: inline-block;
    min-width: 600px;
    height: 100px;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="style.css" rel="stylesheet">
    <title>Document</title>
</head>
<body>
    
    <div class="carousel">
        <div id="carousel-item-wrapper">
            <div style="background-color: red" class="carousel-item"></div>
            <div style="background-color: blue" class="carousel-item"></div>
            <div style="background-color: yellow" class="carousel-item"></div>
        </div>
    </div>

    <button role="button" onclick="moveCarousel()">Move carousel</button>

</body>
</html>

匿名用户

在回答您的问题之前,请先做一件事:尝试在stackoverflow上发布最小工作示例,因为
a)这将使您的答案对其他人更有用;
b)因为这将帮助您隔离和调试。若要从完整网站转到MWE,请删除内容,直到只保留问题,而不保留其他内容。

现在:我不确定您是否理解display:flex.listreel的含义。 这是一个flexbox,一个允许简化格式化的web技术,你可能已经在一些教程中看到过它。 但是flexbox设置需要的不仅仅是display:flex。 你可以在这里阅读更多:CSS-Tricks post on Flexbox(不是我的,但我经常使用它)

对于初学者,尝试将flex:0 0 100%添加到.menuItem中,它告诉浏览器您希望轮播菜单项占.listreel宽度的100%。 然后,暂时将overflow-x设置为auto,这将显示滚动条。

以后您可能不想要滚动条; 因此您可以将overflow-x设置回hidded。 我将假设您了解一些javascript--下一步将添加一些javascript以使其工作:

<script>
function moveTheListItems(){
    var listReel = document.getElementsByClassName("ListReel")[0]; // get a reference to the listReel
    listReel.scrollBy(listReel.clientWidth,0); // scroll it to reveal the next frame
}
setInterval(moveTheListItems,500); // run this function every 500ms = half a second
</script>

如果回答了你的问题,按橙色向上按钮向上投票(并接受底部的勾号)是很好的礼节;)

希望有帮助!