[Parallax Animation]实现知乎 Android 客户端启动页视差滚动效果_html/css_WEB-ITnose
原文地址:http://www.codefrom.com/c/198
前言
Parallax Scrolling (视差滚动),是一种常见的动画效果。视差一词来源于天文学,但在日常生活中也有它的身影。在疾驰的动车上看风景时,会发现越是离得近的,相对运动速度越快,而远处的山川河流只是缓慢的移动着,这就是最常见的视差效果。视差动画独有的层次感能带来极为逼真的视觉体验,iOS、Android Launcher、Website 都将视差动画作为提升用户视觉愉悦度的不二选择。
客户端应用第一次打开出现引导页也不是什么新鲜的事儿,ViewPager 配上几张设计师精心绘制的图片,分分钟即可了事。但是总有人把平凡的事情做到不平凡,如本文的知乎客户端,亦或是新浪微博贺岁版,百度贴吧某版等众多应用里都出现了视差动画的身影,随着用户手指的滑动,反馈以灵动、贴近真实的视觉以及操作体验,对应用的初始印象登时被提升到一个极高的点。
给我印象最深的是去年新浪微博的贺岁版,引导页是一系列的年画,里面有红色剪纸的小孩儿,滑动界面的时候感觉这些元素在『动』,是真正的灵动,能勾起人童年的回忆,年味儿十足。不过话说我年怎么过跟新浪微博一毛钱关系都没有,但是这个启动页却是深得我意。只是这个版本的微博找不到了,正好前两天看到知乎的启动页做的也不错,就正好拿来练练手吧。
本文就知乎 Android 客户端启动页面为例,教你如何实现视差滚动效果。
界面分析
细心把玩下知乎的启动页,不难分析出来,视差动画主要体现在背景层渐变、内容层元素差异滚动上,动画内容分别是:
- 内容:元素差异滚动,形成视差效果()
- 背景:随着界面的滑动,颜色由深蓝色渐变为浅蓝色()
- 文字:底部提示文案会随页面变动而切换,有简单的淡入淡出效果
- 界面动画:界面打开,元素的出场动画(第一页以及最后一页)
鉴于其它几项比较简单,本文主要讲视差动画以及背景渐变的实现,其它几项请自行参阅代码,见后文。
Parallax Scrolling
这里的视差滚动效果,主要表现为内容元素滚动速率的差异上。比如在 ViewPager 中滑动了 1px ,而 A 元素移动 2px , B 元素移动 1.5px ,这种移动差距的比率,我称之为 parallaxCofficient ,即 视差系数 或者 视差速率 ,正是同一个界面中的元素,由于层级不同,赋予的视差系数不同,在移动速度上的差异形成了视差的错觉,这就是我们要追求的效果。
那知道原理就好办了,使用 ViewPager.OnPageChangeListener ,动态计算不就得了。 no no no ! 后面完成背景渐变效果确实需要计算这个,但是 ViewPager 已经为我们准备好了变形元素 transformium : ViewPager.PageTransformer ,它有一个抽象方法 transformPage(View page, float position) ,正是为我们完成视差动画量身定制的。
ViewPager.PageTransformer
PageTransformer 在 ViewPager 滑动时被触发,它为我们自定义页面中进行视图变换打开了一扇大门。
javapublic abstract void transformPage (View page, float position)
在 ViewPager 源码中,我们可以很直观的看到它的调用过程:
java// ViewPager#onPageScrolledif (mPageTransformer != null) { final int scrollX = getScrollX(); final int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { final View child = getChildAt(i); final LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (lp.isDecor) continue; final float transformPos = (float) (child.getLeft() - scrollX) / getClientWidth(); mPageTransformer.transformPage(child, transformPos); }}
Param 1: View page
从上面的代码中,不难看出,page 就是当前被滑动的页面,调试得知,每一个 child view 被 NoSaveStateFrameLayout 包装,也就是说 page.getChildAt(0) 即是每个 page 实际的 child view 。
Param 2: float position
position 这个参数不看代码或者文档,总会误以为就是我们熟知的 integer position ,不过它实际上是滑动页面的一个相对比例,本质跟 1、2、3、4 这种 position 是一样的。
比如知乎启动页共有 6 个页面,分别是 A、B、C、D、E、F 初始状态也就是 A 页面静止时,A 页面的 position 正好是 0 ,B 页面是 1 。而后滑动页面(B -> A),在这个过程中 A 的 position 是间于 [-1, 0] ,B 页面则是间于 [0, 1] 。
不过这个参数的文档却是简单不够直观,对照上面的例子,现在应该很清晰了。
Position of page relative to the current front-and-center position of the pager. 0 is front and center. 1 is one full page position to the right, and -1 is one page position to the left.
ParallaxTransformer
根据上面的分析,我们可以得出一个相对简单的自定义 transformer ,对 page view 进行遍历,递增或者递减其 parallaxCofficient ,以得到我们预期的效果,具体的系数设置请参考代码。
javaclass ParallaxTransformer implements ViewPager.PageTransformer { float parallaxCoefficient; float distanceCoefficient; public ParallaxTransformer(float parallaxCoefficient, float distanceCoefficient) { this.parallaxCoefficient = parallaxCoefficient; this.distanceCoefficient = distanceCoefficient; } @Override public void transformPage(View page, float position) { float scrollXOffset = page.getWidth() * parallaxCoefficient; // ... // layer is the id collection of views in this page for (int id : layer) { View view = page.findViewById(id); if (view != null) { view.setTranslationX(scrollXOffset * position); } scrollXOffset *= distanceCoefficient; } }}
背景渐变
留心才会发现,从第一页滑动到最后一页,背景色会平滑的从深蓝色过度到浅蓝色,这种效果又该怎么实现呢?
用过 Property Animation 的同学应该知道,以前的 Animation 只能用在 View 上,而 Property Animation 却可以用在任意类型属性值上,这归功于 TypeEvaluator 。
正好我们有 ArgbEvaluator ,它可以估算两个颜色值之间,任意部分的色值。因此,只需要指定起始色值以及最终的色值,传入滑动所对应的 fraction 即当前位置相对总距离的比例值,即可获得相应的色值。
javapublic class ArgbEvaluator implements TypeEvaluator { public Object evaluate(float fraction, Object startValue, Object endValue) { // ... }}
当然,前面说到需要使用 ViewPager.OnPageChangeListener 的:
javaclass GuidePageChangeListener implements ViewPager.OnPageChangeListener { ArgbEvaluator mColorEvaluator; int mPageWidth, mTotalScrollWidth; int mGuideStartBackgroundColor, mGuideEndBackgroundColor; public GuidePageChangeListener() { mColorEvaluator = new ArgbEvaluator(); mPageWidth = getWindowManager().getDefaultDisplay().getWidth(); mTotalScrollWidth = mPageWidth * mAdapter.getCount(); mGuideStartBackgroundColor = getResources().getColor(R.color.guide_start_background); mGuideEndBackgroundColor = getResources().getColor(R.color.guide_end_background); } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { float ratio = (mPageWidth * position + positionOffsetPixels) / (float) mTotalScrollWidth; Integer color = (Integer) mColorEvaluator.evaluate(ratio, mGuideStartBackgroundColor, mGuideEndBackgroundColor); mPager.setBackgroundColor(color); } @Override public void onPageSelected(int position) {} @Override public void onPageScrollStateChanged(int state) {}}
源码
代码已经 push 到 Github 了,诸位自取。不过请注意,其素材均取自于知乎 Android 客户端(你懂的),学习交流即可,请勿用作商业用途。
还求更优雅的实现方式,欢迎发起 pull request 。
Github : Zhihu-Parallax-Animation
参考
原文地址:http://www.codefrom.com/c/198
更多技术文章请访问:码源|专注开源技术分享

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











HTML은 간단하고 배우기 쉽고 결과를 빠르게 볼 수 있기 때문에 초보자에게 적합합니다. 1) HTML의 학습 곡선은 매끄럽고 시작하기 쉽습니다. 2) 기본 태그를 마스터하여 웹 페이지를 만들기 시작하십시오. 3) 유연성이 높고 CSS 및 JavaScript와 함께 사용할 수 있습니다. 4) 풍부한 학습 리소스와 현대 도구는 학습 과정을 지원합니다.

HTML은 웹 구조를 정의하고 CSS는 스타일과 레이아웃을 담당하며 JavaScript는 동적 상호 작용을 제공합니다. 세 사람은 웹 개발에서 의무를 수행하고 화려한 웹 사이트를 공동으로 구축합니다.

anexampleStartingtaginhtmlis, whithbeginsaparagraph.startingtagsareessentialinhtmlastheyinitiate rements, definetheirtypes, andarecrucialforstructurituringwebpages 및 smanstlingthedom.

WebDevelopmentReliesonHtml, CSS 및 JavaScript : 1) HtmlStructuresContent, 2) CSSSTYLESIT, 및 3) JAVASCRIPTADDSINGINTERACTIVITY, BASISOFMODERNWEBEXPERIENCES를 형성합니다.

웹 주석 기능에 대한 Y 축 위치 적응 알고리즘이 기사는 Word 문서와 유사한 주석 기능을 구현하는 방법, 특히 주석 간격을 다루는 방법을 모색합니다 ...

GiteEpages 정적 웹 사이트 배포 실패 : 404 오류 문제 해결 및 해결시 Gitee ...

이미지를 클릭 한 후 주변 이미지를 산란 및 확대하는 효과를 얻으려면 많은 웹 디자인이 대화식 효과를 달성해야합니다. 특정 이미지를 클릭하여 주변을 만들 수 있습니다 ...

HTML, CSS 및 JavaScript는 웹 개발의 세 가지 기둥입니다. 1. HTML은 웹 페이지 구조를 정의하고 등과 같은 태그를 사용합니다. 2. CSS는 색상, 글꼴 크기 등과 같은 선택기 및 속성을 사용하여 웹 페이지 스타일을 제어합니다.
