1# transform样式动画 2 3设置transform属性对组件进行旋转、缩放、移动和倾斜。 4 5 6## 设置静态动画 7 8创建一个正方形并旋转90°变成菱形,并用下方的长方形把菱形下半部分遮盖形成屋顶,设置长方形translate属性值为(150px,-150px)确定坐标位置形成门,再使用position属性使横纵线跟随父组件(正方形)移动到指定坐标位置,接着设置scale属性使父子组件一起变大形成窗户大小,最后使用skewX属性使组件倾斜后设置坐标translate(200px,-830px)得到烟囱。 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} 206.rect{ 207 width: 100px; 208 height: 100px; 209 animation: rotate 3s infinite; 210 margin-left: 100px; 211} 212.rect1{ 213 background-color: #f76160; 214} 215.rect2{ 216 background-color: #60f76f; 217 /* 改变原点位置*/ 218 transform-origin: 10% 10px; 219} 220.rect3{ 221 background-color: #6081f7; 222 /* 改变原点位置*/ 223 transform-origin: right bottom; 224} 225@keyframes rotate { 226 from { 227 transform: rotate(0deg) 228 } 229 to { 230 transform: rotate(360deg); 231 } 232} 233/* 3d示例样式 */ 234.rotate3d{ 235 margin-top: 150px; 236 flex-direction: column; 237 background-color:#F1F3F5; 238 display: flex; 239 align-items: center; 240 width: 80%; 241 height: 600px; 242 border-radius: 300px; 243 border: 1px solid #ec0808; 244} 245.content{ 246 padding-top: 150px; 247 display: flex; 248 align-items: center; 249 justify-content: center; 250} 251/* react4 react5 翻转形成眼睛 */ 252.rect4{ 253 width: 100px; 254 height: 100px; 255 animation: rotate3d1 1000ms infinite; 256 background: linear-gradient(#e6c4ec, #be15d9) 257} 258.rect5{ 259 width: 100px; 260 height: 100px; 261 animation: rotate3d1 1000ms infinite; 262 margin-left: 100px; 263 background: linear-gradient(#e6c4ec, #be15d9) 264} 265.mouse{ 266 margin-top: 150px; 267 width: 200px; 268 height: 100px; 269 border-radius: 50px; 270 border: 1px solid #e70303; 271 animation: rotate3d2 1000ms infinite; 272} 273/* 眼睛的动效 */ 274@keyframes rotate3d1{ 275 0% { 276 transform:rotate3d(0,0,0,0deg) 277 } 278 50% { 279 transform:rotate3d(20,20,20,360deg); 280 } 281 100% { 282 transform:rotate3d(0,0,0,0deg); 283 } 284} 285/* 嘴的动效 */ 286@keyframes rotate3d2{ 287 0% { 288 transform:rotate3d(0,0,0,0deg) 289 } 290 33% { 291 transform:rotate3d(0,0,10,30deg); 292 } 293 66% { 294 transform:rotate3d(0,0,10,-30deg); 295 } 296 100% { 297 transform:rotate3d(0,0,0,0deg); 298 } 299} 300``` 301 302 303 304>  **说明:** 305> transform-origin变换对象的原点位置,如果仅设置一个值,另一个值为50%,若设置两个值第一个值表示X轴的位置,第二个值表示Y轴的位置。 306 307 308## 设置缩放动画 309 310设置scale样式属性实现涟漪动画,先使用定位确定元素的位置,确定坐标后创建多个组件实现重合效果,再设置opacity属性改变组件不透明度实现组件隐藏与显示,同时设置scale值使组件可以一边放大一边隐藏,最后设置两个组件不同的动画执行时间,实现扩散的效果。 311 312设置sacle3d中X轴、Y轴、Z轴的缩放参数实现动画。 313 314```html 315<!-- xxx.hml --> 316<div class="container"> 317 <div class="circle"> 318 <text>ripple</text> 319 </div> 320 <div class="ripple"></div> 321 <div class="ripple ripple2"></div> 322 <!-- 3d --> 323 <div class="content"> 324 <text>spring</text> 325 </div> 326</div> 327``` 328 329```css 330/* xxx.css */ 331.container { 332 flex-direction: column; 333 background-color:#F1F3F5; 334 width: 100%; 335 position: relative; 336} 337.circle{ 338 margin-top: 400px; 339 margin-left: 40%; 340 width: 100px; 341 height: 100px; 342 border-radius: 50px; 343 background:linear-gradient(#dcaec1, #d3a8e3); 344 z-index: 1; position: absolute; 345} 346.ripple{ 347 margin-top: 400px; 348 margin-left: 40%; 349 position: absolute; z-index: 0; 350 width: 100px; 351 height: 100px; 352 border-radius: 50px; 353 background:linear-gradient(#dcaec1,#d3a8e3); 354 animation: ripple 5s infinite; 355} 356/* 设置不同的动画时间 */ 357.ripple2{ 358 animation-duration: 2.5s; 359} 360@keyframes ripple{ 361 0%{ 362 transform: scale(1); 363 opacity: 0.5; 364 } 365 50%{ 366 transform: scale(3); 367 opacity: 0; 368 } 369 100%{ 370 transform: scale(1); 371 opacity: 0.5; 372 } 373} 374text{ 375 color: white; 376 text-align: center; 377 height: 100%; 378 width: 100%; 379} 380.content { 381 margin-top: 700px; 382 margin-left: 33%; 383 width: 200px; 384 height: 100px; 385 animation:rubberBand 1s infinite; 386 /* 设置渐变色 */ 387 background:linear-gradient(#e276aa,#ec0d66); 388 position: absolute; 389} 390@keyframes rubberBand { 391 0% { 392 transform: scale3d(1, 1, 1); 393 } 394 30% { 395 transform: scale3d(1.25, 0.75, 1.1); 396 } 397 40% { 398 transform: scale3d(0.75, 1.25, 1.2); 399 } 400 50% { 401 transform: scale3d(1.15, 0.85, 1.3); 402 } 403 65% { 404 transform: scale3d(.95, 1.05, 1.2); 405 } 406 75% { 407 transform: scale3d(1.05, .95, 1.1); 408 } 409 100%{ 410 transform: scale3d(1, 1, 1); 411 } 412} 413``` 414 415 416 417>  **说明:** 418> 设置transform属性值后,子元素会跟着父元素一起改变,若只改变父元素其他属性值时(如:height,width),子元素不会改变。 419 420 421## 设置matrix属性 422 423matrix是一个入参为六个值的矩阵,6个值分别代表:scaleX, skewY, skewX, scaleY, translateX, translateY。下面示例中设置 了matrix属性为matrix(1,0,0,1,0,200)使组件移动和倾斜。 424 425```html 426<!-- xxx.hml --> 427<div class="container"> 428 <div class="rect"> </div> 429</div> 430``` 431 432```css 433/* xxx.css */ 434.container{ 435 background-color:#F1F3F5; 436 display: flex; 437 justify-content: center; 438} 439.rect{ 440 width: 100px; 441 height: 100px; 442 background-color: red; 443 animation: down 3s infinite forwards; 444} 445@keyframes down{ 446 0%{ 447 transform: matrix(1,0,0,1,0,0); 448 } 449 10%{ 450 transform: matrix(1,0,0,1,0,200); 451 } 452 60%{ 453 transform: matrix(2,1.5,1.5,2,0,700); 454 } 455 100%{ 456 transform: matrix(1,0,0,1,0,0); 457 } 458} 459``` 460 461 462 463 464## 整合transform属性 465 466transform可以设置多个值并且多个值可同时设置,下面案例中展示同时设置缩放(scale),平移(translate),旋转(rotate)属性时的动画效果。 467 468```html 469<!-- xxx.hml --> 470<div class="container"> 471 <div class="rect1"></div> 472 <div class="rect2"></div> 473 <div class="rect3"></div> 474 <div class="rect4"></div> 475 <div class="rect5"></div> 476</div> 477``` 478 479```css 480/* xxx.css */ 481.container{ 482 flex-direction:column; 483 background-color:#F1F3F5; 484 padding:50px; 485} 486.rect1{ 487 width: 100px; 488 height: 100px; 489 background:linear-gradient(#e77070,#ee0202); 490 animation: change1 3s infinite forwards; 491} 492.rect2{ 493 margin-top: 50px; 494 width: 100px; 495 height: 100px; 496 background:linear-gradient(#95a6e8, #2739de); 497 animation: change2 3s infinite forwards; 498} 499.rect3{ 500 margin-top: 50px; 501 width: 100px; 502 height: 100px; 503 background:linear-gradient(#142ee2, #8cb1e5); 504 animation: change3 3s infinite; 505} 506.rect4{ 507 align-self: center; 508 margin-left: 50px; 509 margin-top: 200px; 510 width: 100px; 511 height: 100px; 512 background:linear-gradient(#e2a8df, #9c67d4,#8245d9,#e251c3); 513 animation: change4 3s infinite; 514} 515.rect5{ 516 margin-top: 300px; 517 width: 100px; 518 height: 100px; 519 background:linear-gradient(#e7ded7, #486ccd, #94b4d2); 520 animation: change5 3s infinite; 521} 522/* change1 change2 对比 */ 523@keyframes change1{ 524 0%{ 525 transform: translate(0,0); transform: rotate(0deg) 526 } 527 100%{ 528 transform: translate(0,500px); 529 transform: rotate(360deg) 530 } 531} 532/* change2 change3 对比属性顺序不同的动画效果 */ 533@keyframes change2{ 534 0%{ 535 transform:translate(0,0) rotate(0deg) ; 536 } 537 100%{ 538 transform: translate(300px,0) rotate(360deg); 539 } 540} 541@keyframes change3{ 542 0%{ 543 transform:rotate(0deg) translate(0,0); 544 } 545 100%{ 546 transform:rotate(360deg) translate(300px,0); 547 } 548} 549/* 属性值不对应的情况 */ 550@keyframes change4{ 551 0%{ 552 transform: scale(0.5); 553 } 554 100%{ 555 transform:scale(2) rotate(45deg); 556 } 557} 558/* 多属性的写法 */ 559@keyframes change5{ 560 0%{ 561 transform:scale(0) translate(0,0) rotate(0); 562 } 563 100%{ 564 transform: scale(1.5) rotate(360deg) translate(200px,0); 565 } 566} 567``` 568 569 570 571>  **说明:** 572> - 当设置多个transform时,后续的transform值会把前面的覆盖掉。若想同时使用多个动画样式可用复合写法,例:transform: scale(1) rotate(0) translate(0,0)。 573> 574> - transform进行复合写法时,变化样式内多个样式值顺序的不同会呈现不一样的动画效果。 575> 576> - transform属性设置的样式值要一一对应,若前后不对应,则该动画不生效。若设置多个样式值则只会呈现出已对应值的动画效果。 577 578 579## 相关实例 580 581针对transform样式动画开发,有以下相关实例可供参考: 582 583- [`JsAnimation`:动效示例应用(JS)(API8)](https://gitee.com/openharmony/applications_app_samples/tree/samples_monthly_0730/UI/JsAnimation) 584 585- [`JsAnimationStyle`:动画与自定义字体(JS)(API8)](https://gitee.com/openharmony/applications_app_samples/tree/samples_monthly_0730/UI/JsAnimationStyle) 586 587- [`Clock`:时钟(JS)(API8)](https://gitee.com/openharmony/applications_app_samples/tree/samples_monthly_0730/common/Clock) 588 589- [`JsAnimator`:动画(JS)(API8)](https://gitee.com/openharmony/applications_app_samples/tree/samples_monthly_0730/UI/JsAnimation) 590 591- [动画样式(JS)(API8)](https://gitee.com/openharmony/codelabs/tree/master/JSUI/AnimationDemo) 592 593- [图片常见操作(JS)(API8)](https://gitee.com/openharmony/codelabs/tree/master/Media/ImageJsDemo) 594