再来看看帧动画是什么样的效果:896运行结果:可以看到是一帧帧播放的,帧数低的时候有种卡卡的感觉,好像一下一下的分步骤从黄色变成绿色的。那我们把帧数提高一下不就看不到一卡一卡的感觉了吗?来试试看:897运行结果:虽然效果一样了,但是怎么感觉更麻烦了呢?还要自己去指定帧数,而过渡动画都是全自动的,帧动画是不是不如过渡动画呢?实际上并不是这样的,帧动画有着自己的适用场景。接下来我们就来探讨一下何时适合帧动画,何时又适合过渡动画。
我们需要的是一张图片一张图片的去显示,也就是一帧代表一张图片,我们换成帧动画再来试一下:901运行结果:这次看起来是不是就是我们想要的结果了呢。帧动画有些类似于我们小时候翻书,翻书翻得快了里面的图案似乎就动起来了:所以设置一个合理的翻书时间是很有必要的,翻书时间太长就代表翻的慢了,图像就不会那么的连贯。
语法:animation: 定义过的动画名 动画时长 动画运行的方式;动画运行的方式要用到steps这个函数。看起来可能有点晕,但是我们写成英文看起来就会好很多:animation: change-color 7s steps(10);这里面唯一一个新鲜词就是steps,这个steps后面要写上小括号,括号里面就是这次动画要按照多少帧来运行,来看个具体的案例:907运行结果:可以看到这就按照我们所设想的那样:红、橙、黄、绿、青、蓝、紫……咦?紫呢?怎么最后直接跳过紫色直接就进入黑色了呢?原来,这里涉及到了一个帧动画里面一个难以理解的点,在讲这点之前我们先来看结论,这样的话即使没弄懂到底是怎么一回事也可以直接记住结论,让动画按照我们预先设想的那样去运行。
语法:animation: 动画名 时长 step-end infinite;除了在调用动画的语法上最后一个单词不一样,其实主要区别在于定义动画时,定义动画的时候可以多加一帧,来看具体案例:909运行结果:反正最后一帧出不来,那我们直接就在最后多加一帧不就得了,最后一帧写什么都可以,反正最后一帧就像空气一样——你永远也看不到。
之前我们曾经说过,雪碧图在帧动画这一领域独领风骚,那么接下来我们就来分析一下动画领域里面常见的两种形式:过渡动画与帧动画之间的区别。首先我们来看看目前各类网站中最常见的一种动画:过渡动画895运行结果:可以看到盒子的颜色是从黄色慢慢过渡到绿色,所以叫过渡动画,因为其有一个过渡的效果。
有时候想要的动画并不是缩小、放大或者变个颜色之类的这么简单,比如我们需要一个复杂的形变加上复杂的运动轨迹,此时过渡动画就有些相形见绌了。虽然 Canvas 或 SVG 能够实现复杂逻辑的动画效果,但是毕竟不是人人都会这种技术。而且有时候开发时间有限,没有时间用代码来绘制一个炫酷动画,所以这个时候帧动画,配上雪碧图就是最完美的选择。我们用一张条形雪碧图来试一下:
想要运行一个动画,就要先去定义一个动画 —— 鲁迅。那么我们就先来看看矩形图要怎么定义动画:/* 清除浏览器默认边距 */* { padding: 0; margin: 0; }body { /* 这段代码是为了居中显示,不是重点,看不懂的话可以无视 */ height: 100vh; display: flex; align-items: center; justify-content: center; /* 添加背景图 */ background: url(../img/bg.jpg) center / cover;}.animate { background: url(../img/rect.png);}/* 定义动画:动画名(loading) */@keyframes loading { from { background-position: 0 0 } /* 第一个数字代表x轴坐标,第二个数字代表y轴坐标 */ 10% { background-position: -130px 0 } /* x坐标:-130 y坐标:0 */ 20% { background-position: -260px 0 } /* x坐标:-260 y坐标:0 */ 30% { background-position: -390px 0 } /* x坐标:-390 y坐标:0 */ 40% { background-position: -520px 0 } /* x坐标:-520 y坐标:0 */ 50% { background-position: 0 -130px } /* x坐标:0 y坐标:-130 */ 60% { background-position: -130px -130px } /* x坐标:-130 y坐标:-130 */ 70% { background-position: -260px -130px } /* x坐标:-260 y坐标:-130 */ 80% { background-position: -390px -130px } /* x坐标:-390 y坐标:-130 */ 90% { background-position: -520px -130px } /* x坐标:-520 y坐标:-130 */ to { background-position: 0 } /* 最后一帧不显示,可以随便写 */}定义一个名为 loading 的动画,雪碧图上一共有 10 个元素,所以在这里我们定义 11 帧(最后一帧看不到)。每一帧都要对准位置,整张雪碧图的尺寸是 680px * 260px,2 行 5 列。所以高260除以行2等于 130px、宽 680除以列 5还是等于 130px,所以我们的 div 宽高要设置成 130 * 130,第一帧到第五帧都是宽(130px)的倍数,第一帧是0 * 130px,第二帧是1 * 130px,依此类推。到了第五帧(40%)的时候,整个第一行已经都过了一遍,所以第六帧(50%)我们要换到第二行的行首。于是 y 坐标由之前的 0 变成了 -130px,刚好是一行的高度。有的同学可能会有一个疑问:为什么这些坐标都是负值呢?我们还是用图片去理解:小一点的方框代表我们的 div,大方块代表雪碧图,原点为左上角。如果是正值的话,就是雪碧图左上角距离 div 左上角右移。如果值为负的话,就是左移。y 轴同理,正值下移,负值上移。
重点是如何进行调用,先来看一下语法:/* 清除浏览器默认边距 */* { padding: 0; margin: 0; }body { /* 这段代码是为了居中显示,不是重点,看不懂的话可以无视 */ height: 100vh; display: flex; align-items: center; justify-content: center; /* 添加背景图 */ background: url(../img/bg.jpg) center / cover;}.animate { width: 130px; height: 130px; background: url(../img/rect.png); /* 动画: 动画名(loading) 时长(0.6秒) 运行方式(step-end) 动画次数(3次) 填充模式(双向) */ animation: loading .6s step-end 3 both, /* 动画可以定义多个,每个动画用逗号分隔。*/ /* 第二个动画的动画名(animate) 时长(0.8秒) 运行方式(step-end) 延时(1.8秒) 动画次数(无限) */ animate .8s steps(12) 1.8s infinite;}/* 定义动画:动画名(loading) */@keyframes loading { from { background-position: 0 0 } /* 第一个数字代表x轴坐标,第二个数字代表y轴坐标 */ 10% { background-position: -130px 0 } /* x坐标:-130 y坐标:0 */ 20% { background-position: -260px 0 } /* x坐标:-260 y坐标:0 */ 30% { background-position: -390px 0 } /* x坐标:-390 y坐标:0 */ 40% { background-position: -520px 0 } /* x坐标:-520 y坐标:0 */ 50% { background-position: 0 -130px } /* x坐标:0 y坐标:-130 */ 60% { background-position: -130px -130px } /* x坐标:-130 y坐标:-130 */ 70% { background-position: -260px -130px } /* x坐标:-260 y坐标:-130 */ 80% { background-position: -390px -130px } /* x坐标:-390 y坐标:-130 */ 90% { background-position: -520px -130px } /* x坐标:-520 y坐标:-130 */ /* 修改最后一帧,以便动画结束后盒子就应用最后一帧的样式 */ to { /* 下一个动画的宽高 */ width: 216px; height: 300px; /* 下一个动画的雪碧图 */ background-image: url(../img/animate.png); }}/* 定义动画:动画名(animate) */@keyframes animate { from { background-position: 0 } to { background-position: -2600px }}运行结果:这是怎么个原理呢?原来调用动画的时候可以一次性调用多个动画,动画与动画直接用逗号进行分隔。第一个加载动画我们让他重复运行 3 次,由于下一个动画的背景图和宽高都和加载动画不同,所以调用第一个动画时用填充模式将最后一帧定义的样式应用到下个动画上。
实现简单,代码量少,好理解;能根据浏览器自动决定帧率,不需要自己指定帧率;体积小,即使写很多过渡动画也不会有图片那么大。
/* 清除浏览器默认边距 */* { padding: 0; margin: 0; }body { /* 这段代码是为了居中显示,不是重点,看不懂的话可以无视 */ height: 100vh; display: flex; align-items: center; justify-content: center; /* 添加背景图 */ background: url(../img/bg.jpg) center / cover;}.animate { width: 130px; height: 130px; background: url(../img/rect.png); /* 动画: 动画名(loading) 时长(0.6秒) 运行方式(step-end) 动画次数(无限) */ animation: loading .6s step-end infinite;}/* 定义动画:动画名(loading) */@keyframes loading { from { background-position: 0 0 } /* 第一个数字代表x轴坐标,第二个数字代表y轴坐标 */ 10% { background-position: -130px 0 } /* x坐标:-130 y坐标:0 */ 20% { background-position: -260px 0 } /* x坐标:-260 y坐标:0 */ 30% { background-position: -390px 0 } /* x坐标:-390 y坐标:0 */ 40% { background-position: -520px 0 } /* x坐标:-520 y坐标:0 */ 50% { background-position: 0 -130px } /* x坐标:0 y坐标:-130 */ 60% { background-position: -130px -130px } /* x坐标:-130 y坐标:-130 */ 70% { background-position: -260px -130px } /* x坐标:-260 y坐标:-130 */ 80% { background-position: -390px -130px } /* x坐标:-390 y坐标:-130 */ 90% { background-position: -520px -130px } /* x坐标:-520 y坐标:-130 */ to { background-position: 0 } /* 最后一帧不显示,可以随便写 */}/* 定义动画:动画名(animate) */@keyframes animate { from { background-position: 0 } to { background-position: -2600px }}咦?条形图只需要定义两行?一个from一个to???是的,这就是为什么推荐制作雪碧图的时候做成一行的原因。你只需要定义一开始的时候图像在原点,然后最后的时候图像有多宽,你就写负多少:这个图是2600像素,所以to里面的background-position就是 -2600px。数了一下这张雪碧图里面一共有 12 个元素,所以 steps() 括号里面要写12。div 盒子的宽高应该正好和雪碧图里面的一个元素的宽高相对应:用雪碧图的 宽 2600 除以 12 等于 216.666… 无限循环。咱们取一个近似值,就 216px 吧。所以宽高设置为 216 * 300,怎么设置呢?要让加载动画结束之后(也就是定义加载动画的最后一帧)div 就变成这个宽高。/* 清除浏览器默认边距 */* { padding: 0; margin: 0; }body { /* 这段代码是为了居中显示,不是重点,看不懂的话可以无视 */ height: 100vh; display: flex; align-items: center; justify-content: center; /* 添加背景图 */ background: url(../img/bg.jpg) center / cover;}.animate { width: 130px; height: 130px; background: url(../img/rect.png); /* 动画: 动画名(loading) 时长(0.6秒) 运行方式(step-end) 动画次数(无限) */ animation: loading .6s step-end infinite;}/* 定义动画:动画名(loading) */@keyframes loading { from { background-position: 0 0 } /* 第一个数字代表x轴坐标,第二个数字代表y轴坐标 */ 10% { background-position: -130px 0 } /* x坐标:-130 y坐标:0 */ 20% { background-position: -260px 0 } /* x坐标:-260 y坐标:0 */ 30% { background-position: -390px 0 } /* x坐标:-390 y坐标:0 */ 40% { background-position: -520px 0 } /* x坐标:-520 y坐标:0 */ 50% { background-position: 0 -130px } /* x坐标:0 y坐标:-130 */ 60% { background-position: -130px -130px } /* x坐标:-130 y坐标:-130 */ 70% { background-position: -260px -130px } /* x坐标:-260 y坐标:-130 */ 80% { background-position: -390px -130px } /* x坐标:-390 y坐标:-130 */ 90% { background-position: -520px -130px } /* x坐标:-520 y坐标:-130 */ /* 修改最后一帧,以便动画结束后盒子就应用最后一帧的样式 */ to { /* 下一个动画的宽高 */ width: 216px; height: 300px; /* 下一个动画的雪碧图 */ background-image: url(../img/animate.png); }}/* 定义动画:动画名(animate) */@keyframes animate { from { background-position: 0 } to { background-position: -2600px }}
柱状图支持动画效果,只需设置 animation = true 即可启动动画功能。与动画相关配置包括:配置名类型默认值说明animationbooleanfalse是否启动动画效果animationThresholdnumber2000关闭动画的阈值,在 animation = true 的情况下,若数据量超过该值则关闭动画效果animationDurationnumber | function1000初始动画的时长animationEasingstringcubicOut初始动画的缓动效果animationDelaynumber | function初始动画的延迟animationDurationUpdatenumber300数据更新动画时长animationEasingUpdatestringcubicOut数据更新动画的缓动效果animationDelayUpdatenumber | function数据更新动画的延迟默认配置下,只需设置 animation = true 即可启动动画效果,简单示例:1361示例效果:与 CSS3 动画类似,下列属性可以微调动画执行的细节:animationDuration: 初始动画执行周期;animationEasing: 初始动画的缓动效果,只能使用内置的缓动函数,可选值请参考 缓动示例;animationDelay: 初始动画延迟时间,支持数值或函数类型。通过设置,可以调整出更加生动的动画效果,例如在上例基础上设置如下属性:{ animation: true, animationEasing: 'elasticOut', animationDuration: function(index) { return index * 300; },}示例效果如下:细心的读者应该已经注意到,上述配置表中存在两类属性,一是初始动画,即图表首次渲染动画;二是数据更新动画,即在图表初始化后,通过调用 setOption 或 appendData 函数促使数据发生变化时执行的动画效果,相关属性包括:animationDurationUpdate:数据更新动画执行周期;animationEasingUpdate:数据更新动画的缓动效果,只能使用内置的缓动函数,可选值请参考 缓动示例;animationDelayUpdate:数据更新动画延迟时间。例如在上例基础上,动画配置修改为:{ animation: true, animationEasingUpdate: 'elasticOut', animationDurationUpdate: function(index) { return index * 100; },}注意初始化与插入数据时,动画效果的差异:
定义好了就可以去调用了,来看一下怎么调用:/* 清除浏览器默认边距 */* { padding: 0; margin: 0; }body { /* 这段代码是为了居中显示,不是重点,看不懂的话可以无视 */ height: 100vh; display: flex; align-items: center; justify-content: center; /* 添加背景图 */ background: url(../img/bg.jpg) center / cover;}.animate { width: 130px; height: 130px; background: url(../img/rect.png); /* 动画: 动画名(loading) 时长(0.6秒) 运行方式(step-end) 动画次数(无限) */ animation: loading .6s step-end infinite;}/* 定义动画:动画名(loading) */@keyframes loading { from { background-position: 0 0 } /* 第一个数字代表x轴坐标,第二个数字代表y轴坐标 */ 10% { background-position: -130px 0 } /* x坐标:-130 y坐标:0 */ 20% { background-position: -260px 0 } /* x坐标:-260 y坐标:0 */ 30% { background-position: -390px 0 } /* x坐标:-390 y坐标:0 */ 40% { background-position: -520px 0 } /* x坐标:-520 y坐标:0 */ 50% { background-position: 0 -130px } /* x坐标:0 y坐标:-130 */ 60% { background-position: -130px -130px } /* x坐标:-130 y坐标:-130 */ 70% { background-position: -260px -130px } /* x坐标:-260 y坐标:-130 */ 80% { background-position: -390px -130px } /* x坐标:-390 y坐标:-130 */ 90% { background-position: -520px -130px } /* x坐标:-520 y坐标:-130 */ to { background-position: 0 } /* 最后一帧不显示,可以随便写 */}为了能够让同学们在浏览器里直接看结果,我们这里写了一个可运行的案例:910运行结果:  可以看到效果就已经很完美的呈现出来了,那么接下来我们再来添加一下条形雪碧图,看看条形雪碧图的用法有何不同。
animation 是动画,而 transition 是过渡,它们用法很相似,但实际又不大相同,可以说 animation 是 transition 的升级版,它可以创建一个持续的自动执行动画。
定义好动画之后就需要在想要的位置去调用啦,先来学习一下动画调用的语法:animation: name duration timing-function delay iteration-count direction fill-mode;当然写的时候可绝对不是这么写的啊,只有冒号前面的animation这个单词不变,剩下单词全部都要替换,那么要替换成什么呢?请看中文翻译版:animation: 定义过的动画名 动画时长 动画运行的方式 延迟 动画次数 动画方向 填充模式;是不是看到这里直接晕了,甚至有种想关掉网页的冲动?不要怕,这些只是看起来吓人,其实都是纸老虎。而且也不是这些属性都要用到,哪个属性你用不到就可以不写,通常我们只会用到几个常用的。
同样,我们可以使用 CSS 动画来实现元素的过渡效果。CSS 动画用法类似 CSS 过渡,在过渡的不同阶段对应的 Class 会作用于元素。但是在动画中 v-enter 类名在节点插入 DOM 后不会立即删除,而是在 animationend 事件触发时删除。相信同学们在日常业务开发中一定使用过 Dialog,接下来我们就使用 CSS 动画来实现它的过渡效果:678代码解释:HTML 代码第 3-5 行,我们使用 transition 组件包裹 <p> 标签,transition 组件指定 name 为 bounce 指令 v-show 控制 <p> 标签的显示和隐藏;HTML 代码第 2 行,定义按钮 button,点击修改 show 的值来控制标签 <p> 的显示隐藏;CSS 中我们定义了样式两个样式:元素入场样式: bounce-enter-active,它执行动画 bounce-in。元素出场样式: bounce-leave-active,它执行动画 bounce-out。JS 代码第 6 行,定义数据 show,初始值为 true。
语法:animation: 动画名 时长 step-end both;来看具体案例:908运行结果:可以看到成功了,紫色出来了,而且永远都不会再回到默认的黑色了。这究竟是怎么一回事呢?step-end和both这两个单词到底是什么意思呢?先不要着急,咱们先把结论记下来,原理放到后面讲。
首先使用过渡动画看看会是什么效果:900运行结果:过渡动画确实是好,但是在这种情况下真的不适合用它。
定义:栈帧(Stack Frame)是用于支持虚拟机进行方法调用和方法执行的数据结构。它是虚拟机运行时数据区中的 java 虚拟机栈的栈元素。栈帧存储了方法的局部变量表、操作数栈、动态链接和方法返回地址等信息。栈帧初始化大小:在编译程序代码的时候,栈帧中需要多大的局部变量表内存,多深的操作数栈都已经完全确定了。 因此一个栈帧需要分配多少内存,不会受到程序运行期变量数据的影响,而仅仅取决于具体的虚拟机实现。栈帧结构:如下图所示,在一个线程中,只有位于栈顶的栈帧才是有效的,称为当前栈帧,与这个栈帧相关联的方法称为当前方法。每一个方法从调用开始至执行完成的过程,都对应着一个栈帧在虚拟机里面从入栈到出栈的过程。从上图中我们能够看到,栈帧的组成结构,下文我们将对局部变量表,操作数栈,动态链表以及返回地址进行讲解。
如果学过一些编程语言的同学会知道,有一个词叫做变量,这个变量通常是需要事先定义好才能够去使用。CSS 动画也是同理,需要先定义,才能够去使用。接下来我们就来看看该如何定义一个 CSS 动画: @keyframes 动画名 { 动画内容 }@keyframes 是一个固定的写法,表示要定义一个动画,后面要空一格再写你的动画名,然后大括号里面再写上对应的动画内容。学过 JavaScript 的同学(没学过的话也没关系,可以继续往下看)可以把 @keyframes 理解为 JS 中的 var,就相当于定义了一个变量。大括号里面写的可以是百分比,百分比后面的大括号里面就是你自己想要的 CSS 样式啦!假如我们定义一个名为 change-color 的动画:<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>@keyframes</title> <style> /* 先定义一个名为change-color的动画 */ @keyframes change-color { 0% { color: red } /* 红 */ 16% { color: orange } /* 橙 */ 32% { color: yellow } /* 黄 */ 48% { color: green } /* 绿 */ 64% { color: cyan } /* 青 */ 80% { color: blue } /* 蓝 */ 100% { color: purple } /* 紫 */ } </style></head><body> </body></html>TIPS:0% 可以写成 from,100% 可以写成 to,效果完全一致,只是一个别名。我们按照红橙黄绿青蓝紫的这么一个彩虹颜色顺序定义了一个名为 change-color 的动画,但是此时却没有任何的效果,这是因为目前仅仅只是定义了这个动画,并没有去指定哪个元素会用到这个动画,以及该如何使用这个动画。那么接下来就让我一起来看看该如何使用这个动画吧!
如果我们不想让它结束,那就十秒过后再来十秒,十秒完再十秒,无限重复、无限循环:animation: name duration iteration-count;翻译过来就是:animation: 定义过的动画名 动画时长 动画次数;904运行结果:运行次数可以写具体的数字,动画会根据你写的数字来运行相应的次数,想要无限运行的话就写infinite虽然成功的无限循环了,但是目前看来有个缺点,那就是最后一帧紫色结束后突然就变成了第一帧的红色,没有任何的过渡效果。有两个解决方案:1. 定义动画的时候最后一帧再变回红色:905运行结果:2. 交替动画什么是交替动画呢?简单来说就是从第一帧红到最后一帧紫运行完了之后,再从最后一帧紫到第一帧红,然后再从红到紫、从紫到红,大红大紫。这种动画就不用最后一帧再定义回第一帧的红色了,直接定义从红到紫即可。来看看语法:animation: 定义过的动画名 动画时长 动画次数 动画方向;906运行结果:
本章节我们主要介绍 Vue.js 的过渡效果与动画效果。包括如何编写自定义 CSS 动画、如何配合第三方 CSS 动画库、过渡钩子函数的使用、如何使用第三方 JavaScript 动画库。本小节的内容相对之前有些难度,同学们在阅读一遍之后如果不能完全掌握,建议反复阅读,并把本小节的所有案例自己实现一遍,相信通过多次的练习一定可以掌握。
实现的效果通常来说相对简单;不够灵活,如果实现一些复杂动画就有些相形见绌了;通常无法快速实现美工想出的一些天马行空的复杂特效。最后这个缺点怎么理解呢?是这样,由于部分美工对界面效果要求较高,有时候会想出一些前端难以快速制作出来的效果,然而她们并不理解技术上的难度,会误认为这是个很容易实现的效果。所以此时如果将效果丢给美工(让其渲染序列帧雪碧图或 gif 动态图),既可以节约出开发时间(有时开发时间真的很紧,功能都快开发不完了,不能在样式上花费过多时间),又可以让美工知难而退(相信我,把任务交给美工的时候,她们突然就会觉得这个特效也不是特别有必要了)。
上例的问题是从 init 到 setOption 这段时间内,图表容器没有内容,一片空白,可能会让用户误解为 bug,因此需要给容器加上 loading 效果以提示用户正在加载数据。echarts 内置了一套简单的加载动画效果,通过 echartInstance.showLoading 方法触发;通过 echartInstance.hideLoading 方法关闭,例如:1303示例效果:echartInstance.showLoading 函数签名如下:(type?: string, opts?: Object) => void参数:type:可选,加载动画类型,目前只支持 ‘default’;opts:可选,加载动画配置项,默认配置项:{ text: 'loading', color: '#c23531', textColor: '#000', maskColor: 'rgba(255, 255, 255, 0.8)', zlevel: 0}提示:echarts 目前只提供了一种加载动画样式,而且没有对外暴露加载动画的扩展接口。如果应用场景要求使用自定义动画,可以自行实现,在图表容器上覆盖一层遮罩层,并在遮罩层上叠加加载动画效果。
其实你在大部分网站看到的一些交互动画都是过渡动画,这么一看感觉好像帧动画没什么优势啊。其实不然,接下来我们将用雪碧图来让大家见识一下帧动画的厉害之处。
怎么样是不是很帅气呢?这就是雪碧图帧动画的优势所在。如果纯用CSS来实现这段特效那简直让人无从下手,但用雪碧图+帧动画就可以很轻松的实现。下一小节我们将在此基础上再添加一个动画,快来看看多个动画是如何并存的吧!
细心的朋友们应该会注意到,在布局文件的<ViewFlipper/>标签中有这么两个属性:android:inAnimation="@anim/in_from_right"android:outAnimation="@anim/out_from_left"根据 2.1 小节对属性的介绍,我们知道这是用来设置出场和入场动画的,所以接下来我们就来完善这两个动画效果,首先按照以下步骤创建一个动画资源:右键点击“res”目录,一次选择“New” -> “Android Resource Directory”在“Resource type”中选择“anim”,点“OK”,创建一个动画资源目录此时“res”目录下就有了“anim”文件夹,在里面创建四个动画文件:in_from_left.xml:表示从左侧进入的动画,代码如下:<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> <translate android:duration="1400" android:fromXDelta="-100%" android:toXDelta="0%"/></set>其中<translate/>标签表示一个 TranslateAnimation,专门用来实现移动补间动画,具体关于动画的用法在后面的动画专题章节有详细的讲解,这里我们关注 ViewFlipper,对动画只需要做一点了解即可。其余三个动画都类似:**in_from_right.xml:**表示从右侧进入,代码如下:<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> <translate android:duration="1400" android:fromXDelta="100%" android:fromYDelta="0%" /></set>**out_from_left:**从左侧移出:<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> <translate android:duration="1400" android:fromXDelta="0%" android:toXDelta="-100%"/></set>**out_from_right:**从右侧移出:<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> <translate android:duration="1400" android:fromXDelta="0%" android:fromYDelta="0%" android:toXDelta="100%" android:toYDelta="0%" /></set>
在这里老师要先给大家介绍一种在 Dreamweaver CC 2018 中插入动画的方式,下面老师先简要介绍一种方式,这种方式其实在 Dreamweaver CC 2018 中很显眼,很容易被看到。第一步:我们还是新建一个空白的 HTML 文档。详细步骤不在此赘述,请大家主动翻阅前几节的慕课 wiki 文档自行学习。第二步:我们在右侧的面板中,选择动画合成,然后会弹出选择文件的画面,大家只要选择制作好的文件就可以了。由于资源需要到互联网上搜集,大家在互联网上很容易找到相关的资源,由于版权的问题,老师不方便在此处给大家展示选择后的动画效果。同学们应该课下自己多多练习。体会这种动画插入方式的便捷之处。下图是对 Dreamweaver CC 2018 右侧面板的展示。插入完成后,点击插入好的动画,我们依然可以在属性面板中看到长宽高的编辑界面,具体界面大家可以参考上一节的多媒体文件长宽的设置,那里有更详细的说明和指引。在这里我们只需要掌握一个简单动画的插入流程就可以,需要用的时候知道到哪里去寻找快捷操作方式即可。以上便是我们完完全全通过 Dreamweaver CC 2018 来为网页插入简单动画的基本过程!当然,由于大家的素材复杂程度不同,我们做出来的网页最终会因为动画效果的不同而内容大不相同,其实在这里老师要强调的是,动画素材的选择和内容的设计,要比动画的位置重要,合适的位置要比如何插入动画重要。所以大家要在网页中使用动画时素材的选择严加把控,符合网页的主题,不能顾此失彼,忙东忙西之间失去了网页的主题和设计目标。
上一章我们已经了解了雪碧图需要的基本CSS语法,那么这一章节我们将带领大家体验一下动画的语法,以及不同动画种类之间的区别。动画通常分为两种形式:一种是过渡动画、另一种是帧动画。
如果你有选择困难症的话,我可以给你个小小的建议:兼容性要求高的用雪碧图、不怎么考虑兼容性的新项目用iconfont。但雪碧图也并不仅仅只是能做个图标而已,如果是帧动画技术的话雪碧图是难以替代的。好多网页小游戏或者一些网页炫酷动画就用到了雪碧图的帧动画技术,那么接下来就让我们开启雪碧图的学习之旅吧!
动态链接的基本概念及作用如下:每个栈帧都包含一个指向运行时常量池(JVM 运行时数据区域)中该栈帧所属方法属性的引用,持有这个引用是为了支持方法调用过程中的动态链接。在 Class 文件格式的常量池(存储字面量和符号引用)中存有大量的符号引用(1. 类的全限定名,2. 字段名和属性,3. 方法名和属性),字节码中的方法调用指令就以常量池中指向方法的符号引用为参数。这些符号引用一部分会在类加载过程的解析阶段的时候转化为直接引用(指向目标的指针、相对偏移量或者是一个能够直接定位到目标的句柄),这种转化称为静态解析。另外一部分将在每一次的运行期期间转化为直接引用,这部分称为动态链接。返回地址:返回地址代表的是方法执行结束,方法执行结束有两种方式,我们来具体看下栈帧中返回地址的作用:当一个方法开始执行后,只有两种方式可以退出这个方法。第一种方式是执行引擎遇到任意一个方法返回的字节码指令(例如:return),这时候可能会有返回值传递给上层的方法调用者(调用当前方法的方法称为调用者),是否有返回值和返回值的类型将根据遇到何种方法返回指令来决定,这种退出方法的方式称为正常完成出口(Normal Method Invocation Completion)。另外一种退出方式是,在方法执行过程中遇到了异常,并且这个异常没有在方法体内得到处理,无论是 Java 虚拟机内部产生的异常,还是代码中使用 throw 字节码指令产生的异常,只要在本方法的异常处理器表中没有搜索到匹配的异常处理器,就会导致方法退出,这种退出方法的方式称为异常完成出口(Abrupt Method Invocation Completion)。一个方法使用异常完成出口的方式退出,是不会给它的上层调用者产生任何返回值的。方法退出的过程实际上就等同于把当前栈帧出栈,因此退出时可能执行的操作有:恢复上层方法的局部变量表和操作数栈,把返回值(如果有的话)压入调用者栈帧的操作数栈中,调整程序计数器的值以指向方法调用指令后面的一条指令等。