• 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: 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  width: 100%;
206  height: 100%;
207}
208.rect {
209  width: 100px;
210  height: 100px;
211  animation: rotate 3s infinite;
212  margin-left: 100px;
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: linear-gradient(#e6c4ec, #be15d9)
259}
260.rect5 {
261  width: 100px;
262  height: 100px;
263  animation: rotate3d1 1000ms infinite;
264  margin-left: 100px;
265  background: linear-gradient(#e6c4ec, #be15d9)
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:linear-gradient(#dcaec1, #d3a8e3);
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:linear-gradient(#dcaec1,#d3a8e3);
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  /* 设置渐变色 */
389  background:linear-gradient(#e276aa,#ec0d66);
390  position: absolute;
391}
392@keyframes rubberBand {
393  0% {
394    transform: scale3d(1, 1, 1);
395  }
396  30% {
397    transform: scale3d(1.25, 0.75, 1.1);
398  }
399  40% {
400    transform: scale3d(0.75, 1.25, 1.2);
401  }
402  50% {
403    transform: scale3d(1.15, 0.85, 1.3);
404  }
405  65% {
406    transform: scale3d(.95, 1.05, 1.2);
407  }
408  75% {
409    transform: scale3d(1.05, .95, 1.1);
410  }
411  100%{
412    transform: scale3d(1, 1, 1);
413  }
414}
415```
416
417![zh-cn_image_0000001220396251](figures/zh-cn_image_0000001220396251.gif)
418
419> **说明:**
420> 设置transform属性值后,子元素会跟着父元素一起改变,若只改变父元素其他属性值时(如:height,width),子元素不会改变。
421
422
423## 设置matrix属性
424
425matrix是一个入参为六个值的矩阵,6个值分别代表:scaleX, skewY, skewX, scaleY, translateX, translateY。下面示例中设置 了matrix属性为matrix(1,0,0,1,0,200)使组件移动和倾斜。
426
427```html
428<!-- xxx.hml -->
429<div class="container">
430  <div class="rect"> </div>
431</div>
432```
433
434```css
435/* xxx.css */
436.container{
437  background-color:#F1F3F5;
438  display: flex;
439  justify-content: center;
440  width: 100%;
441  height: 100%;
442}
443.rect{
444  width: 100px;
445  height: 100px;
446  background-color: red;
447  animation: down 3s infinite forwards;
448}
449@keyframes down{
450  0%{
451    transform: matrix(1,0,0,1,0,0);
452  }
453  10%{
454    transform: matrix(1,0,0,1,0,200);
455  }
456  60%{
457    transform: matrix(2,1.5,1.5,2,0,700);
458  }
459  100%{
460    transform: matrix(1,0,0,1,0,0);
461  }
462}
463```
464
465![zh-cn_image_0000001174756580](figures/zh-cn_image_0000001174756580.gif)
466
467
468## 整合transform属性
469
470transform可以设置多个值并且多个值可同时设置,下面案例中展示同时设置缩放(scale),平移(translate),旋转(rotate)属性时的动画效果。
471
472```html
473<!-- xxx.hml -->
474<div class="container">
475  <div class="rect1"></div>
476  <div class="rect2"></div>
477  <div class="rect3"></div>
478  <div class="rect4"></div>
479  <div class="rect5"></div>
480</div>
481```
482
483```css
484/* xxx.css */
485.container{
486  width: 100%;
487  height: 100%;
488  flex-direction:column;
489  background-color:#F1F3F5;
490  padding:50px;
491}
492.rect1{
493  width: 100px;
494  height: 100px;
495  background:linear-gradient(#e77070,#ee0202);
496  animation: change1 3s infinite forwards;
497}
498.rect2{
499  margin-top: 50px;
500  width: 100px;
501  height: 100px;
502  background:linear-gradient(#95a6e8, #2739de);
503  animation: change2 3s infinite forwards;
504}
505.rect3{
506  margin-top: 50px;
507  width: 100px;
508  height: 100px;
509  background:linear-gradient(#142ee2, #8cb1e5);
510  animation: change3 3s infinite;
511}
512.rect4{
513  align-self: center;
514  margin-left: 50px;
515  margin-top: 200px;
516  width: 100px;
517  height: 100px;
518  background:linear-gradient(#e2a8df, #9c67d4,#8245d9,#e251c3);
519  animation: change4 3s infinite;
520}
521.rect5{
522  margin-top: 300px;
523  width: 100px;
524  height: 100px;
525  background:linear-gradient(#e7ded7, #486ccd, #94b4d2);
526  animation: change5 3s infinite;
527}
528/* change1 change2 对比 */
529@keyframes change1{
530  0%{
531    transform: translate(0,0);    transform: rotate(0deg)
532  }
533  100%{
534    transform: translate(0,500px);
535    transform: rotate(360deg)
536  }
537}
538/* change2 change3 对比属性顺序不同的动画效果 */
539@keyframes change2{
540  0%{
541    transform:translate(0,0) rotate(0deg) ;
542  }
543  100%{
544    transform: translate(300px,0) rotate(360deg);
545  }
546}
547@keyframes change3{
548  0%{
549    transform:rotate(0deg) translate(0,0);
550  }
551  100%{
552    transform:rotate(360deg)  translate(300px,0);
553  }
554}
555/* 属性值不对应的情况 */
556@keyframes change4{
557  0%{
558    transform: scale(0.5);
559  }
560  100%{
561    transform:scale(2) rotate(45deg);
562  }
563}
564/* 多属性的写法 */
565@keyframes change5{
566  0%{
567    transform:scale(0) translate(0,0) rotate(0);
568  }
569  100%{
570    transform: scale(1.5) rotate(360deg) translate(200px,0);
571  }
572}
573```
574
575![zh-cn_image_0000001220554911](figures/zh-cn_image_0000001220554911.gif)
576
577> **说明:**
578> - 当设置多个transform时,后续的transform值会把前面的覆盖掉。若想同时使用多个动画样式可用复合写法,例:transform: scale(1) rotate(0) translate(0,0)。
579>
580> - transform进行复合写法时,变化样式内多个样式值顺序的不同会呈现不一样的动画效果。
581>
582> - transform属性设置的样式值要一一对应,若前后不对应,则该动画不生效。若设置多个样式值则只会呈现出已对应值的动画效果。
583
584
585## 相关实例
586
587针对transform样式动画开发,有以下相关实例可供参考:
588
589- [`JsAnimation`:动效示例应用(JS)(API8)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/UI/JsAnimation)
590
591- [`JsAnimationStyle`:动画与自定义字体(JS)(API8)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/UI/JsAnimationStyle)
592
593- [`Clock`:时钟(JS)(API8)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/common/Clock)
594
595- [`JsAnimator`:动画(JS)(API8)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/UI/JsAnimation)
596
597- [动画样式(JS)(API8)](https://gitee.com/openharmony/codelabs/tree/master/JSUI/AnimationDemo)
598
599- [图片常见操作(JS)(API8)](https://gitee.com/openharmony/codelabs/tree/master/Media/ImageJsDemo)
600