学习 kityminder 笔记(九)
2015-11-24 00:00
369 查看
继续学习 kityminder.
=== module/style.js ===
=== module/text.js ===
FONT_ADJUST 用于针对不同系统,浏览器,字体 做居中兼容性处理......
前面看 font.js 时跳过以等待看 text.js, 则现在补看.
=== module/font.js ===
=== 回顾 basestyle.js ===
=== module/view.js ===
=== module/zoom.js ===
=== 以上完成了第一遍对 module/*.js 的遍览, 现在可以回顾一下比较重要的 render 部分.
已知在 render.js 中扩展了方法 Minder.renderNode(node), 伪代码及解释如下:
回顾一下最基本的 TextRenderer:
这样大致理解了 render 过程. 表述为将一个 node(可认为是一个 json object, 含一组属性)对应到画布元素(一个或
多个)的过程. 通过扩展机制1(注册到 _rendererClass[]) 的方法为每个节点产生 renderers[], 再通过扩展机制2
(注册到 style_hooks[]) 来支持节点的 TextRenderer 的各种 style 扩展. 其它类型的 Renderer 没有扩展机制2.
(END)
=== 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)
相关文章推荐
- Jeasyframe 2015 版本发布
- ubuntu 部署 redis 主从节点配置
- ubuntu 安装 redis集群
- 天下数据浅谈服务器稳定性对于网站有哪些突出影响
- 继承、实现、依赖、关联、聚合、组合的联系与区别
- 位于美国PR机房的VPS——alpharacks速度测试
- c#之如何安全的跨线程访问控件
- java实现多线程的三种方式
- 升级Ember到2.2.0版本
- 测试_51CTO的博客
- 精确运算避免使用float和double
- Ambari在离线环境中安装Hadoop集群
- 【转】一个短URL生成算法
- Tomcat7.0配置JNDI数据源
- git commit 回退
- SQL(mysql)通过生日字段得到年龄
- QQ侧滑删除分享(工具类)
- 今天有空,写了一个自定义控件 也就是发送短信的按钮
- redis数据结构-简单动态字符串(sds)
- sublime text 2.0.2 配置