Apple Watch 带有一个名为 Breathe 的内置应用程序,提醒您,嗯,呼吸。 事实上,它不仅仅是提醒您呼吸,但是需要提醒自己呼吸的想法让我发笑。 关键是,这个应用程序有一个非常棒的界面,带有一个很棒的动画。

我认为用原生 CSS 重现这个设计会很有趣。 我已经完成了这项工作,感觉非常接近。
查看 CodePen 上 Geoff Graham (@geoffgraham) 的作品 Apple Watch 呼吸 App 动画.
制作圆形
首先,我们需要一组圆形来组成看起来像花的图案。 应用程序本身会为计时器添加的每一分钟添加一个圆形,但我们将在这个演示中使用六个静态圆形。 感觉上,我们可以使用 ::before
和 ::after
来减少 HTML 标记,但我们可以保持简单。
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
我们将使每个圆形的完整尺寸为 125px
,这是一个任意数字。 重要的是,圆形默认状态应全部叠放在彼此的顶部。 我们可以使用绝对定位来实现这一点。
.circle {
border-radius: 50%;
height: 125px;
position: absolute;
transform: translate(0, 0);
width: 125px;
}
请注意,我们使用 transform
属性的 translate
函数来居中所有内容。 我最初尝试使用基本的 top, right, bottom, left
属性,但后来发现动画 translate
要平滑得多。 我最初还认为将圆形定位在完全展开的状态将是最好的起点,但后来发现以这种方式创建动画非常麻烦,因为它需要将每个动画重置为居中。 经验教训!
如果我们在此停止,屏幕上将不会显示任何内容,因为我们尚未设置 background
颜色。 我们将在稍后讨论应用程序中使用的漂亮花哨的颜色,但现在添加一个带有透明度的白色背景可能会有所帮助,以便在工作时看到正在发生的事情。
查看 CodePen 上 Geoff Graham (@geoffgraham) 的作品 Apple Watch 呼吸 App – 第一步.
我们需要一个容器!
您可能已经注意到,我们的圆形整齐地叠放,但距离视窗的实际中心很远。 我们需要将这些圆形包裹在一个父元素中,以便我们可以定位整个圆形。 此外,该容器将充当稍后脉动并旋转整个圆形的元素。 这是我必须用艰苦的方式学到的另一课,因为我固执地不想使用容器的额外标记,并认为我可以绕过它。
我们在这里将容器命名为 .watch-face
,并将其设置为与单个圆形相同的宽度和高度。
<div class="watch-face">
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
</div>
现在,我们可以向 body 元素添加一些 flex
,以便将所有内容居中。
body {
background: #000;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
查看 CodePen 上 Geoff Graham (@geoffgraham) 的作品 Apple Watch 呼吸 App – 第二步.
接下来,动画圆形
在这一点上,我很想看到圆形以那种整齐的花卉叠加排列排列。 我知道,在没有看到它们定位的情况下,动画每个圆形的精确位置会很困难,所以我覆盖了每个圆形中的 transform
属性,以查看它们会落在哪里。
我们可以为每个圆形设置一个类,但使用 :nth-child
似乎更简单。
.circle:nth-child(1) {
transform: translate(-35px, -50px);
}
/* Skipping 2-5 for brevity... */
.circle:nth-child(6) {
transform: translate(35px, 50px);
}
我尝试了几次才找到合适的坐标。 它最终取决于圆形的尺寸,可能需要进行一些调整。
查看 CodePen 上 Geoff Graham (@geoffgraham) 的作品 Apple Watch 呼吸 App – 第步 3.
有了坐标,我们就可以注册动画。 我删除了应用于每个 :nth-child
的 transform
坐标,并将它们移动到关键帧中
@keyframes circle-1 {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(-35px, -50px);
}
}
/* And so on... */
我必须承认,我使用的方法感觉很笨拙,因为每个圆形都有自己的动画。 最好有一个动画可以控制所有圆形,以便推动和重新居中圆形,但也许阅读这篇文章的其他人有想法,可以在评论区分享。
现在,我们可以将这些动画应用于每个 :nth-child
,以代替 transform
.circle:nth-child(1) {
animation: circle-1 4s ease alternate infinite;
}
/* And so on... */
请注意,我们将 animation-timing-function
设置为 ease
,因为感觉很流畅……至少对我来说是! 我们还将 animation-direction
设置为 alternate
,以便动画来回播放,并将 animation-iteration-count
设置为 inifinite
,以便动画持续运行。
查看 CodePen 上 Geoff Graham (@geoffgraham) 的作品 Apple Watch 呼吸 App – 第步 4.
颜色,颜色,颜色!
哦,是的,让我们把它涂上颜色! 从我所能看到的信息来看,这个设计中只有两种颜色,不透明度使它看起来更像一个频谱。
左侧的圆形是绿色的,右侧的圆形是蓝色的。 我们可以选择奇数圆形来应用绿色,选择偶数圆形来应用蓝色。
.circle:nth-child(odd) {
background: #61bea2;
}
.circle:nth-child(even) {
background: #529ca0;
}
哦,别忘了从 .circle
元素中删除白色背景。 它不会有任何问题,但清理一下总是好的。 我必须承认,我在第一次做的时候忘记了这一点。
查看 CodePen 上 Geoff Graham (@geoffgraham) 的作品 Apple Watch 呼吸 App – 第步 5.
同样在这一点上,评论区中的其他人建议用 mix-blend-mode
替换 opacity
,并使用 screen
值,以更佳的方式混合圆形的颜色。 我已经更新了演示和代码。
脉动和旋转
还记得我们创建的恼人的 .watch-face
容器吗? 好吧,我们可以对它进行动画处理,使圆形进出脉动,同时旋转整个圆形。
我完全忘记了 transform
函数可以链接在一起。 这使事情变得更干净,因为它允许我们在同一行上应用 scale()
和 rotate()
。
@keyframes pulse {
0% {
transform: scale(.15) rotate(180deg);
}
100% {
transform: scale(1);
}
}
……并将它应用于 .watch-face
元素。
.watch-face {
height: 125px;
width: 125px;
animation: pulse 4s cubic-bezier(0.5, 0, 0.5, 1) alternate infinite;
}
与圆形一样,我们希望动画双向运行并无限重复。 在这种情况下,当圆形叠放在一起时,缩放会缩小到一个非常小的尺寸,并且整个圆形在向外旋转一半后会返回。
我必须承认,在找到最流畅或最精确的动画的正确 animation-timing-function
方面,我并不是高手。 我玩了 cubic-bezier
,找到了一些我认为感觉很棒的东西,但可能像 ease-in
这样的库存值也能达到同样的效果。
现在一起!
以下是在同一个演示中将所有内容压缩在一起。
查看 CodePen 上 Geoff Graham (@geoffgraham) 的作品 Apple Watch 呼吸 App 动画.
现在,请记住要呼吸,让我们都度过一个平静的一天。 ☮️
我认为这些圆形需要一个
mix-blend-mode
,除了 IE/Edge,比如mix-blend-mode: screen
。好主意!
您对如何制作这个的解释很棒。 我很喜欢结果。
我试图让颜色更好地混合,并在圆形上使用了
mix-blend-mode: color-dodge;
。 它并不完美,但更接近 Apple 的效果。哈哈,我看到 C. M. Helmer 也有同样的想法!
当然,这是一个好主意——我可能需要根据结果来修改它。:)
很棒的讲解,以及对干净简洁的 css 的赞赏!
很棒的演示!谢谢!
我喜欢这种简单的教程,请多发布这样的内容。干得好!
尝试将
mix-blend-mode: screen;
添加到.circle
规则中。是的,这是一个好主意,上面已经有人提了几次。
哈哈,干得好!我也喜欢教程的简洁性。感谢分享。
干得好!你也可以尝试不为每个圆添加其他动画,而是使用 transform-origin,就像这里 https://codepen.io/anon/pen/Xzqazq。虽然不太一样,但很相似。
啊,不错,这是一个更优雅的解决方案!感谢你的建议。:)
这是一个很棒的补充,也是一个更优雅的方法。感谢你的建议!
好吧,这与代码示例无关,而是与应用程序本身有关——虽然听起来很有趣,但它实际上对患有各种神经症或焦虑症的人很有用,比如我(虽然只是轻微的,但它确实让我放松了不少)。
所以,是的,它实际上相当不错:D
顺便说一句,很棒的例子!
酷炫的教程 Geoff,它启发我去尝试制作一个方形的,很有趣!https://codepen.io/o-sewell/full/GOXLLz/
谢谢!
我喜欢它!干得好。:)
很棒的结果!在 Swift 中为 iOS 制作了类似的东西 BreatheView.