• 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,-710px)得到烟囱。
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: 135px;
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    width: 100%;
206    height: 100%;
207}
208.rect {
209    width: 100px;
210    height: 100px;
211    animation: rotate 3s infinite;
212    margin-left: 30px;
213}
214.rect1 {
215    background-color: #f76160;
216}
217.rect2 {
218    background-color: #60f76f;
219/* 改变原点位置*/
220    transform-origin: 10% 10px;
221}
222.rect3 {
223    background-color: #6081f7;
224/*  改变原点位置*/
225    transform-origin: right bottom;
226}
227@keyframes rotate {
228    from {
229        transform: rotate(0deg)
230    }
231    to {
232        transform: rotate(360deg);
233    }
234}
235/* 3d示例样式 */
236.rotate3d {
237    margin-top: 150px;
238    flex-direction: column;
239    background-color:#F1F3F5;
240    display: flex;
241    align-items: center;
242    width: 80%;
243    height: 600px;
244    border-radius: 300px;
245    border: 1px solid #ec0808;
246}
247.content {
248    padding-top: 150px;
249    display: flex;
250    align-items: center;
251    justify-content: center;
252}
253/* react4 react5 翻转形成眼睛 */
254.rect4 {
255    width: 100px;
256    height: 100px;
257    animation: rotate3d1 1000ms infinite;
258    background-color: darkmagenta;
259}
260.rect5 {
261    width: 100px;
262    height: 100px;
263    animation: rotate3d1 1000ms infinite;
264    margin-left: 100px;
265    background-color: darkmagenta;
266}
267.mouse {
268    margin-top: 150px;
269    width: 200px;
270    height: 100px;
271    border-radius: 50px;
272    border: 1px solid #e70303;
273    animation: rotate3d2 1000ms infinite;
274}
275/* 眼睛的动效 */
276@keyframes rotate3d1 {
277    0% {
278        transform:rotate3d(0,0,0,0deg)
279    }
280    50% {
281        transform:rotate3d(20,20,20,360deg);
282    }
283    100% {
284        transform:rotate3d(0,0,0,0deg);
285    }
286}
287/* 嘴的动效 */
288@keyframes rotate3d2 {
289    0% {
290        transform:rotate3d(0,0,0,0deg)
291    }
292    33% {
293        transform:rotate3d(0,0,10,30deg);
294    }
295    66% {
296        transform:rotate3d(0,0,10,-30deg);
297    }
298    100% {
299        transform:rotate3d(0,0,0,0deg);
300    }
301}
302```
303
304![zh-cn_image_0000001220316305](figures/zh-cn_image_0000001220316305.gif)
305
306> **说明:**
307> transform-origin变换对象的原点位置,如果仅设置一个值,另一个值为50%,若设置两个值第一个值表示X轴的位置,第二个值表示Y轴的位置。
308
309
310## 设置缩放动画
311
312设置scale样式属性实现涟漪动画,先使用定位确定元素的位置,确定坐标后创建多个组件实现重合效果,再设置opacity属性改变组件不透明度实现组件隐藏与显示,同时设置scale值使组件可以一边放大一边隐藏,最后设置两个组件不同的动画执行时间,实现扩散的效果。
313
314设置sacle3d中X轴、Y轴、Z轴的缩放参数实现动画。
315
316```html
317<!-- xxx.hml -->
318<div class="container">
319  <div class="circle">
320    <text>ripple</text>
321  </div>
322  <div class="ripple"></div>
323  <div class="ripple ripple2"></div>
324  <!-- 3d -->
325  <div class="content">
326    <text>spring</text>
327  </div>
328</div>
329```
330
331```css
332/* xxx.css */
333.container {
334    flex-direction: column;
335    background-color:#F1F3F5;
336    width: 100%;
337    position: relative;
338}
339.circle{
340    margin-top: 400px;
341    margin-left: 40%;
342    width: 100px;
343    height: 100px;
344    border-radius: 50px;
345    background-color: mediumpurple;
346    z-index: 1;  position: absolute;
347}
348.ripple{
349    margin-top: 400px;
350    margin-left: 40%;
351    position: absolute;  z-index: 0;
352    width: 100px;
353    height: 100px;
354    border-radius: 50px;
355    background-color: blueviolet;
356    animation: ripple 5s infinite;
357}
358/* 设置不同的动画时间 */
359.ripple2{
360    animation-duration: 2.5s;
361}
362@keyframes ripple{
363    0%{
364        transform: scale(1);
365        opacity: 0.5;
366    }
367    50%{
368        transform: scale(3);
369        opacity: 0;
370    }
371    100%{
372        transform: scale(1);
373        opacity: 0.5;
374    }
375}
376text{
377    color: white;
378    text-align: center;
379    height: 100%;
380    width: 100%;
381}
382.content {
383    margin-top: 700px;
384    margin-left: 33%;
385    width: 200px;
386    height: 100px;
387    animation:rubberBand 1s infinite;
388    background-color: darkmagenta;
389    position: absolute;
390}
391@keyframes rubberBand {
392    0% {
393        transform: scale3d(1, 1, 1);
394    }
395    30% {
396        transform: scale3d(1.25, 0.75, 1.1);
397    }
398    40% {
399        transform: scale3d(0.75, 1.25, 1.2);
400    }
401    50% {
402        transform: scale3d(1.15, 0.85, 1.3);
403    }
404    65% {
405        transform: scale3d(.95, 1.05, 1.2);
406    }
407    75% {
408        transform: scale3d(1.05, .95, 1.1);
409    }
410    100%{
411        transform: scale3d(1, 1, 1);
412    }
413}
414```
415
416![zh-cn_image_0000001220396251](figures/zh-cn_image_0000001220396251.gif)
417
418> **说明:**
419> 设置transform属性值后,子元素会跟着父元素一起改变,若只改变父元素其他属性值时(如:height,width),子元素不会改变。
420
421
422## 设置matrix属性
423
424matrix是一个入参为六个值的矩阵,6个值分别代表:scaleX, skewY, skewX, scaleY, translateX, translateY。下面示例中设置 了matrix属性为matrix(1,0,0,1,0,200)使组件移动和倾斜。
425
426```html
427<!-- xxx.hml -->
428<div class="container">
429  <div class="rect"> </div>
430</div>
431```
432
433```css
434/* xxx.css */
435.container{
436  background-color:#F1F3F5;
437  display: flex;
438  justify-content: center;
439  width: 100%;
440  height: 100%;
441}
442.rect{
443  width: 100px;
444  height: 100px;
445  background-color: red;
446  animation: down 3s infinite forwards;
447}
448@keyframes down{
449  0%{
450    transform: matrix(1,0,0,1,0,0);
451  }
452  10%{
453    transform: matrix(1,0,0,1,0,200);
454  }
455  60%{
456    transform: matrix(2,1.5,1.5,2,0,700);
457  }
458  100%{
459    transform: matrix(1,0,0,1,0,0);
460  }
461}
462```
463
464![zh-cn_image_0000001174756580](figures/zh-cn_image_0000001174756580.gif)
465
466
467## 整合transform属性
468
469transform可以设置多个值并且多个值可同时设置,下面案例中展示同时设置缩放(scale),平移(translate),旋转(rotate)属性时的动画效果。
470
471```html
472<!-- xxx.hml -->
473<div class="container">
474  <div class="rect1"></div>
475  <div class="rect2"></div>
476  <div class="rect3"></div>
477  <div class="rect4"></div>
478  <div class="rect5"></div>
479</div>
480```
481
482```css
483/* xxx.css */
484.container{
485    width: 100%;
486    height: 100%;
487    flex-direction:column;
488    background-color:#F1F3F5;
489    padding:50px;
490}
491.rect1{
492    width: 100px;
493    height: 100px;
494    background-color: red;
495    animation: change1 3s infinite forwards;
496}
497.rect2{
498    margin-top: 50px;
499    width: 100px;
500    height: 100px;
501    background-color: darkblue;
502    animation: change2 3s infinite forwards;
503}
504.rect3{
505    margin-top: 50px;
506    width: 100px;
507    height: 100px;
508    background-color: darkblue;
509    animation: change3 3s infinite;
510}
511.rect4{
512    align-self: center;
513    margin-left: 50px;
514    margin-top: 200px;
515    width: 100px;
516    height: 100px;
517    background-color: darkmagenta;
518    animation: change4 3s infinite;
519}
520.rect5{
521    margin-top: 300px;
522    width: 100px;
523    height: 100px;
524   background-color: cadetblue;
525    animation: change5 3s infinite;
526}
527/* change1 change2 对比 */
528@keyframes change1{
529    0%{
530        transform: translate(0,0);    transform: rotate(0deg)
531    }
532    100%{
533        transform: translate(0,500px);
534        transform: rotate(360deg)
535    }
536}
537/* change2 change3 对比属性顺序不同的动画效果 */
538@keyframes change2{
539    0%{
540        transform:translate(0,0) rotate(0deg) ;
541    }
542    100%{
543        transform: translate(300px,0) rotate(360deg);
544    }
545}
546@keyframes change3{
547    0%{
548        transform:rotate(0deg) translate(0,0);
549    }
550    100%{
551        transform:rotate(360deg)  translate(300px,0);
552    }
553}
554/* 属性值不对应的情况 */
555@keyframes change4{
556    0%{
557        transform: scale(0.5);
558    }
559    100%{
560        transform:scale(2) rotate(45deg);
561    }
562}
563/* 多属性的写法 */
564@keyframes change5{
565    0%{
566        transform:scale(0) translate(0,0) rotate(0);
567    }
568    100%{
569        transform: scale(1.5) rotate(360deg) translate(200px,0);
570    }
571}
572```
573
574![zh-cn_image_0000001220554911](figures/zh-cn_image_0000001220554911.gif)
575
576> **说明:**
577> - 当设置多个transform时,后续的transform值会把前面的覆盖掉。若想同时使用多个动画样式可用复合写法,例:transform: scale(1) rotate(0) translate(0,0)。
578>
579> - transform进行复合写法时,变化样式内多个样式值顺序的不同会呈现不一样的动画效果。
580>
581> - transform属性设置的样式值要一一对应,若前后不对应,则该动画不生效。若设置多个样式值则只会呈现出已对应值的动画效果。
582
583## 相关实例
584
585针对transform样式动画开发,有以下相关实例可供参考:
586
587- [`JsComponentCollection`:JS组件集合(JS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/code/UI/JsComponentClollection/JsComponentCollection)
588
589