CSS3 动画详解 谷歌浏览器架构和渲染原理 游戏制作

·  阅读 359

CSS3 动画

前言

css3 动画 两大组成部分:transition(过度)和animation(动画);
同时, 还有transform属性来对2D/3D节点进行平移、缩放、旋转以及拉伸. (这个平时在布局也会用到 它本身没有脱离文档流 经过transform的节点 原位置保持不变 只是对节点本身进行动画变形 这一点对于一些重绘回流的性能优化是有一定帮助的

如果做一些css3d 游戏的话,perspectiveperspective-origintransform-style: preserve-3d这个三个3d属性值 就需要了解一下了, 它们构成了CSS的3d世界.

做一款CSS3D游戏或css3动画需要的知识和概念

Chrome 浏览器

包括:1 个浏览器(Browser)主进程、1 个 GPU 进程、1 个网络(NetWork)进程、多个渲染进程和多个插件进程。

1、浏览器进程。

主要负责界面显示、用户交互、子进程管理,同时提供存储等功能。

2、渲染进程。

浏览器内核进程, 核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎 BlinkJavaScript 引擎 V8 都是运行在该进程中,默认情况下,Chrome 会为每个 Tab 标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。

它有几大类子线程:

1、GUI线程

2、JS引擎线程

3、事件触发线程

4、定时器线程

5、网络请求线程

3、GPU 进程。

GPU 进程的使用初衷是为了实现 3D CSS 的效果,只是随后网页、Chrome 的 UI 界面都选择采用 GPU 来绘制,这使得 GPU 成为浏览器普遍的需求。最后,Chrome 在其多进程架构上也引入了 GPU 进程。

4、网络进程。

主要负责页面的网络资源加载。

5、插件进程。

主要是负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响。

css3 动画渲染过程

  • 布局
  • 渲染
  • 合成
  • 绘制

布局(排版)

浏览器会先计算每一个元素在屏幕上占有多少空间大小。所以在这个“布局”过程中,与元素的width和height位置有着很大的联系。在任何时候,只有改变元素的宽高,或者元素属性【top/left】,浏览器对元素布局都会重新计算一次。

就算是使用JavaScript在DOM添加或者删除元素,都会导致浏览器重新计算元素的布局,浏览器必须重新渲染一次页面。

tip: 排版方式简单说一下, 正常流中的文字排版、正常流中的盒、绝对定位元素、浮动元素排版、 flex排版和grid排版, 盒模型

渲染

总体来说,可以分为两大类:图形和文字。 这个过程就是填充像素:描绘文本、盒的背景、SVG元素、着色图片、边框和阴影。绘制的过程是在内存发生的,页面中的各个部分形成很多图层。若是修改元素的背景颜色,那么浏览器就会重新绘制它。

tip:

一般的操作系统都会提供一个底层库,比如在android中,有个大名鼎鼎的Skia,而windows平台则有GDI,一般的浏览器会做一个兼容层来处理掉平台差异.

盒中的文字,也需要用底层库来支持,叫做字体库。字体库提供读取字体文件的基本能力,它能根据字符的码点抽取出字形.

字形分为像素字形和矢量字形两种。通常的字体,会在6px,8px等小尺寸提供像素字形,比较大的尺寸则提供矢量字形。矢量字形本身就需要经过渲染才能继续渲染到元素的位图上去。目前最常用的字体库是Freetype,这是一个C++编写的开源的字体库。

还有阴影效果 要特别说明一下,无论是canvas 动画还是css动画 都是需要注意的。 阴影,它可能非常巨大,或者渲染到非常遥远的位置,所以为了优化,浏览器实际的实现中会把阴影作为一个独立的盒子来处理

这个过程是不会把子元素绘制到渲染的位图上的,这样,当父子元素的相对位置发生变化时,可以保证渲染的结果能够最大程度被缓存,减少重新渲染。

合成

主流浏览器一般根据 position、transform 等属性来决定合成策略,来“猜测”这 些元素未来可能发生变化, 新的 CSS 标准中,规定了 will-change 属性,可以由 业务代码来提示浏览器的合成策略,灵活运用这样的特性,可以大大提升合成策略的效 果

绘制

浏览器将所有绘制完成的图层,提取为屏幕上的图像

浏览器并不需要用代码来处理, 只需要把最终要显示的位图交给操作系统或者显式驱动, 这取决于浏览器运行的环境.

opacity和transform两个属性值发生改变的时候,元素渲染的时间非常少。这时候,浏览器会将元素提升到自己的绘制图层并使用GPU【计算机图形处理器】加速。因为元素是存在浏览器自己的绘制图层内,所以在整个图像变化中主图层不会发生变化,也无须重新绘制

tip:

这里可以提一个问题点:得到每个元素的位图后,并且对它们部分进行了合成,那么绘制过程,实是否z-index 把它们依次绘 制到屏幕上

实际上,“绘制”发生的频率比我们想象中要高得多。我们考虑一个情况:鼠标划 过浏览器显示区域。这个过程中,鼠标的每次移动,都造成了重新绘制,如果我们不重新 绘制,就会产生大量的鼠标残影。

这个时候,限制绘制的面积就很重要了。

计算机图形学中,我们使用的方案就是“脏矩形”算法,也就是把屏幕均匀地分成若干矩 形区域

当鼠标移动、元素移动或者其它导致需要重绘的场景发生时,我们只重新绘制它所影响到 的几个矩形区域就够了。比矩形区域更小的影响最多只会涉及 4 个矩形,大型元素则覆盖 多个矩形。

设置合适的矩形区域大小,可以很好地控制绘制时的消耗。设置过大的矩形会造成绘制面 积增大,而设置过小的矩形则会造成计算复杂

我们重新绘制脏矩形区域时,把所有与矩形区域有交集的合成层(位图)的交集部分绘制 即可

transform 变换变形属性

  1. rotate(angle)/rotate3d(x,y,z,angle): 根据给定的角度顺时针或逆时针旋转元素/ 3d 绕x,y,z 旋转。 单位是deg —— 度数

  2. scale(x,y)/scale3d(x,y,z):增加或减少元素的大小, 原始宽高的倍数。 单位 数字.

    tip:scaleX(-1) 定义一个 轴向对称性(axial symmetry) ,它具有一个垂直轴通过原点 (由 transform-origin 属性规定)。 如果设置的值大于1,那么元素将沿X轴被放大。如果值为1,元素保持不变。如果值小于1,元素会沿X轴被缩小。如果设置的值为0,那么那元素被无限缩小,消失在屏幕中。值可以是负数,负数值不会缩放元素,而是会对元素在水平轴上进行翻转。

  3. skew(x-angle,y-angle): 元素沿 X 和 Y 轴倾斜给定角度。 单位是deg —— 度数

  4. translate(x,y)/translate3d(x,y,z): translate是位移的意思, 而且是相对自身的位置进行位移。 单位 像素值 %

  5. transform-origin: x-axis(left center rigth length %) y-axis(同左) z-axis(length); 这个属性是设置变换原点的作用。 上面的属性都支持变换原点

  6. transform-style 规定如何在 3D 空间中呈现被嵌套的元素, flat|preserve-3d; 子元素是否保留其 3D 位置。

  7. perspective: number|none; 属性定义 3D 元素视图的距离,以像素计, 其子元素会获得透视效果,而不是元素本身。 注释:perspective 属性只影响 3D 转换元素。 *可以理解为相机*

  8. perspective-origin: x-axis(lefft center right length) y-axis(top center bottom length %); CSS 属性 perspective-origin 指定了观察者的位置,用作 perspective 属性的消失点。

  9. backface-visibility: visible|hidden; 定义当元素不面向屏幕时是否可见。

transition 过度属性

transition: property duration timing-function delay

描述
transition-property过渡CSS属性
transition-duration过渡时间
transition-timing-function速度曲线
transition-delay过渡效果延迟出发时间

transition产生动画的条件是transition设置的property发生变化.

可以设置一些伪类:hover, :active ,类名, js事件 切换改变元素属性触发,无法自动触发或者页面加载的时候出发 是一次性的,不能重复发生,除非一再触发 只能定义开始状态和结束状态,不能定义中间状态,也就是说只有两个状态.

一个或多个 CSS 属性的过渡效果,多个属性之间用逗号进行分隔, (关键字none,关键字all,命名 CSS 属性的)

1transition: all 1s ease;
2transition: width 1s ease, height 1s ease;
3transition-property: width , height; transition-duration: 1s; transition-timing-function: ease;

复制代码

animation

是transition属性的扩展,弥补了transition的很多不足,可以理解为animation是由多个transition的效果叠加,并且可操作性更强,能够做出复杂酷炫的效果。 特别是@keyframes提供更多的控制,尤其是时间轴的控制,这点让css animation更加强大

语法:animation: name duration timing-function delay iteration-count direction play-state fill-mode;

  1. name 用来调用@keyframes定义好的动画,与@keyframes定义的动画名称一致

  2. duration 指定元素播放动画所持续的时间

  3. timing-function 规定速度效果的速度曲线,是针对每一个小动画所在时间范围的变换速率

  4. delay 定义在浏览器开始执行动画之前等待的时间,值整个animation执行之前等待的时间

  5. iteration-count 定义动画的播放次数,可选具体次数或者无限(infinite)

  6. direction 设置动画播放方向:normal(按时间轴顺序),reverse(时间轴反方向运行),alternate(轮流,即来回往复进行),alternate-reverse(动画先反运行再正方向运行,并持续交替运行)

  7. play-state 控制元素动画的播放状态,通过此来控制动画的暂停和继续,两个值:running(继续),paused(暂停)

  8. fill-mode 控制动画结束后,元素的样式,有四个值:none(回到动画没开始时的状态),forwards(动画结束后动画停留在结束状态),backwords(动画回到第一帧的状态),both(根据animation-direction轮流应用forwards和backwards规则),注意与iteration-count不要冲突(动画执行无限次)。

动画设计:

一维 fish_box 实现动态鱼效果

盒子里面为一种鱼类包含一到多条一样的,绝对布局重叠在一起。

里面鱼类的gif效果实现或则雪碧图动画主要技术点:

transition-timing-function/animation-timing-function属性值steps

Steps(<number_of_steps>,)阶跃函数. 雪碧图的实现动画, 把雪碧图被分段分且两个关键帧之间的动画效果,默认是ease.
有两个参数:
参数一是把这次过渡分成几段几帧,可以理解同视频就是每一帧时间播放的图片 分段分帧显示执行, 不是状态的过渡.
参数二是表示分成几段后,他是start还是end去执行动画。参数二有两个可选值start和end,默认是end.
在我们的@keyframes中申明的动作将会发生的关键。这个值是可选的,在没有传递参数时,默认为”end”
start:左--持续函数,执行每一帧step时候,都以左侧端点为起点,立即跳到第一个step的结尾处的状态直到这一步时间结束。
end:右--持续函数。执行每一帧step保持状态到这一帧时间结束,再跳到下一帧,最后一帧的有所不同,这一帧的终点时间,直接回到了整个动画起点,开始了第二次动画。

二维 y 实现动态鱼运动时的动作 比如摇摆前进或上下晃动前进

@-webkit-keyframes left_right_1_y {
    0% {
        top: 15%;
    }
    30% {
        top: 16%;
    }
    50% {
        top: 15%;
    }
    70% {
        top: 16%;
    }
    100% {
        top: 15%;
    }
}

@-webkit-keyframes left_right_2_y {
    0% {
        top: 25%;
        -webkit-transform: rotateZ(0deg);
        transform: rotateZ(0deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
    25% {
        -webkit-transform: rotateZ(-20deg);
        transform: rotateZ(-20deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
    50% {
        top: 0%;
    }
    75% {
        -webkit-transform: rotateZ(10deg);
        transform: rotateZ(10deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
    100% {
        top: 50%;
        -webkit-transform: rotateZ(10deg);
        transform: rotateZ(10deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
}

复制代码

三维 x 设计动态鱼的运动路线 比如屏幕的某一端动到另一端。

@-webkit-keyframes left_right_1_x {
    0% {
        left: 0%;
    }
    100% {
        left: 150%;
    }
}
复制代码

四维 right_left_xx left_right_xx 设计动态鱼的活动的圈或空间 以及运动的方向

    position: absolute;
    width: 100%;
    height: 100%;
    transforM: scaleX(-1);
复制代码

五维 fishGroup 动态鱼的拷贝或则 四维的平行分支鱼

.fishGroup .fish_wrap:nth-child(2) .fish_box {
    -webkit-transform: translate(-100%, -50%);
    transform: translate(-100%, -50%);
}

.fishGroup .fish_wrap:nth-child(3) .fish_box {
    -webkit-transform: translate(-150%, 25%);
    transform: translate(-150%, 25%);
}

.fishGroup .fish_wrap:nth-child(4) .fish_box {
    -webkit-transform: translate(-250%, 65%);
    transform: translate(-250%, 65%);
}

.fishGroup .fish_wrap:nth-child(5) .fish_box {
    -webkit-transform: translate(-320%, -25%);
    transform: translate(-320%, -25%);
}
复制代码

效果图:

image.png

代码

@charset "utf-8";
body, div {
    margin: 0;
    padding: 0
}

.aquarium {
    position: absolute;
    width: 100%;
    height: 100%;
    overflow: hidden;
    z-index: 0;
}

.fish_box {
    display: inline-block;
}

.fishGroup .fish_wrap:nth-child(2) .fish_box {
    -webkit-transform: translate(-100%, -50%);
    transform: translate(-100%, -50%);
}

.fishGroup .fish_wrap:nth-child(3) .fish_box {
    -webkit-transform: translate(-150%, 25%);
    transform: translate(-150%, 25%);
}

.fishGroup .fish_wrap:nth-child(4) .fish_box {
    -webkit-transform: translate(-250%, 65%);
    transform: translate(-250%, 65%);
}

.fishGroup .fish_wrap:nth-child(5) .fish_box {
    -webkit-transform: translate(-320%, -25%);
    transform: translate(-320%, -25%);
}

.left_right_1 {
    position: absolute;
    width: 100%;
    height: 70%;
}

.left_right_1 .x {
    display: inline-block;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    -webkit-animation: left_right_1_x 70s linear infinite;
    animation: left_right_1_x 70s linear infinite;
}

@-webkit-keyframes left_right_1_x {
    0% {
        left: 0%;
    }
    100% {
        left: 150%;
    }
}

.left_right_1 .y {
    display: inline-block;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    -webkit-animation: left_right_1_y 1.5s ease infinite;
    animation: left_right_1_y 1.5s ease infinite;
}

@-webkit-keyframes left_right_1_y {
    0% {
        top: 15%;
    }
    30% {
        top: 16%;
    }
    50% {
        top: 15%;
    }
    70% {
        top: 16%;
    }
    100% {
        top: 15%;
    }
}

.left_right_2 {
    position: absolute;
    width: 100%;
    height: 70%;
}

.left_right_2 .x {
    display: inline-block;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    -webkit-animation: left_right_2_x 25s linear infinite;
    animation: left_right_2_x 25s linear infinite;
}

@-webkit-keyframes left_right_2_x {
    0% {
        left: 0%;
    }
    100% {
        left: 150%;
    }
}

.left_right_2 .y {
    display: inline-block;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    -webkit-animation: left_right_2_y 25s ease-in-out infinite;
    animation: left_right_2_y 25s ease-in-out infinite;
}

@-webkit-keyframes left_right_2_y {
    0% {
        top: 25%;
        -webkit-transform: rotateZ(0deg);
        transform: rotateZ(0deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
    25% {
        -webkit-transform: rotateZ(-20deg);
        transform: rotateZ(-20deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
    50% {
        top: 0%;
    }
    75% {
        -webkit-transform: rotateZ(10deg);
        transform: rotateZ(10deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
    100% {
        top: 50%;
        -webkit-transform: rotateZ(10deg);
        transform: rotateZ(10deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
}

.left_right_3 {
    position: absolute;
    width: 100%;
    height: 70%;
}

.left_right_3 .x {
    display: inline-block;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    -webkit-animation: left_right_3_x 60s linear infinite;
    animation: left_right_3_x 60s linear infinite;
}

@-webkit-keyframes left_right_3_x {
    0% {
        left: 0%;
    }
    100% {
        left: 150%;
    }
}

.left_right_3 .y {
    display: inline-block;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    -webkit-animation: left_right_3_y 60s ease-in-out infinite;
    animation: left_right_3_y 60s ease-in-out infinite;
}

@-webkit-keyframes left_right_3_y {
    0% {
        top: 50%;
        -webkit-transform: rotateZ(0deg);
        transform: rotateZ(0deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
    25% {
        top: 80%;
        -webkit-transform: rotateZ(40deg);
        transform: rotateZ(40deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
    38% {
        top: 80%;
        -webkit-transform: rotateZ(0deg);
        transform: rotateZ(0deg);
    }
    50% {
        top: 80%;
        -webkit-transform: rotateZ(0deg);
        transform: rotateZ(0deg);
    }
    75% {
        -webkit-transform: rotateZ(40deg);
        transform: rotateZ(40deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
    100% {
        top: 25%;
        -webkit-transform: rotateZ(0deg);
        transform: rotateZ(0deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
}

.right_left_1 {
    position: absolute;
    width: 100%;
    height: 100%;
    transforM: scaleX(-1);
}

.right_left_1 .x {
    display: inline-block;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 70%;
    -webkit-animation: right_left_1_x 25s linear infinite;
    animation: right_left_1_x 25s linear infinite;
}

@-webkit-keyframes right_left_1_x {
    0% {
        left: 0%;
    }
    100% {
        left: 150%;
    }
}

.right_left_1 .y {
    display: inline-block;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    -webkit-animation: right_left_1_y 25s ease-in-out infinite;
    animation: right_left_1_y 25s ease-in-out infinite;
}

@-webkit-keyframes right_left_1_y {
    0% {
        top: 75%;
    }
    100% {
        top: 75%;
    }
}

.right_left_2 {
    position: absolute;
    width: 100%;
    height: 70%;
    transform: scaleX(-1);
}

.right_left_2 .x {
    display: inline-block;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 70%;
    -webkit-animation: right_left_2_x 30s linear infinite;
    animation: right_left_2_x 30s linear infinite;
}

@-webkit-keyframes right_left_2_x {
    0% {
        left: 0%;
    }
    100% {
        left: 100%;
    }
}

.right_left_2 .y {
    display: inline-block;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    -webkit-animation: right_left_2_y 30s ease-in-out infinite;
    animation: right_left_2_y 30s ease-in-out infinite;
}

@-webkit-keyframes right_left_2_y {
    0% {
        top: 100%;
        -webkit-transform: rotateZ(0deg);
        transform: rotateZ(0deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
    25% {
        -webkit-transform: rotateZ(-20deg);
        transform: rotateZ(-20deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
    50% {
        top: 0%;
    }
    75% {
        -webkit-transform: rotateZ(20deg);
        transform: rotateZ(20deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
    100% {
        top: 100%;
        -webkit-transform: rotateZ(90deg);
        transform: rotateZ(90deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
}

.right_left_3 {
    position: absolute;
    width: 100%;
    height: 100%;
    transform: scaleX(-1);
}

.right_left_3 .x {
    display: inline-block;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    -webkit-animation: right_left_3_x 35s linear infinite;
    animation: right_left_3_x 35s linear infinite;
}

@-webkit-keyframes right_left_3_x {
    0% {
        left: 0%;
    }
    100% {
        left: 100%;
    }
}

.right_left_3 .y {
    display: inline-block;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    -webkit-animation: right_left_3_y 35s ease-in-out infinite;
    animation: right_left_3_y 35s ease-in-out infinite;
}

@-webkit-keyframes right_left_3_y {
    0% {
        top: 50%;
        -webkit-transform: rotateZ(0deg);
        transform: rotateZ(0deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
    25% {
        -webkit-transform: rotateZ(20deg);
        transform: rotateZ(20deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
    50% {
        top: 90%;
    }
    75% {
        -webkit-transform: rotateZ(-20deg);
        transform: rotateZ(-20deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
    100% {
        top: 50%;
        -webkit-transform: rotateZ(-50deg);
        transform: rotateZ(-50deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
}

.right_left_4 {
    position: absolute;
    width: 100%;
    height: 70%;
    transforM: scaleX(-1);
}

.right_left_4 .x {
    display: inline-block;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    -webkit-animation: right_left_4_x 50s linear infinite;
    animation: right_left_4_x 50s linear infinite;
}

@-webkit-keyframes right_left_4_x {
    0% {
        left: 0%;
    }
    100% {
        left: 100%;
    }
}

.right_left_4 .y {
    display: inline-block;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    -webkit-animation: right_left_4_y 50s ease-in-out infinite;
    animation: right_left_4_y 50s ease-in-out infinite;
}

@-webkit-keyframes right_left_4_y {
    0% {
        top: 50%;
        -webkit-transform: rotateZ(0deg);
        transform: rotateZ(0deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
    25% {
        -webkit-transform: rotateZ(20deg);
        transform: rotateZ(20deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
    50% {
        top: 90%;
    }
    75% {
        -webkit-transform: rotateZ(-20deg);
        transform: rotateZ(-20deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
    100% {
        top: 50%;
        -webkit-transform: rotateZ(0deg);
        transform: rotateZ(0deg);
        -webkit-transform-origin: 0% 0%;
        transform-origin: 0% 0%;
    }
}

.fish_1 {
    background: url(../images/fish/fish1.png) no-repeat 0 0;
    width: 55px;
    height: 37px;
    -webkit-animation: fish_1_play 0.5s steps(4) infinite;
    animation: fish_1_play 0.5s steps(4) infinite;
}

@-webkit-keyframes fish_1_play {
    0% {
        background-position: 0 0
    }
    100% {
        background-position: 0 -148px
    }
}

.fish_2 {
    background: url(../images/fish/fish2.png) no-repeat 0 0;
    width: 78px;
    height: 64px;
    -webkit-animation: fish_2_play 0.5s steps(4) infinite;
    animation: fish_2_play 0.5s steps(4) infinite;
}

@-webkit-keyframes fish_2_play {
    0% {
        background-position: 0 0
    }
    100% {
        background-position: 0 -256px
    }
}

.fish_6 {
    background: url(../images/fish/fish6.png) no-repeat 0 0;
    width: 105px;
    height: 79px;
    -webkit-animation: fish_6_play 1.5s steps(8) infinite;
    animation: fish_6_play 1.5s steps(8) infinite;
}

@-webkit-keyframes fish_6_play {
    0% {
        background-position: 0 0
    }
    100% {
        background-position: 0 -632px
    }
}

.fish_7 {
    background: url(../images/fish/fish7.png) no-repeat 0 0;
    width: 92px;
    height: 151px;
    -webkit-animation: fish_7_play 1s steps(6) infinite;
    animation: fish_7_play 1s steps(6) infinite;
}

@-webkit-keyframes fish_7_play {
    0% {
        background-position: 0 0
    }
    100% {
        background-position: 0 -906px
    }
}

.fish_8 {
    background: url(../images/fish/fish8.png) no-repeat 0 0;
    width: 174px;
    height: 126px;
    -webkit-animation: fish_8_play 1s steps(8) infinite;
    animation: fish_8_play 1s steps(8) infinite;
}

@-webkit-keyframes fish_8_play {
    0% {
        background-position: 0 0
    }
    100% {
        background-position: 0 -1008px
    }
}

.fish_9 {
    background: url(../images/fish/fish9.png) no-repeat 0 0;
    width: 166px;
    height: 183px;
    -webkit-animation: fish_9_play 1s steps(8) infinite;
    animation: fish_9_play 1s steps(8) infinite;
}

@-webkit-keyframes fish_9_play {
    0% {
        background-position: 0 0
    }
    100% {
        background-position: 0 -1464px
    }
}

.fish_10 {
    background: url(../images/fish/fish10.png) no-repeat 0 0;
    width: 178px;
    height: 187px;
    -webkit-animation: fish_10_play 1s steps(6) infinite;
    animation: fish_10_play 1s steps(6) infinite;
}

@-webkit-keyframes fish_10_play {
    0% {
        background-position: 0 0
    }
    100% {
        background-position: 0 -1122px
    }
}

/*fish.css*/
@CHARSET "UTF-8";
#fishBody {
    position: fixed;
    height: 100vh;
    max-width: 100vw;
    overflow: hidden;
    margin: 0 auto;
    width:  100%;
    background: url(../images/fish/5bj.jpg) no-repeat center top;
    background-attachment: fixed;
    background-size:  cover;
}

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSS3制作捕鱼达人游戏场景动画特效 - A5源码</title>
<link rel="stylesheet" href="style/index.css">
</head>
<body>
<div id="fishBody">
    <div class="aquarium">
        <div class="fishGroup">
            <div class="fish_wrap left_right_2"><div class="x"><div class="y"><div class="fish_box"><div class="fish_1"></div></div></div></div></div>
            <div class="fish_wrap left_right_2"><div class="x"><div class="y"><div class="fish_box"><div class="fish_1"></div></div></div></div></div>
            <div class="fish_wrap left_right_2"><div class="x"><div class="y"><div class="fish_box"><div class="fish_1"></div></div></div></div></div>
            <div class="fish_wrap left_right_2"><div class="x"><div class="y"><div class="fish_box"><div class="fish_1"></div></div></div></div></div>
        </div>
        <div class="fishGroup">
            <div class="fish_wrap right_left_4"><div class="x"><div class="y"><div class="fish_box"><div class="fish_2"></div></div></div></div></div>
            <div class="fish_wrap right_left_4"><div class="x"><div class="y"><div class="fish_box"><div class="fish_2"></div></div></div></div></div>
            <div class="fish_wrap right_left_4"><div class="x"><div class="y"><div class="fish_box"><div class="fish_2"></div></div></div></div></div>
            <div class="fish_wrap right_left_4"><div class="x"><div class="y"><div class="fish_box"><div class="fish_2"></div></div></div></div></div>
        </div>
        <div class="fishGroup">
            <div class="fish_wrap right_left_4"><div class="x"><div class="y"><div class="fish_box"><div class="fish_2"></div></div></div></div></div>
            <div class="fish_wrap right_left_4"><div class="x"><div class="y"><div class="fish_box"><div class="fish_2"></div></div></div></div></div>
            <div class="fish_wrap right_left_4"><div class="x"><div class="y"><div class="fish_box"><div class="fish_2"></div></div></div></div></div>
            <div class="fish_wrap right_left_4"><div class="x"><div class="y"><div class="fish_box"><div class="fish_2"></div></div></div></div></div>
        </div>
        <div class="fishGroup">
            <div class="fish_wrap left_right_3"><div class="x"><div class="y"><div class="fish_box"><div class="fish_6"></div></div></div></div></div>
            <div class="fish_wrap left_right_3"><div class="x"><div class="y"><div class="fish_box"><div class="fish_6"></div></div></div></div></div>
        </div>
        <div class="fishGroup">
            <div class="fish_wrap left_right_1"><div class="x"><div class="y"><div class="fish_box"><div class="fish_7"></div></div></div></div></div>
            <div class="fish_wrap left_right_1"><div class="x"><div class="y"><div class="fish_box"><div class="fish_7"></div></div></div></div></div>
        </div>
        <div class="fish_wrap right_left_3">
            <div class="x">
                <div class="y">
                    <div class="fish_box">
                        <div class="fish_8">
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div class="fish_wrap right_left_1">
            <div class="x">
                <div class="y">
                    <div class="fish_box">
                        <div class="fish_9">
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div class="fish_wrap right_left_2">
            <div class="x">
                <div class="y">
                    <div class="fish_box">
                        <div class="fish_10">
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

</body>
</html>
复制代码
分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改