动画效果 - animation 线性动画/关键帧动画 animation和tranlation区别 Animate.css 动画库 侧边栏显示和隐藏 自动轮播

1,118 阅读4分钟

基本概念

animation 属性简写,用于设置动画属性(6个属性)

animation 和 transition 的区别

  • 相同点:都是随着时间改变元素的属性值
  • 不同点:transition 需要触发一个事件(例如,hover/click等)才会随时间改变CSS属性;transition 不需要事件触发也能实现

基本语法

div{ 
  animation: keyframes_name / duration / timing-function / delay / 
      iteration-count / direction ;
}
/* 方式一:from to */
@keyframes keyframes_name {
    from {
        /* ... */
    }
    to {
        /* ... */
    }
}
/* 方式二:设置百分比 */
@keyframes keuframes_name {
    0% {
        /* ... */
    }
    50% {
        /* ... */
    }
    100% {
        /* ... */
    }
}

单一属性

属性名说明
animation-name动画名称;必须与规则@keyframes配合使用
animation-duration动画持续时间;eg.animation-duration: 3s;
animation-timing-function动画过渡类型;linear/ease/ease-in/ease-in-out/cubic-bezier()
animation-delay动画延迟时间;eg.animation-delay: 0.5s;
animation-iteration-count动画循环次数; infinite / number
animation-direction是否反向运动;normal / reverse / alternate / alternate-reverse

其他属性

animation-play-state

animation-play-state 属性规定动画正在运行还是暂停

animation-play-state: running(默认,运动) / paused(暂停) ;

div:hover{
    animation: iName 2s linear 2ms infinite normal;
    /* 鼠标悬停在上停止,移开继续运动 */
    animation-play-state: paused;
}

animation-fill-mode

animation-fill-mode 属性规定动画在播放之前或之后,其动画效果是否可见(保留最后帧/初始帧),相当于是否将动画之后的结果定住

animation-fill-mode: forwards(保留最后帧) / backwards(保留初始帧);

steps 关键帧动画

  • steps() 阶跃函数,不同于linear、ease等柔和的线性变化的动画效果,steps()能够实现具体到单个帧的动画,即关键帧动画,该效果能够让动画从一个帧跳变到另一个帧,而不是慢慢渐变过去。
/* 基本语法 */
animation: 
    <name> 
    <duration> 
    <timing-function  / steps(num,start/end)/steps-start/steps-end> 
    <delay> 
    <iteration-count>
    <direction>;
属性值说明
steps(num)num: 每阶段的动画帧数,例如,如果num为3,则@keyframes name { 0%{...} 50%{...} 100%{...}}就是0%-50%由3帧逐步完成,50%-100%由3帧逐步完成;第二个参数此时默认为 end
steps(num,start/end)start: 在每帧起点发生阶跃,如果帧数设置为1,动画开始的时候,第一区间还没有执行,就直接到跳变到该区间动画完成度100%的位置,此时便直接进入到下一区间了,因此肉眼看不到第一区间的画面,如果帧数设置大于1,比如,steps(4,start),动画开始的时候,第一区间也很会立马跳变,但因为第一区间设置了4帧,因此跳变的时候,不会直接跳到100%,而是完成度25%的位置,此时还在第一区间,因此能够看到第一区间的闪烁画面;end:阶跃跳变发生在每一帧结束,因此当倒数第二个区间执行完,便会立马跳变到最后一个区间的第一帧,此时如果帧数设置为1,则每个区间就相当于一帧,那么最后一个区间的动画执行一帧后,会立马跳变到100%完成度,此时,100%的动画就显示不出来了;如果帧数设置大于1,例如steps(4,end),那么跳变到最后一个区间的时候,还有4个帧,则除了最后一个看不到,最后一个区间的其它3帧都能看到了;steps-start 等同于 steps(1,start) / steps-end 等同于 steps(1,end)

关键帧动画说明 steps-start.png

关键帧动画说明 steps-end.png

.swiper{
    animation: swiperHorse 2s steps(1,start) 2ms infinite;
}
@keyframes swiperHorse{
0%{
    /* 这一区间会被跳过 */
    background-color: red;
}
25%{
    background-color: green;
}
50%{
    background-color: black;
}
75%{
    background-color:plum ;
}
100%{
    background-color: yellow;
}
}

steps(1,start).gif

reference 1 reference 2

属性 - transform-style 创建3d平台

  • transform-style 设置元素的子元素是位于3d空间还是2d平面。
/* 默认,2d平面 */
transform-style: flat;
/* 使用3d效果,必须在父元素内设置该属性 */
transform-style: preserve-3d;

属性 - perspective 景深

  • 设置3d效果的时候,是没有默认观察者距离对象的距离是如何的,而在现实生活中,3d图形有着空间上近大远小的概念,这也是3d区别于2d的地方,因此,需要通过 景深 来设置。
  • perspective 属性指定观察者与 z=0 平面的距离,使具有三维位置变换的元素产生透视效果(近大远小)

基本观察位置

/* 默认,none */
perspective: none;
/* 数值,一般设置为900-1200px之间,不要过大,这样近大远小的效果不明显 */
transform: perspective(800px); /* 子元素中使用 */
perspective: 800px; /* 父元素中使用;如果两个都设置会发生冲突,建议只设置父元素 */

3D观察位置

/* perspective-origin 观察3d元素的位置/角度 */
/* 观察点 中心 */
perspective-origin:center center | 50% 50%;
/* 观察点 左上角 */
perspective-origin:top left;
/* 观察点 右下角 */
perspective-origin:100% 100%;

示例

侧边栏显示/隐藏

<head>
    <title>Document</title>
    <style>
        html,body{height: 100%;}
        /* 设置动画 */
        @keyframes sideBarExhibit {
            from{
                transform: translateX(-100%);
            }
            to{
                transform: translateX(0%);
            }            
        }
        @keyframes sideBarHidden {
            from{
                transform: translateX(0%);
            }
            to{
                transform: translateX(-100%);
            }            
        }
        .main{
            height: 100%;
            background-color: thistle;            
        }
        .side{
            width: 20%;
            height: 100%;
            background-color: plum;
            transform: translateX(-100%);
        }
        
        .main:hover .side{
            /* 引入动画:初始向左移动出屏幕,隐藏 */
            /* 触发动画 */
            animation: sideBarExhibit 0.5s linear 2ms;
            /* 动画结束后,保留最后一帧 */
            animation-fill-mode: forwards;
        }
        .main:active .side{
            animation: sideBarHidden 0.5s linear 2ms;
        }
    </style>
</head>
<body>
    <div class="main">
        <div class="side"></div>
    </div>
</body>

animation 侧边栏显示和隐藏.gif

自动轮播图

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        /* 轮播图 - 容器 */
        .swiper-container{
            width: 300px;
            height: 200px;
            margin: auto;
            /* 不显示后面的轮播图片 */
            overflow: hidden;
        }
        /* 轮播图 - 包裹 */
        .swiper-wrapper{
            /* 宽度设置大一些,一遍放下更多轮播图片 */
            width: 2000px;
            height: 100%;
        }
        /* 轮播图 - 图片 */
        .swiper-side{
            /* 放图片的盒子宽度设置为与最外层容器的宽度一致 */
            width: 300px;
            height: 100%;
            /* 浮动,让屠屏呈现水平并排 */
            float: left;
            /* 让每个轮播图片居中 */
            text-align: center;
            animation: swiperHorse 25s ease-in-out 2ms infinite;
        }
        .swiper-side img{
            width: 100%;
            height: 100%;
        }
        /* 定义轮播动画 */
        @keyframes swiperHorse{
            /* 切换 从1到2 耗时占5% */
            0%{
                transform: translateX(-0%);
            }
            /* 停留 在2 耗时占20% */
            5%{
                transform: translateX(-100%);
            }
            25%{
                transform: translateX(-100%);
            }
            30%{
                transform: translateX(-200%);
            }
            50%{
                transform: translateX(-200%);
            }
            55%{
                transform: translateX(-300%);
            }
            75%{
                transform: translateX(-300%);
            }
            80%{
                transform: translateX(-400%);
            }
            100%{
                transform: translateX(-400%);
            }
        }
    </style>
</head>
<body>
    <div class="swiper-container">
        <div class="swiper-wrapper">
            <div class="swiper-side"><img src="./planet/planet1.jpeg"/></div>
            <div class="swiper-side"><img src="./planet/planet2.jpeg"/></div>
            <div class="swiper-side"><img src="./planet/planet3.jpeg"/></div>
            <div class="swiper-side"><img src="./planet/planet4.jpeg"/></div>
            <!-- 为与第一张轮播图片相衔接 -->
            <div class="swiper-side"><img src="./planet/planet1.jpeg"/></div>
        </div>
    </div>
</body>

animation 自动轮播图.gif

3D 立方体展示

<head>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        body,html{
            height: 100%;
        }
        .container{
            width: 40%;
            height: 60%;
            border: 3px solid black;
            border-radius: 50%;
            margin: 50px auto;
            position: relative;
            /* 父元素 - 设置3d平台,子元素才能使用3d效果 */
            transform-style: preserve-3d;
            /* 设置 景深 */
            /* perspective: 400px; */
            transform: rotate3d(1,1,1,0deg);
        }
        .container:hover{
            animation: round 9s linear 2ms infinite;
            transform: scale3d(50px,0,90px);
        }
        @keyframes round{
            0%{
                transform: rotate3d(1,1,1,0deg) scale3d(1,1,1);
            }
            25%{
                transform: rotate3d(1,1,1,360deg) scale3d(1.2,1,0.9);
            }
            50%{
                transform: rotate3d(1,1,1,90deg) scale3d(0.9,1.6,0.8);
            }
            100%{
                transform: rotate3d(1,1,1,360deg) scale3d(1,1.6,0.9);
            }
        }
        div{
            width: 200px;
            height: 200px;
            position: absolute;
            top: 50%;
            left: 50%;
            margin-top: -100px;
            margin-left: -100px;
            border: 1px solid gray;
            display: flex;
        }
        img{
            width: 100%;
            height: 100%;
            margin: auto;
            /* 设置透明度 */
            opacity: 0.6;
        }
        div:nth-child(1){
            transform: translateZ(100px);
        }
        div:nth-child(2){
            transform: translateX(-100px) rotateY(90deg);
        }
        div:nth-child(3){
            transform: translateY(-100px) rotateX(90deg);
        }
        div:nth-child(4){
            transform: translateY(100px) rotateX(-90deg);
        }
        div:nth-child(5){
            transform: translateX(100px) rotateY(90deg);
        }
        div:nth-child(6){
            transform: translateZ(-100px);
        }
        
    </style>
</head>
<body>
    <section class="container">
        <div><img src="./planet/planet1.jpeg"></div>
        <div><img src="./planet/planet2.jpeg"></div>
        <div><img src="./planet/planet3.jpeg"></div>
        <div><img src="./planet/planet4.jpeg"></div>
        <div><img src="./planet/planet5.jpeg"></div>
        <div><img src="./planet/planet6.jpeg"></div>
    </section>
</body>

3D立方体展示.gif

animation 动画库

下载链接:Animate.css —— CSS3 动画库