前言:

制作灵感来源于 http://species-in-pieces.com/ 这个网站,此网站作者是来自阿姆斯特丹的设计师 Bryan James,其借用纯CSS技术表现出30种濒危动物的碎片拼图形象,用转瞬即逝的动画来暗示这些动物目前的处境。

首先,所有动物形象都是借助 clip-path 这一 css3 属性通过各 三角拼接而成,这一属性不仅可以画 三角 还可以画出任意形状。

为了实现一个这样的动画编辑器,工具方面使用了浏览器的 Canvas2d 和 localStorage,代码风格上 大量使用了 fp 风格的代码。

代码风格:

一个比较典型的设计如下:

      // 获取画布 div
      let drawboardGetter = () => $(".polygon-wrap");

这里 $ 是实现的一个简易原型,并未引入 jQuery,可以使代码精简。

使用这些自定义 getter 函数的目的是来代替所有 纯函数 不纯的部分,这样即便整个纯函数链有不纯的部分,也不影响各种功能链的正常运行,因为这些 getter 的引用变更不会引发任何错误。

实现步骤:

第一步新建一个 html 文件来完成编辑器的功能。

作为一个编辑器,首先要能手动画三角形,可用一个 canvas 来记录鼠标点击处的位置,起到一个提示三角形大概轮廓的效果:

数据方面分别区分两种单元,图案 和 三角形,三角形组成图案,图案之间可以切换,用 函数+组合 的方式生成一个实例,使其具备功能:

      // 一个图案的点管理器
      let pmgInstance = null;
      let pointArrMgGetter = () => pmgInstance || (pmgInstance = mkPointArrMaker(basicArrMaker()));

显然生成的 点数组 getter 都会具备相同的数据结构,因此可以像一个相同类型的变量一样穿梭于各种外部函数之间。

然后设计下编辑器的 ui 部分,是可拖动可隐藏的还有之前停留位置的记录功能,可拖动和可隐藏的设计随便拿一个编辑器比如 ps,unity-editor 这种对功能框都有这种设计,为了更方便使用,我还设计了一个右键点击编辑器空白处可以隐藏编辑器的功能,这样不用去点一般在右上角很小的关闭按钮,实际使用起来我个人感觉很流畅。

      // 使一个 div 可以被鼠标拖动
      const mkDragable = (div, propTopHandler, eventHandler) => { /* ... */ }

上面这个函数会让一个 div 变成可被拖动并在某些时机触发相应的钩子;

动画部分全部是借助 css 实现的,也就是浏览器默认的绘图功能,那作为一个编辑器就要有随时能准确更新 css 的功能,具体点就是更新 style 标签里的内容,使它变成 freeStyle:(ps:用来实现 数据 => css代码 功能函数也必不可少)

      // 插入css规则
      const {
        insertCssRule,
        alterCssByClassName,
        alterMainCss,
        inserKeyframeRule,
        alterCssByKeyFrameName,
      } = (() => { /* */ }

代码层 状态模式 这种设计也是必须的,因为用户在使用鼠标点击的时候 最基本的就可能处在三种情形: 三角形形状编辑,三角形位置编辑,绘制三角形。

        // 状态切换器
        function tabToState(mode, val = true) { /**/ }

事件绑定方面有经验的开发会选择事件派发,简而言之就是绑在父元素,性能理论上也会好些。

回到 html 部分,为了用最简洁的方式实现三角形的动画过渡,这里我使用了 div 复用的设计,说白了一个舞台两场戏,都是原来那群龙套。

这里就还需要设计一个所有 div 如何按顺序开始变换到自己在下一副图案中位置的问题,这个对最终效果的展示至关重要,后面会展示对比效果。

      // 某个 div 开始跳舞
      const mkDivUiWork = (singleConfig, arrSource) => (i) => {
        // 三角形重置
        singleConfig.showDomFrameConfig(arrSource[i].dom, 0);
        // 是否在舞台上
        arrSource[i].show = true;
      };

这里的封装是为了将这个群演 div 的戏份储存起来,这样后面总导演就能安排他们的出场时机。

万事具备,实现功能就顺理成章了,不过肯定有很多细节可以完善和优化的地方。

鉴于我的艺术素养有限,就从临摹开始来完成动画图形,这里开个 nodejs 服务用来将网站截图存储本地,去掉跨域限制后画到浏览器里面,然后就可以仿照着临摹了,临摹这里有两个要注意的地方,第一个是叠加的两个三角形后面的三角形要靠想象力先画出来,因为暂时没有新增调整三角间层级的功能,先绘制的三角形层级会比后绘制的高;第二是默认临摹出的三角形是无法自动获取被临摹三角的颜色的,需要点击 临摹取色 进入取色状态,填充点击在画板上此位置取到的像素颜色。

特点设计:

局部的编辑器也做了区分,比如双击一个三角就可以调出仅 针对 三角形形状编辑功能和三角形位置编辑功能的 编辑器,而其余的两个 图案编辑器 和 临摹图案编辑器是显示出来可以让用户点击的,流程设计大概如下:

临摹图案编辑器显示图案 => 单击连点临摹绘制三角形 => 双击三角形可编辑位置和形状 => 打开图案编辑器保存图案

双击三角形调出编辑器即可以用按钮切换编辑位置和形状的功能,也可以直接右键鼠标实现功能的快速切换)

三角本身的动画也是在双击三角弹出编辑器上通过增减关键帧实现(具体就是变更 css 样式里 keyframe 的帧设置):

最后就是图案间动画的切换了,因为前面已经实现了 freeStyle,因而一旦一幅图的 freeStyle 被切到了另一幅图的 freeStyle,此时浏览器的绘图引擎在 transition 的影响下就开始自动工作了:

但是由于所有群演是同时开始动作的,就会让人眼花缭乱看不过来,之前提到封装每个群演的行为这时候就起作用了,我们可以安排他们一个一个按顺序执行,这里其实可以用各种缓动函数来 控制,比如开场缓慢,中场热烈,收尾迅速,就像原来网站里的动物间切换的律动效果一样。

这里用一个固定间隔 200 ms 来展示效果,当然这个固定间隔不仅可以提前配置也可以实时更改:

其实到这里除了出场间隔还有一个问题,就是三角形的绘制顺序问题。举个例子,群演 小黑 在剧本A(图案A)中是在西北角位置,在剧本B(图案B)中却被安排到了东南角位置,那么转场过程中,小黑 就不得不从西北角跑到东南角,这给观众带来的观影体验请参照(周星驰在喜剧之王中演死人龙套的场景),小黑 明显抢戏了。

因此在图案绘制过程中我都是遵循从右下到左上的绘图顺序,这样图案间的过渡就会流畅很多。但显然这是治标不治本的解决方案,小黑应该遵循就近原则自动补位。

这也是我还没实现的功能,不过思路也比较清晰,因为所有三角位置都清楚的情况下通过计算调整两场群演间的映射关系就可以了。还有的问题包括两个图案所用三角(群演)数量不匹配的问题,上图结尾可以发现新的群演是通过天外飞仙的方式登场的,可能需要调整下出场效果。

最后和原网站对比,可以发现编辑器还缺少的一些功能,比如应该可以配置背景图,可以配置图案的整体动画,动物身体下的阴影动画配置,这些都是可以列计划完成的。

spieces-in-pieces动画编辑器的更多相关文章

  1. 【咸鱼教程】Wing动画编辑器创建精美(一般-_-)开场动画

    游戏中会用着一些简单的动画,公司一般使用的dragonbones制作,导出二进制格式或者MC来使用.感觉一些简单动画直接使用动画编辑器更加简便些. 引擎版本:5.0.14wing版本:4.1.0 一 ...

  2. 【v2.x OGE教程 11】 动画编辑器帮助文档

    ] 动画编辑器帮助文档 版本号 日期 作者 说明 1.0 2014-9-3 橙子游戏 文档创建       一.简单介绍 动画编辑器用于游戏动画的可视化编辑,支持序列帧动画和关键帧动画.通过解析生成的 ...

  3. cocos creator 动画编辑器以及骨骼动画的使用

    一.普通动画的设置 1.添加动画组件 a.添加空节点=>添加动画组件 b.新建Clip文件=>打开编辑模式添加动画编辑(并且把添加的clip文件拖动到右边面板的Default Clip 与 ...

  4. Egret Wing4.0.3 动画编辑器

    一 exml上摆放组件 切换动画编辑 创建动画组,命名test1. 选中一个对象,创建动画(必须选中一个对象后,+号才会亮.且一个对象只能创建一个动画) 之后和Flash差不多.在时间轴插入关键帧. ...

  5. Mecanim动画编辑器 - 加入动画层实现并行动作

    1.创建新的状态层 a) 通过下图的1button创建一个新的层   b) 通过下图2属性设置图层的权重.假设为0,则该图层的状态不会影响到总的状态机  c) Mask是设置动画的Avatar的关联节 ...

  6. cocos2dx骨骼动画Armature源码分析(一)

    源码分析一body { font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 1.6; padding-to ...

  7. Flash动画

    Flash (交互式矢量图和Web动画标准) Flash是由macromedia公司推出的交互式矢量图和 Web 动画的标准,由Adobe公 司收购.做Flash动画的人被称之为闪客.网页设计者使用 ...

  8. android游戏动画特效的一些处理

    游戏中避免不了需要一些动画特效的处理,有些是不方便用美术或者美工来处理的,那么就由我们程序猿来搞了.直接进入正题. 首先是Animation,Animation针对view,可以控制view的位移.缩 ...

  9. Cocos2d-x——CocosBuilder官方帮助文档翻译3 动画

    Working with Animations 动画 You can use CocosBuilder for creating character animations, animating com ...

随机推荐

  1. Azure Functions(二)集成 Azure Blob Storage 存储文件

    一,引言 上一篇文章有介绍到什么是 SeverLess ,ServerLess 都有哪些特点,以及多云环境下 ServerLess 都有哪些解决方案.在这众多解决方案中就包括 Function App ...

  2. 解决ROS及Fast-RTPS安装和使用中raw.githubusercontent.com无法连接的问题

    资料参考: https://blog.csdn.net/weixin_44692299/article/details/105869229

  3. Java自学第10期——File类与IO流(输入输出流、处理流、转换流、缓冲流、Properties集合、打印流)

    1.IO简介 IO(输入输出)通过java.io包下的类和接口来支持,包下包括输入.输出两种IO流,每种输入输出流又可分为字符流和字节流两大类. 2.File类 File类是io包下与平台无关的文件和 ...

  4. 【原创】Linux虚拟化KVM-Qemu分析(十)之virtio驱动

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: KVM版本:5.9 ...

  5. mui调用本地相册调用相机上传照片

    调用mui的常用库和jquery html部分: <header class="mui-bar mui-bar-nav"> <a class="mui- ...

  6. git相关问题

    1.git查看远程分支更新到本地 git clone 项目地址,示例如下: git clone https://github.com/zhongyushi-git/vue-test.git 在拉取时, ...

  7. CSS 书写禅机

    这是未来的趋势所向,如是我行. 注意:原文发表于 2017-9-6,随着框架不断演进,部分内容可能已不适用. CSS 日渐惹人憎恶. 究其原因颇多,归根结底,皆因 CSS 给人的感觉总是飘渺迷蒙.变幻 ...

  8. Python函数注解

    目录 函数注解概述 实际应用 inspect模块 业务代码 总结 以下内容基于Python 3x 涉及的知识前提: 建议理解Python装饰器后学习此内容 函数注解概述 函数注解可以针对函数的参数.返 ...

  9. const成员函数可以将非const指针作为返回值吗?

    先给出一段代码 class A { int *x; public: int *f() const { return x; } }; 成员函数f返回指向私有成员 x 的非常量指针,我认为这会修改成员x ...

  10. Hi3559板载u-boot、kernel及rootfs烧录过程及心得

    这一篇随笔讲叙述下基于Hi3559AV100的BOXER-8410AI板载u-boot.kernel及rootfs烧录具体过程及遇到问题的解决方法与心得. 1.前期板载启动测试和烧录手段 1.1.烧写 ...