如何为 window 旋转木马菜单制作动画?

How can i animate a window carousel menu?

我一直在四处寻找如何制作不同的旋转木马,但我正在努力寻找一种资源来教我它实际上做了什么,而不是仅仅向我扔代码。时间浪费在误导性视频上,您必须在最后下载他们的特殊脚本! :-(

我想先在香草JS/Css中理解它,然后努力理解Pug/Scss。

我有以下内容:

.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>

我尝试按照自己的方式行事,但我完全被卡住了 - 我设想绿色框需要均匀间隔,并且在一条直线上,落在框外的项目将不可见并且滚动将循环项目 "Carousel" 样式..

到目前为止,我已经尝试了很多东西,但我什至似乎无法将我的 container/green 盒子弯曲过来,更不用说开始制作动画了!

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

非常感谢

在我回答你的问题之前做一件简单的事情:尝试 post Whosebug 上的最小工作示例 (MWE),因为
a) 这将让您的回答对他人更有用;
b) 因为它会帮助你隔离和调试。要从完整网站转到 MWE,请删除内容,直到只剩下问题,然后 none 其他内容。

现在: 我不确定您是否理解 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 设置回 hidden。我假设您知道一些 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>

希望对您有所帮助!

让我们先想想轮播应该做什么。它应该从查看容器的侧面滚动新图像/项目,对吗?

这意味着我们希望我们的轮播项目是轮播容器的整个宽度,所以项目填满了容器,其余的则挂在外面。现在我们不想看到轮播外的其他轮播项目,为此我们可以在轮播容器上使用 overflow: hidden 。此 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>

我们有一个用于轮播 (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 开始。

我们根据需要为轮播容器设置定义的widthheight属性。我们希望将相同的宽度和高度应用于 carousel-item,以便它们填满 carousel window。我们还想在 .carousel 容器上设置前面提到的 overflow: hidden,以便在不需要时不显示其他项目。

现在我已经将轮播项目的宽度设置为 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)值来移动长长的轮播项目水平列表,以便我们想要的元素与 [=19= 对齐] 元素("display window" 可以这么说)。

最后,它有 transitition: left 0.5s 告诉浏览器任何时候 left 属性改变(通常由 JS),浏览器将 animate值的变化。也就是说,如果我们首先有 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 的值是 <value>px 的字符串。接下来我们要从中减去轮播宽度(因此项目正确向上滑动)。我还使用了模运算符,它只是余数除法。这意味着一旦我减去太多,它就会结束。现在唯一剩下的就是将这个新值 left 应用到包装器。

总而言之,实现看起来有点像这样: (编辑:我将高度更改为 100px 而不是 200px 以使其适合 运行 代码片段 window)

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>