Heim  >  Artikel  >  Web-Frontend  >  Tipps und Details zur CSS-Animation

Tipps und Details zur CSS-Animation

巴扎黑
巴扎黑Original
2017-09-20 09:45:191816Durchsuche

Dieser Artikel soll einige weniger häufig verwendete CSS-Techniken vorstellen, ergänzt durch einige Praktiken, damit die Leser ein tieferes Verständnis der CSS-Animationseffekte erlangen können. Freunde, die es benötigen, können darauf verweisen

Ich fürchte, der Titel ist etwas zu groß. Wenn Sie die folgenden Fähigkeiten beherrschen, werfen Sie bitte einen Blick darauf. Dieser Artikel soll einige weniger häufig verwendete CSS-Fähigkeiten vorstellen Praktiken, damit die Leser die CSS-Animation besser verstehen und beherrschen können.

Kommen wir ohne weitere Umschweife zur Sache. Die in diesem Artikel erwähnten Animationen beziehen sich alle auf CSS-Animationen ohne besondere Erklärung.

Positive und negative Drehungen heben sich gegenseitig auf

Hmm. Der Name ist sehr seltsam, wie ein mathematisches Konzept.

Rotation ist ein sehr häufig verwendetes Attribut


{
  transform: rotate(90deg);
}

Welche fortgeschrittenen Techniken für die Rotation gibt es? Natürlich können Sie transfrom-origin ändern, um den Drehmittelpunkt zu ändern.

Nur ​​ein Scherz, wahrscheinlich weiß jeder, wie man den Rotationsmittelpunkt ändert. Die Technik, die ich hier vorstellen möchte, besteht darin, die positive und negative Rotation des übergeordneten Elements zu nutzen, um einige coole 3D-Effekte zu erzeugen.

Nehmen Sie zunächst das Szenario an. Wir haben eine solche Ebene der HTML-Struktur:


<p class="reverseRotate">
    <p class="rotate">
        <p class="content">正负旋转相消3D动画</p>
    </p>
</p>

Der Stil ist wie folgt:

.content ist unser Hauptinhalt. Stellen Sie sich nun vor, dass das Vorgängerelement .rotate eine lineare 360°-Drehung nach vorne durchführt und das übergeordnete Element .reverseRotate eine lineare 360°-Drehung nach hinten durchführt. Was ist der Effekt?

Der CSS-Code lautet wie folgt:


.rotate {
    animation: rotate 5s linear infinite; 
}
.reverseRotate {
    animation: reverseRotate 5s linear infinite; 
}
@keyframes rotate {
    100% {
        transform: rotate(360deg);
    }
}
@keyframes reverseRotate {
    100% {
        transform: rotate(-360deg);
    }
}

Erstaunlich! Da sich einer vorwärts und der andere rückwärts dreht und die Beschleunigungsfunktion dieselbe ist, sieht das gesamte content immer noch wie ein stationärer aus! Beachten Sie, dass es sehr wichtig ist, dass das gesamte content stillsteht.

Einige Leser werden verfluchen, wenn sie das sehen, Sie sind ein zurückgebliebener Mensch. Wenn Sie aufhören, gibt es dann keine Animation? Woher haben Sie Ihre Animationsfähigkeiten?

Keine Sorge! Obwohl es stationär aussieht, drehen sich tatsächlich beide Elemente des Vorfahren! Dies mag wie ein beruhigender Effekt erscheinen, doch dahinter verbirgt sich tatsächlich eine Unterströmung. Die Verwendung der Entwicklertools zum Auswählen des äußersten Vorfahrenelements sieht folgendermaßen aus:

In diesem Fall denken wir weiter darüber nach, ob ich einem Vorfahrenelement einige andere Elemente hinzufüge das gedreht wird. Welchen Effekt wird die Animation haben? Es ist aufregend, nur darüber nachzudenken.

Um einen Bezug zur 3D-Animation in der Kopie herzustellen, fügen wir zunächst 3D-Transformationen zu diesen Elementen hinzu:


p {
    transform-style: preserve-3d;
    perspective: 500px;
}

Versuchen Sie dann, sie zu ändern Fügen Sie für die obige Rotationsanimation eine zusätzliche Rotation hinzu. >Wow, das muss sorgfältig verstanden werden. Da die Inhaltsebene

statisch ist, sich die beiden äußeren Ebenen jedoch tatsächlich drehen, entspricht das Festlegen von zusätzlichem

dem Überlagern einer weiteren Animation. Da die Vorwärts- und Rückwärtsdrehungen versetzt sind, kann die gesamte Animation nur angezeigt werden Die Animation des rotierenden
erzeugt den oben genannten Effekt.

@keyframes rotate {
    0% {
        transform: rotateX(0deg) rotateZ(0deg);
    }
    50% {
        transform: rotateX(40deg) rotateZ(180deg);
    }
    100% {
        transform: rotateX(0deg) rotateZ(360deg);
    }
}
CodePen-Demo – Destruktive CSS-Animation mit positiver und negativer Rotation

Die Animation ist die gleiche, aber die Lockerung ist anders

Okay, fahren wir mit dem nächsten Tipp fort.

Manchmal gibt es auf unserer Seite einige Elemente mit derselben Animation. Um die Animation weniger starr zu machen, können wir derselben Animation verschiedene Beschleunigungsfunktionen zuweisen, um den Animationseffekt zu erzielen. contentrotateX(40deg)Angenommen, wir haben die folgende Struktur: rotateX(40deg)

Der Stil ist wie folgt:

Wir geben ihnen die gleiche Animation, geben ihnen aber unterschiedliche Beschleunigungsfunktionen (Animations-Timing-Funktion), wie folgt:


<p class="container">
    <p class="ball ball1"></p>
    <p class="ball ball2"></p>
    <p class="ball ball3"></p>
</p>

Auf diese Weise ein einfaches Laden Der Effekt wird erzeugt. (Natürlich ist diese Technik relativ einfach, das Erlernen der richtigen Anwendung ist der Schlüssel)

CodePen-Demo – Die Animation ist die gleiche, aber die Lockerung ist anders


Wunderbare Lockerung
.ball1 {
    animation: move 1s ease-in infinite alternate;
}
.ball2 {
    animation: move 1s linear infinite alternate;
}
.ball3 {
    animation: move 1s ease-out infinite alternate;
}
@keyframes move {
    100% {
        transform: translateY(5vw);
    }
}

Die Timing-Funktion der Lockerungsfunktion nimmt in der Animation eine sehr wichtige Stellung ein.

Wenn Sie

,

,

und andere standardmäßig in CSS bereitgestellte Beschleunigungsfunktionen nicht verwenden möchten, können Sie anpassen , unten Auf dieser Website können Sie ganz einfach die benötigte Beschleunigungsfunktion aufrufen und den entsprechenden Kubikbezier erhalten. cubic-bezier.com

Übergang abgesagt

linearease-in

我们在制作页面的时候,为了让页面更加有交互感,会给按钮,阴影,颜色等样式添加过渡效果,配合 hover 一起使用。

这个是常规思维,如果我们的元素一开始是没有过渡效果,只有 hover 上去才给它添加一个过渡,又或者一开始元素是有过渡效果的,当我们 hover 上去时,取消它的过渡,会碰撞出什么样的火花呢?

使用这个技巧(也许算不上技巧,纯粹好玩),我们可以制作出一些有趣的效果,例如下面这个感觉是利用就 JS 才完成的动画,其实是纯 CSS 动画:

其实就小圆圈是元素默认是带有 transition 的,只有在 hover 上去的时候,取消它的过渡,简单的过程:

  • 由于一开始它的颜色的透明的,而 hover 的时候会赋予它颜色值,但是由于 hover 时过渡被取消了,所有它会直接显示。

  • hover 离开的时候,它的原本的过渡又回来了,这个时候它会从有颜色到透明值缓慢渐变消失。

可以戳这里感受一下:

CodePen Demo -- Cancle transition

动画层级的控制,保持动画层级在最上方

这个问题可能有一点难理解。需要了解 CSS 动画渲染优化的相关知识。

先说结论,动画层级的控制的意思是尽量让需要进行 CSS 动画的元素的 z-index 保持在页面最上方,避免浏览器创建不必要的图形层(GraphicsLayer),能够很好的提升渲染性能。

OK,再一次提到了图形层(GraphicsLayer),这是一个浏览器渲染原理相关的知识(WebKit/blink内核下)。

简单来说,浏览器为了提升动画的性能,为了在动画的每一帧的过程中不必每次都重新绘制整个页面。在特定方式下可以触发生成一个合成层,合成层拥有单独的 GraphicsLayer。

需要进行动画的元素包含在这个合成层之下,这样动画的每一帧只需要去重新绘制这个 Graphics Layer 即可,从而达到提升动画性能的目的。

那么一个元素什么时候会触发创建一个 Graphics Layer 层?从目前来说,满足以下任意情况便会创建层:

  • 硬件加速的 iframe 元素(比如 iframe 嵌入的页面中有合成层)

  • 硬件加速的插件,比如 flash 等等

  • 使用加速视频解码的 元素

  • 3D 或者 硬件加速的 2D Canvas 元素

  • 3D 或透视变换(perspective、transform) 的 CSS 属性

  • 对自己的 opacity 做 CSS 动画或使用一个动画变换的元素

  • 拥有加速 CSS 过滤器的元素

  • 元素有一个包含复合层的后代节点(换句话说,就是一个元素拥有一个子元素,该子元素在自己的层里)

  • 元素有一个 z-index 较低且包含一个复合层的兄弟元素

本题中说到的动画层级的控制,原因就在于上面生成层的最后一条:

元素有一个 z-index 较低且包含一个复合层的兄弟元素。

这里是存在坑的地方,首先我们要明确两点:

  1. 我们希望我们的动画得到 GPU 硬件加速,所以我们会利用类似 transform: translate3d() 这样的方式生成一个 Graphics Layer 层。

  2. Graphics Layer 虽好,但不是越多越好,每一帧的渲染内核都会去遍历计算当前所有的 Graphics Layer ,并计算他们下一帧的重绘区域,所以过量的 Graphics Layer 计算也会给渲染造成性能影响。

记住这两点之后,回到上面我们说的坑。

假设我们有一个轮播图,有一个 ul 列表,结构如下:


e8f5c74c2e445a663d1be11ec1ea30fb
    ab7863aa92413627b6d3a3f990074b6f轮播图94b3e26ee717c64999d7867364b1b4a3
    74208dc2409290cdfcb863d04dbdcf53
        25edfb22a4f469ecb59f1190150159c6列表libed06894275b65c1ab86501b08a632eb
        25edfb22a4f469ecb59f1190150159c6列表libed06894275b65c1ab86501b08a632eb
        25edfb22a4f469ecb59f1190150159c6列表libed06894275b65c1ab86501b08a632eb
        25edfb22a4f469ecb59f1190150159c6列表libed06894275b65c1ab86501b08a632eb
    929d1f5ca49e04fdcb27f9465b944689
94b3e26ee717c64999d7867364b1b4a3

假设给他们定义如下 CSS:


.swiper {
    position: static;
    animation: 10s move infinite;
} 
.list {
    position: relative;
}
@keyframes move {
    100% {
        transform: translate3d(10px, 0, 0);
    }
}

由于给 .swiper 添加了 translate3d(10px, 0, 0) 动画,所以它会生成一个 Graphics Layer,如下图所示,用开发者工具可以打开层的展示,图形外的黄色边框即代表生成了一个独立的复合层,拥有独立的 Graphics Layer 。

<

但是!在上面的图中,我们并没有给下面的 list 也添加任何能触发生成 Graphics Layer 的属性,但是它也同样也有黄色的边框,生成了一个独立的复合层。

原因在于上面那条元素有一个 z-index 较低且包含一个复合层的兄弟元素。我们并不希望 list 元素也生成 Graphics Layer ,但是由于 CSS 层级定义原因,下面的 list 的层级高于上面的 swiper,所以它被动的也生成了一个 Graphics Layer 。

使用 Chrome,我们也可以观察到这种层级关系,可以看到 .list 的层级高于 .swiper

所以,下面我们修改一下 CSS ,改成:


.swiper {
    position: relative;
    z-index: 100;
}   
.list {
    position: relative;
}

这里,我们明确使得 .swiper 的层级高于 .list ,再打开开发者工具观察一下:

可以看到,这一次,.list 元素已经没有了黄色外边框,说明此时没有生成 Graphics Layer 。再看看层级图:

此时,层级关系才是我们希望看到的,.list 元素没有触发生成 Graphics Layer 。而我们希望需要硬件加速的 .swiper 保持在最上方,每次动画过程中只会独立重绘这部分的区域。

总结

  • GPU 硬件加速也会有坑,当我们希望使用利用类似 transform: translate3d() 这样的方式开启 GPU 硬件加速,一定要注意元素层级的关系,尽量保持让需要进行 CSS 动画的元素的 z-index 保持在页面最上方。

  • Graphics Layer 不是越多越好,每一帧的渲染内核都会去遍历计算当前所有的 Graphics Layer ,并计算他们下一帧的重绘区域,所以过量的 Graphics Layer 计算也会给渲染造成性能影响。

  • 可以使用 Chrome ,用上面介绍的两个工具对自己的页面生成的 Graphics Layer 和元素层级进行观察然后进行相应修改。

  • 上面观察页面层级的 chrome 工具非常吃内存?好像还是一个处于实验室的功能,分析稍微大一点的页面容易直接卡死,所以要多学会使用第一种观察黄色边框的方式查看页面生成的 Graphics Layer 这种方式。

数字动画

很多技巧单独拿出来可能都显得比较单薄,我觉得最重要的是平时多积累,学会融会贯通,在实际项目中灵活组合运用,最近项目需要一个比较富有科技感的数字计数器,展示在线人数的不断增加。因为是内部需求,没有设计稿,靠前端自由发挥。

运用了上面提到的一些小技巧,参考了一些 CodePen 上的效果,整了个下述的 3D 数字计数效果,纯 CSS 实现,效果图如下:

Das obige ist der detaillierte Inhalt vonTipps und Details zur CSS-Animation. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn