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 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 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} 207.rect{ 208 width: 100px; 209 height: 100px; 210 animation: rotate 3s infinite; 211 margin-left: 100px; 212} 213.rect1{ 214 background-color: #f76160; 215} 216.rect2{ 217 background-color: #60f76f; 218 /* Change the origin position.*/ 219 transform-origin: 10% 10px; 220} 221.rect3{ 222 background-color: #6081f7; 223 /* Change the origin position.*/ 224 transform-origin: right bottom; 225} 226@keyframes rotate { 227 from { 228 transform: rotate(0deg) 229 } 230 to { 231 transform: rotate(360deg); 232 } 233} 234/* 3D sample style */ 235.rotate3d{ 236 margin-top: 150px; 237 flex-direction: column; 238 background-color:#F1F3F5; 239 display: flex; 240 align-items: center; 241 width: 80%; 242 height: 600px; 243 border-radius: 300px; 244 border: 1px solid #ec0808; 245} 246.content{ 247 padding-top: 150px; 248 display: flex; 249 align-items: center; 250 justify-content: center; 251} 252/* Use react4 and react5 to shape eyes. */ 253.rect4{ 254 width: 100px; 255 height: 100px; 256 animation: rotate3d1 1000ms infinite; 257 background: linear-gradient(#e6c4ec, #be15d9) 258} 259.rect5{ 260 width: 100px; 261 height: 100px; 262 animation: rotate3d1 1000ms infinite; 263 margin-left: 100px; 264 background: linear-gradient(#e6c4ec, #be15d9) 265} 266.mouse{ 267 margin-top: 150px; 268 width: 200px; 269 height: 100px; 270 border-radius: 50px; 271 border: 1px solid #e70303; 272 animation: rotate3d2 1000ms infinite; 273} 274/* Eye animation */ 275@keyframes rotate3d1{ 276 0% { 277 transform:rotate3d(0,0,0,0deg) 278 } 279 50% { 280 transform:rotate3d(20,20,20,360deg); 281 } 282 100% { 283 transform:rotate3d(0,0,0,0deg); 284 } 285} 286/* Mouth animation */ 287@keyframes rotate3d2{ 288 0% { 289 transform:rotate3d(0,0,0,0deg) 290 } 291 33% { 292 transform:rotate3d(0,0,10,30deg); 293 } 294 66% { 295 transform:rotate3d(0,0,10,-30deg); 296 } 297 100% { 298 transform:rotate3d(0,0,0,0deg); 299 } 300} 301``` 302 303 304 305> **NOTE** 306> 307> **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. 308 309 310## Designing Scaling Animation 311 312This 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. 313 314Set the scaling values for the x-axis, y-axis, and z-axis in **scale3d** to implement the animation. 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/* Set different animation durations for different components. */ 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 /* Set the gradient.*/ 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 418 419> **NOTE** 420> 421> 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. 422 423 424## Setting matrix 425 426The 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. 427 428```html 429<!-- xxx.hml --> 430<div class="container"> 431 <div class="rect"> </div> 432</div> 433``` 434 435```css 436/* xxx.css */ 437.container{ 438 background-color:#F1F3F5; 439 display: flex; 440 justify-content: center; 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 465 466 467## Integrating transform Attributes 468 469You 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. 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 flex-direction:column; 486 background-color:#F1F3F5; 487 padding:50px; 488} 489.rect1{ 490 width: 100px; 491 height: 100px; 492 background:linear-gradient(#e77070,#ee0202); 493 animation: change1 3s infinite forwards; 494} 495.rect2{ 496 margin-top: 50px; 497 width: 100px; 498 height: 100px; 499 background:linear-gradient(#95a6e8, #2739de); 500 animation: change2 3s infinite forwards; 501} 502.rect3{ 503 margin-top: 50px; 504 width: 100px; 505 height: 100px; 506 background:linear-gradient(#142ee2, #8cb1e5); 507 animation: change3 3s infinite; 508} 509.rect4{ 510 align-self: center; 511 margin-left: 50px; 512 margin-top: 200px; 513 width: 100px; 514 height: 100px; 515 background:linear-gradient(#e2a8df, #9c67d4,#8245d9,#e251c3); 516 animation: change4 3s infinite; 517} 518.rect5{ 519 margin-top: 300px; 520 width: 100px; 521 height: 100px; 522 background:linear-gradient(#e7ded7, #486ccd, #94b4d2); 523 animation: change5 3s infinite; 524} 525/* Use change1 and change2 for comparison. */ 526@keyframes change1{ 527 0%{ 528 transform: translate(0,0); transform: rotate(0deg) 529 } 530 100%{ 531 transform: translate(0,500px); 532 transform: rotate(360deg) 533 } 534} 535/*change2 and change3 compare the animation effects with different attribute sequences.*/ 536@keyframes change2{ 537 0%{ 538 transform:translate(0,0) rotate(0deg) ; 539 } 540 100%{ 541 transform: translate(300px,0) rotate(360deg); 542 } 543} 544@keyframes change3{ 545 0%{ 546 transform:rotate(0deg) translate(0,0); 547 } 548 100%{ 549 transform:rotate(360deg) translate(300px,0); 550 } 551} 552/* Where the attribute values do not match. */ 553@keyframes change4{ 554 0%{ 555 transform: scale(0.5); 556 } 557 100%{ 558 transform:scale(2) rotate(45deg); 559 } 560} 561/* Multi-attribute format */ 562@keyframes change5{ 563 0%{ 564 transform:scale(0) translate(0,0) rotate(0); 565 } 566 100%{ 567 transform: scale(1.5) rotate(360deg) translate(200px,0); 568 } 569} 570``` 571 572 573 574> **NOTE** 575> 576> - 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). 577> 578> - When using the shorthand notation, note that the animation effect varies according to the sequence of the style values. 579> 580> - 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.