[英]Flow Builder (visual editor)
I want to build a Flow Builder for my clients to give them an entirely way to construct data inside my dashboard editor, inspired with manychat flow builder我想为我的客户构建一个 Flow Builder,为他们提供一种在我的仪表板编辑器中构建数据的完整方式,灵感来自于manychat flow builder
I have a simple app which has UI editor I have a need to build a workflow tool, allowing people to drag nodes onto a canvas, connect outlets of nodes to inputs of other nodes... Zoom.etc.我有一个简单的应用程序,它有 UI 编辑器我需要构建一个工作流工具,允许人们将节点拖到画布上,将节点的出口连接到其他节点的输入...... Zoom.etc。
I am inspired with a manychat editor which u can see it here https://manychat.com/我受到了一个多聊天编辑器的启发,你可以在这里看到它https://manychat.com/
More how it look in manychat更多它在多聊天中的样子
Looking for suggestions on how to get started... Curious if there are frameworks/libraries anyone would recommend making this easier or just confirmation that I should just start whipping out Javascript to handle the drags/drops/line drawing/etc.寻找关于如何开始的建议......好奇是否有框架/库,有人会建议让这更容易,或者只是确认我应该开始使用 Javascript 来处理拖放/画线/等。
I have found this library named rete.js我找到了这个名为 rete.js 的库
So far this is what I have.到目前为止,这就是我所拥有的。
js js
var numSocket = new Rete.Socket('Number value');
var VueNumControl = {
props: ['readonly', 'emitter', 'ikey', 'getData', 'putData'],
template: '<input type="number" :readonly="readonly" :value="value" @input="change($event)" @dblclick.stop="" @pointermove.stop=""/>',
data() {
return {
value: 0,
}
},
methods: {
change(e){
this.value = +e.target.value;
this.update();
},
update() {
if (this.ikey)
this.putData(this.ikey, this.value)
this.emitter.trigger('process');
}
},
mounted() {
this.value = this.getData(this.ikey);
}
}
class NumControl extends Rete.Control {
constructor(emitter, key, readonly) {
super(key);
this.component = VueNumControl;
this.props = { emitter, ikey: key, readonly };
}
setValue(val) {
this.vueContext.value = val;
}
}
class NumComponent extends Rete.Component {
constructor(){
super("Number");
}
builder(node) {
var out1 = new Rete.Output('num', "Number", numSocket);
return node.addControl(new NumControl(this.editor, 'num')).addOutput(out1);
}
worker(node, inputs, outputs) {
outputs['num'] = node.data.num;
}
}
class AddComponent extends Rete.Component {
constructor(){
super("Add");
}
builder(node) {
var inp1 = new Rete.Input('num1',"Number", numSocket);
var inp2 = new Rete.Input('num2', "Number2", numSocket);
var out = new Rete.Output('num', "Number", numSocket);
inp1.addControl(new NumControl(this.editor, 'num1'))
inp2.addControl(new NumControl(this.editor, 'num2'))
return node
.addInput(inp1)
.addInput(inp2)
.addControl(new NumControl(this.editor, 'preview', true))
.addOutput(out);
}
worker(node, inputs, outputs) {
var n1 = inputs['num1'].length?inputs['num1'][0]:node.data.num1;
var n2 = inputs['num2'].length?inputs['num2'][0]:node.data.num2;
var sum = n1 + n2;
this.editor.nodes.find(n => n.id == node.id).controls.get('preview').setValue(sum);
outputs['num'] = sum;
}
}
(async () => {
var container = document.querySelector('#rete');
var components = [new NumComponent(), new AddComponent()];
var editor = new Rete.NodeEditor('demo@0.1.0', container);
editor.use(ConnectionPlugin.default);
editor.use(VueRenderPlugin.default);
editor.use(ContextMenuPlugin.default);
editor.use(AreaPlugin);
editor.use(CommentPlugin.default);
editor.use(HistoryPlugin);
editor.use(ConnectionMasteryPlugin.default);
var engine = new Rete.Engine('demo@0.1.0');
components.map(c => {
editor.register(c);
engine.register(c);
});
var n1 = await components[0].createNode({num: 2});
var n2 = await components[0].createNode({num: 0});
var add = await components[1].createNode();
n1.position = [80, 200];
n2.position = [80, 400];
add.position = [500, 240];
editor.addNode(n1);
editor.addNode(n2);
editor.addNode(add);
editor.connect(n1.outputs.get('num'), add.inputs.get('num1'));
editor.connect(n2.outputs.get('num'), add.inputs.get('num2'));
editor.on('process nodecreated noderemoved connectioncreated connectionremoved', async () => {
console.log('process');
await engine.abort();
await engine.process(editor.toJSON());
});
editor.view.resize();
AreaPlugin.zoomAt(editor);
editor.trigger('process');
})();
Here is HTML这是 HTML
<div id="rete"></div>
<a target="_blank" href="https://github.com/retejs/rete"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/652c5b9acfaddf3a9c326fa6bde407b87f7be0f4/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6f72616e67655f6666373630302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png"></a>
Here is codepen code pen demo这是codepen代码笔演示
Unfortunately, this does not give what I want,不幸的是,这并没有给我想要的,
What do I need to do to get what I need?我需要做什么才能得到我需要的东西? or is there any library which I can try?
或者有没有我可以尝试的图书馆?
ManyChat uses PIXI.js to build the flow builder. ManyChat 使用 PIXI.js 来构建流构建器。 I found out myself when reading through their bundle codes (who the hell read compiled codes, yes I did :))
我在阅读他们的捆绑代码时发现了自己(谁他妈的阅读了编译代码,是的,我做到了:))
Seems like they use React-PIXI - a react wrapper of PIXI.js (I'm not sure about this)似乎他们使用 React-PIXI - PIXI.js 的反应包装器(我不确定这一点)
From that observation I can build my own one using VueJS (in a project of my previous company)根据这一观察,我可以使用 VueJS 构建自己的一个(在我以前公司的一个项目中)
You should take a look at PIXI.你应该看看 PIXI。 Some important notices for you (all I collect from Manychat's idea and during my implementation):
给您的一些重要通知(我从Manychat 的想法和实施过程中收集的所有信息):
<canvas width="400" height="600" style="width: 200px; height: 300px;"></canvas>
main.js
main.js
),它在main.js
tween.js
tween.js
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.