Canvas 在Famo.us中绘制曲面之间的地块线?

Canvas 在Famo.us中绘制曲面之间的地块线?,canvas,svg,famo.us,Canvas,Svg,Famo.us,我的目标是能够以一种看起来非常好的方式渲染图形数据库(通过线连接的节点),并在添加新节点时平滑地设置动画。我一直在关注SVG、Canvas,现在又开始关注Famo.us Famo.us似乎对这一点有好处,因为我可以使用Famo.us曲面来渲染每个节点,包括HTML格式的文本和控件。问题是绘制连接节点的线。Famo.us没有线条这样的基本体。它确实有画布表面,但这似乎不是正确的方法 我猜我必须为每条线做一些非常尴尬的事情,比如创建一个高而薄的曲面,然后计算一个变换,使它连接两个曲面。尽管我自己没有

我的目标是能够以一种看起来非常好的方式渲染图形数据库(通过线连接的节点),并在添加新节点时平滑地设置动画。我一直在关注SVG、Canvas,现在又开始关注Famo.us

Famo.us似乎对这一点有好处,因为我可以使用Famo.us曲面来渲染每个节点,包括HTML格式的文本和控件。问题是绘制连接节点的线。Famo.us没有线条这样的基本体。它确实有画布表面,但这似乎不是正确的方法


我猜我必须为每条线做一些非常尴尬的事情,比如创建一个高而薄的曲面,然后计算一个变换,使它连接两个曲面。

尽管我自己没有尝试过类似的方法。我见过一些开发中的东西,涉及一位著名的美国检查员。这基本上是一个chrome的扩展,吸引了一个著名的美国场景的继承权

如果您可能分析代码,并亲自安装扩展以查看其运行情况,那么您可能会找到一条实现所需结果的途径。如果我还记得的话,层次结构是以家谱样式绘制的,它允许动态添加和删除由流体线连接的节点

当然,它正在开发中,可能是一个摇摇晃晃的原型,所以不要期望任何支持或反馈


为什么不使用具有一个狭窄维度和旋转变换的曲面

var lineSurface = new Surface({
  size: [150,1],
  properties: {
    backgroundColor: 'white'
  }
});

var rotateModifier = new StateModifier({
  transform: Transform.rotateZ(Math.PI/4)
});

mainContext.add(rotateModifier1).add(lineSurface);

下面是两个可拖动曲面的工作示例,它们之间有一条直线。该线是使用另一个曲面创建的

运行演示

var引擎=著名的.core.Engine;
var Surface=著名的.core.Surface;
var修饰符=著名的.core.Modifier;
var Transform=著名的.core.Transform;
var Draggable=著名的.modifiers.Draggable;
var StateModifier=著名的.modifiers.StateModifier;
var mainContext=Engine.createContext();
var lineOptions={厚度:2,
线条颜色:'#FA5C4F'};
//线表面
var ls=新曲面({
来源:[0,5],
特性:{
backgroundColor:lineOptions.lineColor
}
});
initLine();
//添加将由直线连接的2个块
ls.s1=createBlock(“s1”[100100]);
ls.s2=createBlock(“s2”,[300100]);
//----------------------
//辅助函数
//----------------------
函数initLine(){
var canvasModifier=新修改器({
大小:函数(){
var len=_getLineLength()+5;
返回[len,lineOptions.thickness];
},
转换:函数(){
var p=_getPosition();
返回Transform.translate(p[0],p[1],0);
}
});
var rotateModifier=新修改器({
转换:函数(){
var_s=_getRect();
var angle=Math.atan2(_s[1],_s[0]);
返回变换rotateZ(角度);
} 
});
add(canvasModifier).add(rotateModifier).add(ls);
}
函数createBlock(cnt,初始位置){
var s=新曲面(
{大小:[100100],
内容:cnt,
特性:{
颜色:'白色',
textAlign:'中心',
背景颜色:“#FA5C4F”
}
});
//保存新曲面的当前位置
s、 当前位置=初始位置;
var draggable=新的draggable();
draggable.obj=s;
s、 管道(可拖动);
mainContext.add(可拖动).add(s);
可拖动。设置位置(初始位置);
draggable.on('update',函数(e){
this.obj.currentPosition=e.position;
});
返回s;
}
//获取行的起始位置
函数_getPosition(){
var dta=_getObjects();
var pnts=_getEndPoints(dta);
返回pnts[0];
}
//获取要计算低静脉压的线的Dx和Dy
函数_getRect(){
var-res=[0,0];
var dta=_getObjects();
var pnts=_getEndPoints(dta);
var p1=pnts[0];
var p2=pnts[1];
res[0]=p2[0]-p1[0];
res[1]=p2[1]-p1[1];
返回res;
}
函数_getLineLength(){
var res=_getRect();
返回Math.sqrt((res[0]*res[0])+(res[1]*res[1]);
}
函数_getEndPoints(dta){
var dx=dta.rm.currentPosition[0]-dta.lmredge;
var dy=dta.bm.currentPosition[1]-dta.tmbedge;

如果((dx)存储库不再公开(或被删除),你有什么进展吗?我问自己同样的问题。我放弃了Famo.us,决定使用canvas和svg作为更好的选择。这很好。他们应该将其作为原语合并到Famo.us中。
var Engine = famous.core.Engine;
var Surface = famous.core.Surface;
var Modifier = famous.core.Modifier;
var Transform = famous.core.Transform;
var Draggable = famous.modifiers.Draggable;
var StateModifier = famous.modifiers.StateModifier;

var mainContext = Engine.createContext();


var lineOptions = {thickness:2,
                 lineColor:'#FA5C4F'};

//line surface
var ls = new Surface({
    origin:[0,.5],
    properties:{
      backgroundColor:lineOptions.lineColor
    }
});
initLine();
//Add the 2 blocks that will be joined by the line
ls.s1 = createBlock("s1",[100,100]);
ls.s2 = createBlock("s2",[300,100]);


//----------------------
//  HELPER FUNCTIONS
//----------------------
function initLine(){
var canvasModifier = new Modifier({
    size:function(){
      var len = _getLineLength()+5;
      return [len,lineOptions.thickness];
    },
    transform: function() {
        var p = _getPosition();
        return Transform.translate(p[0], p[1], 0);
    }
  });

var rotateModifier = new Modifier({
  transform: function (){
    var _s = _getRect();
    var angle  = Math.atan2(_s[1],_s[0]);
    return Transform.rotateZ(angle);
  } 
});

mainContext.add(canvasModifier).add(rotateModifier).add(ls);  
}

function createBlock(cnt,initialPosition){
var s = new Surface(
{ size:[100,100],
  content:cnt,
  properties:{
    color: 'white',
    textAlign: 'center',
    backgroundColor: '#FA5C4F'
  }
});
//Save the current position of the new surface
s.currentPosition = initialPosition;
var draggable = new Draggable();
draggable.obj = s;
s.pipe(draggable);
mainContext.add(draggable).add(s);
draggable.setPosition(initialPosition);
draggable.on('update',function(e){
  this.obj.currentPosition = e.position;   
});
return s;
}

//gets the position of where the line should start
function _getPosition(){
var dta = _getObjects();
var pnts = _getEndPoints(dta);
return pnts[0];
}

//Gets the Dx and Dy of line to calculate hypotenous
function _getRect(){
var res = [0,0];
var dta = _getObjects();
var pnts = _getEndPoints(dta);
var p1 = pnts[0];
var p2 = pnts[1];
res[0] = p2[0]-p1[0];
res[1] = p2[1]-p1[1];
return res;
}
function _getLineLength(){
var res = _getRect();
return Math.sqrt( ((res[0] * res[0]) + (res[1] * res[1])) );
}


function _getEndPoints(dta){
var dx = dta.rm.currentPosition[0]-dta.lmredge;
var dy = dta.bm.currentPosition[1]-dta.tmbedge;
if ( (dx <= 0) && (dy <= 0) ) {
  //objects are overlapping. Draw no line
  return [[0,0],[0,0]];
}
else if (dx > dy){
  //draw line from R and L edges
  var lmYMidPoint = dta.lm.currentPosition[1]+(dta.lm.size[1]/2);
  var rmYMidPoint = dta.rm.currentPosition[1]+(dta.rm.size[1]/2);
  var p1 = [dta.lmredge,lmYMidPoint];
  var p2 = [dta.rm.currentPosition[0],rmYMidPoint];
  return [p1,p2];
}
else {
  //draw line from B and Top edges
  var tmXMidPoint = dta.tm.currentPosition[0]+(dta.tm.size[0]/2);
  var bmXMidPoint = dta.bm.currentPosition[0]+(dta.bm.size[0]/2);
  var p1 = [tmXMidPoint,dta.tmbedge];
  var p2 = [bmXMidPoint,dta.bm.currentPosition[1]];
  return [p1,p2];
}
}

//Mark the objects as 
//top most, left most, bottom most, right most
function _getObjects(){
var lm = _getLeftMost(ls);
var rm = ls.s1;
if (lm == rm){
  rm = ls.s2;
}
var tm = _getTopMost(ls);
var bm = ls.s1;
if (tm == bm){
  bm = ls.s2;
}

var lm_redge = (lm.currentPosition[0]+lm.size[0]);
var lm_bedge = (lm.currentPosition[1]+lm.size[1]);
var rm_redge = (rm.currentPosition[0]+rm.size[0]);
var rm_bedge = (rm.currentPosition[1]+rm.size[1]);

var tm_redge = (tm.currentPosition[0]+tm.size[0]);
var tm_bedge = (tm.currentPosition[1]+tm.size[1]);
var bm_redge = (bm.currentPosition[0]+bm.size[0]);
var bm_bedge = (bm.currentPosition[1]+bm.size[1]);


return {lm:lm,rm:rm,tm:tm,bm:bm,
        lmredge:lm_redge,
        lmbedge:lm_bedge,
        rmredge:rm_redge,
        rmbedge:rm_bedge,
        tmredge:tm_redge,
        tmbedge:tm_bedge,
        bmredge:bm_redge,
        bmbedge:bm_bedge};
}

function _getLeftMost(obj){
if (obj.s1.currentPosition[0] <= obj.s2.currentPosition[0]){
  return obj.s1;
} else {
  return obj.s2;
}
}

function _getTopMost(obj){
if (obj.s1.currentPosition[1] <= obj.s2.currentPosition[1]){
  return obj.s1;
} else {
  return obj.s2;
}
}