关于harmonyos:开发指导利用CSS动画实现HarmonyOS动效一

82次阅读

共计 12871 个字符,预计需要花费 33 分钟才能阅读完成。

注:本文内容分享转载自 HarmonyOS Developer 官网文档

一. CSS 语法参考
CSS 是形容 HML 页面构造的款式语言。所有组件均存在零碎默认款式,也可在页面 CSS 款式文件中对组件、页面自定义不同的款式。请参考通用款式理解兼容 JS 的类 Web 开发范式反对的组件款式。

尺寸单位
● 逻辑像素 px(文档中以 <length> 示意):
○ 默认屏幕具备的逻辑宽度为 720px(配置见配置文件中的 window 大节),理论显示时会将页面布局缩放至屏幕理论宽度,如 100px 在理论宽度为 1440 物理像素的屏幕上,理论渲染为 200 物理像素(从 720px 向 1440 物理像素,所有尺寸放大 2 倍)。

○ 额定配置 autoDesignWidth 为 true 时(配置见配置文件中的 window 大节),逻辑像素 px 将依照屏幕密度进行缩放,如 100px 在屏幕密度为 3 的设施上,理论渲染为 300 物理像素。利用须要适配多种设施时,倡议采纳此办法。

● 百分比(文档中以 <percentage> 示意):示意该组件占父组件尺寸的百分比,如组件的 width 设置为 50%,代表其宽度为父组件的 50%。

款式导入
为了模块化治理和代码复用,CSS 款式文件反对 @import 语句,导入 css 文件。

申明款式
每个页面目录下存在一个与布局 hml 文件同名的 css 文件,用来形容该 hml 页面中组件的款式,决定组件应该如何显示。

1.  外部款式,反对应用 style、class 属性来管制组件的款式。例如:

<!-- index.hml -->
<div class="container">
  <text style="color: red">Hello World</text>
</div>
/* index.css */
.container {justify-content: center;}

2.  文件导入,合并内部款式文件。例如,在 common 目录中定义款式文件 style.css,并在 index.css 文件首行中进行导入:、

/* style.css */
.title {font-size50px;}
/* index.css */
@import '../../common/style.css';
.container {justify-content: center;}

选择器
css 选择器用于抉择须要增加款式的元素,反对的选择器如下表所示:

示例:

<!-- 页面布局 xxx.hml -->
<div id="containerId" class="container">
  <text id="titleId" class="title"> 题目 </text>
  <div class="content">
    <text id="contentId"> 内容 </text>
  </div>
</div>
/* 页面款式 xxx.css */
/* 对所有 div 组件设置款式 */
div {flex-direction: column;}
/* 对 class="title" 的组件设置款式 */
.title {font-size30px;}
/* 对 id="contentId" 的组件设置款式 */
#contentId {font-size20px;}
/* 对所有 class="title" 以及 class="content" 的组件都设置 padding 为 5px */
.title.content {padding5px;}
/* 对 class="container" 的组件下的所有 text 设置款式 */
.container text {color#007dff;}
/* 对 class="container" 的组件下的间接后辈 text 设置款式 */
.container > text {color#fa2a2d;}

以上款式运行成果如下:

其中“.container text”将“题目”和“内容”设置为蓝色,而“.container > text”间接后辈选择器将“题目”设置为红色。2 者优先级雷同,但间接后辈选择器申明程序靠后,将前者款式笼罩(优先级计算见选择器优先级)。

选择器优先级
选择器的优先级计算规定与 w3c 规定保持一致(只反对:内联款式,id,class,tag,后辈和间接后辈),其中内联款式为在元素 style 属性中申明的款式。

当多条选择器申明匹配到同一元素时,各类选择器优先级由高到低程序为:内联款式 > id > class > tag。

伪类
css 伪类是选择器中的关键字,用于指定要抉择元素的非凡状态。例如,:disabled 状态能够用来设置元素的 disabled 属性变为 true 时的款式。

除了单个伪类之外,还反对伪类的组合,例如,:focus:checked 状态能够用来设置元素的 focus 属性和 checked 属性同时为 true 时的款式。反对的单个伪类如下表所示,依照优先级降序排列:

伪类示例如下,设置按钮的:active 伪类能够管制被用户按下时的款式:

<!-- index.hml -->
<div class="container">
  <input type="button" class="button" value="Button"></input>
</div>
/* index.css */
.button:active {background-color#888888;/* 按钮被激活时,背景色彩变为 #888888 */}

阐明
针对弹窗类组件及其子元素不反对伪类成果,包含 popup、dialog、menu、option、picker

款式预编译
预编译提供了利用特有语法生成 css 的程序,能够提供变量、运算等性能,令开发者更便捷地定义组件款式,目前反对 less、sass 和 scss 的预编译。应用款式预编译时,须要将原 css 文件后缀改为 less、sass 或 scss,如 index.css 改为 index.less、index.sass 或 index.scss。

● 以后文件应用款式预编译,例如将原 index.css 改为 index.less:

/* index.less */
/* 定义变量 */
@colorBackground: #000000;
.container {background-color: @colorBackground; /* 应用以后 less 文件中定义的变量 */}

● 援用预编译文件,例如 common 中存在 style.scss 文件,将原 index.css 改为 index.scss,并引入 style.scss:

/* style.scss */
/* 定义变量 */
$colorBackground#000000;

在 index.scss 中援用:

/* index.scss */
/* 引入内部 scss 文件 */
@import '../../common/style.scss';
.container {background-color$colorBackground/* 应用 style.scss 中定义的变量 */}

阐明
援用的预编译文件倡议放在 common 目录进行治理。

CSS 款式继承 6+
css 款式继承提供了子节点继承父节点款式的能力,继承下来的款式在多选择器款式匹配的场景下,优先级排最低,以后反对以下款式的继承:
● font-family
● font-weight
● font-size
● font-style
● text-align
● line-height
● letter-spacing
● color
● visibility

二. CSS 动画

1. 属性款式动画
在关键帧(Keyframes)中动静设置父组件的 width 和 height,实现组件变大放大。子组件设置 scale 属性使父子组件同时缩放,再设置 opacity 实现父子组件的显示与暗藏。

<!-- xxx.hml -->
<div class="container">
  <div class="fade">
    <text>fading away</text>
  </div>
  <div class="bigger">
    <text>getting bigger</text>
  </div>
</div>
/* xxx.css */
.container {
background-color:#F1F3F5;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width100%;
height100%;
}
.fade {
width30%;
height200px;
left35%;
top25%;
position: absolute;
animation2s change infinite friction;
}
.bigger {
width20%;
height100px;
background-color: blue;
animation2s change1 infinite linear-out-slow-in;
}
text {
width100%;
height100%;
text-align: center;
color: white;
font-size35px;
animation2s change2 infinite linear-out-slow-in;
}
/* 色彩变动 */
@keyframes change{
from {
background-color#f76160;
opacity1;
}
to {
background-color#09ba07;
opacity0;
}
}
/* 父组件大小变动 */
@keyframes change1 {
0% {
width20%;
height100px;
}
100% {
width80%;
height200px;
}
}
/* 子组件文字缩放 */
@keyframes change2 {
0% {transform: scale(0);
}
100% {transform: scale(1.5);
}
}

阐明
● animation 取值不辨别先后,duration(动画执行工夫)/ delay(动画提早执行工夫)依照呈现的先后顺序解析。

● 必须设置 animation-duration 款式,否则时长为 0 则不会有动画成果。当设置 animation-fill-mode 属性为 forwards 时,组件间接展现最初一帧的款式。

2.  transform 款式动画
设置 transform 属性对组件进行旋转、缩放、挪动和歪斜。

设置动态动画
创立一个正方形并旋转 90°变成菱形,并用下方的长方形把菱形下半局部遮蔽造成屋顶,设置长方形 translate 属性值为 (150px,-150px) 确定坐标地位造成门,再应用 position 属性使横纵线追随父组件(正方形)挪动到指定坐标地位,接着设置 scale 属性使父子组件一起变大造成窗户大小,最初应用 skewX 属性使组件歪斜后设置坐标 translate(200px,-710px)失去烟囱。

<!-- xxx.hml -->
<div class="container">
  <div class="top"></div>
  <div class="content"></div>
  <div class="door"></div>
  <!-- 窗户 -->
  <div class="window">
    <div class="horizontal"></div>
    <div class="vertical"></div>
  </div>
  <div class="chimney"></div>
</div>
/* xxx.css */
.container {
width:100%;
height:100%;
background-color:#F1F3F5;
align-items: center;
flex-direction: column;
}
.top{
z-index: -1;
position: absolute;
width428px;
height428px;
background-color#860303;
transform: rotate(45deg);
margin-top284px;
margin-left148px;
}
.content{
margin-top500px;
width600px;
height400px;
background-color: white;
border:  1px solid black;
}
.door{
width100px;
height135px;
background-color#1033d9;
transform: translate(150px,-137px);
}
.window{
z-index1;
position: relative;
width100px;
height100px;
background-color: white;
border1px solid black;
transform: translate(-150px,-400px) scale(1.5);
}
/* 窗户的横轴 */
.horizontal{
position: absolute;
top50%;
width100px;
height5px;
background-color: black;
}
/* 窗户的纵轴 */
.vertical{
position: absolute;
left50%;
width5px;
height100px;
background-color: black;
}
.chimney{
z-index: -2;
width40px;
height100px;
border-radius15px;
background-color#9a7404;
transform: translate(200px,-710px) skewX(-5deg);
}

设置平移动画
小球降落动画,扭转小球的 Y 轴坐标实现小球着落,在下一段是工夫内减小 Y 轴坐标实现小球回弹,让每次回弹的高度逐次减小直至回弹高度为 0,就模拟出了小球降落的动画。

<!-- xxx.hml -->
<div class="container">
  <div class="circle"></div>
  <div class="flower"></div>
</div>
/* xxx.css */
.container {
width:100%;
height:100%;
background-color:#F1F3F5;
display: flex;
justify-content: center;
}
.circle{
width100px;
height100px;
border-radius50px;
background-color: red;
/* forwards 停在动画的最初一帧 */
animation: down 3s fast-out-linear-in forwards;
}
.flower{
position: fixed;
width80%;
margin-left10%;
height5px;
background-color: black;
top1000px;
}
@keyframes down {
0%{transform: translate(0px,0px);
}
/* 着落 */
15%{transform: translate(10px,900px);
}
/* 开始回弹 */
25%{transform: translate(20px,500px);
}
/* 着落 */
35%{transform: translate(30px,900px);
}
/* 回弹 */
45%{transform: translate(40px,700px);
}
55%{transform: translate(50px,900px);
}
65%{transform: translate(60px,800px);
}
80%{transform: translate(70px,900px);
}
90%{transform: translate(80px,850px);
}
/* 进行 */
100%{transform: translate(90px,900px);
}
}

设置旋转动画
设置不同的原点地位(transform-origin)扭转元素所围绕的旋转核心。rotate3d 属性前三个参数值别离为 X 轴、Y 轴、Z 轴的旋转向量,第四个值为旋转角度,旋转向角度可为负值,负值则代表旋转方向为逆时针方向。

<!-- xxx.hml -->
<div class="container">
  <div class="rotate">
    <div class="rect rect1"></div>
    <div class="rect rect2"></div>
    <div class="rect rect3"></div>
  </div>
  <!-- 3d 属性 -->
  <div class="rotate3d">
    <div class="content">
        <div class="rect4"></div>
        <div class="rect5"> </div>
    </div>
    <div class="mouse"></div>
  </div>
</div>
/* xxx.css */
.container {
flex-direction: column;
background-color:#F1F3F5;
display: flex;
align-items: center;
justify-content: center;
width100%;
height100%;
}
.rect {
width100px;
height100px;
animation: rotate 3s infinite;
margin-left30px;
}
.rect1 {background-color#f76160;}
.rect2 {
background-color#60f76f;
/* 扭转原点地位 */
transform-origin10% 10px;
}
.rect3 {
background-color#6081f7;
/*  扭转原点地位 */
transform-origin: right bottom;
}
@keyframes rotate {
from {transform: rotate(0deg)
}
to {transform: rotate(360deg);
}
}
/* 3d 示例款式 */
.rotate3d {
margin-top150px;
flex-direction: column;
background-color:#F1F3F5;
display: flex;
align-items: center;
width80%;
height600px;
border-radius300px;
border1px solid #ec0808;
}
.content {
padding-top150px;
display: flex;
align-items: center;
justify-content: center;
}
/* react4 react5 翻转造成眼睛 */
.rect4 {
width100px;
height100px;
animation: rotate3d1 1000ms infinite;
background-color: darkmagenta;
}
.rect5 {
width100px;
height100px;
animation: rotate3d1 1000ms infinite;
margin-left100px;
background-color: darkmagenta;
}
.mouse {
margin-top150px;
width200px;
height100px;
border-radius50px;
border1px solid #e70303;
animation: rotate3d2 1000ms infinite;
}
/* 眼睛的动效 */
@keyframes rotate3d1 {
0% {transform:rotate3d(0,0,0,0deg)
}
50% {transform:rotate3d(20,20,20,360deg);
}
100% {transform:rotate3d(0,0,0,0deg);
}
}
/* 嘴的动效 */
@keyframes rotate3d2 {
0% {transform:rotate3d(0,0,0,0deg)
}
33% {transform:rotate3d(0,0,10,30deg);
}
66% {transform:rotate3d(0,0,10,-30deg);
}
100% {transform:rotate3d(0,0,0,0deg);
}
}

阐明
transform-origin 变换对象的原点地位,如果仅设置一个值,另一个值为 50%,若设置两个值第一个值示意 X 轴的地位,第二个值示意 Y 轴的地位。

设置缩放动画
设置 scale 款式属性实现涟漪动画,先应用定位确定元素的地位,确定坐标后创立多个组件实现重合成果,再设置 opacity 属性扭转组件不透明度实现组件暗藏与显示,同时设置 scale 值使组件能够一边放大一边暗藏,最初设置两个组件不同的动画执行工夫,实现扩散的成果。

设置 sacle3d 中 X 轴、Y 轴、Z 轴的缩放参数实现动画。

<!-- xxx.hml -->
<div class="container">
  <div class="circle">
    <text>ripple</text>
  </div>
  <div class="ripple"></div>
  <div class="ripple ripple2"></div>
  <!-- 3d -->
  <div class="content">
    <text>spring</text>
  </div>
</div>
/* xxx.css */
.container {
flex-direction: column;
background-color:#F1F3F5;
width100%;
position: relative;
}
.circle{
margin-top400px;
margin-left40%;
width100px;
height100px;
border-radius50px;
background-color: mediumpurple;
z-index1; position: absolute;
}
.ripple{
margin-top400px;
margin-left40%;
position: absolute; z-index0;
width100px;
height100px;
border-radius50px;
background-color: blueviolet;
animation: ripple 5s infinite;
}
/* 设置不同的动画工夫 */
.ripple2{animation-duration2.5s;}
@keyframes ripple{
0%{transform: scale(1);
opacity0.5;
}
50%{transform: scale(3);
opacity0;
}
100%{transform: scale(1);
opacity0.5;
}
}
text{
color: white;
text-align: center;
height100%;
width100%;
}
.content {
margin-top700px;
margin-left33%;
width200px;
height100px;
animation:rubberBand 1s infinite;
background-color: darkmagenta;
position: absolute;
}
@keyframes rubberBand {
0% {transform: scale3d(111);
}
30% {transform: scale3d(1.250.751.1);
}
40% {transform: scale3d(0.751.251.2);
}
50% {transform: scale3d(1.150.851.3);
}
65% {transform: scale3d(.951.051.2);
}
75% {transform: scale3d(1.05, .951.1);
}
100%{transform: scale3d(111);
}
}

阐明
设置 transform 属性值后,子元素会跟着父元素一起扭转,若只扭转父元素其余属性值时(如:height,width),子元素不会扭转。

设置 matrix 属性
matrix 是一个入参为六个值的矩阵,6 个值别离代表:scaleX, skewY, skewX, scaleY, translateX, translateY。上面示例中设置 了 matrix 属性为 matrix(1,0,0,1,0,200) 使组件挪动和歪斜。

<!-- xxx.hml -->
<div class="container">
  <div class="rect"> </div>
</div>
/* xxx.css */
.container{
  background-color:#F1F3F5;
  display: flex;
  justify-content: center;
  width100%;
  height100%;
}
.rect{
  width100px;
  height100px;
  background-color: red;
  animation: down 3s infinite forwards;
}
@keyframes down{
  0%{transformmatrix(1,0,0,1,0,0);
  }
  10%{transformmatrix(1,0,0,1,0,200);
  }
  60%{transformmatrix(2,1.5,1.5,2,0,700);
  }
  100%{transformmatrix(1,0,0,1,0,0);
  }
}

整合 transform 属性
transform 能够设置多个值并且多个值可同时设置,上面案例中展现同时设置缩放(scale),平移(translate),旋转(rotate)属性时的动画成果。

<!-- xxx.hml -->
<div class="container">
  <div class="rect1"></div>
  <div class="rect2"></div>
  <div class="rect3"></div>
  <div class="rect4"></div>
  <div class="rect5"></div>
</div>
/* xxx.css */
.container{
width100%;
height100%;
flex-direction:column;
background-color:#F1F3F5;
padding:50px;
}
.rect1{
width100px;
height100px;
background-color: red;
animation: change1 3s infinite forwards;
}
.rect2{
margin-top50px;
width100px;
height100px;
background-color: darkblue;
animation: change2 3s infinite forwards;
}
.rect3{
margin-top50px;
width100px;
height100px;
background-color: darkblue;
animation: change3 3s infinite;
}
.rect4{
align-self: center;
margin-left50px;
margin-top200px;
width100px;
height100px;
background-color: darkmagenta;
animation: change4 3s infinite;
}
.rect5{
margin-top300px;
width100px;
height100px;
background-color: cadetblue;
animation: change5 3s infinite;
}
/* change1 change2 比照 */
@keyframes change1{
0%{transform: translate(0,0); transform: rotate(0deg)
}
100%{transform: translate(0,500px);
transform: rotate(360deg)
}
}
/* change2 change3 比照属性程序不同的动画成果 */
@keyframes change2{
0%{transform:translate(0,0) rotate(0deg) ;
}
100%{transform: translate(300px,0) rotate(360deg);
}
}
@keyframes change3{
0%{transform:rotate(0deg) translate(0,0);
}
100%{transform:rotate(360deg) translate(300px,0);
}
}
/* 属性值不对应的状况 */
@keyframes change4{
0%{transform: scale(0.5);
}
100%{transform:scale(2) rotate(45deg);
}
}
/* 多属性的写法 */
@keyframes change5{
0%{transform:scale(0) translate(0,0) rotate(0);
}
100%{transform: scale(1.5) rotate(360deg) translate(200px,0);
}
}

阐明
● 当设置多个 transform 时,后续的 transform 值会把后面的笼罩掉。若想同时应用多个动画款式可用复合写法,例:transform: scale(1) rotate(0) translate(0,0)。
● transform 进行复合写法时,变动款式内多个款式值程序的不同会出现不一样的动画成果。
● transform 属性设置的款式值要一一对应,若前后不对应,则该动画不失效。若设置多个款式值则只会呈现出已对应值的动画成果。

正文完
 0