热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:精通CSS第10章变换过渡与动画学习笔记

篇首语:本文由编程笔记#小编为大家整理,主要介绍了精通 CSS 第 10 章 变换过渡与动画 学习笔记相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了精通 CSS 第 10 章 变换过渡与动画 学习笔记相关的知识,希望对你有一定的参考价值。






精通 CSS 第 10 章 变换、过渡与动画 学习笔记

这一章主要讲的还是让元素“动”起来的特性,主要内容在以下几章学习笔记中有讲到,这里可以算是一个系统性整合了:


  • CSS3 新特性学习

    中含了 transition特性,即过渡

  • CSS 2D Transform 学习笔记

    2D 变换的笔记在这里

  • CSS 动画 学习笔记和学习案例

    动画,即 关键帧动画@keyframe 的笔记在这里

  • 学完一起做个走马灯吧 - CSS 3D 转换学习笔记&学习案例

    3D 变换的笔记在这里

都学过了,所以这一章的内容会很快的过一遍,顺便拾遗补漏。


概述

翻了一下书中讲的狗家的案例,是真的挺好看的:

google-story-book

点进去之后还能够看到狗家的各个产品,都是用这种三维的效果制作的,体感挺好。


二维变换

从技术角度来说,变换(transform) 改变的是元素所在的 坐标系统

一种看待变换的角度是把他们看成“畸变场”——任何落在元素渲染空间内的像素都会被畸变场必火,然后再将他们传输到页面上的新位置,或改变大小。元素本身还在页面上原来的位置,但它们畸变之后的“影像”已经变换了。

为元素应用变化后,会为元素最初所在的位置创建所谓的 局部坐标系统。页面上任会保留原本的像素空间位置,但是畸变后的局部坐标系不会影响原本的像素空间。



这种说法也能够解释为什么二维转换不会影响到其他元素,毕竟元素本身的位置没有产生任何的改变,受到影响的是元素的“投影”。


例如说下面这个例子:


distorted-coordinators


畸变后元素的局部过标系统如上图所示,并不会影响到原本的的位置坐标系:


orig-coordinators


这部分源码为:


html>
<html lang&#61;"en">
<head>
<meta charset&#61;"UTF-8" />
<title>Documenttitle>
<style>
body {
padding: 100px;
}
.box {
width: 100px;
height: 100px;
margin-top: 20px;
top: 200px;
left: 200px;
background-color: #eee;
outline: 1px solid;
transform: rotate(45deg);
}
style>
head>
<body>
abcdefg
<div class&#61;"box">div>
hijklmn
body>
html>


变换原点

transform-origin属性&#xff0c;默认情况下&#xff0c;变换是以元素边框盒子的中心作为原点。

变换原点会对元素的旋转产生不同的效果&#xff0c;如将原点从中心修改成左上角&#xff0c;再进行 45° 旋转所产生的效果&#xff1a;

origin-center

left-top


<html lang&#61;"en">
<head>
<meta charset&#61;"UTF-8" />
<title>Simple transformtitle>
<style>
body {
padding: 50px 200px;
}
.box {
width: 100px;
height: 100px;
background-color: #eee;
outline: 1px solid;
/* 注视下面这行代码查看不同效果 */
transform-origin: 0 0;
transform: rotate(45deg); /* 1 */
}
style>
head>
<body>
origin left-top:
<div class&#61;"box">div>
body>
html>

平移

translate属性&#xff0c;使得元素沿着 x 轴 和/或 y 轴进行移动。


多重变换

案例中是结合了 transform 和 translate&#xff0c;效果图如下&#xff1a;

transform&#43;translate

其实现方法是利用伪元素 before 添加 § 3&#xff0c;再用绝对定位将伪元素中的内容放到 list-style 占用的空间上。before 中的数字是使用了另一种 CSS 的特性 counter 去实现的计数效果。

最初的效果如下&#xff1a;

initial-stage

设置了绝对定位之后&#xff0c;作为 自定义的列表样式属性 的定位如下&#xff1a;

position-absolute

为了能够更清楚地看到样式&#xff0c;我暂时将 li元素 中的内容注释掉了。

实现平移后的效果如下&#xff1a;

after-translate

这里已经设置了 transform-origin: 100% 100%;&#xff0c;即等同于 transform-origin: right bottom;&#xff0c;将右下角作为旋转中心后&#xff0c;实现旋转 -90° 就完成了最终的效果。

完整实现代码&#xff1a;


<html lang&#61;"en">
<head>
<meta charset&#61;"UTF-8" />
<title>Using transform-origin to rotate texttitle>
<style>
body {
font-family: Baskerville, Times, Times New Roman, serif;
font-size: 1.25em;
padding: 3em;
}
h1 {
font-weight: 400;
}
.rules {
counter-reset: rulecount 2;
list-style: none;
padding: 0;
margin: 0;
}
.rules li {
line-height: 1.5;
min-height: 1.75em;
counter-increment: rulecount;
max-width: 35em;
border-left: 1.5em solid #777;
padding-left: 0.5em;
position: relative;
margin-bottom: 0.5em;
}
.rules li:before {
position: absolute;
top: 0;
left: 0;
padding-right: 0.25em;
display: block;
color: #777;
color: #fff;
line-height: 1.5em;
padding-left: 0.25em;
content: "§ " counter(rulecount);
transform: translate(-100%, -100%) rotate(-90deg);
transform-origin: 100% 100%;
}
style>
head>
<body>
<h1>Fight Club rulesh1>
<ol class&#61;"rules" start&#61;"3">
<li>If someone says ”stop”, goes limp or taps out, the fight is over.li>
<li>Only two guys to a fight.li>
<li>One fight at a time.li>
<li>No shirts, no shoes.li>
<li>Fights will go on as long as they have to.li>
<li>If this is your first night at FIGHT CLUB, you HAVE to fight.li>
ol>
body>
html>

平移与旋转的顺序是非常重要的&#xff0c;因为平移的是相对于元素的局部坐标系进行的操作。如果先旋转再进行位移&#xff0c;那么就需要重新计算位移的角度&#xff0c;否则会产生下面的结果&#xff1a;

coordinator-off

transform属性修改为 transform: rotate(-90deg) translate(80%, -120%); 还是能够产生一样的效果。


缩放和变形

scaleskew 两个属性。

scale&#xff0c;缩放理解起来比较简单&#xff0c;就是对元素产生放大和缩小的变化。

skew 我觉得比较好理解的代入方法是斜体&#xff0c;斜体是对字体倾斜&#xff0c;skew 是对元素倾斜。以上面多重变换的例子&#xff0c;简单的修改一下后会有这样的效果&#xff1a;

skew

修改过的 CSS 部分如下

.rules li {
line-height: 2.5;
min-height: 1.75em;
counter-increment: rulecount;
max-width: 35em;
padding-left: 0.5em;
position: relative;
background-color: #e5212e;
border-left: 1.5em solid #aa031c;
transform: skewX(15deg);
}
.rules li:nth-child(even) {
background-color: #aa031c;
border-color: #6b0011;
transform: skewX(-15deg);
}

只是对颜色的搭配进行了一点儿的修改&#xff0c;就有了深浅折叠的感觉&#xff0c;模拟出了 3D 的效果。


二维矩阵变换

本质上来说&#xff0c;旋转也好&#xff0c;位移也好&#xff0c;都是在一个平面上对元素进行操作&#xff0c;CSS 也提供了一个更加直观明了的属性去进行计算平面直角坐标系&#xff1a;矩阵matrix()

以数学的角度来说&#xff0c;它能够更加直观明了的表明想要操作的结果&#xff0c;如&#xff1a;

.some-content {
transform: matrix(1.41, 1.41, -1.16, 1.66, 70.7, 70.7);
/* 与下面的效果一样 */
transform: rotate(45deg) translate(100px, 0) scale(2) skewX(10deg);
}

但是很明显&#xff0c;对于人来说&#xff0c;第二条 CSS 更加方便理解&#xff0c;能够直观的理解这条 CSS 想要实现的目的是什么。


变换与性能

使用 变换(transform) 只会影响到相关元素的直角坐标系&#xff0c;不需要浏览器去重新计算对整个页面造成的影响&#xff0c;因此相应的性能会高一些。


过渡

过渡是一种动画&#xff0c;可以从一个状态过渡到另一个状态&#xff0c;常见的有按钮的点击、菜单栏的展开、元素的切入等。

只需要指定想要的效果以及延续的时间&#xff0c;浏览器能够相对快速地对页面的变化进行重绘&#xff0c;并且会自动双向运行。如当元素处于 hover 状态时触发时会产生的过渡&#xff0c;不再 hover 状态时即会反向运行。

press-me

实现代码&#xff1a;


<html lang&#61;"en">
<head>
<meta charset&#61;"UTF-8" />
<meta name&#61;"viewport" content&#61;"width&#61;device-width, initial-scale&#61;1.0" />
<title>Button transitiontitle>
<style>
button {
cursor: pointer;
border: 0;
padding: 0.5em 1em;
color: #fff;
border-radius: 0.25em;
outline: none;
font-size: 1em;
background-color: #173b6d;
background-image: linear-gradient(to bottom, #1a4a8e, #173b6d);
box-shadow: 0 0.25em 0 rgba(23, 59, 109, 0.3), inset 0 1px 0 rgba(0, 0, 0, 0.3);
transition: all 150ms ease-in;
}
button:active {
box-shadow: 0 0 0 rgba(23, 59, 109, 0.3), inset 0 1px 0 rgba(0, 0, 0, 0.3);
transform: translateY(0.25em);
}
style>
head>
<body>
<button>Press me!button>
body>
html>

过渡计时函数

transition-timing-function属性&#xff0c;目前有 9 个值&#xff0c;比较值得注意的有以下几个&#xff1a;


  • ease&#xff0c;即默认值

    开始的时候稍慢些&#xff0c;迅速加快&#xff0c;最后快接近终值的时候再慢下来

  • ease-in

    开始慢&#xff0c;后来快

  • ease-out

    与 ease-in 相反

  • ease-in-out

    ease-in 和 ease-in-out 的结合&#xff0c;两头慢中间快

  • linear

    线性匀速

  • 三次贝塞尔函数

    cubic-bezier(p1, p2, p3, p4)&#xff0c;需要提供 4 个点去定义三次贝塞尔函数

    上面的实现&#xff0c;包括 ease 的系列和 linear 底层都是依赖于三次贝塞尔函数实现的。如 ease 可以被重写为 cubic-bezier(0.25, 0.1, 0.25, 1.0)&#xff0c;linear 的三次贝塞尔函数为 cubic-bezier(0.0, 0.0, 1.0, 1.0) 等。

    matrix 一样&#xff0c;都不是给普通人看和用的&#xff0c;如果有特殊需求应该是可以网上找到公式去套用的。

  • 步进函数(steps)

    steps 的原理和 翻书画 相似&#xff0c;以前看到过就是通过图像快速的闪现&#xff0c;使其在视网膜中停留的时间过短&#xff0c;人的大脑就会自动的产生联想&#xff0c;看起来就和动画效果相似。

    之前做的一个特效是奔跑的北极熊&#xff0c;使用的就是 steps 实现的&#xff1a;

    polar-bear


使用不同的正向和反向过渡

就是一个有持续的过度效果&#xff0c;但是通过覆写其他的属性&#xff0c;即刻取消过渡效果&#xff0c;依旧以 hover 为例&#xff1a;

.sample {
transition: background-position 0s stpes(6);
}
.sample:hover {
transition-duration: 0.6s;
}

上面的代码中&#xff0c;当鼠标悬浮时会有一个时间长为 0.6s 的过渡阶段&#xff0c;但是一旦鼠标不悬浮于元素上了&#xff0c;因为过度的时间只有 0s&#xff0c;所以反向过度看起来即刻就消失了。


“黏着”过渡

即无限延长过渡时间段&#xff0c;使得反向过渡看起来失效&#xff0c;从而达成实现的过渡效果悬停的感觉。

.sample {
transition: background-position 9999999999s stpes(6);
}
.sample:hover {
transition-duration: 0.6s;
}

延迟过渡

即控制在多久之后才会令过渡效果触发。


过渡的能与不能

过渡只能应用于二者之间有明确的过渡阶段的效果&#xff0c;例如说颜色的变化——本质上来说&#xff0c;网页上的颜色还是通过 rgb 或是 16 进制 转换的值&#xff0c;从纯黑色的 #000 到纯白色的#fff 自然是可以通过计算中间值来达到过度的效果的。

但是对于没有过渡阶段的属性&#xff0c;过渡就无法应用了&#xff0c;例如说 display属性&#xff0c;display: none;display: block; 中间不存在过渡属性&#xff0c;自然也无法产生过渡动画。

另外一种就是过渡属性有可计算的变化量&#xff0c;但是所赋的值无法进行计算&#xff0c;例如说高度宽度盒子大小等都需要提供参数&#xff0c;但是当参数值为 auto 的时候&#xff0c;过渡就无法正确的计算可变化的数值&#xff0c;因此也就无法产生动画效果。


CSS 关键帧动画

过渡给予了一段动画开始和结束的定义&#xff0c;但是如果中间有其他的动画定义就无法被实现了&#xff0c;而使用关键帧动画可以从仅有两个阶段的尴尬境地脱离出来。

书中的案例就很厉害了&#xff0c;将「生命的幻象」部分的动画展示出来了&#xff0c;下面是关键帧的分割&#xff1a;

key-frames

结合起来的效果如下&#xff1a;

box-model

关键帧部分的实现为&#xff1a;

&#64;keyframes roll {
from {
transform: translateX(-100%);
animation-timing-function: ease-in-out;
}
20% {
transform: translateX(-100%) skewX(15deg);
}
28% {
transform: translateX(-100%) skewX(0deg);
animation-timing-function: ease-out;
}
45% {
transform: translateX(-100%) skewX(-5deg) rotate(20deg) scaleY(1.1);
animation-timing-function: ease-in-out;
}
50% {
transform: translateX(-100%) rotate(45deg) scaleY(1.1);
animation-timing-function: ease-in;
}
60% {
transform: translateX(-100%) rotate(90deg);
}
65% {
transform: translateX(-100%) rotate(90deg) skewY(10deg);
}
70% {
transform: translateX(-100%) rotate(90deg) skewY(0deg);
}
to {
transform: translateX(-100%) rotate(90deg);
}
}

三维变换

关于三维变换&#xff0c;书中实现的一个案例是菜单案例&#xff0c;其效果与下图相似&#xff1a;

flip

这部分内容大多都在 学完一起做个走马灯吧 - CSS 3D 转换学习笔记&学习案例 中讲过了&#xff0c;这里也就不再赘述了。






推荐阅读
author-avatar
chasewindboy
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有