• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# transform样式动画
2
3设置transform属性对组件进行旋转、缩放、移动和倾斜。
4
5
6## 设置静态动画
7
8创建一个正方形并旋转90°变成菱形,并用下方的长方形把菱形下半部分遮盖形成屋顶,设置长方形translate属性值为(150px,-150px)确定坐标位置形成门,再使用position属性使横纵线跟随父组件(正方形)移动到指定坐标位置,接着设置scale属性使父子组件一起变大形成窗户大小,最后使用skewX属性使组件倾斜后设置坐标translate(200px,-830px)得到烟囱。
9
10```html
11<!-- xxx.hml -->
12<div class="container">
13  <div class="top"></div>
14  <div class="content"></div>
15  <div class="door"></div>
16  <!-- 窗户 -->
17  <div class="window">
18    <div class="horizontal"></div>
19    <div class="vertical"></div>
20  </div>
21  <div class="chimney"></div>
22</div>
23```
24
25```css
26/* xxx.css */
27.container {
28  width:100%;
29  height:100%;
30  background-color:#F1F3F5;
31  align-items: center;
32  flex-direction: column;
33}
34.top{
35  z-index: -1;
36  position: absolute;
37  width: 428px;
38  height: 428px;
39  background-color: #860303;
40  transform: rotate(45deg);
41  margin-top: 284px;
42  margin-left: 148px;
43}
44.content{
45  margin-top: 500px;
46  width: 600px;
47  height: 400px;
48  background-color: white;
49  border:  1px solid black;
50}
51.door{
52  width: 100px;
53  height: 150px;
54  background-color: #1033d9;
55  transform: translate(150px,-137px);
56}
57.window{
58  z-index: 1;
59  position: relative;
60  width: 100px;
61  height: 100px;
62  background-color: white;
63  border: 1px solid black;
64  transform: translate(-150px,-400px) scale(1.5);
65}
66/* 窗户的横轴 */
67.horizontal{
68  position: absolute;
69  top: 50%;
70  width: 100px;
71  height: 5px;
72  background-color: black;
73}
74/* 窗户的纵轴 */
75.vertical{
76  position: absolute;
77  left: 50%;
78  width: 5px;
79  height: 100px;
80  background-color: black;
81}
82.chimney{
83  z-index: -2;
84  width: 40px;
85  height: 100px;
86  border-radius: 15px;
87  background-color: #9a7404;
88  transform: translate(200px,-710px) skewX(-5deg);
89}
90```
91
92![zh-cn_image_0000001220634677](figures/zh-cn_image_0000001220634677.png)
93
94
95## 设置平移动画
96
97小球下降动画,改变小球的Y轴坐标实现小球下落,在下一段是时间内减小Y轴坐标实现小球回弹,让每次回弹的高度逐次减小直至回弹高度为0,就模拟出了小球下降的动画。
98
99```html
100<!-- xxx.hml -->
101<div class="container">
102  <div class="circle"></div>
103  <div class="flower"></div>
104</div>
105```
106
107```css
108/* xxx.css */
109.container {
110  width:100%;
111  height:100%;
112  background-color:#F1F3F5;
113  display: flex;
114  justify-content: center;
115}
116.circle{
117  width: 100px;
118  height: 100px;
119  border-radius: 50px;
120  background-color: red;
121  /* forwards停在动画的最后一帧 */
122  animation: down 3s fast-out-linear-in forwards;
123}
124.flower{
125  position: fixed;
126  width: 80%;
127  margin-left: 10%;
128  height: 5px;
129  background-color: black;
130  top: 1000px;
131}
132@keyframes down {
133  0%{
134    transform: translate(0px,0px);
135  }
136  /* 下落 */
137  15%{
138    transform: translate(10px,900px);
139  }
140  /* 开始回弹 */
141  25%{
142    transform: translate(20px,500px);
143  }
144  /* 下落 */
145  35%{
146    transform: translate(30px,900px);
147  }
148  /* 回弹 */
149  45%{
150    transform: translate(40px,700px);
151  }
152  55%{
153    transform: translate(50px,900px);
154  }
155  65%{
156    transform: translate(60px,800px);
157  }
158  80%{
159    transform: translate(70px,900px);
160  }
161  90%{
162    transform: translate(80px,850px);
163  }
164  /* 停止 */
165  100%{
166    transform: translate(90px,900px);
167  }
168}
169```
170
171![zh-cn_image_0000001174756438](figures/zh-cn_image_0000001174756438.gif)
172
173
174## 设置旋转动画
175
176设置不同的原点位置(transform-origin)改变元素所围绕的旋转中心。rotate3d属性前三个参数值分别为X轴、Y轴、Z轴的旋转向量,第四个值为旋转角度,旋转向角度可为负值,负值则代表旋转方向为逆时针方向。
177
178```html
179<!-- xxx.hml -->
180<div class="container">
181  <div class="rotate">
182    <div class="rect rect1"></div>
183    <div class="rect rect2"></div>
184    <div class="rect rect3"></div>
185  </div>
186  <!-- 3d属性 -->
187  <div class="rotate3d">
188    <div class="content">
189        <div class="rect4"></div>
190        <div class="rect5"> </div>
191    </div>
192    <div class="mouse"></div>
193  </div>
194</div>
195```
196
197```css
198/* xxx.css */
199.container {
200  flex-direction: column;
201  background-color:#F1F3F5;
202  display: flex;
203  align-items: center;
204  justify-content: center;
205}
206.rect{
207  width: 100px;
208  height: 100px;
209  animation: rotate 3s infinite;
210  margin-left: 100px;
211}
212.rect1{
213  background-color: #f76160;
214}
215.rect2{
216  background-color: #60f76f;
217  /* 改变原点位置*/
218  transform-origin: 10% 10px;
219}
220.rect3{
221  background-color: #6081f7;
222  /*  改变原点位置*/
223  transform-origin: right bottom;
224}
225@keyframes rotate {
226  from {
227    transform: rotate(0deg)
228  }
229  to {
230    transform: rotate(360deg);
231  }
232}
233/* 3d示例样式 */
234.rotate3d{
235  margin-top: 150px;
236  flex-direction: column;
237  background-color:#F1F3F5;
238  display: flex;
239  align-items: center;
240  width: 80%;
241  height: 600px;
242  border-radius: 300px;
243  border: 1px solid #ec0808;
244}
245.content{
246  padding-top: 150px;
247  display: flex;
248  align-items: center;
249  justify-content: center;
250}
251/* react4 react5 翻转形成眼睛 */
252.rect4{
253  width: 100px;
254  height: 100px;
255  animation: rotate3d1 1000ms infinite;
256  background: linear-gradient(#e6c4ec, #be15d9)
257}
258.rect5{
259  width: 100px;
260  height: 100px;
261  animation: rotate3d1 1000ms infinite;
262  margin-left: 100px;
263  background: linear-gradient(#e6c4ec, #be15d9)
264}
265.mouse{
266  margin-top: 150px;
267  width: 200px;
268  height: 100px;
269  border-radius: 50px;
270  border: 1px solid #e70303;
271  animation: rotate3d2 1000ms infinite;
272}
273/* 眼睛的动效 */
274@keyframes rotate3d1{
275  0% {
276    transform:rotate3d(0,0,0,0deg)
277  }
278  50% {
279    transform:rotate3d(20,20,20,360deg);
280  }
281  100% {
282    transform:rotate3d(0,0,0,0deg);
283  }
284}
285/* 嘴的动效 */
286@keyframes rotate3d2{
287  0% {
288    transform:rotate3d(0,0,0,0deg)
289  }
290  33% {
291    transform:rotate3d(0,0,10,30deg);
292  }
293  66% {
294    transform:rotate3d(0,0,10,-30deg);
295  }
296  100% {
297    transform:rotate3d(0,0,0,0deg);
298  }
299}
300```
301
302![zh-cn_image_0000001220316305](figures/zh-cn_image_0000001220316305.gif)
303
304> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
305> transform-origin变换对象的原点位置,如果仅设置一个值,另一个值为50%,若设置两个值第一个值表示X轴的位置,第二个值表示Y轴的位置。
306
307
308## 设置缩放动画
309
310设置scale样式属性实现涟漪动画,先使用定位确定元素的位置,确定坐标后创建多个组件实现重合效果,再设置opacity属性改变组件不透明度实现组件隐藏与显示,同时设置scale值使组件可以一边放大一边隐藏,最后设置两个组件不同的动画执行时间,实现扩散的效果。
311
312设置sacle3d中X轴、Y轴、Z轴的缩放参数实现动画。
313
314```html
315<!-- xxx.hml -->
316<div class="container">
317  <div class="circle">
318    <text>ripple</text>
319  </div>
320  <div class="ripple"></div>
321  <div class="ripple ripple2"></div>
322  <!-- 3d -->
323  <div class="content">
324    <text>spring</text>
325  </div>
326</div>
327```
328
329```css
330/* xxx.css */
331.container {
332  flex-direction: column;
333  background-color:#F1F3F5;
334  width: 100%;
335  position: relative;
336}
337.circle{
338  margin-top: 400px;
339  margin-left: 40%;
340  width: 100px;
341  height: 100px;
342  border-radius: 50px;
343  background:linear-gradient(#dcaec1, #d3a8e3);
344  z-index: 1;  position: absolute;
345}
346.ripple{
347  margin-top: 400px;
348  margin-left: 40%;
349  position: absolute;  z-index: 0;
350  width: 100px;
351  height: 100px;
352  border-radius: 50px;
353  background:linear-gradient(#dcaec1,#d3a8e3);
354  animation: ripple 5s infinite;
355}
356/* 设置不同的动画时间 */
357.ripple2{
358  animation-duration: 2.5s;
359}
360@keyframes ripple{
361  0%{
362    transform: scale(1);
363    opacity: 0.5;
364  }
365  50%{
366    transform: scale(3);
367    opacity: 0;
368  }
369  100%{
370    transform: scale(1);
371    opacity: 0.5;
372  }
373}
374text{
375  color: white;
376  text-align: center;
377  height: 100%;
378  width: 100%;
379}
380.content {
381  margin-top: 700px;
382  margin-left: 33%;
383  width: 200px;
384  height: 100px;
385  animation:rubberBand 1s infinite;
386  /* 设置渐变色 */
387  background:linear-gradient(#e276aa,#ec0d66);
388  position: absolute;
389}
390@keyframes rubberBand {
391  0% {
392    transform: scale3d(1, 1, 1);
393  }
394  30% {
395    transform: scale3d(1.25, 0.75, 1.1);
396  }
397  40% {
398    transform: scale3d(0.75, 1.25, 1.2);
399  }
400  50% {
401    transform: scale3d(1.15, 0.85, 1.3);
402  }
403  65% {
404    transform: scale3d(.95, 1.05, 1.2);
405  }
406  75% {
407    transform: scale3d(1.05, .95, 1.1);
408  }
409  100%{
410    transform: scale3d(1, 1, 1);
411  }
412}
413```
414
415![zh-cn_image_0000001220396251](figures/zh-cn_image_0000001220396251.gif)
416
417> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
418> 设置transform属性值后,子元素会跟着父元素一起改变,若只改变父元素其他属性值时(如:height,width),子元素不会改变。
419
420
421## 设置matrix属性
422
423matrix是一个入参为六个值的矩阵,6个值分别代表:scaleX, skewY, skewX, scaleY, translateX, translateY。下面示例中设置 了matrix属性为matrix(1,0,0,1,0,200)使组件移动和倾斜。
424
425```html
426<!-- xxx.hml -->
427<div class="container">
428  <div class="rect"> </div>
429</div>
430```
431
432```css
433/* xxx.css */
434.container{
435  background-color:#F1F3F5;
436  display: flex;
437  justify-content: center;
438}
439.rect{
440  width: 100px;
441  height: 100px;
442  background-color: red;
443  animation: down 3s infinite forwards;
444}
445@keyframes down{
446  0%{
447    transform: matrix(1,0,0,1,0,0);
448  }
449  10%{
450    transform: matrix(1,0,0,1,0,200);
451  }
452  60%{
453    transform: matrix(2,1.5,1.5,2,0,700);
454  }
455  100%{
456    transform: matrix(1,0,0,1,0,0);
457  }
458}
459```
460
461![zh-cn_image_0000001174756580](figures/zh-cn_image_0000001174756580.gif)
462
463
464## 整合transform属性
465
466transform可以设置多个值并且多个值可同时设置,下面案例中展示同时设置缩放(scale),平移(translate),旋转(rotate)属性时的动画效果。
467
468```html
469<!-- xxx.hml -->
470<div class="container">
471  <div class="rect1"></div>
472  <div class="rect2"></div>
473  <div class="rect3"></div>
474  <div class="rect4"></div>
475  <div class="rect5"></div>
476</div>
477```
478
479```css
480/* xxx.css */
481.container{
482  flex-direction:column;
483  background-color:#F1F3F5;
484  padding:50px;
485}
486.rect1{
487  width: 100px;
488  height: 100px;
489  background:linear-gradient(#e77070,#ee0202);
490  animation: change1 3s infinite forwards;
491}
492.rect2{
493  margin-top: 50px;
494  width: 100px;
495  height: 100px;
496  background:linear-gradient(#95a6e8, #2739de);
497  animation: change2 3s infinite forwards;
498}
499.rect3{
500  margin-top: 50px;
501  width: 100px;
502  height: 100px;
503  background:linear-gradient(#142ee2, #8cb1e5);
504  animation: change3 3s infinite;
505}
506.rect4{
507  align-self: center;
508  margin-left: 50px;
509  margin-top: 200px;
510  width: 100px;
511  height: 100px;
512  background:linear-gradient(#e2a8df, #9c67d4,#8245d9,#e251c3);
513  animation: change4 3s infinite;
514}
515.rect5{
516  margin-top: 300px;
517  width: 100px;
518  height: 100px;
519  background:linear-gradient(#e7ded7, #486ccd, #94b4d2);
520  animation: change5 3s infinite;
521}
522/* change1 change2 对比 */
523@keyframes change1{
524  0%{
525    transform: translate(0,0);    transform: rotate(0deg)
526  }
527  100%{
528    transform: translate(0,500px);
529    transform: rotate(360deg)
530  }
531}
532/* change2 change3 对比属性顺序不同的动画效果 */
533@keyframes change2{
534  0%{
535    transform:translate(0,0) rotate(0deg) ;
536  }
537  100%{
538    transform: translate(300px,0) rotate(360deg);
539  }
540}
541@keyframes change3{
542  0%{
543    transform:rotate(0deg) translate(0,0);
544  }
545  100%{
546    transform:rotate(360deg)  translate(300px,0);
547  }
548}
549/* 属性值不对应的情况 */
550@keyframes change4{
551  0%{
552    transform: scale(0.5);
553  }
554  100%{
555    transform:scale(2) rotate(45deg);
556  }
557}
558/* 多属性的写法 */
559@keyframes change5{
560  0%{
561    transform:scale(0) translate(0,0) rotate(0);
562  }
563  100%{
564    transform: scale(1.5) rotate(360deg) translate(200px,0);
565  }
566}
567```
568
569![zh-cn_image_0000001220554911](figures/zh-cn_image_0000001220554911.gif)
570
571> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
572> - 当设置多个transform时,后续的transform值会把前面的覆盖掉。若想同时使用多个动画样式可用复合写法,例:transform: scale(1) rotate(0) translate(0,0)。
573>
574> - transform进行复合写法时,变化样式内多个样式值顺序的不同会呈现不一样的动画效果。
575>
576> - transform属性设置的样式值要一一对应,若前后不对应,则该动画不生效。若设置多个样式值则只会呈现出已对应值的动画效果。
577
578
579## 相关实例
580
581针对transform样式动画开发,有以下相关实例可供参考:
582
583- [`JsAnimation`:动效示例应用(JS)(API8)](https://gitee.com/openharmony/applications_app_samples/tree/samples_monthly_0730/UI/JsAnimation)
584
585- [`JsAnimationStyle`:动画与自定义字体(JS)(API8)](https://gitee.com/openharmony/applications_app_samples/tree/samples_monthly_0730/UI/JsAnimationStyle)
586
587- [`Clock`:时钟(JS)(API8)](https://gitee.com/openharmony/applications_app_samples/tree/samples_monthly_0730/common/Clock)
588
589- [`JsAnimator`:动画(JS)(API8)](https://gitee.com/openharmony/applications_app_samples/tree/samples_monthly_0730/UI/JsAnimation)
590
591- [动画样式(JS)(API8)](https://gitee.com/openharmony/codelabs/tree/master/JSUI/AnimationDemo)
592
593- [图片常见操作(JS)(API8)](https://gitee.com/openharmony/codelabs/tree/master/Media/ImageJsDemo)
594