Creator|折纸翻书效果

1,580

简介

本文主要实现了类似于折纸翻书的效果。

主要技术点:

  • 多边形遮罩
  • 节点截图
  • 自定义assmbler Demo引擎版本:2.4.4

效果

2021-06-29 10.50.56.gif

分析

一眼看上去图像分为三部分:其中【1】的区域是图中【1】+【2】那么大。

image.png

基本思路:

【1】部分使用多边形遮罩,这样的好处是【1】内的spine等动画还可以继续播放,另一个好处是假设第二页在第一页的下面,当第一页使用多边形遮罩后,其实第二页直接就露出来了,这样第二页的所有动画其实都不受影响。先不考虑2的区域如何实现,现在就变成了当手指move时,不断的去计算1的包围盒,并且设置多边形遮罩,使第二页的页面露出来,效果如图:

2021-06-29 11.14.27.gif

多边形遮罩主要核心代码:

    mask._updateGraphics = function (polygon) {
      let node = this.node;
      // @ts-ignore
      let graphics = mask._graphics;
      // Share render data with graphics content
      graphics.clear(false);
      // @ts-ignore
      let width = node._contentSize.width;
      // @ts-ignore
      let height = node._contentSize.height;
      // @ts-ignore
      let x = -width * node._anchorPoint.x;
      // @ts-ignore
      let y = -height * node._anchorPoint.y;
      if (!polygon) {
        graphics.rect(x, y, width, height);
        graphics.close();
        graphics.fill();
        return;
      }
      graphics.lineWidth = 10;
      graphics.fillColor.fromHEX("#ff0000");

      if (polygon.length === 0) polygon.push(cc.v2(0, 0));
      graphics.moveTo(polygon[0].x, polygon[0].y);
      for (let i = 1; i < polygon.length; i++) {
        graphics.lineTo(polygon[i].x, polygon[i].y);
      }
      graphics.lineTo(polygon[0].x, polygon[0].y);
      graphics.fill();
    };

【2】部分使用的是自定义assmbler,这部分东西需要多多理解。群里大佬有过一些详细的讲解,我贴几个链接。

  1. forum.cocos.org/t/topic/103…
  2. forum.cocos.org/t/topic/950…

官方文档

docs.cocos.com/creator/man…

思路:假设我们已经拿到了2区域的位置坐标,如何将下一页的纹理显示到这个区域里面?

  • 获取下一页的截图。
  • 将截图纹理进行自定义渲染。 第一步很好做到,重点是第二步。

在说第二步之前还是得回归到前面的一个问题,就是我们已经假设拿到了所有的区域坐标,这部分坐标是如何获取到的?贴一个@白玉无冰大佬的教程: forum.cocos.org/t/topic/112…

大佬的文章里有如何获取到手指划过时得到两个区域的方法。注:上述链接中的代码是3.0引擎的,很多api和2.x区别还是很大滴,主要是理解数学计算的过程。

借鉴(白嫖)到大佬的分割代码之后,我们可以得到两个关键的东西splitPolygons和splitUvs

splitPolygons是两个区域的分割坐标组成的数组,splitUvs是两个区域的分割的纹理坐标组成的数组。

如果我们将前面截图获取到的纹理的顶点坐标设置成splitPolygon,将其纹理坐标设置成splitUv,并且设置了正确的索引数组,那么得到的就是一个看起来被调整了角度的只有部分显示的图片。效果如图:

image.png 这时可以发现,宇智波鼬变得有点可怕呢。。。 出现这个情况的原因是我们的uv取得是漏出来区域的部分的坐标,需要轴对称一下采样当前纹理相对于y轴对称的另一面的纹理。。方法就是 1-当前纹理坐标.x。

image.png 这样效果就OK了。

真的ok了吗?

完善

1.给翻页的缝隙加一点阴影。没啥技术含量,就是算坐标然后贴一个黑乎乎的九宫格图片上去,调整一下透明度就ok了。

image.png

2.翻到中轴线自动切页:更没啥技术含量,翻到一半自动翻过去。。。体验稍微好一点,要不然可能会出现从底下往上翻的情况。。

关于自定义assmbler的知识,没接触过的需要一点点时间去梳理,上面大佬们和官方的文章已经讲解的很好了,这里就不再赘述了。

总结:

  1. 当前页面用多边形遮罩
  2. 当点击屏幕时根据坐标判断是【下一页】的操作还是【上一页】的操作,然后调整下层页面的zindex,使漏出来的页面是对应的上下页。
  3. 此时把预先截好的图拿出来作为纹理,通过自定义assmbler渲染出来即可。

其实整体思路和@白玉无冰大佬的折纸很像。

引擎方面试了2.3.2和2.4.4都可以运行。。

工程内是个简单的demo,而且可能会有一些小bug,不过正常使用应该没问题。如果用于生产,资源管理那些需要自己去处理。

demo地址

参考链接

  1. forum.cocos.org/t/topic/103…
  2. forum.cocos.org/t/topic/950…
  3. forum.cocos.org/t/topic/112…