1# transform样式动画 2<!--Kit: ArkUI--> 3<!--Subsystem: ArkUI--> 4<!--Owner: @CCFFWW--> 5<!--Designer: @yangfan229--> 6<!--Tester: @lxl007--> 7<!--Adviser: @HelloCrease--> 8 9设置transform属性对组件进行旋转、缩放、移动和倾斜。 10 11 12## 设置静态动画 13 14创建一个正方形并旋转90°变成菱形,并用下方的长方形把菱形下半部分遮盖形成屋顶,设置长方形translate属性值为(150px,-150px)确定坐标位置形成门,再使用position属性使横纵线跟随父组件(正方形)移动到指定坐标位置,接着设置scale属性使父子组件一起变大形成窗户大小,最后使用skewX属性使组件倾斜后设置坐标translate(200px,-710px)得到烟囱。 15 16```html 17<!-- xxx.hml --> 18<div class="container"> 19 <div class="top"></div> 20 <div class="content"></div> 21 <div class="door"></div> 22 <!-- 窗户 --> 23 <div class="window"> 24 <div class="horizontal"></div> 25 <div class="vertical"></div> 26 </div> 27 <div class="chimney"></div> 28</div> 29``` 30 31```css 32/* xxx.css */ 33.container { 34 width:100%; 35 height:100%; 36 background-color:#F1F3F5; 37 align-items: center; 38 flex-direction: column; 39} 40.top{ 41 z-index: -1; 42 position: absolute; 43 width: 428px; 44 height: 428px; 45 background-color: #860303; 46 transform: rotate(45deg); 47 margin-top: 284px; 48 margin-left: 148px; 49} 50.content{ 51 margin-top: 500px; 52 width: 600px; 53 height: 400px; 54 background-color: white; 55 border: 1px solid black; 56} 57.door{ 58 width: 100px; 59 height: 135px; 60 background-color: #1033d9; 61 transform: translate(150px,-137px); 62} 63.window{ 64 z-index: 1; 65 position: relative; 66 width: 100px; 67 height: 100px; 68 background-color: white; 69 border: 1px solid black; 70 transform: translate(-150px,-400px) scale(1.5); 71} 72/* 窗户的横轴 */ 73.horizontal{ 74 position: absolute; 75 top: 50%; 76 width: 100px; 77 height: 5px; 78 background-color: black; 79} 80/* 窗户的纵轴 */ 81.vertical{ 82 position: absolute; 83 left: 50%; 84 width: 5px; 85 height: 100px; 86 background-color: black; 87} 88.chimney{ 89 z-index: -2; 90 width: 40px; 91 height: 100px; 92 border-radius: 15px; 93 background-color: #9a7404; 94 transform: translate(200px,-710px) skewX(-5deg); 95} 96``` 97 98 99 100 101## 设置平移动画 102 103小球下降动画,改变小球的Y轴坐标实现小球下落,在下一段时间内减小Y轴坐标实现小球回弹,让每次回弹的高度逐次减小直至回弹高度为0,就模拟出了小球下降的动画。 104 105```html 106<!-- xxx.hml --> 107<div class="container"> 108 <div class="circle"></div> 109 <div class="flower"></div> 110</div> 111``` 112 113```css 114/* xxx.css */ 115.container { 116 width:100%; 117 height:100%; 118 background-color:#F1F3F5; 119 display: flex; 120 justify-content: center; 121} 122.circle{ 123 width: 100px; 124 height: 100px; 125 border-radius: 50px; 126 background-color: red; 127 /* forwards停在动画的最后一帧 */ 128 animation: down 3s fast-out-linear-in forwards; 129} 130.flower{ 131 position: fixed; 132 width: 80%; 133 margin-left: 10%; 134 height: 5px; 135 background-color: black; 136 top: 1000px; 137} 138@keyframes down { 139 0%{ 140 transform: translate(0px,0px); 141 } 142 /* 下落 */ 143 15%{ 144 transform: translate(10px,900px); 145 } 146 /* 开始回弹 */ 147 25%{ 148 transform: translate(20px,500px); 149 } 150 /* 下落 */ 151 35%{ 152 transform: translate(30px,900px); 153 } 154 /* 回弹 */ 155 45%{ 156 transform: translate(40px,700px); 157 } 158 55%{ 159 transform: translate(50px,900px); 160 } 161 65%{ 162 transform: translate(60px,800px); 163 } 164 80%{ 165 transform: translate(70px,900px); 166 } 167 90%{ 168 transform: translate(80px,850px); 169 } 170 /* 停止 */ 171 100%{ 172 transform: translate(90px,900px); 173 } 174} 175``` 176 177 178 179 180## 设置旋转动画 181 182设置不同的原点位置(transform-origin)改变元素所围绕的旋转中心。rotate3d属性前三个参数值分别为X轴、Y轴、Z轴的旋转向量,第四个值为旋转角度,旋转角度可为负值,负值则代表旋转方向为逆时针方向。 183 184```html 185<!-- xxx.hml --> 186<div class="container"> 187 <div class="rotate"> 188 <div class="rect rect1"></div> 189 <div class="rect rect2"></div> 190 <div class="rect rect3"></div> 191 </div> 192 <!-- 3d属性 --> 193 <div class="rotate3d"> 194 <div class="content"> 195 <div class="rect4"></div> 196 <div class="rect5"> </div> 197 </div> 198 <div class="mouse"></div> 199 </div> 200</div> 201``` 202 203```css 204/* xxx.css */ 205.container { 206 flex-direction: column; 207 background-color:#F1F3F5; 208 display: flex; 209 align-items: center; 210 justify-content: center; 211 width: 100%; 212 height: 100%; 213} 214.rect { 215 width: 100px; 216 height: 100px; 217 animation: rotate 3s infinite; 218 margin-left: 30px; 219} 220.rect1 { 221 background-color: #f76160; 222} 223.rect2 { 224 background-color: #60f76f; 225/* 改变原点位置*/ 226 transform-origin: 10% 10px; 227} 228.rect3 { 229 background-color: #6081f7; 230/* 改变原点位置*/ 231 transform-origin: right bottom; 232} 233@keyframes rotate { 234 from { 235 transform: rotate(0deg) 236 } 237 to { 238 transform: rotate(360deg); 239 } 240} 241/* 3d示例样式 */ 242.rotate3d { 243 margin-top: 150px; 244 flex-direction: column; 245 background-color:#F1F3F5; 246 display: flex; 247 align-items: center; 248 width: 80%; 249 height: 600px; 250 border-radius: 300px; 251 border: 1px solid #ec0808; 252} 253.content { 254 padding-top: 150px; 255 display: flex; 256 align-items: center; 257 justify-content: center; 258} 259/* rect4 rect5 翻转形成眼睛 */ 260.rect4 { 261 width: 100px; 262 height: 100px; 263 animation: rotate3d1 1000ms infinite; 264 background-color: darkmagenta; 265} 266.rect5 { 267 width: 100px; 268 height: 100px; 269 animation: rotate3d1 1000ms infinite; 270 margin-left: 100px; 271 background-color: darkmagenta; 272} 273.mouse { 274 margin-top: 150px; 275 width: 200px; 276 height: 100px; 277 border-radius: 50px; 278 border: 1px solid #e70303; 279 animation: rotate3d2 1000ms infinite; 280} 281/* 眼睛的动效 */ 282@keyframes rotate3d1 { 283 0% { 284 transform:rotate3d(0,0,0,0deg) 285 } 286 50% { 287 transform:rotate3d(20,20,20,360deg); 288 } 289 100% { 290 transform:rotate3d(0,0,0,0deg); 291 } 292} 293/* 嘴的动效 */ 294@keyframes rotate3d2 { 295 0% { 296 transform:rotate3d(0,0,0,0deg) 297 } 298 33% { 299 transform:rotate3d(0,0,10,30deg); 300 } 301 66% { 302 transform:rotate3d(0,0,10,-30deg); 303 } 304 100% { 305 transform:rotate3d(0,0,0,0deg); 306 } 307} 308``` 309 310 311 312> **说明:** 313> 314> transform-origin变换对象的原点位置,如果仅设置一个值,另一个值为50%,若设置两个值第一个值表示X轴的位置,第二个值表示Y轴的位置。 315 316 317## 设置缩放动画 318 319设置scale样式属性实现涟漪动画,先使用定位确定元素的位置,确定坐标后创建多个组件实现重合效果,再设置opacity属性改变组件不透明度实现组件隐藏与显示,同时设置scale值使组件可以一边放大一边隐藏,最后设置两个组件不同的动画执行时间,实现扩散的效果。 320 321设置scale3d中X轴、Y轴、Z轴的缩放参数实现动画。 322 323```html 324<!-- xxx.hml --> 325<div class="container"> 326 <div class="circle"> 327 <text>ripple</text> 328 </div> 329 <div class="ripple"></div> 330 <div class="ripple ripple2"></div> 331 <!-- 3d --> 332 <div class="content"> 333 <text>spring</text> 334 </div> 335</div> 336``` 337 338```css 339/* xxx.css */ 340.container { 341 flex-direction: column; 342 background-color:#F1F3F5; 343 width: 100%; 344 position: relative; 345} 346.circle{ 347 margin-top: 400px; 348 margin-left: 40%; 349 width: 100px; 350 height: 100px; 351 border-radius: 50px; 352 background-color: mediumpurple; 353 z-index: 1; position: absolute; 354} 355.ripple{ 356 margin-top: 400px; 357 margin-left: 40%; 358 position: absolute; z-index: 0; 359 width: 100px; 360 height: 100px; 361 border-radius: 50px; 362 background-color: blueviolet; 363 animation: ripple 5s infinite; 364} 365/* 设置不同的动画时间 */ 366.ripple2{ 367 animation-duration: 2.5s; 368} 369@keyframes ripple{ 370 0%{ 371 transform: scale(1); 372 opacity: 0.5; 373 } 374 50%{ 375 transform: scale(3); 376 opacity: 0; 377 } 378 100%{ 379 transform: scale(1); 380 opacity: 0.5; 381 } 382} 383text{ 384 color: white; 385 text-align: center; 386 height: 100%; 387 width: 100%; 388} 389.content { 390 margin-top: 700px; 391 margin-left: 33%; 392 width: 200px; 393 height: 100px; 394 animation:rubberBand 1s infinite; 395 background-color: darkmagenta; 396 position: absolute; 397} 398@keyframes rubberBand { 399 0% { 400 transform: scale3d(1, 1, 1); 401 } 402 30% { 403 transform: scale3d(1.25, 0.75, 1.1); 404 } 405 40% { 406 transform: scale3d(0.75, 1.25, 1.2); 407 } 408 50% { 409 transform: scale3d(1.15, 0.85, 1.3); 410 } 411 65% { 412 transform: scale3d(.95, 1.05, 1.2); 413 } 414 75% { 415 transform: scale3d(1.05, .95, 1.1); 416 } 417 100%{ 418 transform: scale3d(1, 1, 1); 419 } 420} 421``` 422 423 424 425> **说明:** 426> 427> 设置transform属性值后,子元素会跟着父元素一起改变,若只改变父元素其他属性值时(如:height,width),子元素不会改变。 428 429 430## 设置matrix属性 431 432matrix是一个入参为六个值的矩阵,6个值分别代表:scaleX, skewY, skewX, scaleY, translateX, translateY。下面示例中设置了matrix属性为matrix(1,0,0,1,0,200)使组件移动和倾斜。 433 434```html 435<!-- xxx.hml --> 436<div class="container"> 437 <div class="rect"> </div> 438</div> 439``` 440 441```css 442/* xxx.css */ 443.container{ 444 background-color:#F1F3F5; 445 display: flex; 446 justify-content: center; 447 width: 100%; 448 height: 100%; 449} 450.rect{ 451 width: 100px; 452 height: 100px; 453 background-color: red; 454 animation: down 3s infinite forwards; 455} 456@keyframes down{ 457 0%{ 458 transform: matrix(1,0,0,1,0,0); 459 } 460 10%{ 461 transform: matrix(1,0,0,1,0,200); 462 } 463 60%{ 464 transform: matrix(2,1.5,1.5,2,0,700); 465 } 466 100%{ 467 transform: matrix(1,0,0,1,0,0); 468 } 469} 470``` 471 472 473 474 475## 整合transform属性 476 477transform可以设置多个值并且多个值可同时设置,下面案例中展示同时设置缩放(scale),平移(translate),旋转(rotate)属性时的动画效果。 478 479```html 480<!-- xxx.hml --> 481<div class="container"> 482 <div class="rect1"></div> 483 <div class="rect2"></div> 484 <div class="rect3"></div> 485 <div class="rect4"></div> 486 <div class="rect5"></div> 487</div> 488``` 489 490```css 491/* xxx.css */ 492.container{ 493 width: 100%; 494 height: 100%; 495 flex-direction:column; 496 background-color:#F1F3F5; 497 padding:50px; 498} 499.rect1{ 500 width: 100px; 501 height: 100px; 502 background-color: red; 503 animation: change1 3s infinite forwards; 504} 505.rect2{ 506 margin-top: 50px; 507 width: 100px; 508 height: 100px; 509 background-color: darkblue; 510 animation: change2 3s infinite forwards; 511} 512.rect3{ 513 margin-top: 50px; 514 width: 100px; 515 height: 100px; 516 background-color: darkblue; 517 animation: change3 3s infinite; 518} 519.rect4{ 520 align-self: center; 521 margin-left: 50px; 522 margin-top: 200px; 523 width: 100px; 524 height: 100px; 525 background-color: darkmagenta; 526 animation: change4 3s infinite; 527} 528.rect5{ 529 margin-top: 300px; 530 width: 100px; 531 height: 100px; 532 background-color: cadetblue; 533 animation: change5 3s infinite; 534} 535/* change1 change2 对比 */ 536@keyframes change1{ 537 0%{ 538 transform: translate(0,0); transform: rotate(0deg) 539 } 540 100%{ 541 transform: translate(0,500px); 542 transform: rotate(360deg) 543 } 544} 545/* change2 change3 对比属性顺序不同的动画效果 */ 546@keyframes change2{ 547 0%{ 548 transform:translate(0,0) rotate(0deg) ; 549 } 550 100%{ 551 transform: translate(300px,0) rotate(360deg); 552 } 553} 554@keyframes change3{ 555 0%{ 556 transform:rotate(0deg) translate(0,0); 557 } 558 100%{ 559 transform:rotate(360deg) translate(300px,0); 560 } 561} 562/* 属性值不对应的情况 */ 563@keyframes change4{ 564 0%{ 565 transform: scale(0.5); 566 } 567 100%{ 568 transform:scale(2) rotate(45deg); 569 } 570} 571/* 多属性的写法 */ 572@keyframes change5{ 573 0%{ 574 transform:scale(0) translate(0,0) rotate(0); 575 } 576 100%{ 577 transform: scale(1.5) rotate(360deg) translate(200px,0); 578 } 579} 580``` 581 582 583 584> **说明:** 585> - 当设置多个transform时,后续的transform值会把前面的覆盖掉。若想同时使用多个动画样式可用复合写法,例:transform: scale(1) rotate(0) translate(0,0)。 586> 587> - transform进行复合写法时,变化样式内多个样式值顺序的不同会呈现不一样的动画效果。 588> 589> - transform属性设置的样式值要一一对应,若前后不对应,则该动画不生效。若设置多个样式值则只会呈现出已对应值的动画效果。 590 591 592## 相关实例 593 594针对transform样式动画开发,有以下相关实例可供参考: 595 596- [`JsClock`:时钟(JS)(API10)](https://gitcode.com/openharmony/applications_app_samples/tree/master/code/Solutions/Tools/JsClock) 597 598- [动画样式(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/JSUI/AnimationDemo) 599 600- [图片常见操作(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Media/ImageOperation) 601