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: 150px; 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 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 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: 100px; 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: linear-gradient(#e6c4ec, #be15d9) 259} 260.rect5 { 261 width: 100px; 262 height: 100px; 263 animation: rotate3d1 1000ms infinite; 264 margin-left: 100px; 265 background: linear-gradient(#e6c4ec, #be15d9) 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 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: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/* 设置不同的动画时间 */ 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 /* 设置渐变色 */ 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> **说明:** 420> 设置transform属性值后,子元素会跟着父元素一起改变,若只改变父元素其他属性值时(如:height,width),子元素不会改变。 421 422 423## 设置matrix属性 424 425matrix是一个入参为六个值的矩阵,6个值分别代表:scaleX, skewY, skewX, scaleY, translateX, translateY。下面示例中设置 了matrix属性为matrix(1,0,0,1,0,200)使组件移动和倾斜。 426 427```html 428<!-- xxx.hml --> 429<div class="container"> 430 <div class="rect"> </div> 431</div> 432``` 433 434```css 435/* xxx.css */ 436.container{ 437 background-color:#F1F3F5; 438 display: flex; 439 justify-content: center; 440 width: 100%; 441 height: 100%; 442} 443.rect{ 444 width: 100px; 445 height: 100px; 446 background-color: red; 447 animation: down 3s infinite forwards; 448} 449@keyframes down{ 450 0%{ 451 transform: matrix(1,0,0,1,0,0); 452 } 453 10%{ 454 transform: matrix(1,0,0,1,0,200); 455 } 456 60%{ 457 transform: matrix(2,1.5,1.5,2,0,700); 458 } 459 100%{ 460 transform: matrix(1,0,0,1,0,0); 461 } 462} 463``` 464 465 466 467 468## 整合transform属性 469 470transform可以设置多个值并且多个值可同时设置,下面案例中展示同时设置缩放(scale),平移(translate),旋转(rotate)属性时的动画效果。 471 472```html 473<!-- xxx.hml --> 474<div class="container"> 475 <div class="rect1"></div> 476 <div class="rect2"></div> 477 <div class="rect3"></div> 478 <div class="rect4"></div> 479 <div class="rect5"></div> 480</div> 481``` 482 483```css 484/* xxx.css */ 485.container{ 486 width: 100%; 487 height: 100%; 488 flex-direction:column; 489 background-color:#F1F3F5; 490 padding:50px; 491} 492.rect1{ 493 width: 100px; 494 height: 100px; 495 background:linear-gradient(#e77070,#ee0202); 496 animation: change1 3s infinite forwards; 497} 498.rect2{ 499 margin-top: 50px; 500 width: 100px; 501 height: 100px; 502 background:linear-gradient(#95a6e8, #2739de); 503 animation: change2 3s infinite forwards; 504} 505.rect3{ 506 margin-top: 50px; 507 width: 100px; 508 height: 100px; 509 background:linear-gradient(#142ee2, #8cb1e5); 510 animation: change3 3s infinite; 511} 512.rect4{ 513 align-self: center; 514 margin-left: 50px; 515 margin-top: 200px; 516 width: 100px; 517 height: 100px; 518 background:linear-gradient(#e2a8df, #9c67d4,#8245d9,#e251c3); 519 animation: change4 3s infinite; 520} 521.rect5{ 522 margin-top: 300px; 523 width: 100px; 524 height: 100px; 525 background:linear-gradient(#e7ded7, #486ccd, #94b4d2); 526 animation: change5 3s infinite; 527} 528/* change1 change2 对比 */ 529@keyframes change1{ 530 0%{ 531 transform: translate(0,0); transform: rotate(0deg) 532 } 533 100%{ 534 transform: translate(0,500px); 535 transform: rotate(360deg) 536 } 537} 538/* change2 change3 对比属性顺序不同的动画效果 */ 539@keyframes change2{ 540 0%{ 541 transform:translate(0,0) rotate(0deg) ; 542 } 543 100%{ 544 transform: translate(300px,0) rotate(360deg); 545 } 546} 547@keyframes change3{ 548 0%{ 549 transform:rotate(0deg) translate(0,0); 550 } 551 100%{ 552 transform:rotate(360deg) translate(300px,0); 553 } 554} 555/* 属性值不对应的情况 */ 556@keyframes change4{ 557 0%{ 558 transform: scale(0.5); 559 } 560 100%{ 561 transform:scale(2) rotate(45deg); 562 } 563} 564/* 多属性的写法 */ 565@keyframes change5{ 566 0%{ 567 transform:scale(0) translate(0,0) rotate(0); 568 } 569 100%{ 570 transform: scale(1.5) rotate(360deg) translate(200px,0); 571 } 572} 573``` 574 575 576 577> **说明:** 578> - 当设置多个transform时,后续的transform值会把前面的覆盖掉。若想同时使用多个动画样式可用复合写法,例:transform: scale(1) rotate(0) translate(0,0)。 579> 580> - transform进行复合写法时,变化样式内多个样式值顺序的不同会呈现不一样的动画效果。 581> 582> - transform属性设置的样式值要一一对应,若前后不对应,则该动画不生效。若设置多个样式值则只会呈现出已对应值的动画效果。 583 584 585## 相关实例 586 587针对transform样式动画开发,有以下相关实例可供参考: 588 589- [`JsAnimation`:动效示例应用(JS)(API8)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/UI/JsAnimation) 590 591- [`JsAnimationStyle`:动画与自定义字体(JS)(API8)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/UI/JsAnimationStyle) 592 593- [`Clock`:时钟(JS)(API8)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/common/Clock) 594 595- [`JsAnimator`:动画(JS)(API8)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/UI/JsAnimation) 596 597- [动画样式(JS)(API8)](https://gitee.com/openharmony/codelabs/tree/master/JSUI/AnimationDemo) 598 599- [图片常见操作(JS)(API8)](https://gitee.com/openharmony/codelabs/tree/master/Media/ImageJsDemo) 600