CSS portal_html/css_WEB-ITnose

WBOY
リリース: 2016-06-24 11:16:26
オリジナル
1517 人が閲覧しました

ブラウザでスリリングな 3D 効果プロジェクトを構築するために、必ずしも JavaScript を使用する必要はありません。この記事では、純粋な CSS で実装された複雑なアニメーション効果を紹介します。

ポータルオンラインデモアドレス、Githubソースコードアドレス

オリジナルビデオ

ビデオは、3Dアニメーションシーンの構築、美化、アニメーション効果を示しています。この記事では、CSS3 を使用してこのポータル ビデオを再描画します。登場人物がドアからドアへ渡っていく過程に注目してください。以下は元のビデオです:

このビデオは、最初にリリースされたとき、私の心に深く刻み込まれました。 Portal (Narbacular Drop の作成者) は、楽しい 3D プラットフォームのパズル ゲームを紹介します。

ビデオでは、このゲームで戦利品を取得する方法が以前のゲームとは異なることがわかります。この記事では、HTML と CSS のみを使用してこのシナリオを再現できるかどうかを試してみます。

下の写真は作成予定のシーンです。

はじめに

CSS を作成する際には、プレフィックス フリーまたは SASS を使用することをお勧めします。これにより、CSS を記述するときにプレフィックスを繰り返し記述する必要がなくなります。さらに、さまざまなブラウザーでの互換性プレフィックスの問題にも注意してください。完全なソース コード、CSS、SASS、HTML は Github にあります。

規約

私たちのプロジェクトはChromeで開発およびテストされており、Internet Explorerブラウザとは互換性がありません。コードに含まれるいくつかの興味深い 3D アニメーション テクノロジは、現在主流ではありませんが、将来のフロントエンド開発において無視できない重要性を持っています。

準備

まず、HTML でコンテナを作成し、3D シーンのコンテンツをここに配置することをブラウザーに伝えます。

<article class="container"></article>
ログイン後にコピー

ここでは、これが独立したコンテンツであることを示すために HTML5 のarticle タグを使用します。
最初に言及したい特性は遠近感です。このプロパティの値は、3D シーンの被写界深度をピクセル値として表します。通常の設定範囲は800px~1200pxです。

このシーンは私たちにとって大きな家のように感じられます。視点の値を 2600px に設定し、接頭辞を無視して次のように記述します。

article.container { perspective: 2600px;}
ログイン後にコピー

消失点

このコンテナには Z 軸の被写界深度があります。私たちは決断する必要があります。その視点をチェックしてください。パースペクティブオリジン属性を設定することにより、消失点を設定し、上から下を見るか、片側から見るかを決定します。

.container { perspective-origin: 50% -1400px;}
ログイン後にコピー

perspective-origin この属性は、水平方向と垂直方向の 2 つの値に設定できます。ここでは水平方向を 50%、垂直方向を上方向に 1400 ピクセルに設定します。それは私たちが物体を下から見ているのと同じです。

この値はChromeブラウザのinspect要素と肉眼で調整して決定しました。必要なシーンを設定する場合、値はこの値よりも高い場合も低い場合もあります。表現したい効果によって異なります。また、この値はアニメーションやその他の興味深い視点変更効果に影響することに注意してください。

ベクトルはありません、Victor

HTML のオブジェクトは非常に普通の HTML 要素であり、幅と高さを備えた長方形です。これは、3D オブジェクトを作成するときに、これらの長方形を配置すべき場所に配置する必要があることを意味します。この方法は、点から線、そしてグラフィックへの方法とは異なります。つまり、円や立方体を使って描くことはできません。

3D シーンに HTML 要素を配置するには、transform 属性を使用する必要があります。

Graphic Transform

transform は、HTML 要素に対する一連の調整を実現できます。たとえば、要素を移動したり、角度を回転したり、傾けたり、ズームインまたはズームアウトしたりできます。これらの変換は積み重ねることができます。

.example { transform: rotateY(45deg) translateZ(-100px);}
ログイン後にコピー

このコードは、要素を Y 軸に沿って時計回りに 45 度回転させ、Z 軸に沿って 100 ピクセル戻すことを意味します。効果は次の図に示すとおりです。

transform-origin 属性

要素を回転したい場合は、開始点を設定する必要があります。これを実現するには、transform-origin 属性を使用します。パラメータ、つまり X 軸と Y 軸、Z 軸。

.default-origin { transform-origin: 50% 50% 0;}
ログイン後にコピー

この例では、特別な設定はせず、元のデフォルト値を保持していますが、そのような属性があることを知っておく必要があります。

始めましょう

レンダリングと組み合わせて、独自の 3D 傑作を組み立てます。 HTML と CSS を使用して 3D オブジェクトを構築することから始めましょう。私たちの方法と他の 3D ソフトウェアの違いを理解するには、少し時間を割く必要があります。

<section class="stage">  <div class="shadow"></div>  <div class="back-left"></div>  <div class="back-right"></div>  <div class="platform-left"><span></span></div>  <div class="platform-right"><span></span></div>  <div class="pit-left"></div>  <div class="pit-right"></div>  <div class="pit-back"></div></section>
ログイン後にコピー

stage は、シーン全体の壁、プラットフォーム、窪んだ場所、影の部分をすべての要素を保持するために使用します。

この形状を作成し始めたとき、壁をプラットフォームに直接配置し、回転して位置を調整しようとしましたが、形状は等長的に見えました。これを行うより簡単な方法は、最初に各パーツを配置してから、全体を 45 度傾けることです。

この考えにより、HTML は次の平面図になります。

写真のように、左リアは左側に、右リアは右側に揃います。この効果を実現するために、後で全体を 45 度回転させます。

.stage div { position: absolute; transform-style: preserve-3d;}
ログイン後にコピー
ログイン後にコピー

在使用变形之前,我们先给div添加公共的属性。

.stage div { position: absolute; transform-style: preserve-3d;}
ログイン後にコピー
ログイン後にコピー

每个div都设置为绝对定位,事先将transform-style设置为 3D 视图。

接下来我们就可以单独设置div的大小和位置了。

.stage .back-left { background-color: #6b522b; border-left: 6px solid #574625; border-top: 6px solid #8a683d; height: 120px; transform: rotateY(90deg) translateX(-256px); width: 500px;}
ログイン後にコピー

以上的规则描述了3D场景中的一个500像素宽,120像素高的浅棕色的一面墙。div沿着Y轴旋转90度,沿着X轴向后推,通过6像素的边框创造一个有景深的错觉。

back-right也设置类似的属性。

.stage .back-right { background-color: #9c7442; border-right: 6px solid #78552c; border-top: 6px solid #b5854a; height: 120px; transform: translateX(253px) translateZ(3px); width: 446px;}
ログイン後にコピー

这个div要更小一点,像视频中的那样,不那么方。

接下来,加一些平台,和凹陷。

.stage .platform-left { background-color: #bcb3a8; border-bottom: 6px solid #857964; height: 220px; transform: rotateX(90deg) translateY(396px) translateX(253px) translateZ(-13px); width: 446px;}.stage .platform-right { background-color: #bcb3a8; border-bottom: 6px solid #847660; border-right: 6px solid #554c3d; height: 164px; transform: rotateX(90deg) translateY(88px) translateX(253px) translateZ(-41px); width: 446px;}.stage .pit-left { background-color: #4d4233; height: 800px; transform: translate3D(254px, 125px, 285px); width: 447px;}.stage .pit-right { background-color: #847660; height: 800px; top: -1400px; transform: translate3D(254px, 125px, 173px); width: 451px;}.stage .pit-back { background-color: #6b522b; height: 220px; transform: rotateY(90deg) translate3D(-200px, 87px, 168px); width: 170px;}
ログイン後にコピー

目前我们的图形如下:

目前和目标图形不一样,我们还需要把它旋转一下,给section增加一个transform的属性。

.stage { margin: 0 auto; transform-style: preserve-3d; transform: rotateY(-45deg); width: 460px;}
ログイン後にコピー

效果如下:

你可能注意到了边框有一个很漂亮的景深的效果,特别是在边角的地方,颜色不同,有45度的旋转。
因为我们是斜45度看过去的,所以这个效果是很可能出现的。有个别的角落看着有出入,但考虑到我们直接用的边框,没有引用图片,有这个瑕疵,是可以忍受的。

关于影子

视频里,平台下面有一个很漂亮的阴影。我们可以使用CSS的属性 box-shadow 来实现。

.stage .shadow { background-color: transparent; box-shadow: -600px 0 50px #afa79f; height: 550px; transform: rotateX(90deg) translateZ(-166px) translateX(550px); width: 550px;}
ログイン後にコピー

给div加了一个盒阴影,阴影本身是透明的,与实体偏离600像素,整体偏离了stage,所以是可见的。效果如下:

红和蓝

接下来我们添加一些装饰和鲜艳的门。

两个入口使用HTML来表示。

<div class="portal red"></div><div class="portal blue"></div>
ログイン後にコピー

两个div,一个表示红色的门,一个表示蓝色的门。两个都分别设置一些过渡色来实现发光的效果。
因为只用了一个div元素,所以我们可以尝试使用CSS伪类来实现整体效果。

第一步,先创建一个门的形状。

.stage .portal { background-color: black; border-radius: 44px/62px; box-shadow: 0 0 15px 4px white; height: 72px; width: 48px;}
ログイン後にコピー

用 border-radius 属性实现椭圆形,白色阴影实现发光的效果。同时我们给伪类也定义相同的大小
和边框。

.stage .portal:before { border-radius: 44px/62px; border: 4px solid white; content: ""; display: block; height: 72px; margin-left: -4px margin-top: -4px; width: 48px;}
ログイン後にコピー

门的整体效果已经设置完了,之后我们需要分别设置蓝色的门和红色的门。

首先,红色的门:

.stage .portal.red { background: radial-gradient(#000000, #000000 50%, #ff4640 70%); border: 7px solid #ff4640; transform: translate3D(223px, 25px, 385px) rotateY(90deg) skewX(5deg);}.stage .portal.blue { background: radial-gradient(#000000, #000000 50%, #258aff 70%); border: 7px solid #258aff; transform: translate3D(586px, 25px, 4px) skewX(-5deg);}
ログイン後にコピー

红色的门,我们给了一个放射性渐变的颜色和一个红色边框。通过transform将其放置到左侧墙上。蓝色的门类似,放置到右侧墙上。测试的时候,两个看起来都有一些错位,所以我给他们加了5度的倾斜。

传送门的光

早先,我们就在两个平台里分别放了一个span标签。我们可以利用这个span来定义每个门下面的照射到平台上的光。

.stage .platform-left span { background: radial-gradient(left, #f3cac8, #c8b8ad 70px, #bcb3a8 90px); display: block; height: 200px; left: 0; position: absolute; width: 120px;}.stage .platform-right span { background: radial-gradient(top, #cdebe8, #c2cbc1 40px, #bcb3a8 60px); display: block; height: 60px; left: 280px; position: absolute; width: 150px;}
ログイン後にコピー

两个span都被绝对定位在门下方,一个红色光,一个蓝色光。其实伪元素也可以实现这个效果,
但是伪元素对动画的支持不好。

在右侧的墙上,需要一个门表示退出。你可能想像不到我们用边框就实现了这个效果。一个的div和有颜色的边框做了一个内凹的效果。

门的HTML放在stage 里。

<div class="door"></div>
ログイン後にコピー

给门设置几个边框,然后定位到右墙上。

.stage .door { background: #efe8dd; border-bottom: 6px solid #bcb3a8; border-left: 7px solid #78552e; height: 85px; transform: translate3D(450px, 34px, 4px); width: 65px;}
ログイン後にコピー

下边框和左边框与平面和右面墙重合,有一种景深的感觉。不设置上边框,左边框立在左侧,展示的效果也很好。

关于人物

有了传送门之后,我们需要有一个人物可以从一边到达另一边。第一步,先画一个人物。

刚开始的时候,我尝试了让一个人物从传送门进去,然后动画停止,立即从另一边继续。但当我让人物停止,在传送门之间移动的时候,会有闪烁。为了解决这个问题,我使用了2个人物,分别让他们移动。

创建人物

人物主要两部分组成,头部和身体。腿是用身体的伪类创建的。同理,创建一个人物的影子。

<div class="dude one">  <figure class="head"></figure>  <figure class="body"></figure>  <div class="dude-shadow one">    <figure class="head"></figure>    <figure class="body"></figure>  </div></div>
ログイン後にコピー

因为影子是人物的一部分,所以要同时移动。CSS如下:

.dude, .dude-shadow { height: 100px; width: 30px;}.dude figure, .dude-shadow figure { background-color: black; display: block; position: absolute;}.dude figure.head, .dude-shadow figure.head { border-radius: 22px; height: 20px; left: 3px; top: 0; width: 20px;}.dude figure.body, .dude-shadow figure.body { border-radius: 30px 30px 0 0; height: 30px; top: 21px; width: 26px;}.dude figure.body:before, .dude figure.body:after, .dude-shadow figure.body:before, .dude-shadow figure.body:after { background-color: black; content: ""; height: 15px; position: absolute; top: 30px; width: 9px;}.dude figure.body:before, .dude-shadow figure.body:before { left: 3px;}.dude figure.body:after, .dude-shadow figure.body:after { left: 14px;}
ログイン後にコピー

我们用这些样式来描述人物和影子。每个部分是绝对定位,border-radius 来设置圆角。腿用伪元素来定义,然后分别定义位置。

第一个人物

人物构建好了之后,将其定位到开始的位置。

.stage .dude.one { transform: translate3D(514px, 50px, 375px) rotateY(78deg);}.stage .dude-shadow.one { opacity: 0.1; transform: translateX(-12px) rotateX(90deg) translateY(8px);}
ログイン後にコピー

CSS 位置的变换既包含人物本身,也包含人物的影子,人物的透明度设置为0.1, 而不是设置成灰色,
这样做的好处是允许你看见影子后面的背景细节。

第一个人物现在在初始位置,参考视频,我们将人物旋转了一个相同的角度。稍后我们会加一些特效让他穿过传送门。

举起手来

第二个人物有更多的细节,手, 这个想法是人物穿越传送门时产生的,象征着他们举起手来庆祝。

以下是HTML代码:

<div class="dude two">    <figure class="head"></figure>    <figure class="body"></figure>    <figure class="arm left"></figure>    <figure class="arm right"></figure>    <div class="dude-shadow two">        <figure class="head"></figure>        <figure class="body"></figure>        <figure class="arm left"></figure>        <figure class="arm right"></figure>    </div></div>
ログイン後にコピー

第二个人物开始是透明的动画效果,然后在第一个人物动画效果开始的中途穿过传送门(第一个人物到达传送门),设置第二个人物定位在传送门。

.stage .dude.two { transform: translate3D(610px, 40px, 10px) rotateY(15deg);}.stage .dude.two figure.arm { background: black; height: 8px; position: absolute; top: 20px; width: 20px;}.stage .dude.two figure.arm.left { left: -13px; transform: rotateZ(40deg);}.stage .dude.two figure.arm.right { right: -10px; transform: rotateZ(-40deg);}.stage .dude-shadow.two { opacity: 0.1; transform: translateY(12px) translateX(-16px) translateZ(-6px) rotateZ(-90deg) rotateY(90deg) rotateZ(50deg) skewX(30deg) scaleX(0.8);}
ログイン後にコピー

第二个人物将会赋予他手, 手一开始是消失的,但是稍后会出现。

整体设置

当人物和背景都在出现在相应的位置, 这个场景已经准备好开始一些动画效果

让我们看看是怎么实现让它看起来像一个小人从第一个传送门到达第二个门。

动画

如果你看了示例,您会看到几个动画。但我将重点放在人物穿过门的动画,没有讲述所有的动画实现。

关键帧动画

通过使用keyframes来实现HTML的关键帧动画。然后用animation来执行一系列的关键帧动画。
第一件事是让人物从左边的传送门进入。下面是第一组关键帧:

@keyframes move-dude-one {  /* Character flies into scene */  0% { transform: translate3D(514px, -10px, 375px) rotateY(78deg) scaleY(2); }  /* Waits a moment */  1%, 18% { opacity: 1; transform: translate3D(514px, 50px, 375px) rotateY(78deg) scaleY(1); }  /* Moves toward the portal */  34%, 39% { opacity: 1; transform: translate3D(284px, 40px, 375px) rotateY(78deg); }  /* Pauses, them jumps in */  41%, 42% { opacity: 1; transform: translate3D(234px, 40px, 375px) rotateY(78deg); }  /* Vanishes */  43%, 100% { opacity: 0; transform: translate3D(234px, 40px, 375px) rotateY(78deg); }}/* Note: Use prefixes, such as @-webkit-keyframes, @-moz-keyframes, etc! */
ログイン後にコピー

关键帧是一系列的步骤,使用百分比来描述。百分比的设置会涉及到动画的时间。那么,如果一个动画持续10秒,10%设置为1秒。90%设置为9秒。

为了让人物完美的穿过传送门,我们每隔10秒设置一个动画。关于每个阶段的动画,我在代码中写了注释。
每个阶段都用了transform属性来设置人物的位置和角度。43%的时候,动画将人物的不透明度设置为0。这时将第一个人物在传送门消失。第二个人物出现。在我们这么做之前,让我们先把第一个动画加到第一个人物上:

.dude.one { animation: move-dude-one 10s linear infinite; opacity: 0;}
ログイン後にコピー

将animation属性应用到了due one元素上。设置了动画名称,动画时长10s,无限循环播放。为了确保角色在动画开始之前是隐藏的,不透明度设置成0。

完成之后,让我们为第二个人物进行相应的设置:

@keyframes move-dude-two {  /* Dude be invisible */  0%, 42% { opacity: 0; transform: translate3D(610px, 40px, 10px) rotateY(15deg); }  /* Apparato! */  42.5% { display: block; opacity: 1; transform: translate3D(610px, 40px, 10px) rotateY(15deg); }  /* Move onto the platform */  46%, 75% { opacity: 1; transform: translate3D(610px, 40px, 120px) rotateY(15deg); }  /* Stand there for a bit */  76%, 97% { opacity: 0; transform: translate3D(610px, -10px, 120px) rotateY(15deg) scaleY(2); }  /* Fly up into the sky! */  98%, 100% { opacity: 0; transform: translate3D(610px, -10px, 120px) rotateY(15deg) scaleY(2); }}@keyframes arms {  /* No arms */  0%, 53% { opacity: 0; }  /* Yes arms! */  54%, 100% { opacity: 1; }}
ログイン後にコピー

按计划,动画在42%的时候开始。这个人物穿过传送门,站了一会儿,然后飞向天空。
第二组关键帧动画描述它的手。手开始是看不见的,然后举了起来。      

我们给第二个人物添加了如下的动画:

.dude.two { animation: move-dude-two 10s linear infinite; opacity: 0;}.dude.two figure.arm { animation: arms 10s linear infinite; opacity: 0;}
ログイン後にコピー

两个动画设置完了,由于需要很好的配合第一个动画,都设置了持续10秒,无限循环。
如果你还没有完成,可以在主流浏览器中打开演示示例做参考,不过最好不要是Internet Explorer浏览器。

浏览器兼容性   

谈到浏览器兼容性的时候,需要注意的是,目前这个示例不兼容Internet Explorer。
Firefox有点瑕疵,但也还可以。Safari(苹果对webkit支持补丁之后)和chrome几乎是100%支持的。
抛开浏览器,在不同设备之间的展示效果。测试结果显示,iphone上的Safari比PC上的chrome效果要好。因为3D transforms的CSS属性,需要依赖于图形硬件。

源码下载

查看在线门户CSS演示或从Github下载源代码。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート