言うまでもなく、H5 は現在非常に人気があり、さまざまなアイデアや効果が次々と登場しています。しかし、H5 テクノロジーの導入に関する記事は非常に少なく、多くの学生が不安を感じています。混乱した。この記事は、マルチスクリーン CSS アニメーション テクノロジの実装から始まり、H5 テクノロジの実装に関するいくつかのアイデアを提供できると思います。
現在、CSS3 は広く使用されており、その重要なメンバーの 1 つが CSS3 アニメーションです。さらに、CSS アニメーションの徐々に深化と普及が進むにつれ、より複雑で繊細なアニメーション シーンが春の雨後の筍のように湧き出てきます。たとえば、先月の「Corporate QQ-New Year’s Blessing」アクティビティ:
上記のビデオの録画を手伝ってくれた Shirley に感謝します。ビデオ コンテンツは携帯電話での表示効果ですが、この「Corporate New.年の祝福活動」は当初デスクトップ側のみでしたが、後にモバイル側にも補助的な機能強化(アクティブページの UV の 5.7% に相当するクリック数の増加)が追加されました。現在、他の同僚によって実装された QQ Space 5.0 予約ページの第 2 バージョンなど、ほとんどの同様のページはモバイル デバイス専用です。
QR コードをスキャンします (ログインが必要です)。いずれかのリンクを選択してください:
ここをクリックしてデモにアクセスしてください
したがって、もう少し適応スキルが必要です。ただし、アニメーション効果の実装も実際には同じ起源を持ち、最終的な実装には多くの蓄積が必要ですが、一部の学生は知らないかもしれない 3 つの関連する CSS テクニックについて説明します。
注: サンプル コードのプライベート プレフィックスは省略されています。ご自身で判断してください
1. クラス名 アクティブとアニメーションのトリガー まず、各画面でアニメーションをトリガーするためにアクティブを使用することは、ほぼ一般的な手法になっており、デフォルトの業界標準となることも推奨されます。
一般的なアプローチは、JS を使用してクラス名をアクティブに追加することです。
container.classList.add("active");
作成したアニメーションが高品質であれば、このコンテンツを閲覧するたびに、
container.classList.remove("active");container.offsetWidth = container.offsetWidth;container.classList.add("active");
2. クラス名アクティブおよびアニメーション制御手法を使用してアニメーションの再生を具体的に制御するにはどうすればよいですか?通常、私たちの最初の反応は、アニメーションの完全な CSS コードがアクティブな状態で表示される次のメソッドを使用することです。
.element1 { /* 尺寸与定位 */ }.element2 { /* 尺寸与定位 */ }.element3 { /* 尺寸与定位 */ }....active .element1 { animate: name1 1s; }.active .element2 { animate: name2 1s; }.active .element3 { animate: name2 1s; }...
実装と機能の点では、上記のメソッドは非常に優れています。理解しやすく、間違いが起こりにくくなります。ただし、個人的には CSS3 で anime-play-state 属性を使用して各画面アニメーションを制御することを好みます。実装は次のとおりです。
アニメーション関連の CSS コードは、要素:
.element1 { /* 尺寸与定位 */ animate: name1 1s; }.element2 { /* 尺寸与定位 */ animate: name2 1s; }.element3 { /* 尺寸与定位 */ animate: name3 1s; }...
.animate などのクラス名を作成し、このクラス名をアニメーションを使用するすべての要素に追加します。 >次の CSS コード:
私が個人的に後者の方法を好む理由は、「押し付けがましくない」感覚があり、コードレベルが明確であり、制御関係が明確です。後のメンテナンスや拡張に役立ちます。
.animate { animation-play-state: paused;}.active .animate { animation-play-state: running;}
は CSS ステートメント全体をハングさせるだけです。次の記述方法がサポートされています。
.element { animate: shake 4s 2s both infinite paused; }
ヒント 2. さまざまな状態での連続アニメーション
.element { animate: shake 4s 2s both infinite; animation-play-state: paused;}
場合によっては、アニメーションが波ではなく、複数の状態に分割されることがあります。
ポイントはアニメーションの分解と遅延です。
私の知る限り、1 つのキーフレーム宣言だけを使用してこの効果を実現する方法はありません。1 回だけ実行されるアニメーションと無限ループ アニメーションというアニメーションの状態に変化があるためです。
どうすればいいですか?アニメーションを分解して、2 つのアニメーション キーフレームのアニメーション キーフレームの説明を書くことができます。
次に、これらのキーフレーム アニメーションを個別に適用します。どうやって応用すればいいのでしょうか?ヒントは 2 つあります:
1. カンマとマルチアニメーションの値は次のとおりです:
@keyframes fadeIn { /* ... */ }@keyframes float { /* ... */ }
ここで、float .5s 1s 無限、1s はアニメーションの実行遅延時間です。無限に浮遊するアニメーションなので、2 つのアニメーションが完全に連動し、1 つのアニメーションのように感じられます。実際、これは単なるアニメーションです。これが、CSS を使用してアニメーション効果を実現することをお勧めする理由です。
この書き方には互換性の問題はなく、誰でも快適に使用できます。
<div class="element">小火箭</div>.element { animation: fadeIn 1s, float .5s 1s infinite; } /* 我淡出, 需要1秒;我1秒后开始无限漂浮 */
2. ラベルのネストと独立したアニメーション ネストされたラベルを通じて連続アニメーションを実装することもできます。たとえば、
驚く人もいるかもしれません。アニメーション自体は、複数のアニメーションの並列処理をサポートしています。タグをネストしたい場合は、それを使用する必要はありません。はい、この例を見てみると、まさにその通りです。しかし:
① 提取公用动画这类多屏动画是有N多元素同时执行不同的动画。比方说,火箭是淡出,然后上下漂浮;火箭的火焰是淡出,然后大小变化;黑洞是淡出,然后左右随波。你如何实现?
如果纯粹借助animation语法,应该是:
.element1 { animation: fadeIn 1s, float .5s 1s infinite; } /* 我淡出, 需要1秒;我1秒后开始无限漂浮 */.element2 { animation: fadeIn 1s, size .5s 1s infinite; } /* 我淡出, 需要1秒;我1秒后开始大小变化 */.element3 { animation: fadeIn 1s, move .5s 1s infinite; } /* 我淡出, 需要1秒;我1秒后开始左右移动 */
可以看到,淡出是公用的动画效果,我们可以借助嵌套标签,实现公用语法的合并,方面后期维护:
.element-wrap { animation: fadeIn 1s; } /* 大家都1秒淡出 */.element1 { animation: float .5s 1s infinite; } /* 我1秒后无限漂浮 */.element2 { animation: size .5s 1s infinite; } /* 我1秒后忽大忽小 */.element3 { animation: move .5s 1s infinite; } /* 我1秒后左右移动 */
②避免变换冲突有个元素动画是边360度旋转、边放大(从0放大到100%),像这种具有典型特征的动画我们显然要独立提取与公用的:
@keyframes spin { /* transform: rotate... */ }@keyframes zoomIn { /* transform: scale... */ }
好了,现在问题来了,变放大边旋转:
.element { animation: spin 1s, zoomIn 1s; } /* 旋转:啊,完蛋啦,我被放大覆盖啦! */
由于都是使用transform, 发生了残忍的覆盖。当然,有好事的人会说,你使用zoom不就好了!确实,如果只是移动端,使用zoom确实棒棒哒!但是,我们这个企业活动,PC是主战场,因此,FireFox浏览器(FF不识zoom)是不能无视的。
怎么办?重新建一个名为spinZoomIn的动画关键帧描述还是?对啊,你直接外面套一层标签不就万事大吉了。
.element-wrap { animation: spin 1s; } /* 我转转转 */
.element { animation: zoomIn 1s; } /* 我大大大 */
1. 这里的“无侵入定位”指不受animation影响的元素定位,包含两部分:一是不使用keyframes关键帧决定初始位置;二是不要使用keyframes中出现的属性定位。
①. 不使用keyframes决定初始位置应该都知道,css3animation的fill-mode可以决定元素动画结束前后的位置,也就是也具有定位的作用。此时,可能就会有小伙伴,故作聪明,利用animation keyframes 0% {}或form{}去做定位,貌似,还省了写代码。看上去很赞,实际上狭隘了,这对于对animation支持不佳或不支持的浏览器实际上是不友好的,例如Android2.3不支持animation-fill-mode, IE6-IE9不支持css3 animation,于是乎,当遭遇这些浏览器的时候,页面动画元素的布局实际上是毁掉的。所以,这些动画元素定位的时候,需要使用“无侵入定位”,也就是,就算页面没有animation, 我也是个“标致人儿”。
②. 不使用keyframes中出现的属性定位举个例子,有个球,正好定位在模块的中心,同时有个无限旋转效果。使用transform: translate(-50%,-50%)居中定位再合适不过了,不用我心里难受,于是,使用了transform定位。此时,冲突发生,旋转动画也是需要transform变换的。
@keyframes spin { 0% { transform: rotate(0); } 100% { transform: rotate(360deg); }}
要么使用业界约定俗成spin覆盖,要么另起炉灶没法重用:
@keyframes spin-trans { 0% { transform: rotate(0) translate(-50%,-50%); } 100% { transform: rotate(360deg) translate(-50%,-50%); }}
显然,都是不合适的。建议使用传统left/top/margin进行定位,与transform变换动画“无侵入”。
2. 这里的“居中定位准则”包含两部分:一是元素定位在容器中间位置;二是元素的定位方式为居中定位。
①. 元素定位在容器中间容器以及容器内的动画元素可以看成是一个动画模块,为了这个模块可以轻松驾驭水平布局和垂直局部,里面的动画元素形成的整体一定要在容器的中间,不要被设计稿或周围环境影响。
举个简单例子,本文一开始展示的「企业QQ-新年祝福」活动。
企业产品用户特点比较鲜明:一是访问主要集中在桌面端,二是有70~80%用户使用的是webkit/blink内核浏览器。所以,大家可以理解为何设计稿明明针对桌面端,却有如此多细腻的动画设计了。
故事是这样的,桌面版做好了,1024-1224自适应,IE7以上都兼容(无侵入定位准则)(除了没动画),好棒!此时负责视觉的晓玲同学希望也能适配移动端,可以增加一定的传播,我觉得挺好的,于是,决定通过技术手段,让活动页面能游走于桌面和移动之间,同时,保证各种动画效果棒棒哒!
结果,发现自己留了一个坑,拿第2屏举例,桌面版,长这样,右侧动画内容并不是完全居中的:
本着高度还原设计稿的原则,所有动画元素都经过测量定位,按照PSD中的参考线左上角(left/top),结果整体左侧冒出60像素:
于是,问题来了,当移动端做响应式适配时候,由于容器内的动画元素不是居中的,所以——
后来,进行了修改,内部动画元素整体居中,外部容器桌面端做左侧60像素偏移,于是,适配移动端时候,就正好是居中的啦。
②. 定位方式为居中定位所谓“居中定位”是相对“传统定位”而言的。Web页面中的模块、文字什么的默认都是相对于左上角堆砌的,所以,很自然地,我们在重构页面,做布局,写交互效果的时候,也都是相对左上角定位。活用元素本身的定位特性,这是很赞的也推荐这么做!但是,如果你和多元素CSS动画打交道,可能就需要改变下惯性思维了,很重要的一点就是“从以左上角为参考点变成以中心点为参考点”。
我们在实现多元素动画效果时候,会出现两类角色:一是容器;二是容器里面诸多动画元素。
其中,对于容器元素,尤其在做移动端产品时候,我们很自然会让其居中定位:
.container { position: absolute; left: 50%; top: 50%; transform: translate3d(-50%, -50%, 0);}
这样,各种尺寸的手机,我们都能让其居中显示(大尺寸可能需要一定的缩放)。
但是,我们有没有想过让容器里面的诸多动画元素也居中定位显示呢?
用代码来解释就是从左上角定位(或右上角定位):
.example { position: absolute; left: 100px; top: 100px;}
变成中心点定位+ margin偏移:
.example { position: absolute; left: 50%; top: 50%; margin-left: -100px; margin-top: -100px;}
有同学可能要疑问了,why? 前面一步到位不挺好的,后面这样分两步走岂不是多余?
在大多数情况下,我们的应用场景比较单一,或只需要玩转移动端,或只需要驾驭桌面端,此时,上面两种定位的优劣是看不出来的。
但是,遇到一些复杂的应用场景,尤其涉及到容器尺寸或定位方式改变的时候,后面的定位优势就可以看出来。
比方说一开始提到的qzone5.0的例子,如果我们把容器宽度加大(实际是不会的,示意目的),如414像素:
会发现,宇航员和飞船在小行星之外了,也就是动画元素不是聚拢状态了。
所以,大家看出居中定位的优势来了没有:
动画元素之间的位置关系不受容器尺寸影响;
居中特性遭遇多场景时适应性更强;
还是拿去年年底做的「企业QQ-新年祝福」活动举例,第8屏:
其中,中间的“王强”和“马老板”这些数据有可能是没有的,也就是很有可能这一屏只有文字和宇航员,但同时还要保持整体垂直居中。很显然,宇航员和火箭所在的容器不能是绝对定位,否则脱离文档流,不能和上面元素保持合适垂直间距同时垂直居中。我们仍然有2种实现方法:
固定容器宽度,例如350像素宽,然后,里面左上角定位等,本身margin: auto水平居中;
容器不设定width大小,直接里面动画元素居中定位;
方法1问题在于:
第7屏是类似结构,但是其动画容器宽度不是350像素,没法重用;
当在iPhone5/iPhone5s下,屏幕320像素宽(小于350像素),由于左上角定位,因此,整体不是居中效果;
而方法2,屏幕尺寸再小,也是居中的,只不过两侧有所剪裁。最终,移动端适配时候,我们不必关心定位问题,只要合适缩放就可以了。
以上两屏示意demo戳这里
首先,大家要明白,本文所展示的三个技术技巧属于个人经验建议,注意,是建议。里面所提到的所有解决方法都有更加直观、通俗的实现,对于大多数的产品而言,技术的价值体现已经足够;同时应用场景千千万,没有什么一方通行的方法,例如居中定位准则,有时候,可能就是需要非居中定位。
但是,作为一个有技术追求的技术从业人员,对技术的精益求精一定是有价值的,无论是对自己,还是公司。有人可能会反驳,我们这个项目明明只会针对移动端,你还花心思考虑低配的事情,岂不是白白浪费时间和人力成本。古人有云:“不以善小而不为”,这种去粗取精的小经验虽然看上去没什么实质性成长,对眼前项目也没多少价值体现,但是积累足够多,会产生质变的,填坑的事情少了,工作也更轻松与快乐,对公司产生的价值也更大。
高瞻远瞩积跬步,登峰造极至千里。
好了,以上就是自己对于多屏CSS动画方面的一些技巧体会,希望可以对大家的学习有所帮助。当然,资历有限,要是文中有什么表述不准确的地方,欢迎指正;也欢迎针锋相对的讨论,共同成长。
元のリンクこの記事はインターネットからのものです。あなたの権利が侵害されている場合は、時間内に QQ: 123464386 にご連絡ください。できるだけ早く対応いたします。