行为和脚本
jtopo提供了行为控制系统(behaviourSystem),可以将写好的脚本(函数)应用到指定的图元对象(Node、Link)上。
脚本定义
js
import {
Stage,
Layer,
} from '@jtopo/core';
// jtopo 的数据和脚本是分离,分别独立存在的
// 下面演示:1. 创建空场景 2. 加载 3. 执行脚本
// 1. 创建空的场景
const stage = new Stage('divId');
const layer = new Layer();
stage.addChild(layer);
stage.show();
// 事先准备好一个场景信息 (json数据可以通过编辑器或者序列化得到)
let sceneInfo = {
// 数据(layer序列化的字符串)
json: '{version":"2.4.0","Roots":[0],"Styles":......}';
// 脚本 (函数的形式存在,两个入参: stage,layer, jtopo)
script: function (stage, layer, jtopo) {
// 脚本涉及到的对象引用通过 layer.querySelector()方法来获取
let leaderNode = layer.querySelector('[text="leader"]');
let node = layer.querySelector('[name="myNode"]');
// leaderNode 和 node 是同级,并非父子关系
// 事件触发执行
node.on('click', function(){
node.text = 'clicked';
});
// 定义一个可复用的行为 : ‘将节点附着到另外一个节点的右上角’
stage.behaviourSystem.defBehaviour('附着右上角', {
// 初始化仅第一次执行
first(node) {
node.text = '';
},
// 每一帧绘制前执行
update(node, context) {
let leaderNode = context[0];
// 计算leaderNode的右上角坐标,并修改node的xy
node.x = leaderNode.x + leaderNode.width * 0.5;
node.y = leaderNode.y - leaderNode.height * 0.5;
}
});
// 行为执行时的’上下文环境‘
let context = [leaderNode];
// 为节点node对象添加一个名为 '附着右上角' 的行为控制
stage.behaviourSystem.addBehaviour(node, '附着右上角', context);
}
}
// 2. 加载数据
layer.openJson(sceneInfo.json);
// 3. 运行脚本
layer.runScript(sceneInfo.script);
脚本序列化
从 2.4.0 版本开始:
序列化时:脚本可以在序列化时嵌入到json中了。
反序列化时:可以通过Runtime来执行, 如下示例:
js
import {Runtime} from '@jtopo/core';
// 三个入参:stage, layer, jtopo
function myScript(stage, layer, jtopo) {
let fromNode = layer.querySelector('[name="fromNode"]');
// 注意:此时是运行时,已经脱离了开发环境, 用过jtopo引用来访问各种类对象
let node = new jtopo.Node('');
layer.addChild(node);
//....
}
// 序列化时把脚本代码嵌入json, 增加了info字段,可以增加画面的额外信息
const withScriptJson = layer.toFileJson({
script: myScript.toString(),
info: {
author: 'Jack',
date: '2020-01-01',
description: 'XXX车间控制图-A'
//...
}
});
// 反序列化加载数据时
layer.openJson(withScriptJson).then((jsonObj)=>{
// 执行脚本
Runtime.execute(jsonObj.script, layer);
});