分析动画
仔细看了好几遍鸿蒙OS的开机动画,大致分成以下几个阶段:
- 字母O的睁眼效果,直接把上面大佬写的copy下来
- HarmonyOS 除了O之外的其他字母显现,并且整体缩小向左平移
- 平移的同时会有一个聚光灯效果,像一个手电筒照亮在O上面,然后扩散至全部字母显现
- 字母O下方的下划线动效
开敲
屏幕兼容问题
首先需要考虑的一个问题是兼容,当然这里说的不是兼容IE😥……只是需要简单兼容一下不同屏幕大小的显示,确保在PC和手机上能正常显示
简单用媒体查询rem布局写了一下不同分辨率屏幕下的显示大小,主要为了自己方便计算,这里贴一下代码,不做太多解释了,不熟悉的可以去了解一下rem布局的原理
html {
font-size: 10px;
}
@media screen and (max-width: 767px) {
html {
font-size: 6px;
}
}
@media screen and (min-width: 768px) and (max-width: 1023px) {
html {
font-size: 8px;
}
}
@media screen and (min-width: 1024px) and (max-width: 1199px) {
html {
font-size: 10px;
}
}
@media screen and (min-width: 1200px) {
html {
font-size: 12px;
}
}
字母O的睁眼动画就不做解释了,直接去看原文,我在此基础上做了修改
HarmonyOS 除了O之外的其他字母显现,并且整体缩小向左平移
html结构如下,做了一些修改
<div class="container">
<span class="delay">Harmony</span>
<div class="letter">
<ul class="ul">
<li class="harmony"></li>
</ul>
<ul class="ul">
<li class="harmony"></li>
</ul>
<svg>
<filter id="blur">
<feGaussianBlur in="SourceGraphic" stdDeviation="0 6" />
</filter>
</svg>
</div>
<span class="delay">S</span>
</div>
除了O之外其他字母显现
这个很容易,用opacity
就可以实现,等2秒是让字母O动画结束后执行,加这个动画的目的主要是先让字母O执行完动画,配合聚光灯效果
.delay{
opacity: 0;
animation: fade_in 2s 0.5s forwards;
}
@keyframes fade_in {
to {
opacity: 1;
}
}
整体缩小向左平移
首先想到的是缩放然后向左平移,最后发现平移都没必要了,直接默认整体放大,原点设置在左侧中间位置,这样缩小动画的时候会整体以左边为基点恢复到原位
chrome在放大后动画感觉不是那么丝滑,没关系,不用在意这些细节……用火狐浏览器效果不错
scale(2.5)
大概试了个值,这个时候字母O刚好在中间,差不多就行,不用在意这些细节……
cubic-bezier(0.1, 0.6, 0, 1)
这个贝塞尔曲线是自己试出来的,感觉效果比较类似
.container {
position: relative;
display: flex;
justify-content: center;
font-size: 10rem;
color: white;
transform: scale(2.5);
transform-origin: 100% 50%;
animation: move 0.8s 1.5s cubic-bezier(0.1, 0.6, 0, 1) forwards;
}
@keyframes move {
to {
transform: none;
}
}
聚光灯效果
html结构新增<div class="shadow__spot"></div>
与class="container"
同级
这个其实我首先想到的就是类似聚光灯效果的蒙版扩散,所以在codepen上搜了一下,有个效果比较满意:[XWdRwrm],但是这个css属性值不能使用动画过渡,想实现的话应该需要js,所以我又想到了用渐变色做蒙版好像也可以,但是渐变色的属性值也是不支持动画过渡的,我改成红色先看一下效果:
.shadow__spot {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: radial-gradient(circle, transparent 6rem, red 20rem);
animation: fade_spot 1s 1.5s forwards;
}
@keyframes fade_spot {
to {
background: radial-gradient(circle, transparent 30rem, red 60rem);
}
}
额……难道还得用js?
不,总有简单粗暴的方法,既然不支持过渡,那就直接放大,放大到全部显示为止……
.shadow__spot {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: radial-gradient(circle, transparent 6rem, red 20rem);
animation: fade_spot 1s 1.5s forwards;
}
@keyframes fade_spot {
to {
transform: translateX(10rem) scale(5);
}
}
效果好像还不错,把颜色改成黑色就大功告成了
注意这里加了个translateX(10rem)
让蒙版向右偏移了一点,主要目的是为了尽量让焦点聚焦在字母O上,更接近官方动画效果,也是个大概值……
注意这里scale(5)
放大5倍后是会出现滚动条的,所以在body上设置了overflow: hidden
字母O下方的下划线动效
这个比较简单就不多做解释了,直接flex布局,水平居中改变宽度就实现了
html结构中svg
标签下方添加<div class="line"></div>
.letter .line{
position: absolute;
bottom: 0;
width: 100%;
height: 1rem;
display: flex;
justify-content: center;
}
.letter .line::after{
content: '';
width: 0%;
background-color: #146df7;
animation: line 0.5s 1.7s forwards;
}
@keyframes line {
to {
width: 60%;
}
}
最后看一下最终效果,火狐浏览器比较丝滑,我录个火狐的运行gif图
是不是有内味了?
其实最后还有个扫光效果,懒得搞了,也是比较简单,类似于骨架屏的扫光
全部代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Harmony</title>
<style>
* {
padding: 0;
margin: 0;
}
html {
height: 100%;
font-size: 10px;
}
body {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
font-family: Arial;
background-color: black;
overflow: hidden;
}
@media screen and (max-width: 767px) {
html {
font-size: 6px;
}
}
@media screen and (min-width: 768px) and (max-width: 1023px) {
html {
font-size: 8px;
}
}
@media screen and (min-width: 1024px) and (max-width: 1199px) {
html {
font-size: 10px;
}
}
@media screen and (min-width: 1200px) {
html {
font-size: 12px;
}
}
.container {
position: relative;
display: flex;
justify-content: center;
font-size: 10rem;
color: white;
transform: scale(2.5);
transform-origin: 100% 50%;
animation: move 0.8s 1.5s cubic-bezier(0.1, 0.6, 0, 1) forwards;
}
.delay{
opacity: 0;
animation: fade_in 2s 0.5s forwards;
}
.letter {
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
}
.letter .ul {
position: relative;
width: 7rem;
height: 3.5rem;
padding: 1rem;
list-style: none;
overflow: hidden;
}
.letter .ul:first-of-type {
padding-bottom: 0;
}
.letter .ul:last-of-type {
padding-top: 0;
/* margin-top: -2px; */
/* animation: letter-move .1s 1.2s forwards; */
}
.letter .ul .harmony {
position: absolute;
top: 1rem;
left: 1rem;
width: 5rem;
height: 5rem;
border: 1rem solid white;
border-radius: 50%;
transform: translateY(50%);
box-shadow: 0px 0px 1.5rem 0px white, inset 0 0 1rem white;
animation: move 1.2s forwards, shadow 1.5s 1.2s forwards;
}
.letter .ul:last-of-type>.harmony {
top: auto;
bottom: 1rem;
transform: translateY(-50%);
filter: url(#blur);
}
.letter svg {
position: absolute;
width: 0;
height: 0;
}
.letter .line{
position: absolute;
bottom: 0;
width: 100%;
height: 1rem;
display: flex;
justify-content: center;
}
.letter .line::after{
content: '';
width: 0%;
background-color: #146df7;
animation: line 0.5s 1.7s forwards;
}
.shadow__spot {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: radial-gradient(circle, transparent 6rem, black 20rem);
animation: fade_spot 1s 1.5s forwards;
}
@keyframes move {
to {
transform: none;
}
}
@keyframes shadow {
to {
box-shadow: none;
}
}
@keyframes fade_spot {
to {
transform: translateX(10rem) scale(5);
}
}
@keyframes fade_in {
to {
opacity: 1;
}
}
@keyframes line {
to {
width: 60%;
}
}
/* @keyframes letter-move {
to { margin-top: 0 }
} */
</style>
</head>
<body>
<div class="container">
<span class="delay">Harmony</span>
<div class="letter">
<ul class="ul">
<li class="harmony"></li>
</ul>
<ul class="ul">
<li class="harmony"></li>
</ul>
<svg>
<filter id="blur">
<feGaussianBlur in="SourceGraphic" stdDeviation="0 6" />
</filter>
</svg>
<div class="line"></div>
</div>
<span class="delay">S</span>
</div>
<div class="shadow__spot"></div>
<script>
const filterElem = document.querySelector('feGaussianBlur')
const clearFilter = () => {
const value = parseFloat(filterElem.getAttribute('stdDeviation').split(' ')[1]) - 0.06
if (value > 0) {
filterElem.setAttribute('stdDeviation', `0 ${value}`)
requestAnimationFrame(clearFilter)
} else {
return
}
}
setTimeout(clearFilter, 300)
</script>
</body>
</html>
最后呢,很多开发朋友不知道需要学习那些鸿蒙技术?鸿蒙开发岗位需要掌握那些核心技术点?为此鸿蒙的开发学习必须要系统性的进行。
而网上有关鸿蒙的开发资料非常的少,假如你想学好鸿蒙的应用开发与系统底层开发。你可以参考这份资料,少走很多弯路,节省没必要的麻烦。由两位前阿里高级研发工程师联合打造的《鸿蒙NEXT星河版OpenHarmony开发文档》里面内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(Harmony NEXT)技术知识点
如果你是一名Android、Java、前端等等开发人员,想要转入鸿蒙方向发展。可以直接领取这份资料辅助你的学习。下面是鸿蒙开发的学习路线图。
高清完整版请点击→《鸿蒙NEXT星河版开发学习文档》
针对鸿蒙成长路线打造的鸿蒙学习文档。话不多说,我们直接看详细资料鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,帮助大家在技术的道路上更进一步。
《鸿蒙 (OpenHarmony)开发学习视频》
《鸿蒙生态应用开发V2.0白皮书》
《鸿蒙 (OpenHarmony)开发基础到实战手册》
《鸿蒙开发基础》
《鸿蒙开发进阶》
《鸿蒙开发实战》
获取这份鸿蒙星河版学习资料,请点击→《鸿蒙NEXT星河版开发学习文档》
总结
鸿蒙—作为国家主力推送的国产操作系统。部分的高校已经取消了安卓课程,从而开设鸿蒙课程;企业纷纷跟进启动了鸿蒙研发。
并且鸿蒙是完全具备无与伦比的机遇和潜力的;预计到年底将有 5,000 款的应用完成原生鸿蒙开发,未来将会支持 50 万款的应用。那么这么多的应用需要开发,也就意味着需要有更多的鸿蒙人才。鸿蒙开发工程师也将会迎来爆发式的增长,学习鸿蒙势在必行!