reddit_如何仅使用HTML和CSS构建Reddit启发的加载微调器

reddit

by Daniel Miller

丹尼尔·米勒(Daniel Miller)

如何仅使用HTML和CSS构建Reddit启发的加载微调器 (How to build a Reddit-inspired loading spinner with only HTML and CSS)

Reddit’s mobile app has a rather striking loading spinner reminiscent of orbital bodies circling a planet or star. Most developers would reach for JavaScript or SVGs for a task like this, but thanks to animation-iteration-count: infinite; and a few other hacks and tricks, that’s not even necessary. Today I’m going to show you how to code a Reddit-inspired spinner purely in HTML and CSS!

Reddit的移动应用程序有一个非常引人注目的加载微调框,让人想起环绕行星或恒星的轨道物体。 大多数开发人员可以通过JavaScript或SVG来完成这样的任务,但是要感谢animation-iteration-count : infinite; 以及其他一些技巧和技巧,甚至没有必要。 今天,我将向您展示如何仅使用HTML和CSS编写Reddit风格的微调器!

Here’s the final result:

这是最终结果:

基本设定 (Basic Setup)

Let’s start by writing some HTML DOM elements onto which we can pin the center circle and each of the rotating orbitals.

让我们从编写一些HTML DOM元素开始,我们可以将中心圆和每个旋转的轨道固定在其上。

<div class="center"></div>
<div class="inner-spin">
    
  ...
    
</div>
<div class="outer-spin">
    
  ...
    
</div>

The inner-spin and outer-spin elements will be the parents nodes of everything that needs to be animated, and eventually we’ll apply the CSS keyframes transforms to these parent nodes.

inner-spin outer-spin元素和outer-spin元素将是所有需要动画处理的元素的父节点,最终,我们将CSS 关键帧转换应用于这些父节点。

In the code example above, the ellipses () stand in for the arcs and orbiting “moons.” Both the inner and the outer rings each contain two arcs and two moons, but for reasons that will become clear a bit later, each arc is actually composed of two CSS shapes, so we need a total of eight arcs and four moons. The HTML in full looks like this:

在上面的代码示例中,椭圆( )代表弧和环绕的“月球”。 内圈和外圈都包含两个弧和两个卫星,但是由于稍后会变得清楚的原因,每个弧实际上由两个CSS形状组成,因此我们总共需要八个弧和四个卫星。 完整HTML看起来像这样:

<div class="center"></div>
<div class="inner-spin">
  
  <div class="inner-arc inner-arc_start-a"></div>
  <div class="inner-arc inner-arc_end-a"></div>
  <div class="inner-arc inner-arc_start-b"></div>
  <div class="inner-arc inner-arc_end-b"></div>
  
  <div class="inner-moon-a"></div>
  <div class="inner-moon-b"></div>
  
</div>
<div class="outer-spin">
  
  <div class="outer-arc outer-arc_start-a"></div>
  <div class="outer-arc outer-arc_end-a"></div>
  <div class="outer-arc outer-arc_start-b"></div>
  <div class="outer-arc outer-arc_end-b"></div>
  
  <div class="outer-moon-a"></div>
  <div class="outer-moon-b"></div>
  
</div>

CSS形状 (CSS Shapes)

It’s possible to draw circles and arcs in CSS by simply creating a square <div>and setting border-radius to 50%.

只需创建一个正方形<div>并将border-radius设置为50%,就可以在CSS中绘制圆和弧。

Each side of the border can take a different color or can be set to transparent. The background-color property sets the shape’s fill, if any.

边框的每一侧可以采用不同的颜色,也可以设置为transparentbackground-color属性设置形状的填充(如果有)。

It’s easy to draw 90, 180, and 270 degree arcs by simply setting one or more sides of the border to be transparent. However, if you look closely at the spinner at the top of the page, you’ll notice that the “tail” of each orbital leaves a gap between itself and the moon behind it. That means that, although the arc lengths are close to 180 degrees, they’re a little shy of 180.

只需将边框的一侧或多侧设置为透明,就可以轻松绘制90、180和270度弧线。 但是,如果您仔细查看页面顶部的微调器,您会注意到每个轨道的“尾巴”在其自身与后面的月亮之间留有间隙。 这意味着,尽管圆弧的长度接近180度,但比180长一点。

To draw circle segments of irregular lengths in CSS requires a bit of a hack. To do this we need to draw two adjacent 90-degree arc segments and rotate one slightly so that they overlap, leaving an apparent arc segment of about 160 degrees.

在CSS中绘制不规则长度的圆弧段需要一点技巧。 为此,我们需要绘制两个相邻的90度弧段,并稍微旋转一个,以便它们重叠,从而留下大约160度的视弧段。

Looking back up at the HTML now, you might now be able to guess why we’ve set two nodes for each arc (an arc_start and arc_end). These will be used to represent each part of a single overlapping arc representing the tail of each orbital.

现在回头看一下HTML,您现在可以猜测为什么我们为每个弧设置两个节点( arc_startarc_end )。 这些将用于表示单个重叠弧的每个部分,该重叠弧表示每个轨道的尾巴。

设置CSS (Setting Up the CSS)

To start with, we’ll set a CSS variable to represent the color of the spinner and another variable to represent a -50%, -50% translate which we’ll use throughout the CSS to center shapes around their center (as apposed to their upper-left corner, which is the default).

首先,我们将设置一个CSS变量来表示微调框的颜色,并设置另一个变量来表示-50%,-50%转换,我们将在整个CSS中使用该变量将形状围绕其中心居中(如它们的左上角,这是默认值)。

html {
  --spinner: #1EAAF0;
  --center: translate(-50%, -50%);
}

Now we can go ahead and draw the central circle as well.

现在我们可以继续绘制中心圆了。

.center {
   position: absolute;
   width: 30px;
   height: 30px;
   background: var(--spinner);
   border-radius: 50%;
   top: 50%;
   left: 50%;
   transform: var(--center); 
}

The child nodes for each orbital are enclosed inside parent nodes called inner-spin and outer-spin. For now we’ll just use them to center the spinner within the window.

每个轨道的子节点包含在称为inner-spinouter-spin父节点inner-spin 。 现在,我们仅使用它们将微调器在窗口内居中。

.outer-spin, .inner-spin {
  position: absolute;
  top: 50%;
  left: 50%;
}

绘制轨道 (Drawing the Orbitals)

The loading spinner is basically a series of concentric circles, so let’s first focus on drawing just one arc.

加载微调器基本上是一系列同心圆,因此让我们首先关注仅绘制一个圆弧。

Since each arc consists of two overlapping sections, lets start be just drawing two arcs next two each other.

由于每个圆弧都由两个重叠的部分组成,因此让我们开始绘制两个彼此相邻的圆弧。

.inner-arc {
  width: 62px;
  height: 62px;
}
.inner-arc_start-a {
  border-color: transparent transparent transparent green;
  /* NOTE: the order here very much matters! */
  transform: var(--center) rotate(0deg); 
}
.inner-arc_end-a {
  border-color: red transparent transparent transparent;
  transform: var(--center) rotate(0deg);
}

The first transform centers the <div> in the window. Rotation is set to zero degrees to show the default state of the arcs.

第一个转换在窗口中将<div>居中。 旋转设置为零度以显示圆弧的默认状态。

Notice that the arcs don’t line up with the x-crossings on the unit circle. To correct for this, and to make the arcs easier to work with, we rotate the arcs by 45 degrees. Then we slightly over rotate one of the arcs to create a total arc length of about 160 degrees.

请注意,圆弧不与单位圆上的x交叉对齐。 为了对此进行更正,并使弧更易于使用,我们将弧旋转45度。 然后,我们稍微旋转其中一个弧,以创建约160度的总弧长。

.inner-arc_start-a {
  border-color: transparent transparent transparent green;
  transform: var(--center) rotate(65deg); 
}
.inner-arc_end-a {
  border-color: red transparent transparent transparent;
  transform: var(--center) rotate(45deg);
}

Next we can position one of the orbital moons by moving it along the x-axis. Unfortunately, unlike vector graphics such as SVGs, CSS borders are not widthless vectors that accept a stroke style. That means that distances are not automatically measured to the center point of the line. We must take into account the width of the border when positioning objects.

接下来,我们可以通过沿x轴移动轨道卫星之一来对其进行定位。 不幸的是,与矢量图形(例如SVG)不同,CSS边框并不是接受笔触样式的无宽度矢量 。 这意味着不会自动测量到直线中心点的距离。 放置对象时,必须考虑边框的宽度。

This results in a few “magic numbers” that we could probably minimize if we wanted to set more CSS variables and use the calc() function. That seems a bit involved though, so I’ll just position the circle by pixel value for now.

如果我们想设置更多CSS变量并使用calc() 函数 ,这可能会导致一些“ 魔术数字 ”减少到最低calc() 。 不过,这似乎有点涉及,所以我现在就按像素值定位圆。

.inner-moon-a {
   position: absolute;
   top:50%;
   left:50%;
   width: 12px;
   height: 12px;
   background: red;
   border-radius: 50%;
   transform: var(--center) translate(33px, 0); 
}

Next we draw two more arcs, but this time we use the scale(-1, -1) transform. This flips the arcs across both the x- and y-axes, essentially mirroring the contrail.

接下来,我们再绘制两个弧,但是这次我们使用scale(-1, -1)变换。 这会在x轴和y轴上翻转弧,从而基本反映了轨迹。

.inner-arc_start-b {
  border-color: transparent transparent transparent var(--spinner); 
  transform: var(--center) rotate(65deg) scale(-1, -1);
}
.inner-arc_end-b {
  border-color: var(--spinner) transparent transparent transparent;
  transform: var(--center) rotate(45deg) scale(-1, -1);

Finally, for the outer orbit, we simply repeat the CSS from the inner orbit but set a larger <div> height and width! (Imagine how short this CSS could be with SASS mixins!)

最后,对于外层轨道,我们仅从内层轨道重复CSS,但设置更大的<div>高度和宽度! (想像一下,使用SASS mixins,此CSS可能有多短!)

.outer-arc {
  width: 100px;
  height: 100px;
}

添加动画 (Adding the Animation)

The last step is to add animation. First we need to add a single keyframes element that sets the type of animation behavior and the CSS element(s) effected by animation, in this case rotation through a transform property.

最后一步是添加动画。 首先,我们需要添加一个关键帧元素,该元素设置动画行为的类型以及由动画影响CSS元素,在本例中是通过transform属性进行旋转。

@keyframes spin { 100% {transform: rotate(360deg); } }

The identifier “spin” connects the keyframes back to animation attributes that we will add within each parent <div> elements. The animation property sets the temporal information for the animation, meaning that each orbital will orbit at a different speed.

标识符“ spin ”将关键帧连接回动画属性,该属性将添加到每个父<div>元素中。 animation属性设置动画的时间信息,这意味着每个轨道将以不同的速度旋转。

.outer-spin {
  animation: spin 4s linear infinite;
}
.inner-spin {
  animation: spin 3s linear infinite;
}

而已! (That’s it!)

The code for this tutorial can be found on CodePen.io. Please comment — or Tweet at me @PleathrStarfish — if you have a suggestion, observation, or a cool fork of my code!

可以在CodePen.io上找到本教程的代码。 如果您有任何建议,观察或对我的代码很感兴趣,请发表评论-或在@PleathrStarfish上向我鸣叫

翻译自: https://www.freecodecamp.org/news/how-to-build-a-reddit-inspired-loading-spinner-with-only-html-and-css-5b2fca3fdca/

reddit

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值