CSS3-形变、动画

一. CSS3 形变

1. 2D形变

transform是CSS3中具有颠覆性的特征之一,可以实现元素的位移、旋转、倾斜、缩放,甚至支持矩阵方式,配合过渡和即将学习的动画知识,可以取代大量之前只能靠Flash才可以实现的效果。

transform变换变形的意思(transformers 变形金刚)。

① 平移 translate(x, y)

translate 移动平移的意思,可以改变元素的位置。

transform: translate(x,y) 水平方向和垂直方向同时移动(也就是X轴和Y轴同时移动)
transform: translateX(x) 仅水平方向移动(X轴移动)
transform: translateY(Y) 仅垂直方向移动(Y轴移动)
  • x、y 可为正值可为负值,右下为正,左上为负
  • 如果 translate 后面跟的是百分比,那就是移动自己宽高的百分之多少
  • 行内标签没有效果

② 旋转 rotate(deg)

可以对元素进行旋转,正值为顺时针,负值为逆时针;

transform: rotate(45deg);
  • rotate 里面跟度数,单位是 deg
  • 角度为正时,顺时针,角度为负时,逆时针
  • 默认旋转的中心点是元素的中心点

transform-origin:调整元素旋转的原点

该属性必须与 ransform: rotate(); 属性一同使用。

transform-origin: left bottom; /* 沿着左边的线或者下边的线旋转 */
transform: rotate(45deg); /* 改变元素原点到左下角,然后进行顺时旋转45度 */    

如果是4个角,可以用 top right bottom left 这些,如果想要精确的位置,可以用坐标。

transform-origin: 10px 10px; /* 改变元素原点到 x为10 y为10 */ 
transform: rotate(45deg);    /* 然后进行顺时旋转45度 */ 
  • 注意后面的参数 x 和 y 用空格隔开
  • x y 默认旋转的中心点是元素的中心 (50% 50%),等价于 center center
  • 还可以给 x y 设置像素(10px 10px;)或者方位名词(topbottomleftrightcenter

案例:楚乔传

本来六张图重合,鼠标放上去旋转开来,如下:

div {
  width: 250px;
  height: 170px;
  border: 1px solid pink;
  margin: 200px auto;
  position: relative;
}
div img {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  transition: all 0.6s; /* 动画持续时间 */
  transform-origin: top left;  /* 左上角旋转 */
}
div:hover img:nth-child(1) {  /* 鼠标经过div,第一张图片旋转 */
  transform: rotate(60deg);
}
div:hover img:nth-child(2) {  
  transform: rotate(120deg);
}
div:hover img:nth-child(3) {  
  transform: rotate(180deg);
}
div:hover img:nth-child(4) {  
  transform: rotate(240deg);
}
div:hover img:nth-child(5) {  
  transform: rotate(300deg);
}
div:hover img:nth-child(6) {  
  transform: rotate(360deg);
}

③ 缩放 scale(x, y)

transform: scale(0.8, 1);

可以对元素进行水平和垂直方向的缩放,上面语句使用scale方法使该元素在水平方向上缩小了20%,垂直方向上不缩放。

scale(X,Y) 使元素水平方向和垂直方向同时缩放(也就是X轴和Y轴同时缩放)
scaleX(x) 元素仅水平方向缩放(X轴缩放)
scaleY(y) 元素仅垂直方向缩放(Y轴缩放)

scale()的取值默认的值为1,当值设置为0.01到0.99之间的任何值,作用使一个元素缩小;而任何大于或等于1.01的值,作用是让元素放大。

  • transform: scale(2, 2): 宽高都放大了原来的二倍
  • transform: scale(2): 如果只写了一个参数,第二个参数就和第一个参数一致
  • transform: scale(0.5, 0.5): 缩小一半

④ 2D转换综合写法

同时使用多个转换,其格式为 transform: translate() rotate() scale(),顺序不同会影响到转换的效果,因为先旋转会改变坐标轴方向。

div:hover {
  transform: translate(200px, 0) rotate(360deg) scale(1.2);
  transition: all 0.6s; /* 动画持续时间 */
  transform-origin: top left;  /* 左上角旋转 */
}

2. 3D形变

3D 的特点:

  • 近大远小
  • 物体和面遮挡不可见

三维坐标系:

  • x 轴:水平向右 -- x 轴右边是正值,左边是负值
  • y 轴:垂直向下 -- y 轴下面是正值,上面是负值
  • z 轴:垂直屏幕 -- 往外边的是正值,往里面的是负值

① 3D平移 translate3d(x,y,z)

transform: translate3d(x, y, z)

x、y、z 分别表示在对应轴上移动的距离,其中,x和y可以是长度值,也可以是百分比,百分比是相对于其本身元素的宽高,z只能设置长度值。3D 移动就是在 2D 移动的基础上多加了一个可以移动的方向,就是 z 轴方向。

transform: translateX(100px):仅仅是在 x 轴上移动
transform: translateY(100px):仅仅是在 y 轴上移动
transform: translateZ(100px):仅仅是在 z 轴上移动。

translateZ的直观表现形式就是大小变化,实质是XY平面相对于视点的远近变化。说远近就一定会说到离什么参照物远或近,在这里参照物就是perspective属性,比如设置了perspective: 200px,那么translateZ的值越接近200,就是离的越近,看上去也就越大,超过200就看不到了,因为相当于跑到后脑勺去了,我相信你正常情况下,是看不到自己的后脑勺的,透视距离需要写在被视察元素的父盒子上面。

perspective n. 观点;远景;透视图 adj. 透视的

x, y, z 对应的值不能省略,不需要填写用 0 进行填充,如下:

transform: translate3d(100px, 100px, 0)

② 3D旋转 rotate3d(x, y, z, 45deg)

rotate3d(x, y, z, 45deg)

上面代码表示沿着坐标为(x, y, z)的自定义轴旋转45度。除了沿着自定义轴,还可以沿着x 轴、y 轴、z 轴进行旋转,如下:

transform: rotateX(45deg):沿着 x 轴正方向旋转 45 度
transform: rotateY(45deg):沿着 y 轴正方向旋转 45 度
transform: rotateZ(45deg):沿着 z 轴正方向旋转 45 度

沿着z轴进行旋转,z轴是垂直于屏幕的,沿着z轴旋转就和普通旋转效果是一样的。

案例:开门大吉

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        section {
            width: 450px;
            height: 300px;
            border: 1px solid #000;
            margin: 100px auto;
            background: url(images/3.jpg) no-repeat;
            position: relative;
            perspective: 1000px;  /*给父盒子添加透视效果*/
        }
        .door-l, .door-r {
            position: absolute;
            top: 0;
            width: 50%;
            height: 100%;
            background-color: pink;
            transition: all 1s; /*两个门都做过渡效果*/
            background: url(images/bg.png);
        }
        .door-l {
            left: 0;
            border-right: 1px solid #000;
            transform-origin: left;/* 左侧盒子按照左边翻转*/
        }
        .door-r {
            right: 0;
            left: 1px solid #000;
            transform-origin: right;/*  右侧盒子按照右边翻转*/
        }
        .door-l::before, .door-r::before {  /*伪元素 就是插入一个元素标签*/
            content: '';
            position: absolute;
            width: 20px;
            height: 20px;
            border: 1px solid #000;
            border-radius: 50%; /*圆角*/
            top: 50%;
            transform:translateY(-50%); /*translate 如果是百分比, 就是走自己高度的一半*/
        }
        .door-l::before {
            right: 5px; /* 距离右边5 */
        }
        .door-r::before  /* 距离左边5 */
             left: 5px;
        }
        /*鼠标经过section 盒子 两个门盒子 翻转 rotateY*/
        section:hover .door-l {
            transform: rotateY(-130deg);  /*沿着Y旋转,因为往左边翻转,所以是负值*/
        }
        section:hover .door-r {
            transform: rotateY(130deg);
        }
    </style>
</head>
<body>
  <section>
      <div class="door-l"></div>
      <div class="door-r"></div>
  </section>
</body>
</html>

③ 透视距离 perspective

body {
  perspective: 1000px;
}

如果想要网页产生 3D 效果就需要透视距离,也称为视距,所谓的视距就是人的眼睛到屏幕的距离,实际上模仿人类的视觉点,可视为安排一只眼睛去看,这时候眼睛就叫视觉点,距离视觉点越近的物体在电脑平面成像越大,越远成像越小。

  • 视距的单位是px像素
  • 透视需要写在被视察元素的父盒子上面
  • d:就是视距,视距就是指人的眼睛到屏幕的距离,视距越大效果越不明显,视距越小,透视效果越明显
  • z:就是 z 轴的大小,z 轴越大(正值),我们看到的物体就越大

透视距离的使用:

下面美女沿着y轴旋转,效果并不明显,是因为没添加视距,我们添加视距后,效果如下:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
      body {
          perspective: 1000px;  /*视距:眼睛到屏幕的距离,视距越大效果越不明显,视距越小,透视效果越明显*/
      }
      img {
          margin: 100px;
          transition: all 5s;
      }
      img:hover {
          transform: rotateY(360deg);
      }
    </style>
</head>
<body>
  <img src="images/1498446043198.png" WIDTH="300" alt=""/>
</body>
</html>

④ backface-visibility

backface-visibility 属性定义当元素不面向屏幕时是否可见。

上面的开门效果,开门的时候两侧门都是一样的,利用backface-visibility可以实现开关门的时候,两侧门不一样。

翻转盒子案例,效果图:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        div {
            width: 224px;
            height: 224px;
            margin: 100px auto;
            position: relative;
        }
        div img {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            transition: all 3s;
        }
        div img:first-child {
            z-index: 1;  /* 更改层级 */
            backface-visibility: hidden;  /*属性定义当元素不面向屏幕时,就隐藏*/
        }
        div:hover img {
            transform: rotateY(180deg);
        }
    </style>
</head>
<body>
<div>
    <img src="images/qian.svg" alt=""/>
    <img src="images/hou.svg" alt=""/>
</div>
</body>
</html>

二. CSS3 动画

1. 过渡 transition

过渡(transition)是CSS3中具有颠覆性的特征之一,我们可以在不使用 Flash 动画或 JavaScript 的情况下为元素从一种样式变换为另一种样式时添加过渡动画效果,类似于iOS中的UIView动画。

在CSS3里使用transition可以实现过渡动画效果,并且当前元素只要有“属性”发生变化时即存在两种状态(我们用A和B代指),就可以实现平滑的过渡,为了方便演示,采用hover切换两种状态,但是并不仅仅局限于hover状态来实现过渡。

语法格式:

transition: 属性 时间 曲线 延迟;
属性 描述
transition 简写属性,用于在一个属性中设置四个过渡属性。
transition-property 应用过渡的 CSS 属性的名称,如果想要所有的属性都变化过渡,写一个all 就可以,如果有多组属性变化,多组属性用逗号隔开。不可省略。
transition-duration 定义过渡动画花费的时间,默认0s(就是无动画)。不可省略。
transition-timing-function 过渡效果的速度曲线。默认是 "ease"。
transition-delay 延迟多久,默认 0s(立马开始)。

animation-timing-function:规定动画的速度曲线,默认是 ease

div {
        width: 200px;
        height: 100px;
        background-color: pink;
        /* transition 过渡的意思 这句话写到div里面而不是 hover里面 */    
        transition: width 0.6s ease 0s, height 0.3s ease-in 1s;
        /* transition: all 0.6s; 所有属性都变化用all就可以了,后面俩个属性可以省略 */
}
div:hover {  /* 鼠标经过盒子,我们的宽度变为600,高度变为300 */
        width: 600px;
        height: 300px
}

2. 动画 animation

① 动画的简单使用

动画是 CSS3 中最具颠覆性的特征之一,可通过设置多个节点来精确的控制一个或者一组动画,从而实现复杂的动画效果。

  1. 先定义动画
@keyframes 动画名称 {
    0% { /* 动画的开始,等同于 from */
        width: 100px;
    }
    100% { /* 动画的结束,等同于 to */
        width: 200px
    }
}
  1. 再使用定义好的动画
div {
    /* 动画名称 */
    animation-name: 动画名称;
    /* 持续时间 */
    animation-duration: 持续时间;
}

代码如下,动画代码运行之后默认就会执行。

<style>
    div {
      width: 100px;
      height: 100px;
      background-color: aquamarine;
      /* ② 使用动画 */
      animation-name: move;
      animation-duration: 0.5s;
    }

    /* ① 定义动画 */
    @keyframes move{
      0% {
        transform: translate(0px)
      }
      100% {
        transform: translate(500px, 0)
      }
    }
  </style>

② 动画常见属性

iteration,迭代
infinite,无限的
alternate,交替的、轮流的
forwards,向前    backwards,向后

代码演示:

<style>
  div {
    width: 100px;
    height: 100px;
    background-color: aquamarine;
    /* 动画名称 */
    animation-name: move;
    /* 动画花费时长 */
    animation-duration: 2s;
    /* 动画速度曲线 */
    animation-timing-function: ease-in-out;
    /* 动画等待多长时间执行 */
    animation-delay: 2s;
    /* 规定动画播放次数 infinite: 无限循环 */
    animation-iteration-count: infinite;
    /* 是否逆行播放 */
    animation-direction: alternate;
    /* 动画结束之后的状态 */
    animation-fill-mode: forwards;
  }

  div:hover {
    /* 鼠标放上去就暂停 */
    animation-play-state: paused;
  }

  /* 定义动画 */
  @keyframes move {
    0% {
      transform: translate(0px)
    }
    100% {
      transform: translate(500px, 0)
    }
  }
</style>

③ 动画简写方式

  1. 动画简写方式
/* animation: 动画名称 持续时间 运动曲线 延迟多久 播放次数 是否反方向 起始与结束状态 */
animation: name duration timing-function delay iteration-count direction fill-mode
  1. 知识要点
  • 简写属性里面不包含 animation-paly-state
  • 暂停动画 animation-paly-state: paused; 经常和鼠标经过等其他配合使用
  • 要想动画走回来,而不是直接调回来:animation-direction: alternate
  • 盒子动画结束后,停在结束位置:animation-fill-mode: forwards
  1. 代码演示
animation: move 2s linear 1s infinite alternate forwards;

动画案例

小汽车案例:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        img {
            /* animation:动画名称 动画时间 运动曲线 何时开始 播放次数 是否反方向; */
            /* animation: go 2s ease 0s infinite alternate; 引用动画 */
            /* 一般情况下,我们就用前2个 animation: go 2s */
            /* infinite 无限循环 */
            animation: car 5s infinite;  /*引用动画*/
            animation-iteration-count:infinite;  /* 无限循环播放,可以写在上面,也可以单行写 */
        }
        /*定义动画*/
        @keyframes car {
            0% { /*起始位置,等价于 form*/
                transform: translate3d(0, 0, 0);
            }
            50% {
                transform: translate3d(500px, 0, 0);
            }
            51% {
                transform: translate3d(500px, 0, 0) rotateY(180deg);
                /*如果多组变形 都属于 tarnsform 我们用空格隔开就好了*/
            }
            100% {
                transform: translate3d(0, 0, 0) rotateY(180deg);
            }
            /*100% 相当于结束位置 to*/
        }
    </style>
</head>
<body>
  <img src="images/car.jpg"  width="100" alt=""/>
</body>
</html>

无缝滚动案例:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding:0;
        }
        ul {
            list-style: none;
        }
        nav {
            width: 582px;
            height: 86px;
            border: 1px solid pink;
            margin: 100px auto;
            overflow: hidden; /* 不显示超过对象尺寸的内容,超出的部分隐藏掉 */
        }
        nav li {
            float: left;
        }
        nav ul {
            width: 200%;
            animation: moving 5s linear infinite; /*引用动画*/
            /*linear 匀速动画*/
        }
        /*定义动画*/
        @keyframes moving {
            form {
                transform: translateX(0);
            }
            to {
                transform: translateX(-882px);
            }
        }
        nav:hover ul {  /*鼠标经过nav 里面的ul 就暂停动画*/
            animation-play-state:paused;  /*鼠标经过暂停动画*/
        }
    </style>
</head>
<body>
  <nav>
     <ul>
        <li><img src="images/nav1.jpg" alt=""/></li>
        <li><img src="images/nav2.jpg" alt=""/></li>
        <li><img src="images/nav3.jpg" alt=""/></li>
        <li><img src="images/nav4.jpg" alt=""/></li>
        <li><img src="images/nav5.jpg" alt=""/></li>
        <li><img src="images/nav6.jpg" alt=""/></li>
        <li><img src="images/nav7.jpg" alt=""/></li>
        /* 复制一次,产生无缝滚动效果 */
        <li><img src="images/nav1.jpg" alt=""/></li>
        <li><img src="images/nav2.jpg" alt=""/></li>
        <li><img src="images/nav3.jpg" alt=""/></li>
        <li><img src="images/nav4.jpg" alt=""/></li>
        <li><img src="images/nav5.jpg" alt=""/></li>
        <li><img src="images/nav6.jpg" alt=""/></li>
        <li><img src="images/nav7.jpg" alt=""/></li>
     </ul>
  </nav>
</body>
</html>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容