获取我的"啤酒"垂直进度条工作

时间:2017-11-21 23:36:58

标签: javascript html css css3 progress-bar

我试图制作一个看起来像倒空一杯啤酒的进度条。不幸的是,我不是很有艺术气质的人,但我正在尽我所能。

我的概念是这样的:

  1. 有一个<div>有&#34;啤酒&#34;背景,垂直高100%。它隐藏了任何溢出
  2. 在另一个<div>内,相对于父母定位。它包含:
    1. 白色背景<div>模糊&#34;啤酒&#34;模式何时消失
    2. 啤酒泡沫帽的图像
  3. 这是图片上的概念:

    enter image description here

    我几乎成功实现了目标,正如您在此片段中所看到的那样:

    注意:动画需要ES6 async / await

    &#13;
    &#13;
    Promise.timeout = function (delay) {
                return new Promise((resolve) => {
                    setTimeout(resolve, delay);
                });
            };
            Promise.animationFrame = function () {
                return new Promise((resolve) => {
                    requestAnimationFrame(resolve);
                });
            };
            (async function () {
                const progress = document.querySelector("div.top");
                for (let i = 0, l = 1000; i < l; ++i) {
                    progress.style.bottom = (100 - i / 10) + "%";
                    await Promise.animationFrame();
                }
            })();
    &#13;
    html, body, div {
        margin: 0px;
        padding: 0px;
    }
    body {
        width: 100vw;
        height: 100vh;
        overflow: hidden;
    }
    div.progress {
        max-width:300px;
        width: 100vw;
        
        float: left;
        position: relative;
        overflow: hidden;
        height: 100%;
        background-image: url("https://i.imgur.com/SKfSqEv.jpg");
        background-size: 500px;
    
        border-right: 1px solid black;
    }
    div.progress div.top {
        height: 100vh;
        position: relative;
        bottom: 100%;
    }
    div.progress div.top div.white{
        background-color: white;
        width:100%;
        height:100%;
    }
    div.progress div.top div.beer-top {
        /*background-image is at the bottom since it is bse64 */
        background-repeat: repeat-x;
        background-position-y: bottom;
        background-position-x: left;
        background-size: 302px, 100px;
        height: 100px;
    }
    /*div.progress div.top {
        background-position: bottom;
        height: 100%;
        background-image: url("img/beer-top.png");
    }*/
    div.main {
        float: left;
    }
    
    div.progress div.top div.beer-top {
        background-image:  url('https://preview.ibb.co/k2x2V6/beer_top.png');
    }
    &#13;
    <div class="progress">
            <div class="top">
                <div class="white"></div>
            <div class="beer-top"></div>
            </div>
            <!--<div class="progress-area">
    
    
            </div>-->
        </div>
    
        <div class="main">
    
        </div>
    &#13;
    &#13;
    &#13;

    但是有两个大问题:

    1. 这条丑陋的橙色线:
       enter image description here
    2. 因为我将div.white高度设置为100%,所以泡沫被推下来,即使在&#34; 100%&#34;州。最后它也完全消失了。期望的状态是这样的:
       enter image description here
    3. 如何解决这两个问题?

      我正在寻找仅限CSS的解决方案,以便也可以静态显示条形图(例如,当页面加载时没有javascript时为40%)。

      另请注意:将泡沫设置为&#34;白色div&#34;的背景​​。不是一种选择,因为泡沫图像的底部是透明的。

2 个答案:

答案 0 :(得分:1)

因为只需要一个CSS解决方案。您可以将泡沫添加到“白色”div作为背景和白色渐变(当然需要一些tweeking,图像才能完美显示)。

见JSfiddle:

            Promise.timeout = function (delay) {
            return new Promise((resolve) => {
                setTimeout(resolve, delay);
            });
        };
        Promise.animationFrame = function () {
            return new Promise((resolve) => {
                requestAnimationFrame(resolve);
            });
        };
        (async function () {
            const progress = document.querySelector("div.top");
            for (let i = 0, l = 1000; i < l; ++i) {
                progress.style.bottom = (100 - i / 10) + "%";
                await Promise.animationFrame();
            }
        })();
html, body, div {
    margin: 0px;
    padding: 0px;
}
body {
    width: 100vw;
    height: 100vh;
    overflow: hidden;
}
div.progress {
    max-width:300px;
    width: 100vw;
    
    float: left;
    position: relative;
    overflow: hidden;
    height: 100%;
    background-image: url("https://i.imgur.com/SKfSqEv.jpg");
    background-size: 500px;

    border-right: 1px solid black;
}
div.progress div.top {
    height: 100vh;
    position: relative;
    bottom: 100%;
}
div.progress div.top div.white{
    background-color: white;
    width:100%;
    height:100%;
}
div.progress div.top div.beer-top {
    /*background-image is at the bottom since it is bse64 */
    background-repeat: repeat-x;
    background-position-y: bottom;
    background-position-x: left;
    background-size: 302px, 100px;
    height: 100px;
}
/*div.progress div.top {
    background-position: bottom;
    height: 100%;
    background-image: url("img/beer-top.png");
}*/
div.main {
    float: left;
}

div.progress div.top div.beer-top {
    background-image:  url('https://preview.ibb.co/k2x2V6/beer_top.png');
}

.top {
    background: no-repeat;
    background-position: bottom;
    background-image:  url('https://preview.ibb.co/k2x2V6/beer_top.png'),linear-gradient(to top, rgba(0,0,0,0) 1%, rgba(255,255,255,1) 5%);
}
<div class="progress">
        <div class="top">
        </div>
        <!--<div class="progress-area">


        </div>-->
    </div>

    <div class="main">

    </div>

答案 1 :(得分:0)

所以我想出的修正是:

  1. margin-top: -1添加到div.beer-top以删除橙色线条。白色和泡沫div现在重叠,因此当时的div不会透过。
  2. 使用display: flex使div.white填充除div.beer-top空间以外的所有空间。

      div.progress div.top {
          height: 100%;
          position: relative;
          bottom: 100%;
          /**Modern flexbox layout*/
          display: flex;
          flex-direction: column;
      }
      div.progress div.top div.white{
          background-color: white;
          width:100%;
          /*fill remaining space*/
          flex-grow: 1;
      }
    
  3. Promise.timeout = function (delay) {
                return new Promise((resolve) => {
                    setTimeout(resolve, delay);
                });
            };
            Promise.animationFrame = function () {
                return new Promise((resolve) => {
                    requestAnimationFrame(resolve);
                });
            };
            (async function () {
                const progress = document.querySelector("div.top");
                for (let i = 0, l = 1000; i < l; ++i) {
                    progress.style.bottom = (100 - i / 10) + "%";
                    await Promise.animationFrame();
                }
            })();
    html, body, div {
        margin: 0px;
        padding: 0px;
    }
    body {
        width: 100vw;
        height: 100vh;
        overflow: hidden;
    }
    div.progress {
        max-width:300px;
        width: 100vw;
        
        float: left;
        position: relative;
        overflow: hidden;
        height: 100%;
        background-image: url("https://i.imgur.com/SKfSqEv.jpg");
        background-size: 500px;
    
        border-right: 1px solid black;
    }
    div.progress div.top {
        height: 100%;
        position: relative;
        bottom: 100%;
        /**Modern flexbox layout*/
        display: flex;
        flex-direction: column;
    }
    div.progress div.top div.white{
        background-color: white;
        width:100%;
        /*fill remaining space*/
        flex-grow: 1;
    }
    div.progress div.top div.beer-top {
        /*background-image is at the bottom since it is bse64 */
        background-repeat: repeat-x;
        background-position-y: bottom;
        background-position-x: left;
        background-size: 302px, 100px;
        height: 100px;
        
        /** this should hide the blinking orange line atop*/
        margin-top:-2px;
    }
    /*div.progress div.top {
        background-position: bottom;
        height: 100%;
        background-image: url("img/beer-top.png");
    }*/
    div.main {
        float: left;
    }
    
    div.progress div.top div.beer-top {
        background-image:  url('https://preview.ibb.co/k2x2V6/beer_top.png');
    }
    <div class="progress">
            <div class="top">
                <div class="white"></div>
            <div class="beer-top"></div>
            </div>
            <!--<div class="progress-area">
    
    
            </div>-->
        </div>
    
        <div class="main">
    
        </div>