• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Defining Animations with the transform Attribute
2
3
4Set the transform attribute for component rotation, scaling, translation, and skewing.
5
6
7## Designing Static Animation
8
9Create a square and rotate it by 90 degrees to form a rhombus. Cover the lower part of the rhombus with a rectangle to form a roof. Set the **translate** attribute of the rectangle to the coordinate (150px, -150px) to form a door, use the **position** attribute to translate the horizontal and vertical axes to the specified coordinates of the parent component (square), set the **scale** attribute to scale up the parent and child components together to determine the window size, and use the **skewX** attribute to skew the component and set the coordinate translate(200px,-830px) to form a chimney.
10
11```html
12<!-- xxx.hml -->
13<div class="container">
14  <div class="top"></div>
15  <div class="content"></div>
16  <div class="door"></div>
17  <!-- Window -->
18  <div class="window">
19    <div class="horizontal"></div>
20    <div class="vertical"></div>
21  </div>
22  <div class="chimney"></div>
23</div>
24```
25
26```css
27/* xxx.css */
28.container {
29  width:100%;
30  height:100%;
31  background-color:#F1F3F5;
32  align-items: center;
33  flex-direction: column;
34}
35.top{
36  z-index: -1;
37  position: absolute;
38  width: 428px;
39  height: 428px;
40  background-color: #860303;
41  transform: rotate(45deg);
42  margin-top: 284px;
43  margin-left: 148px;
44}
45.content{
46  margin-top: 500px;
47  width: 600px;
48  height: 400px;
49  background-color: white;
50  border:  1px solid black;
51}
52.door{
53  width: 100px;
54  height: 135px;
55  background-color: #1033d9;
56  transform: translate(150px,-137px);
57}
58.window{
59  z-index: 1;
60  position: relative;
61  width: 100px;
62  height: 100px;
63  background-color: white;
64  border: 1px solid black;
65  transform: translate(-150px,-400px) scale(1.5);
66}
67/* Horizontal axis of the window */
68.horizontal{
69  position: absolute;
70  top: 50%;
71  width: 100px;
72  height: 5px;
73  background-color: black;
74}
75/* Vertical axis of the window */
76.vertical{
77  position: absolute;
78  left: 50%;
79  width: 5px;
80  height: 100px;
81  background-color: black;
82}
83.chimney{
84  z-index: -2;
85  width: 40px;
86  height: 100px;
87  border-radius: 15px;
88  background-color: #9a7404;
89  transform: translate(200px,-710px) skewX(-5deg);
90}
91```
92
93![en-us_image_0000001267887841](figures/en-us_image_0000001267887841.png)
94
95
96## Designing Translation Animation
97
98Decrease the y-coordinate over a time frame to make the ball bounce back. Gradually decrease the bounce height until it drops to 0. An animation where the ball falls is hereby created.
99
100```html
101<!-- xxx.hml -->
102<div class="container">
103  <div class="circle"></div>
104  <div class="flower"></div>
105</div>
106```
107
108```css
109/* xxx.css */
110.container {
111  width:100%;
112  height:100%;
113  background-color:#F1F3F5;
114  display: flex;
115  justify-content: center;
116}
117.circle{
118  width: 100px;
119  height: 100px;
120  border-radius: 50px;
121  background-color: red;
122  /* Use forwards to enable the animation stop at the last frame. */
123  animation: down 3s fast-out-linear-in forwards;
124}
125.flower{
126  position: fixed;
127  width: 80%;
128  margin-left: 10%;
129  height: 5px;
130  background-color: black;
131  top: 1000px;
132}
133@keyframes down {
134  0%{
135    transform: translate(0px,0px);
136  }
137  /* Start ball falling. */
138  15%{
139    transform: translate(10px,900px);
140  }
141  /* Start bouncing back. */
142  25%{
143    transform: translate(20px,500px);
144  }
145  /* Let the ball fall. */
146  35%{
147    transform: translate(30px,900px);
148  }
149  /* Let the ball bounce back. */
150  45%{
151    transform: translate(40px,700px);
152  }
153  55%{
154    transform: translate(50px,900px);
155  }
156  65%{
157    transform: translate(60px,800px);
158  }
159  80%{
160    transform: translate(70px,900px);
161  }
162  90%{
163    transform: translate(80px,850px);
164  }
165  /* Stop falling. */
166  100%{
167    transform: translate(90px,900px);
168  }
169}
170```
171
172![en-us_image_0000001222967760](figures/en-us_image_0000001222967760.gif)
173
174
175## Designing Rotation Animation
176
177Set the rotation center around an element in different transform-origin positions. Of the **rotate3d** values, the first three values are the rotation vectors of the x-axis, y-axis, and z-axis, respectively; the fourth value is the rotation angle, which can be a negative value to indicate that the rotation is performed counterclockwise.
178
179```html
180<!-- xxx.hml -->
181<div class="container">
182  <div class="rotate">
183    <div class="rect rect1"></div>
184    <div class="rect rect2"></div>
185    <div class="rect rect3"></div>
186  </div>
187  <!-- 3D attributes -->
188  <div class="rotate3d">
189    <div class="content">
190        <div class="rect4"></div>
191        <div class="rect5"> </div>
192    </div>
193    <div class="mouse"></div>
194  </div>
195</div>
196```
197
198```css
199/* xxx.css */
200.container {
201    flex-direction: column;
202    background-color:#F1F3F5;
203    display: flex;
204    align-items: center;
205    justify-content: center;
206    width: 100%;
207    height: 100%;
208}
209.rect {
210    width: 100px;
211    height: 100px;
212    animation: rotate 3s infinite;
213    margin-left: 30px;
214}
215.rect1 {
216    background-color: #f76160;
217}
218.rect2 {
219    background-color: #60f76f;
220/* Change the origin position.*/
221    transform-origin: 10% 10px;
222}
223.rect3 {
224    background-color: #6081f7;
225/* Change the origin position.*/
226    transform-origin: right bottom;
227}
228@keyframes rotate {
229    from {
230        transform: rotate(0deg)
231    }
232    to {
233        transform: rotate(360deg);
234    }
235}
236/* 3D sample style */
237.rotate3d {
238    margin-top: 150px;
239    flex-direction: column;
240    background-color:#F1F3F5;
241    display: flex;
242    align-items: center;
243    width: 80%;
244    height: 600px;
245    border-radius: 300px;
246    border: 1px solid #ec0808;
247}
248.content {
249    padding-top: 150px;
250    display: flex;
251    align-items: center;
252    justify-content: center;
253}
254/* Use react4 and react5 to shape eyes. */
255.rect4 {
256    width: 100px;
257    height: 100px;
258    animation: rotate3d1 1000ms infinite;
259    background-color: darkmagenta;
260}
261.rect5 {
262    width: 100px;
263    height: 100px;
264    animation: rotate3d1 1000ms infinite;
265    margin-left: 100px;
266    background-color: darkmagenta;
267}
268.mouse {
269    margin-top: 150px;
270    width: 200px;
271    height: 100px;
272    border-radius: 50px;
273    border: 1px solid #e70303;
274    animation: rotate3d2 1000ms infinite;
275}
276/* Eye animation */
277@keyframes rotate3d1 {
278    0% {
279        transform:rotate3d(0,0,0,0deg)
280    }
281    50% {
282        transform:rotate3d(20,20,20,360deg);
283    }
284    100% {
285        transform:rotate3d(0,0,0,0deg);
286    }
287}
288/* Mouth animation */
289@keyframes rotate3d2 {
290    0% {
291        transform:rotate3d(0,0,0,0deg)
292    }
293    33% {
294        transform:rotate3d(0,0,10,30deg);
295    }
296    66% {
297        transform:rotate3d(0,0,10,-30deg);
298    }
299    100% {
300        transform:rotate3d(0,0,0,0deg);
301    }
302}
303```
304
305![en-us_image_0000001220316305](figures/en-us_image_0000001220316305.gif)
306
307> **NOTE**
308>
309> **transform-origin** specifies the origin of an element's transformation. If only one value is set, the other value is 50%. If both values are set, the first value indicates the position on the x-axis, and the second value indicates the position on the y-axis.
310
311
312## Designing Scaling Animation
313
314This example implements a ripple animation with the scale attribute. Here is the overall procedure: First, use the positioning function to determine the coordinates of the element's position. Then, create multiple components to achieve the overlapping effect. After that, set the opacity attribute to hide or display the components. To scale and hide/display a component at the same time, set both the scale and opacity attributes. Finally, set different animation durations for different components to achieve the diffusion effect.
315
316Set the scaling values for the x-axis, y-axis, and z-axis in **scale3d** to implement the animation.
317
318```html
319<!-- xxx.hml -->
320<div class="container">
321  <div class="circle">
322    <text>ripple</text>
323  </div>
324  <div class="ripple"></div>
325  <div class="ripple ripple2"></div>
326  <!-- 3d -->
327  <div class="content">
328    <text>spring</text>
329  </div>
330</div>
331```
332
333```css
334/* xxx.css */
335.container {
336    flex-direction: column;
337    background-color:#F1F3F5;
338    width: 100%;
339    position: relative;
340}
341.circle{
342    margin-top: 400px;
343    margin-left: 40%;
344    width: 100px;
345    height: 100px;
346    border-radius: 50px;
347    background-color: mediumpurple;
348    z-index: 1;  position: absolute;
349}
350.ripple{
351    margin-top: 400px;
352    margin-left: 40%;
353    position: absolute;  z-index: 0;
354    width: 100px;
355    height: 100px;
356    border-radius: 50px;
357    background-color: blueviolet;
358    animation: ripple 5s infinite;
359}
360/* Set different animation durations for different components. */
361.ripple2{
362    animation-duration: 2.5s;
363}
364@keyframes ripple{
365    0%{
366        transform: scale(1);
367        opacity: 0.5;
368    }
369    50%{
370        transform: scale(3);
371        opacity: 0;
372    }
373    100%{
374        transform: scale(1);
375        opacity: 0.5;
376    }
377}
378text{
379    color: white;
380    text-align: center;
381    height: 100%;
382    width: 100%;
383}
384.content {
385    margin-top: 700px;
386    margin-left: 33%;
387    width: 200px;
388    height: 100px;
389    animation:rubberBand 1s infinite;
390    background-color: darkmagenta;
391    position: absolute;
392}
393@keyframes rubberBand {
394    0% {
395        transform: scale3d(1, 1, 1);
396    }
397    30% {
398        transform: scale3d(1.25, 0.75, 1.1);
399    }
400    40% {
401        transform: scale3d(0.75, 1.25, 1.2);
402    }
403    50% {
404        transform: scale3d(1.15, 0.85, 1.3);
405    }
406    65% {
407        transform: scale3d(.95, 1.05, 1.2);
408    }
409    75% {
410        transform: scale3d(1.05, .95, 1.1);
411    }
412    100%{
413        transform: scale3d(1, 1, 1);
414    }
415}
416```
417
418![en-us_image_0000001220396251](figures/en-us_image_0000001220396251.gif)
419
420> **NOTE**
421>
422> After the **transform** attributes are set, the child element changes with the parent element. Value changing of other attributes (such as height and width) of the parent element will not affect the child element.
423
424
425## Setting matrix
426
427The matrix attribute defines a transformation matrix with six input parameters: scaleX, skewY, skewX, scaleY, translateX, and translateY. In the following example, matrix is set to matrix(1,0,0,1,0,200) to skew and translate the component.
428
429```html
430<!-- xxx.hml -->
431<div class="container">
432  <div class="rect"> </div>
433</div>
434```
435
436```css
437/* xxx.css */
438.container{
439  background-color:#F1F3F5;
440  display: flex;
441  justify-content: center;
442  width: 100%;
443  height: 100%;
444}
445.rect{
446  width: 100px;
447  height: 100px;
448  background-color: red;
449  animation: down 3s infinite forwards;
450}
451@keyframes down{
452  0%{
453    transform: matrix(1,0,0,1,0,0);
454  }
455  10%{
456    transform: matrix(1,0,0,1,0,200);
457  }
458  60%{
459    transform: matrix(2,1.5,1.5,2,0,700);
460  }
461  100%{
462    transform: matrix(1,0,0,1,0,0);
463  }
464}
465```
466
467![en-us_image_0000001174756580](figures/en-us_image_0000001174756580.gif)
468
469
470## Integrating transform Attributes
471
472You can set multiple **transform** attributes at the same time to apply different transformations to a component. The following example applies the **scale**, **translate**, and **rotate** attributes simultaneously.
473
474```html
475<!-- xxx.hml -->
476<div class="container">
477  <div class="rect1"></div>
478  <div class="rect2"></div>
479  <div class="rect3"></div>
480  <div class="rect4"></div>
481  <div class="rect5"></div>
482</div>
483```
484
485```css
486/* xxx.css */
487.container{
488    width: 100%;
489    height: 100%;
490    flex-direction:column;
491    background-color:#F1F3F5;
492    padding:50px;
493}
494.rect1{
495    width: 100px;
496    height: 100px;
497    background-color: red;
498    animation: change1 3s infinite forwards;
499}
500.rect2{
501    margin-top: 50px;
502    width: 100px;
503    height: 100px;
504    background-color: darkblue;
505    animation: change2 3s infinite forwards;
506}
507.rect3{
508    margin-top: 50px;
509    width: 100px;
510    height: 100px;
511    background-color: darkblue;
512    animation: change3 3s infinite;
513}
514.rect4{
515    align-self: center;
516    margin-left: 50px;
517    margin-top: 200px;
518    width: 100px;
519    height: 100px;
520    background-color: darkmagenta;
521    animation: change4 3s infinite;
522}
523.rect5{
524    margin-top: 300px;
525    width: 100px;
526    height: 100px;
527   background-color: cadetblue;
528    animation: change5 3s infinite;
529}
530/* Use change1 and change2 for comparison. */
531@keyframes change1{
532    0%{
533        transform: translate(0,0);    transform: rotate(0deg)
534    }
535    100%{
536        transform: translate(0,500px);
537        transform: rotate(360deg)
538    }
539}
540/*change2 and change3 compare the animation effects with different attribute sequences.*/
541@keyframes change2{
542    0%{
543        transform:translate(0,0) rotate(0deg) ;
544    }
545    100%{
546        transform: translate(300px,0) rotate(360deg);
547    }
548}
549@keyframes change3{
550    0%{
551        transform:rotate(0deg) translate(0,0);
552    }
553    100%{
554        transform:rotate(360deg)  translate(300px,0);
555    }
556}
557/* Where the attribute values do not match. */
558@keyframes change4{
559    0%{
560        transform: scale(0.5);
561    }
562    100%{
563        transform:scale(2) rotate(45deg);
564    }
565}
566/* Multi-attribute format */
567@keyframes change5{
568    0%{
569        transform:scale(0) translate(0,0) rotate(0);
570    }
571    100%{
572        transform: scale(1.5) rotate(360deg) translate(200px,0);
573    }
574}
575```
576
577![en-us_image_0000001220554911](figures/en-us_image_0000001220554911.gif)
578
579> **NOTE**
580>
581> - When multiple **transform** attributes are set, the later one overwrites the previous one. To apply multiple transform styles at the same time, use the shorthand notation; that is, write multiple style values in one transform, for example, transform: scale(1) rotate(0) translate(0,0).
582>
583> - When using the shorthand notation, note that the animation effect varies according to the sequence of the style values.
584>
585> - The style values in the **transform** attribute used when the animation starts and ends must be in one-to-one mapping. Only the styles that have value mappings are played.