天天看點

/LGC圖形渲染/翻頁(folding)特效的實作

翻頁(folding)特效的實作 作者: 劉鵬 日期: 2010-06-08 本文詳細介紹了如何實作翻頁(folding)特效。

簡介

翻頁(folding)特效在 UI 中用的多,如轉場、電子書的翻頁等。翻頁(folding) 效果如下圖所示:

/LGC圖形渲染/翻頁(folding)特效的實作
圖1. from 參考資料1

實作 folding 特效有很多方法,包括 2D 的和 3D 的,下面将分别介紹。

2D 方法

總的思路是: 截屏 + 直角三角形 + 三邊形(bezier1/bezier2/line) + timer 更新。如下圖所示。

/LGC圖形渲染/翻頁(folding)特效的實作
圖2. folding特效分解

folding 特效可分解成三部分:

  1. 未翻完的部分,如圖2的區域1;
  2. 翻過去,露出的底圖部分,如圖2的區域2;
  3. 褶皺部分,如圖2的區域3。

仔細分析,可以得到如下的思路:

  1. 區域1是個五變形,用上層的圖填充;
  2. 區域2是個直角三角形,用下層的圖填充;
  3. 區域3是由兩條 bezier 曲線加一條直線構成的三邊形,區域3和區域1之間運用半透明效果。

已知滑鼠目前位置 (x, y)、視窗 width 和 height,很容易算出三個區域各個 頂點的坐标,見圖2。根據頂點坐标,通過 path 接口,可以畫出三個區域的形 狀。 再通過設定剪切域(clip),就可以在三個區域中繪制想要的圖形。

以 QT 為例,僞代碼如下所示:

... ...



    // set composition mode

    painter->setCompositionMode (QPainter::CompositionMode_Source);



    QPainterPath path;



    /* Draw region 1 */



    painter->save ();

    path.moveTo (0,0);

    path.lineTo (mouse_pos.x, 0);

    path.lineTo (WIN_WIDTH, mouse_pos.y);

    path.lineTo (WIN_WIDTH, WIN_HEIGHT);

    path.lintTo (0, WIN_HEIGHT);

    path.closeSubpath ();

    painter->setClipPath (path);

    painter->drawPixmap (0,0, image_up);

    painter->restore();



    /*Draw region 2*/

    painter->save();

    path.clear();

    path.moveTo (mouse_pos.x, 0);

    path.lineTo (WIN_WIDTH, mouse_pos.y);

    path.lineTo (WIN_WIDTH, 0);

    path.closeSubpath ();

    painter->setClipPath (path);

    painter->drawPixmap (0,0,image_down);

    painter->restore();





    /* Draw region 3 */

    path.clear();

    path.moveTo (mouse_pos.x, 0);

    path.cubicTo (c1x, c1y, c2x, c2y, mouse_pos.x, mouse_pos.y);

    path.cubicTo (c1x, c1y, c2x, c2y, WIN_WIDTH, mouse_pos.y);

    path.closeSubpath ();

    painter->setBrush (color);

    painter->drawPath (path);



    ... ...



      

3D 方法

To be continued...

Reference

  1. Folding