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