http://download.csdn.net/source/3250105
App Store-safe Page Curl animations
Even if its usefulness is questionable, the page curl has become one of the signature effects of Apple’s iOS devices so it is no surprise that many developers would like to implement this effect in their apps.
即使不能确定今后这个方法是否有效,page curl已经是苹果的iOS设备的一个标志之一,所以不要惊讶有很多的开发者喜欢在他们的应用程序里使用这个方法
[caption id=”attachment_595” align=”alignnone” width=”600” caption=”iBooks on the iPad doing a page curl”]
Apple uses private APIs
The problem is that the page curl animation used by Apple is not exposed in a public and documented API. Steven Troughton-Smith did a great job at documenting how Apple’s implementation works in his post Apple’s iBooks Dynamic Page Curl . Although Steven’s sample code is a bit rough (as he admits himself), the inner workings become clear: Apple has written a custom Core Image filter that is accessible with the undocumented kCAFilterPageCurl
constant. (Yeah I know, Apple actually tells us in the documentation that Core Image is not available in iPhone OS
. They lied.) This filter accepts two input values, inputAngle
and inputTime
, to control the angle from which the layer is curled up and the magnitude of the curl. For a page curl animation, we would animate inputTime
from 0.0f
to 1.0f
. To attach the filter to a layer, simply add it to an array and assign the array to the layer’s filters
property (ignoring that the documentation says this leads to undefined behavior. In this case, undefined behavior is exactly what we want.). From Steven’s code (edited for clarity):
问题在于page curl这一动画效果并不是以一个公开的方式来发布的接口.Steven Troughton-Smith在他写得Apple’s iBooks Dynamic Page Curl 中,作了大量的工作来阐述Apple的实现机制.尽管Steven的代码很简洁(正如他承认的那样),它的内部工作机制开始清晰:
苹果自定义了一个Core Image 来过滤掉那些未经证实的kCAFilterPageCurl实例的访问.(我知道,苹果实际上tells us in the documentation 在文档中这么说的"Core Image 在iPhone的操作系统中并不提供".他们在说谎)这个过滤器允许两个输入通过,inputAngle和inputTime, 来控制层卷起的角度和幅度.对一个page的卷起动画,我们可以设置inputTime的值0.0f到1.0f,如果要切合层的过滤条件,只要简单地将层添加到一个数组中,并将它指派给层的过滤属性(不要相信文档中说得,这会导致未定义的行为.在这个情况下,这个未定义的行为证实我们需要的.)从Steven的代码中:
The App Store-safe way
I hope Apple makes this public in the future (and if you want to have it, too, you should file a bug and request it). In the meantime, Tom Brow has written Leaves , a simple component that achieves a page curl effect through a very smart combination of mirrored and shaded layers (for translucent pages) and gradient layers (for shadows). Basically, Tom adds to the layer that contains the page content (topPage
):
我希望苹果在未来可以公开这些方法(如果你也想拥有它,你应当file a bug 贴出bug列表并提交).在此期间, Tom Brow 已经写了Leaves ,一个简单的结构,这个结构通过一个很聪明的方式实现了一个翻页效果,它将玻璃效果,阴影层(半透明的页)和渐变层(用于阴影)结合在一起。实际上,Tom增加了一个包含内容的层(topPage):
- an overlay to shade the page during the curl animation (
topPageOverlay
), - a gradient layer that acts as the top page’s shadow during the curl (
topPageShadow
), - a mirrored image of the page that will be displayed on the back of the topPage layer during the curl (
topPageReverseImage
), - a nearly-white overlay to soften the
topPageReverseImage
, - and the page below the current page that will become the new
topPage
after the curl has finished.
1. 一个使page页在翻页动画进行时的蒙板(topPageOverlay),
2. 一个在翻页时作为顶层页阴影的渐变层(topPageShadow),
3. 一个在翻页时在topPage层后面显示出的玻璃效果图片(topPageReverseImage),
4. 一个使topPageReverseImage变的柔和的接近白色的蒙板,
5. 一个在当前页下面的页,在翻页结束时成为新的topPage。
The end result is not quite as stunning as Apple’s solution but it is a very good workaround. As I played around with Tom’s code (I encourage you to take a look at it, it is very clean), I noticed that LeavesView
did not support displaying two pages side by side in landscape mode, so I modified Tom’s code accordingly. At first, I planned to duplicate the entire layer hierarchy for the second page, but then I noticed that even in the side-by-side view it is enough if only the page on the right is animated. It was enough to add a leftPage
layer, modify the page skipping algorithm (skip two pages instead of one) and the display of the topPageReverseImage
layer (display an image of the next page instead a mirrored image of the current page). This is what you get:
最后的结果并不令你惊讶-Apple的解决方法是一个很好的解决方案。当我使用了Tom的代码后(我鼓励你去看一下,很简洁),我注意到它的LevcesView在landscape模式下并不支持显示两个并排式的页面,所以我修改了Tom的代码。起初,我计划给第二个页面复制一个实体层的层次,我接着注意到即使在并排式的视图里,页面在右侧进行动画页足够了。只要添加一个leftPage层,修改页面处理运算(将两个页面替换掉一个页面) 并显示topPageReverseImage层(显示下个页面的image来替换最为玻璃图片的当前页面),这是你看到的效果:
[caption id=”attachment_599” align=”alignnone” width=”600” caption=”Page curl in the Leaves project in side-by-side view”]
The code is not yet perfect: the topPageShadow
is not aligned correctly and I struggled a bit with Tom’s implementation of the page image cache so the code in that section is quite rough. Tom has not yet integrated my modifications into his repository but you can already check out my twopages branch (I love GitHub!). When there is time, I hope we can improve it even more.
这个代码并不完美:topPageShadow 排列的并不正确,与Tom的page image cache 实现也有冲突,因此在这些区域里代码也比较粗糙。
Tom还没有将我修改的代码添加到他的代码中,但是你可以点击这里check out my twopages branch
相信有这么一刻,我们可以将它改进的更好。
2010年6月21日更新:John在maniacdev.com的 nice screencast of the effect in action 。谢谢!
Update June 21, 2010: John from maniacdev.com made a nice screencast of the effect in action . Thanks!