【问题标题】:Changing stacked images opacity value on scroll在滚动时更改堆叠图像的不透明度值
【发布时间】:2022-10-04 21:01:10
【问题描述】:

我有 4 张尺寸相同的图像。 <img> 使用 100% 宽度(它们都堆叠在另一个之上),在它们下方我有标准内容。

需要的效果是:

  1. 当我开始向下滚动时,页面的实际滚动必须在第二张图像开始出现时被阻止(通过平滑地将其opacity 值从 0 更改为 1)。
  2. 一旦达到 100% opacity,第三个图像应该开始出现,依此类推。
  3. 当第 4 张图像达到 100% opacity 时,滚动行为应自行正常化,以允许用户向下滚动到页面的其余部分。
  4. 如果用户向上滚动,应该应用相同的效果,只是向后滚动。

    这是一个初始的codepen link,不知道如何实现效果。提前感谢您的任何想法!

【问题讨论】:

    标签: javascript html css


    【解决方案1】:

    根据反馈更新解决方案:

    • 版本 1 与最初的理解一致,没有更改。 它启动了图像的自动平滑过渡,使用 用户更改滚动方向时的不透明度。
    • 版本 2 使用滚动动作本身来确定不透明度 转换,并以生成滚动事件的速率发生,再次 当用户改变滚动方向时。

    版本 1

    我认为下面的代码符合您的上述要求。希望嵌入式 cmets 解释它是如何工作的。

    此示例使用“setTimeout”通过排队来协调图像的淡化。也可以使用“setInterval”并迭代图像而不是排队来完成。

    我对布局进行了一些调整。请参阅代码中的 cmets。根据您的最终布局,可能有无数种方法可以做到这一点。

    var images;
    var scrollContainer;
    var noScrollDown;
    var noScrollUp;
    var scrollLeft;
    var scrollTop;
    var latch;
    function setUp() {
    
        images = document.getElementsByClassName("image");
    
        scrollContainer = document.getElementById("content");
        noScrollDown = true;
        noScrollUp = true;
        scrollLeft = scrollContainer.scrollLeft;
        scrollTop = scrollContainer.scrollTop;
        latch = false;
    }
    
    function doScrollUp () {
        noScrollUp = false;
        noScrollDown = true;
        scrollContainer.style.overflow = "auto";
        latch = false;
    }
    
    function doScrollDown () {
        noScrollDown = false;
        noScrollUp = true;
        scrollContainer.style.overflow = "auto";
        latch = false;
    }
    
    function fadeIn(ndx) {
        if ( ndx > 3 ) {
            //  Top image is showing so switch direction of allowable scrolling
            doScrollDown();
        } else {
            //  Fade in an image and queue the fade in of the next image
            images[ndx].style.opacity = 1;
            setTimeout(fadeIn, 2000, ndx+1);        //  The time here, in milliseconds, should be the same as the transition time above
        }
    }
    
    function fadeOut(ndx) {
        if ( ndx < 1 ) {
            //  Bottom image is showing so switch direction of allowable scrolling
            doScrollUp();
        } else {
            //  Fade out an image and queue the fade out of the next image
            images[ndx].style.opacity = 0;
            setTimeout(fadeOut, 2000, ndx-1);       //  The time here, in milliseconds, should be the same as the transition time above
        }
    }
    
    function transOpacity() {
        if ( noScrollDown && scrollContainer.scrollTop >= scrollTop ) {
            //  No scroll down allowed, and scroll event tried to go down
            
            //  Scroll back to where the scroll was
            scrollContainer.scrollTo(scrollLeft, scrollTop);  //  This will trigger another scroll event
            
            //  
            if ( ! latch ) {
                latch = true;       //  Stop double processing due to second scroll event triggered above
                scrollContainer.style.overflow = "hidden";
                fadeIn(1);
            }
        } else if ( noScrollUp && scrollContainer.scrollTop <= scrollTop ) {
            //  No scroll up allowed, and scroll event tried to go up
            
            //  Scroll back to where the scroll was
            scrollContainer.scrollTo(scrollLeft, scrollTop);  //  This will trigger another scroll event
            if ( ! latch ) {
                latch = true;       //  Stop double processing due to second scroll event triggered above
                scrollContainer.style.overflow = "hidden";
                fadeOut(3)
            }
        } else {
            scrollLeft = scrollContainer.scrollLeft;
            scrollTop = scrollContainer.scrollTop;
            latch = false;
        }
    }
    .images img {
        width: 100%;            /*  Note that 100% width will cover the scoll bar of the content, when the flow is decoupled with 'display: position;'  */
        max-height: 25vh;       /*  Set a limit on the height of the images, for this example, so that the scroll bar of the content can be fully accessible */
      display: block;
      position: absolute;
      top: 0vh;                 /*  Set the position, for this example, so that the scroll bar of the content can be fully accessible */
    }
    
    
    /*  Set up the required transition on the property relevant property  */
    
    .images img.image {
        opacity: 0;                     /*  The default initial opacity  */
        transition-property: opacity;
        transition-duration: 2s;        /*  The time here, in seconds, needs to be the same as the setTimeout times below  */
    }
    
    
    /*  Initialise the first image as showing, ie, full opacity.  */
    
    .images img.image:nth-of-type(1) {
        opacity: 1;
    }
    
    .content {
        margin-top: 25vh;       /*  For this example, make sure the scroll container is below the images so that the scroll bar is fully accessible.  */
    }
    <body onLoad="setUp()">
    <div>
    
    <div class="images">
    <img src="https://dummyimage.com/1400x600/ff4400/fff.png&text=1" alt="1" class="image">
    <img src="https://dummyimage.com/1400x600/3c00ff/fff.png&text=2" alt="2" class="image">
    <img src="https://dummyimage.com/1400x600/44a10f/fff.png&text=3" alt="3" class="image">
    <img src="https://dummyimage.com/1400x600/d99f2b/fff.png&text=4" alt="4" class="image">
    </div>
    
    <div id="content" class="content" onscroll="transOpacity()" style="height: 50vh; overflow:auto;">
    <p>This should be scrolled down normally - line 1.</p>
    <p>This should be scrolled down normally - line 2.</p>
    <p>This should be scrolled down normally - line 3.</p>
    <p>This should be scrolled down normally - line 4.</p>
    <p>This should be scrolled down normally - line 5.</p>
    <p>This should be scrolled down normally - line 6.</p>
    <p>This should be scrolled down normally - line 7.</p>
    <p>This should be scrolled down normally - line 8.</p>
    <p>This should be scrolled down normally - line 9.</p>
    <p>This should be scrolled down normally - line 10.</p>
    <p>This should be scrolled down normally - line 11.</p>
    <p>This should be scrolled down normally - line 12.</p>
    <p>This should be scrolled down normally - line 13.</p>
    <p>This should be scrolled down normally - line 14.</p>
    <p>This should be scrolled down normally - line 15.</p>
    <p>This should be scrolled down normally - line 16.</p>
    <p>This should be scrolled down normally - line 17.</p>
    <p>This should be scrolled down normally - line 18.</p>
    <p>This should be scrolled down normally - line 19.</p>
    <p>This should be scrolled down normally - line 20.</p>
    <p>This should be scrolled down normally - line 21.</p>
    <p>This should be scrolled down normally - line 22.</p>
    <p>This should be scrolled down normally - line 23.</p>
    <p>This should be scrolled down normally - line 24.</p>
    <p>This should be scrolled down normally - line 25.</p>
    <p>This should be scrolled down normally - line 26.</p>
    <p>This should be scrolled down normally - line 27.</p>
    <p>This should be scrolled down normally - line 28.</p>
    <p>This should be scrolled down normally - line 29.</p>
    <p>This should be scrolled down normally - line 30.</p>
    </div>
    
    </div>
    </body>

    版本 2

    要更改平滑度,请调整常量 opacityIncDec。值越小,过渡越平滑,但需要的时间越长。

    var images;
    var scrollContainer;
    var noScrollDown;
    var noScrollUp;
    var scrollLeft;
    var scrollTop;
    var imgNdx;
    const opacityIncDec = 0.025;
    function setUp() {
    
        images = document.getElementsByClassName("image");
    
        scrollContainer = document.getElementById("content");
        noScrollDown = true;
        noScrollUp = true;
        scrollLeft = scrollContainer.scrollLeft;
        scrollTop = scrollContainer.scrollTop;
        imgNdx = 1;
    }
    
    function doScrollUp () {
        noScrollUp = false;
        noScrollDown = true;
        imgNdx = 1;
    }
    
    function doScrollDown () {
        noScrollDown = false;
        noScrollUp = true;
        imgNdx = 3;
    }
    
    function fadeIn(ndx) {
        var opacity;
        if ( ndx > 3 ) {
            //  Top image is showing so switch direction of allowable scrolling
            doScrollDown();
        } else {
            //  Fade in an image or queue the fade in of the next image
            opacity = images[ndx].style.opacity;
            if ( opacity == "" ) {
                opacity = 0;
            } else {
                opacity = parseFloat(opacity);
            }
            if ( opacity < 1 ) {
                images[ndx].style.opacity = opacity + opacityIncDec
            } else {
                imgNdx += 1;
            }
        }
    }
    
    function fadeOut(ndx) {
        if ( ndx < 1 ) {
            //  Bottom image is showing so switch direction of allowable scrolling
            doScrollUp();
        } else {
            //  Fade out an image and queue the fade out of the next image
            opacity = images[ndx].style.opacity;
            if ( opacity == "" ) {
                opacity = 0;
            } else {
                opacity = parseFloat(opacity);
            }
            if ( opacity > 0 ) {
                images[ndx].style.opacity = opacity - opacityIncDec
            } else {
                imgNdx -= 1;
            }
        }
    }
    
    function transOpacity() {
        if ( noScrollDown && scrollContainer.scrollTop >= scrollTop ) {
            //  No scroll down allowed, and scroll event tried to go down
            
            //  Scroll back to where the scroll was
            scrollContainer.scrollTo(scrollLeft, scrollTop);  //  This will trigger another scroll event
            fadeIn(imgNdx);
        } else if ( noScrollUp && scrollContainer.scrollTop <= scrollTop ) {
            //  No scroll up allowed, and scroll event tried to go up
            
            //  Scroll back to where the scroll was
            scrollContainer.scrollTo(scrollLeft, scrollTop);  //  This will trigger another scroll event
            fadeOut(imgNdx)
        } else {
            scrollLeft = scrollContainer.scrollLeft;
            scrollTop = scrollContainer.scrollTop;
        }
    }
    .images img {
        width: 100%;            /*  Note that 100% width will cover the scroll bar of the content, when the flow is decoupled with 'display: position;'  */
        max-height: 25vh;       /*  Set a limit on the height of the images, for this example, so that the scroll bar of the content can be fully accessible */
      display: block;
      position: absolute;
      top: 0vh;                 /*  Set the position, for this example, so that the scroll bar of the content can be fully accessible */
    }
    
    
    /*  Set up the required transition on the property relevant property  */
    
    .images img.image {
        opacity: 0;                     /*  The default initial opacity  */
    }
    
    /*  Initialise the first image as showing, ie, full opacity.  */
    
    .images img.image:nth-of-type(1) {
        opacity: 1;
    }
    
    .content {
        margin-top: 25vh;       /*  For this example, make sure the scroll container is below the images so that the scroll bar is fully accessible.  */
    }
    <body onLoad="setUp()">
    <div>
    
    <div class="images">
    <img src="https://dummyimage.com/1400x600/ff4400/fff.png&text=1" alt="1" class="image">
    <img src="https://dummyimage.com/1400x600/3c00ff/fff.png&text=2" alt="2" class="image">
    <img src="https://dummyimage.com/1400x600/44a10f/fff.png&text=3" alt="3" class="image">
    <img src="https://dummyimage.com/1400x600/d99f2b/fff.png&text=4" alt="4" class="image">
    </div>
    
    <div id="content" class="content" onscroll="transOpacity()" style="height: 50vh; overflow:auto;">
    <p>This should be scrolled down normally - line 1.</p>
    <p>This should be scrolled down normally - line 2.</p>
    <p>This should be scrolled down normally - line 3.</p>
    <p>This should be scrolled down normally - line 4.</p>
    <p>This should be scrolled down normally - line 5.</p>
    <p>This should be scrolled down normally - line 6.</p>
    <p>This should be scrolled down normally - line 7.</p>
    <p>This should be scrolled down normally - line 8.</p>
    <p>This should be scrolled down normally - line 9.</p>
    <p>This should be scrolled down normally - line 10.</p>
    <p>This should be scrolled down normally - line 11.</p>
    <p>This should be scrolled down normally - line 12.</p>
    <p>This should be scrolled down normally - line 13.</p>
    <p>This should be scrolled down normally - line 14.</p>
    <p>This should be scrolled down normally - line 15.</p>
    <p>This should be scrolled down normally - line 16.</p>
    <p>This should be scrolled down normally - line 17.</p>
    <p>This should be scrolled down normally - line 18.</p>
    <p>This should be scrolled down normally - line 19.</p>
    <p>This should be scrolled down normally - line 20.</p>
    <p>This should be scrolled down normally - line 21.</p>
    <p>This should be scrolled down normally - line 22.</p>
    <p>This should be scrolled down normally - line 23.</p>
    <p>This should be scrolled down normally - line 24.</p>
    <p>This should be scrolled down normally - line 25.</p>
    <p>This should be scrolled down normally - line 26.</p>
    <p>This should be scrolled down normally - line 27.</p>
    <p>This should be scrolled down normally - line 28.</p>
    <p>This should be scrolled down normally - line 29.</p>
    <p>This should be scrolled down normally - line 30.</p>
    </div>
    
    </div>
    </body>

    【讨论】:

    • 谢谢,但这不符合要求。不透明度更改行为仅需要在用户向下滚动(以增加不透明度)和用户向上滚动(以降低不透明度)时进行更改。下一张图像根本不应该有自动的不透明度变化。
    • 对不起,但不清楚你需要什么。上面你说“通过将不透明度从 0 平滑更改为 1”,但在这里你说“没有自动容量更改”。请注意,堆叠在另一个元素顶部的元素淡入淡出就像下面的元素正在淡出一样,即使它不是。一旦新图像开始淡入,您是否希望下面的元素根本不可见?这很容易做到。如果不能,请说明您需要什么。
    猜你喜欢
    • 1970-01-01
    • 2012-09-07
    • 2017-04-25
    • 1970-01-01
    • 2016-12-02
    • 1970-01-01
    • 1970-01-01
    • 2012-07-18
    相关资源
    最近更新 更多