首页 > 解决方案 > 如何在页面向下滚动时为圆形进度条设置动画?

问题描述

我有一个圆形进度条,在页面加载时会产生动画,但我希望它在用户向下滚动到它时产生动画。如果页面加载,用户不会看到动画,因为动画会在他们进入或重新加载页面后运行并结束。

这是我的代码:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<style>

#skill-body{

padding: 10px;  
min-height: 80vh;
color: #F0505C;
background: #191315;

}

.skill-wrapper{

max-width: 1100px;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
margin: auto;
display: flex;

}

.skill-wrapper .card{

width: calc(100% / 2);
height: 300px;
display: flex;
align-items: center;
justify-content: space-evenly;
flex-direction: column;
margin: auto;

}

.skill-wrapper .card .circle{

position: relative;
height: 150px;
width: 150px;
border-radius: 50%;

}

.skill-wrapper .card .circle .box{

height: 100%;
width: 100%;
transform: translate(-50%, -50%) scale(0.9);
border-radius: 50%;

}

.skill-wrapper .card .circle:hover .box{

transform: translate(-50%, -50%) scale(1.19)

}

.skill-wrapper .card .circle .box,
.skill-wrapper .card .circle .box span{

position: absolute;
top: 50%;
left: 50%;
transition: all 0.1s;

}

.skill-wrapper .card .circle .box span{

font-size: 30px;
transform: translate(-50%, -50%);

}


.skill-wrapper .card .text{

font-size: 20px;

}

</style>

<div class="sec" id="skill-body">
        <div class="skill-wrapper">
                <div class="card">
                    <div class="circle">
                        <div class="bar" data-thickness="8"></div>
                        <div class="box"><span>78%</span></div>
                    </div>
                    <div class="text">Illustrator</div>
                </div>
        
                <div class="card ps">
                    <div class="circle">
                        <div class="bar" data-thickness="8"></div>
                        <div class="box"><span>76%</span></div>
                    </div>
                    <div class="text">Photoshop</div>
                </div>
        </div>
    
        <script>
            let options = {
                startAngle: -1.55,
                size: 150,
                value: 0.78,
                fill: {color: "#F0515C"}
            }
            $(".circle .bar").circleProgress(options).on('circle-animation-progress', function(event, progress, stepValue){
                $(this).parent().find("span").text(String(stepValue.toFixed(2).substr(2)) + "%")
            });

            $(".ps .bar").circleProgress({
                value: 0.76,
            });
        </script>
    </div>

标签: javascripthtmlcssprogress-bar

解决方案


我无法让我的外部脚本引用在这个片段中工作,所以我将只使用我生成的一个示例(理论上应该不仅适用于微调器,而且适用于任何 html 元素)。

此示例适用于interval,但您可以使用onscrollonresize以获得更好的性能。我使用的原因interval是给微调器一点延迟,因此您实际上可以看到它开始旋转。

无论如何,所以我在这里使用了该getBoundingClientRect方法来return确定微调器在当前视口中是否可见。然后,如果它是可见的,我们将向微调器添加一个类classList,否则,我们将删除该类。在您的代码中,您可以根据需要使用内置方法来启动或停止旋转。

话虽如此,这里是片段:

const circle = document.getElementById("circle");

function check_if_visible(elmnt) {
    
  var rect = elmnt.getBoundingClientRect();

  return rect.bottom > 0 &&
        rect.right > 0 &&
        rect.left < (window.innerWidth || document.documentElement.clientWidth) /* or $(window).width() */ &&
        rect.top < (window.innerHeight || document.documentElement.clientHeight) /* or $(window).height() */;

}

setInterval(() => {
    if(check_if_visible(circle)) {
    circle.classList.add("turn-around");
  } else {
    circle.classList.remove("turn-around");
  }
}, 1000);
.turn-around * {
  transform-origin: center;
  display: inline-block;
  animation: rot 1050ms infinite linear;
}


@keyframes rot {
  from {transform: rotateZ(0deg)}
  to {transform: rotateZ(360deg)}
}
<div style="font-size: 7vh; color: rgba(0,0,0,0.6); font-family: Comic Sans MS; padding: 30px; padding-bottom: 300px;">
  Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laborum ut, tempore quis consequuntur odio ducimus non, aut incidunt, saepe impedit mollitia? Consectetur adipisicing elit. Commodi sint optio quae culpa sapiente eligendi ad nobis.
<div style="color: red;">To catch the spinner red-handed (ie when it is not spinning), you need to scroll downwards very quickly and keep your eyes peeled!</div>
</div>


<div id="circle" style="height: 6ch; width: 6ch; padding: 10px; font-family: Courier New; position: relative; left: 50%; transform: translateX(-50%); border-radius: 999ch; background: rgba(0,0,0,0.3);">
  <p>Circle</p>
</div>


推荐阅读