文档章节

学习 kityminder 笔记(九)

刘军兴
 刘军兴
发布于 2015/11/24 16:00
字数 1550
阅读 93
收藏 0

继续学习 kityminder.

=== module/style.js === 

 

// 拷贝选中节点的当前样式,包括字体、字号、粗体、斜体、背景色、字体色
// 对应为 styleNames = ['font-size', 'font-family', 'font-weight', 'font-style', 'background', 'color']
class CopyStyleCommand : public Command {
   execute(): 将被选中 node 的 data 与 style 有关的部分复制内部 clipboard
}

// 粘贴已拷贝的样式到选中的节点上
class PasteStyleCommand : public Command {
   execute(): 将 clipboard 中 style 复制到被选中 node 上. 然后布局.
}

// 移除选中节点的样式
class ClearStyleCommand : public Command {
   execute(): 清除被选 node data 中 style, 重新渲染和布局.
}

register module StyleModule {
   commands: copystyle->CopyStyleCommand etc.
}

 

=== module/text.js ===

FONT_ADJUST 用于针对不同系统,浏览器,字体 做居中兼容性处理......

class TextRenderer : public Renderer {
   create(): 为 text 创建 kity.Group 对象, 应是 <g> 元素.
   update(): 得到/计算文本, 样式, 浏览器兼容性调整等数据.
      创建/修改 kity.Text() 对象/元素在 <g> 中. 这里代码较多, 需稍后细看.
   setTextStyle(): 遍历 _styleHooks[] 钩子进行回调.
}

class TextCommand : public Command {
   execute(): 为选中节点设置文本.
}

extend class TextRenderer {
   static _styleHooks: []  // 一种可以扩展 style 的机制...
   static registerStyleHook(): 添加钩子到 _styleHooks[] 中.
}

extend class MinderNode {
   getTextGroup(): ?
}

register module text {
   commands: text->TextCommand,
   renderers: center->TextRenderer
}
这里的问题是, 对于一个 node 的一组 renderers[], 是如何使用的? 前面已经看到很多种不同 renderer 了.


前面看 font.js 时跳过以等待看 text.js, 则现在补看.

=== module/font.js ===

register StyleHook in TextRenderer {
   看起来是得到 node 的字体(font)样式然后渲染到 svg 元素上.
}

// 设置选中节点的字体颜色. 对于 queryValue(), 如果只有一个节点被选中
//   则返回节点颜色; 如果有多个则返回 'mixed', 如果计算是否公共的更好吗?
class fontcolorCommand : public Command {
   execute(): node.data.color = val; 然后 render().
}

// 设置选中节点的背景颜色
class backgroundCommand : public Command {
   execute(): node.data.background = color
}

// 下面 fontfamilyCommand, fontsizeCommand 类似, 略去.
// 很多命令都要求有节点被选中才能使用, 为什么不 mixin 这个函数或属性进去呢?

register module fontmodule {
   commands: forecolor->fontcolorCommand, etc.
}

 

=== 回顾 basestyle.js  ===

// 加粗选中的节点
class boldCommand : public Command {
   execute(): node.data.font-weight = 'bold' or ''
}

class italicCommand : public Command {
   execute(): node.data.font-style = 'italic' or ''
}

register StyleHook[] of TextRenderer {
   根据节点的 font-weight, font-style 属性设置 svg 元素的字体属性.
   这里 hook 弄得有点过复杂, 还有 style-hash 的构成和计算也很麻烦...
}

register module basestylemodule {
   commands: bold->boldCommand, italic->italicCommand.
   shortcutKeys: ctrl+b->bold, ctrl+i->italic
}


=== module/view.js ===

// 当前主要是不知道这个类对应界面什么东西?
class ViewDragger {
   timeline(): ?
   move(),moveTo(): ? 见下面 CameraCommand.
}

// 切换抓手状态,抓手状态下,鼠标拖动将拖动视野,而不是创建选区
// 这个应是对应界面上 '允许拖拽' 按钮(左下部分)
class ToggleHandCommand : Command {
   execute(): status='hand'
}

// 设置当前视野的中心位置到某个节点上. 看起来对应 '定位根节点' 按钮功能?
class CameraCommand : Command {
   execute(): 使用 ViewDragger.move() 来实现.
}

// 指定方向移动当前视野, 在四个方向上可移动一半视野...
class MoveCommand : Command {
   execute(): 使用 ViewDragger.move() 实现, 给出移动距离和时间.
}

register module View {
   commands: hand->ToggleHandCommand etc.
   events: 几个事件的注册及处理, 暂时略.
}

 

=== module/zoom.js ===

// 缩放当前的视野到一定的比例(百分比)
class Zoom : Command {
  execute(): 使用动画(相关词有 animator, timeline, 暂时不熟悉)放大 view.
     发布 viewchange, zoom 事件.
}

class ZoomInCommand/ZoomOutCommand : Command {
   execute(): 缩小/放大, 实现类似于 Zoom.
}

register module Zoom {
   init: 设置缩放比例的数组 [10,20,50,100,200] 可以自定义.
   commands: zoom,zoomin,zoomout
   events: 似乎可以用 mousewheel 来缩放. 未实验成功.
   shortcutKeys: ctrl+=, ctrl+- 对应缩放.
}

 

=== 以上完成了第一遍对 module/*.js 的遍览, 现在可以回顾一下比较重要的 render 部分.

已知在 render.js 中扩展了方法 Minder.renderNode(node), 伪代码及解释如下:

function Minder::renderNode(node) {
  // 1. 如果此节点还未创建 renderers[] 则现在创建.
  if (!node._renderers)
     createRenderersForNode(node);
  
  // 2. 发布 before-render 事件
  fire_event(before-render, ...)
  
  // 3. 遍历所有 render in node._renderers[]. 
  //  此处按照的顺序, 是创建 ._renderers[] 的顺序, 按照程序是
  //     center,left,right,top,bottom,outline,outside.
  node._contentBox = new Box();  // 初始化计算盒子(矩形).
  for-each (renderer) {
    // 3.1 判断(根据上下文) 是否应该渲染.
    if (renderer.should_render?) {
      // 3.1.1 此时需要渲染, 如果渲染图形(元素 <g>)未创建, 则现在创建.
      if (!renderer.<g>)
        renderer.<g> = renderer.create() --> append-to(<g>)
      // 3.1.2 显示该元素
      .<g>.visible = true
      // 3.1.3 更新(update) 渲染图形, 这里我们知道 create() 只调用一次,
      //    update() 每次渲染(改变)时都会被调用. 可能结果存于 box 中.
       last_box = renderer.update(..., .box)
      // 3.1.4 合并渲染区域(符号 += 解释为 merge 方法).
      renderer.content_box += last_box 
    }
    // 3.2 如果不需渲染, 但是已经创建了 svg 图形元素, 则把它们隐藏起来. 
    else if (renderer.<g>) {
      .<g>.visible = false;
    } 
    // 3.3 否则什么都不需要做.
  }

  // 4. 发布 node-render 事件.
  fire-event(node-render, ...)
}


回顾一下最基本的 TextRenderer:

// text 是 'center' 型 renderer, 渲染过程中一般第一个被调用.
class TextRenderer : public Renderer {
  create(): {
    new kity.Group() // 产生一个 <g> 元素, id 为 node_textN, N 为数字.
  }
  update(): {
    // 略去一些 browser 相关兼容代码.
    box = new kity.Box()
    // 遍历 style_hooks[] 让各个模块设置 text-style (简略一些)
    for-each (style_hooks) --> hook(...)
    // 为每行文本创建一个 svg <text> 元素.
    for-each (line) --> new kity.Text(...) add-to(<g>)
    // 再次遍历 style_hooks[] ... 这里不知道为什么遍历第二次? 也许应该先创建 <text> 再设置 style 才对.
    for-each (style_hooks) --> hook(...)
    // 计算一个 textHash, 可能用于比较与上次是否发生了变化.
    text_hash = ....join('/')
    // 返回一个函数, 函数在调用 update() 的 render 中判断和调用.
    // 可能某些地方会延迟调用?
    return function() {
      // 计算 box 并返回的代码.
    }
  }
}

// 回顾一个 style_hook:
FontModule.style_hook = function(node, <g>) {
  color = node.color | node.style.color | ...
  font-family = node.font-family | ...
  font-size = node.font-size | ...
  // 将这些字体相关属性设置到 svg 元素上.
  <g>.fill = color  // color 属性设置到 <g>
  <g>.for-each(<text>)
    <text>.font-family=..., .font-size=...
}

// 另一个 style_hook
BaseStyleModule.style_hook = function(node, <g>) {
  <g>.for-each (<text>)
    <text>.weight = node.font-weight
    <text>.style = node.font-style
}


这样大致理解了 render 过程. 表述为将一个 node(可认为是一个 json object, 含一组属性)对应到画布元素(一个或
多个)的过程. 通过扩展机制1(注册到 _rendererClass[]) 的方法为每个节点产生 renderers[], 再通过扩展机制2
(注册到 style_hooks[]) 来支持节点的 TextRenderer 的各种 style 扩展. 其它类型的 Renderer 没有扩展机制2.

(END)

 

 

 

 

 

© 著作权归作者所有

共有 人打赏支持
刘军兴
粉丝 54
博文 184
码字总数 226359
作品 0
昌平
百度脑图解析:如何进行web复杂应用的渐进式开发

内容来源:2017 年 4 月 8 日,张博在“HTML5梦工场 & 微软开发者沙龙第05期—持续集成”进行《Web复杂应用的 「渐进式」开发》演讲分享。IT 大咖说(微信id:itdakashuo)作为独家视频合作方...

06/04
0
0
学习 kityminder 笔记(五)

接着学习 kityminder, 前面其实没看完 kity, 大致了解之后, 我们先看看 minder 部分, 两者结合起来学更好些. 下载 kityminder-core (按文档说只含核心部分), 从 git-hub, 建立起开发/构造环境...

刘军兴
2015/11/19
0
0
学习 kityminder 笔记(六)

接上篇, 接着学习 kityminder. == core/keyreceiver.js == extend class Minder { init-hook(): 构造时设置选项, 侦听 'paperrender' 事件, 以调用 _initKeyReceiver() _initKeyReceiver():......

刘军兴
2015/11/19
0
0
学习 kityminder 笔记(七)

接上篇继续学习. 本段都是 seajs require(module/*.js) 的, 看起来是按照字母顺序 a-z 排列的, 所以应没什么互相依赖性. 考虑到前面有很多细节都略过, 或不懂, 在学习过程中可能还要不断回顾...

刘军兴
2015/11/20
0
0
再学习 Kity 笔记(五) 初步

在过去两周左右, 一直在学习 kity, kityminder, nodejs, seajs 等一系列项目. 有些认识经过一段时间学习, 已经发生了 变化, 使得原有笔记过时. 兹为深入学习, 有必要回顾复习重新看一遍. Kit...

刘军兴
2015/12/04
68
0

没有更多内容

加载失败,请刷新页面

加载更多

Mac OS X下Maven的安装与配置

Mac OS X 安装Maven: 下载 Maven, 并解压到某个目录。例如/Users/robbie/apache-maven-3.3.3 打开Terminal,输入以下命令,设置Maven classpath $ vi ~/.bash_profile 添加下列两行代码,之后...

TonyStarkSir
今天
3
0
关于编程,你的练习是不是有效的?

最近由于工作及Solution项目的影响,我在重新学习DDD和领域建模的一些知识。然后,我突然就想到了这个问题,以及我是怎么做的? 对于我来说,提升技能的项目会有四种: 纯兴趣驱动的项目。即...

问题终结者
今天
3
0
打开eclipse出现an error has occurred see the log file

解决方法: 1,打开eclipse安装目录下的eclipse.ini文件; 2,打开的文本文件最后添加一行 --add-modules=ALL-SYSTEM 3,保存重新打开Eclipse。...

任梁荣
昨天
4
0
搞定Northwind示例数据库,无论哪个版本的SQLServer都受用

Northwind数据库 从这里可以找到突破口: http://social.msdn.microsoft.com/Forums/zh-CN/Vsexpressvb/thread/8490a1c6-9018-40c9-aafb-df9f79d29cde 下面是MSDN: http://msdn2.microsoft......

QQZZFT
昨天
1
0
mysql主从同步,安装配置操作

准备 两台mysql服务,我这里准备了如下: 主库:192.168.176.128 从库:192.168.176.131 如何在Linux上安装mysql服务,请看https://blog.csdn.net/qq_18860653/article/details/80250499 操作...

小致dad
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部