学习 kityminder 笔记(十一)
学习 kityminder 笔记(十一)
刘军兴 发表于2年前
学习 kityminder 笔记(十一)
  • 发表于 2年前
  • 阅读 79
  • 收藏 0
  • 点赞 0
  • 评论 0

标题:腾讯云 新注册用户域名抢购1元起>>>   

上次看到了 Layout 类及其实做子类 MindLayout 等, 本次研究驱动它们的部分: Minder.layout() 函数.

回顾 core/layout.js 里面相关代码(按照调用顺序):

extend class Minder {
  // 用于在 Minder 类上支持布局(layout).
  function layout(): {
    // 内部函数定义: 稍后研究.
    function layout-node();

    // 1. 清空现有所有节点的布局信息.
    this.root-node.traverse() -> clear node.layout; 

 
    
    // 2. 调用进行第一轮布局.
    layout-node(this.root-node, round = 1);

    // 3. 调用进行第二轮布局, 根据我看 layout 子类, tianpan 类型的需要两轮布局, 
    //    其它可能只需要一轮即可. 但这里不加区分地都调用两次, 是很浪费时间的...
    layout-node(root-node, round = 2);

    
    // 4. 应用布局结果(产生动画,如果图形不复杂的话).
    this.apply-layout-result(动画参数, ...)
    // 发布事件略.
  }
}

这里的重点一是调用 layout-node() 函数, 通过两轮布局计算出节点应该布局到的位置.
二是通过动画(图形复杂时直接移动) 移动 node 到目标布局位置 (从现有位置).

下面先看看 layout-node()

// node 表示要布局的节点, 此函数被递归调用.
function layout-node(node, round=1 or 2) {
  // 剪枝: 收起的节点无需计算. 但实际上 if 语句总是真, 这样白剪?
  // 这里的重点是顺序: 先(递归)访问子节点, 再访问自己. 称为后序遍历?
  if (可以不计算 || true)
    for-each(node's child) 
      -> 递归调用 layout-node(child, round) 

  // 计算一个 childrenInFlow 但却未使用, 不明白是不是调试代码忘记删除了?
  cildrenInFlow = ...

  // 实际驱动 Layout 类进行布局的核心调用在这里.
  node.layout-instance.doLayout(node, node.children, round)
}

通过最后一句调用, 我们将 Minder.layout() 和 Layout.doLayout() 关联在一起. 这样完成了 layout 的流程理解.

 

另一个重点是 Minder.applyLayoutResult():

function Minder.apply-layout-result() {
  complex? = 判断脑图是不是太复杂, 如果太复杂, 下面就不用动画了.
  
  // 内部函数 consume(), apply-matrix(), apply() 定义. 下面研究.
  // 调用内部函数 apply() 处理.
  apply(root-node, init-matrix)
}

// 上面所说内部函数, 放这里单独看.
closure function apply(node, parent-matrix) {
  // 合并变换矩阵. 这里 * 理解为数学矩阵乘法(或某种 matrix 计算即可)
  matrix = node.layout-matrix * parent-matrix;
  // 再加上布局偏移.
  matrix += node.layout-offset

  // 如果当前有动画, 停止动画.
  if (node.layout-timeline) ...timeline.stop()

  // 用动画更新位置(非动画方式略)
  node.layout-timeline = new kity.Animator(...)  // 新建动画对象.
     .start(..., duration, ...) // 开始动画.
     .on('finish', 某些处理略);
   
  // 递归调用, 子节点也产生动画.
  for-each (child)
    apply(child, matrix)
}

(其它两个内部函数如果未用到就略过)

这里的重点一是合并变换矩阵, 节点自己的变换分两部分(layout-matrix, layout-offset), 现在虽未彻底理解两者
分工, 但可先认为是通过函数中方式计算出最终(相对于全局)的布局位置 (matrix).

重点二是使用 kity.Animator() 包装动画, 为此需要先去看看 svg 动画, 以及 kity 对其封装是什么. 这里我想大致
是在 duration 时间内进行(完成)一个移动动画.

这也是为了回答本文第(十)最后提出的问题.

共有 人打赏支持
粉丝 54
博文 141
码字总数 223378
×
刘军兴
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: