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: 150px; 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: 100px; 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: linear-gradient(#e6c4ec, #be15d9) 260} 261.rect5 { 262 width: 100px; 263 height: 100px; 264 animation: rotate3d1 1000ms infinite; 265 margin-left: 100px; 266 background: linear-gradient(#e6c4ec, #be15d9) 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_0000001222807776](figures/en-us_image_0000001222807776.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:linear-gradient(#dcaec1, #d3a8e3); 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:linear-gradient(#dcaec1,#d3a8e3); 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 /* Set the gradient.*/ 391 background:linear-gradient(#e276aa,#ec0d66); 392 position: absolute; 393} 394@keyframes rubberBand { 395 0% { 396 transform: scale3d(1, 1, 1); 397 } 398 30% { 399 transform: scale3d(1.25, 0.75, 1.1); 400 } 401 40% { 402 transform: scale3d(0.75, 1.25, 1.2); 403 } 404 50% { 405 transform: scale3d(1.15, 0.85, 1.3); 406 } 407 65% { 408 transform: scale3d(.95, 1.05, 1.2); 409 } 410 75% { 411 transform: scale3d(1.05, .95, 1.1); 412 } 413 100%{ 414 transform: scale3d(1, 1, 1); 415 } 416} 417``` 418 419![en-us_image_0000001267887837](figures/en-us_image_0000001267887837.gif) 420 421> **NOTE** 422> 423> 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. 424 425 426## Setting matrix 427 428The 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. 429 430```html 431<!-- xxx.hml --> 432<div class="container"> 433 <div class="rect"> </div> 434</div> 435``` 436 437```css 438/* xxx.css */ 439.container{ 440 background-color:#F1F3F5; 441 display: flex; 442 justify-content: center; 443 width: 100%; 444 height: 100%; 445} 446.rect{ 447 width: 100px; 448 height: 100px; 449 background-color: red; 450 animation: down 3s infinite forwards; 451} 452@keyframes down{ 453 0%{ 454 transform: matrix(1,0,0,1,0,0); 455 } 456 10%{ 457 transform: matrix(1,0,0,1,0,200); 458 } 459 60%{ 460 transform: matrix(2,1.5,1.5,2,0,700); 461 } 462 100%{ 463 transform: matrix(1,0,0,1,0,0); 464 } 465} 466``` 467 468![en-us_image_0000001267767853](figures/en-us_image_0000001267767853.gif) 469 470 471## Integrating transform Attributes 472 473You 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. 474 475```html 476<!-- xxx.hml --> 477<div class="container"> 478 <div class="rect1"></div> 479 <div class="rect2"></div> 480 <div class="rect3"></div> 481 <div class="rect4"></div> 482 <div class="rect5"></div> 483</div> 484``` 485 486```css 487/* xxx.css */ 488.container{ 489 width: 100%; 490 height: 100%; 491 flex-direction:column; 492 background-color:#F1F3F5; 493 padding:50px; 494} 495.rect1{ 496 width: 100px; 497 height: 100px; 498 background:linear-gradient(#e77070,#ee0202); 499 animation: change1 3s infinite forwards; 500} 501.rect2{ 502 margin-top: 50px; 503 width: 100px; 504 height: 100px; 505 background:linear-gradient(#95a6e8, #2739de); 506 animation: change2 3s infinite forwards; 507} 508.rect3{ 509 margin-top: 50px; 510 width: 100px; 511 height: 100px; 512 background:linear-gradient(#142ee2, #8cb1e5); 513 animation: change3 3s infinite; 514} 515.rect4{ 516 align-self: center; 517 margin-left: 50px; 518 margin-top: 200px; 519 width: 100px; 520 height: 100px; 521 background:linear-gradient(#e2a8df, #9c67d4,#8245d9,#e251c3); 522 animation: change4 3s infinite; 523} 524.rect5{ 525 margin-top: 300px; 526 width: 100px; 527 height: 100px; 528 background:linear-gradient(#e7ded7, #486ccd, #94b4d2); 529 animation: change5 3s infinite; 530} 531/* Use change1 and change2 for comparison. */ 532@keyframes change1{ 533 0%{ 534 transform: translate(0,0); transform: rotate(0deg) 535 } 536 100%{ 537 transform: translate(0,500px); 538 transform: rotate(360deg) 539 } 540} 541/*change2 and change3 compare the animation effects with different attribute sequences.*/ 542@keyframes change2{ 543 0%{ 544 transform:translate(0,0) rotate(0deg) ; 545 } 546 100%{ 547 transform: translate(300px,0) rotate(360deg); 548 } 549} 550@keyframes change3{ 551 0%{ 552 transform:rotate(0deg) translate(0,0); 553 } 554 100%{ 555 transform:rotate(360deg) translate(300px,0); 556 } 557} 558/* Where the attribute values do not match. */ 559@keyframes change4{ 560 0%{ 561 transform: scale(0.5); 562 } 563 100%{ 564 transform:scale(2) rotate(45deg); 565 } 566} 567/* Multi-attribute format */ 568@keyframes change5{ 569 0%{ 570 transform:scale(0) translate(0,0) rotate(0); 571 } 572 100%{ 573 transform: scale(1.5) rotate(360deg) translate(200px,0); 574 } 575} 576``` 577 578![en-us_image_0000001223127712](figures/en-us_image_0000001223127712.gif) 579 580> **NOTE** 581> 582> - 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). 583> 584> - When using the shorthand notation, note that the animation effect varies according to the sequence of the style values. 585> 586> - 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.