Creator|基于2.x的折纸翻书效果

简介

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

主要技术点:

  • 多边形遮罩
  • 节点截图
  • 自定义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. Creator | 基于Assembler实现的图片切割及自定义遮罩
  2. 【分享】自定义渲染合批之自定义顶点格式(附 Demo 和引擎源码解读)

官方文档

https://docs.cocos.com/creator/manual/zh/advanced-topics/custom-render.html

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

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

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

大佬的文章里有如何获取到手指划过时得到两个区域的方法。注:上述链接中的代码是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. Creator | 基于Assembler实现的图片切割及自定义遮罩
  2. 【分享】自定义渲染合批之自定义顶点格式(附 Demo 和引擎源码解读)
  3. 【assembler 实现】折纸效果/ 竖排文本/
28赞

好东西,真不戳

:100: :100: :100: :100: :100:

背景图不错哟~

:100: :100: :100: :100: :100:
:100: :100: :100: :100: :100:
:100: :100: :100: :100: :100:
:100: :100: :100: :100: :100:
:100: :100: :100: :100: :100:
8587a7aa-7907-4c3e-b51f-de398e621f11

膜拜大佬~~~

你们多写点,我就多嫖点 :grinning:

无敌 :+1:

效果不错哦,如果能够像翻书一样,书的边缘是弯曲的就更好啦!

mark :+1:

可以参考一下乐府的效果,细分一下三角形,再通过算法去卷曲。不过我觉得这种折纸的效果一般都不带卷曲的。。

学习~~~~~~~~

mark!

666666,真心很赞,已支持 :smile:

给大佬递茶

翻牌的变相应用吗

这才是我期望的论坛的样子。膜拜大佬

膜拜大佬~

膜拜大佬!

已购买,怎么使用啊,找半天不知道去哪儿了