这是我尝试翻译成代码的照片。
我还有一些"概念"我需要布置的区域,并且很难找到一种方法,以便以响应方式实现这一目标。我最初的想法就是将所有内容都排除在线条之外,这样我就可以根据每个屏幕尺寸调整它们的位置,然后返回并使用媒体查询为每个元素移位做一组线条来切换它们。对于小型平板电脑和手机尺寸,我认为我只是将粗略的草图做得更大,并且线条指向的每个部分上都有很少的图标,这会打开一个弹出窗口给出解释。
到目前为止,我在这里发现了一些帖子,展示了如何使用SVG和Canvas绘制线条,但我注意到他们给出的示例仅适用于他们设计的窗口大小,当我重新调整了小提琴窗口的大小。一切顺利。
我遇到了几个jsPlumb受到高度赞扬的帖子,虽然我肯定会开始学习和使用它,到目前为止,它似乎不适合我想要做的事情,特别是其他而不管它们在源和目标之间创建和维持一条线的事实,无论它们位于何处。我觉得它的拖延本质对于我想要做的事情是不必要的,并且无法找出是否有办法打开和关闭它,我不希望有人试图向下滚动他们的手机并且卡在屏幕上滑动。
事实证明,在jsPlumb上真的没有多少,但是看着它导致我去了GoJS,这看起来与jsPlumb非常相似但是再一次,我无法找到大量的关于它的信息或许多人深入了解如何用它做事的视频。
我遇到了SVGjs并对其进行了调查,但是从我看到的例子看来,它与我看到的第一个看起来不具备灵活性的SVG和Canvas示例几乎相同。最重要的是,我现在正处于一个可以"宝贝说话的地步"在javascript中,虽然我能够理解它足以识别我不理解和查找的内容,但我还不够流畅地跟上我发现的关于这些库的信息的基调这是为那些已经深入了解JS深度而不需要更多解释的人编写的。
我通常知道你们更喜欢看到我们迄今为止修改的代码示例,以便解决实际编码问题,而不是问你如何做某事n你是否为我们做了所有的编码工作,但我和#39;我甚至不知道该怎么做才能做到这一点。因此,我希望你们能够看到我真正试图以最好的方式接近这个目标,而且不会让我失望。我真的不知道从哪里开始。
答案 0 :(得分:4)
客观地说,看起来你试图在HTML元素中任意锚定的两个点之间绘制一些连接线。在类似的项目中,我使用了这个配方:
结果是一个div,在A点有一个底角,另一个在B点,产生了一个非常好的线,我可以完全控制它。
你需要两次这样才能获得肘关节。您可以在页面渲染或重绘等后触发绘制。
下面的代码段中的工作示例 - 可能在全屏幕中运行最佳,并且在代码集http://codepen.io/JEE42/pen/aBOQGj中以防您想要播放。
/*
muConnector - a class to create a line joining two elements.
To use, call new with id's of both elements and optonal lineStyle (which must be a valid css border line def such as '1px solid #000' , e.g.
var c1=new Connector(id1, id2, lineStyle)
Default line style is '1px solid #666666'
Whatever you use for drag control, call moved(e, ele) per increment of movement, where e=event and ele=the jq element being moved.
*/
var Connector = function(params) {
if (typeof(params) == "undefined") { return false }; // If no params then abandon.
// Process input params.
var ele1=params.ele1 || ''; // First element to link
var ele2=params.ele2 || ''; // Second element to link
if ( ele1.length === 0 || ele2.length === 0) { return false }; // If not two element id's then abandon.
var className=params.class || 'muConnector'
var lineStyle=params.lineStyle || '1px solid #666666'; // CSS style for connector line.
this.gapX1=params.gapX1 || 0; // First element gap before start of connector, etc
this.gapY1=params.gapY1 || 0;
this.gapX2=params.gapX2 || 0;
this.gapY2=params.gapY2 || 0;
this.gap=params.gap || 0; // use a single gap setting.
if ( this.gap > 0 ) {
this.gapX1 = this.gap
this.gapY1 = this.gap
this.gapX2 = this.gap
this.gapY2 = this.gap
}
var pos = function() { // only used for standalone drag processing.
this.left = 0;
this.top = 0;
}
this.PseudoGuid = new (function() { // Make a GUID to use in unique id assignment - from and credit to http://stackoverflow.com/questions/226689/unique-element-id-even-if-element-doesnt-have-one
this.empty = "00000000-0000-0000-0000-000000000000";
this.GetNew = function() {
var fC = function() { return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1).toUpperCase(); }
return (fC() + fC() + "-" + fC() + "-" + fC() + "-" + fC() + "-" + fC() + fC() + fC());
};
})();
this.id = this.PseudoGuid.GetNew(); // use guid to avoid id-clashes with manual code.
this.ele1=($('#'+ele1));
this.ele2=($('#'+ele2));
// Append the div that is the link line into the DOM
this.lineID='L' + this.id;
$('body').append("<div id='" + this.lineID + "' class='" + className + "' style= ></div>")
this.line = $('#L'+ this.id);
this.line.css({ position: 'absolute', 'border-left': this.lineStyle, 'z-index': -100 })
// We may need to store the offsets of each element that we are connecting.
this.offsets=[];
this.offsets[ele1]=new pos;
this.offsets[ele2]=new pos;
this.link(); // show the initial link
}
/*
Approach: draw a zero width rectangle where the top left is located at the centre of ele1.
Compute and make rectangle height equal to the distance between centres of ele1 and ele2.
Now rotate the rectangle to the angle between the points.
Note tracks the edges of the elements so as not to overlay / underlay.
Also can accommodate a gap between edge of element and start of line.
*/
Connector.prototype.link=function link() {
var originX = this.ele1.offset().left + this.ele1.outerWidth() / 2;
var originY = this.ele1.offset().top + this.ele1.outerHeight() / 2;
var targetX = this.ele2.offset().left + this.ele2.outerWidth() / 2;
var targetY = this.ele2.offset().top + this.ele2.outerHeight() / 2;
var l = this.hyp((targetX - originX),(targetY - originY));
var angle = 180 / 3.1415 * Math.acos((targetY - originY) / l);
if(targetX > originX) { angle = angle * -1 }
// Compute adjustments to edge of element plus gaps.
var adj1=this.edgeAdjust(angle, this.gapX1 + this.ele1.width() / 2, this.gapY1 + this.ele1.height() / 2)
var adj2=this.edgeAdjust(angle, this.gapX2 + this.ele2.width() / 2, this.gapY2 + this.ele2.height() / 2)
l = l - ( adj1.hp + adj2.hp)
this.line.css({ left: originX, height: l, width: 0, top: originY + adj1.hp })
.css('-webkit-transform', 'rotate(' + angle + 'deg)')
.css('-moz-transform', 'rotate(' + angle + 'deg)')
.css('-o-transform', 'rotate(' + angle + 'deg)')
.css('-ms-transform', 'rotate(' + angle + 'deg)')
.css('transform', 'rotate(' + angle + 'deg)')
.css('transform-origin', '0 ' + ( -1 * adj1.hp) + 'px');
}
Connector.prototype.Round = function(value, places) {
var multiplier = Math.pow(10, places);
return (Math.round(value * multiplier) / multiplier);
}
Connector.prototype.edgeAdjust = function (a, w1, h1) {
var w=0, h=0
// compute corner angles
var ca=[]
ca[0]=Math.atan(w1/h1) * 180 / 3.1415926 // RADIANS !!!
ca[1]=180 - ca[0]
ca[2]=ca[0] + 180
ca[3]=ca[1] + 180
// Based on the possible sector and angle combinations work out the adjustments.
if ( (this.Round(a,0) === 0) ) {
h=h1
w=0
}
else if ( (this.Round(a,0) === 180) ) {
h=h1
w=0
}
else if ( (a > 0 && a <= ca[0]) || (a < 0 && a >= (-1*ca[0])) ) {
h=h1
w=-1 * Math.tan(a * ( 3.1415926 / 180)) * h1
}
else if ( a > ca[0] && a <= 90 ) {
h=Math.tan((90-a) * ( 3.1415926 / 180)) * w1
w=w1
}
else if ( a > 90 && a <= ca[1] ) {
h=-1 * Math.tan((a-90) * ( 3.1415926 / 180)) * w1
w=w1
}
else if ( a > ca[1] && a <= 180 ) {
h=h1
w=-1 * Math.tan((180 - a) * ( 3.1415926 / 180)) * h1
}
else if ( a > -180 && a <= (-1 * ca[1]) ) {
h=h1
w= Math.tan((a - 180) * ( 3.1415926 / 180)) * h1
}
else if ( a > (-1 * ca[1]) && a <= 0 ) {
h=Math.tan((a-90) * ( 3.1415926 / 180)) * w1
w= w1
}
// We now have the width and height offsets - compute the hypotenuse.
var hp=this.hyp(w, h)
return {hp: hp }
}
Connector.prototype.hyp = function hyp(X, Y) {
return Math.abs(Math.sqrt( (X * X) + ( Y * Y) ))
}
Connector.prototype.moved=function moved(e, ele) {
var id=ele.attr('id');
this.link()
}
var line;
$( document ).ready(function() {
console.log( "ready!" );
var c1=new Connector({ele1: 'a', ele2: 'b', lineStyle: '1px solid red' })
Setup(c1, 'a');
Setup(c1, 'b');
var c2=new Connector({ele1: 'a', ele2: 'c', lineStyle: '1px solid red' })
Setup(c2, 'a');
Setup(c2, 'c');
var c3=new Connector({ele1: 'a', ele2: 'd', lineStyle: '1px solid red' })
Setup(c3, 'a');
Setup(c3, 'd');
var c4=new Connector({ele1: 'b', ele2: 'c'})
Setup(c4, 'b');
Setup(c4, 'c');
var c5=new Connector({ele1: 'b', ele2: 'd'})
Setup(c5, 'b');
Setup(c5, 'd');
var c6=new Connector({ele1: 'c', ele2: 'd'})
Setup(c6, 'c');
Setup(c6, 'd');
function Setup(connector, id) {
var ele=$('#'+id);
ele.on('mousedown.muConnector', function(e){
//#critical: tell the connector about the starting position when the mouse goes down.
connector.offsets[id].left=e.pageX - ele.offset().left;
connector.offsets[id].top=e.pageY - ele.offset().top;
e.preventDefault();
//hook the mouse move
ele.on('mousemove.muConnector', function(e){
ele.css({left: e.pageX - connector.offsets[id].left, top: e.pageY - connector.offsets[id].top}); //element position = mouse - offset
connector.moved(e, ele); // #critical: call the moved() function to update the connector position.
});
//define mouse up to cancel moving and mouse up, they are recreated each mousedown
$(document).on('mouseup', function(e){
ele.off('mousemove.muConnector');
//$(document).off('.muConnector');
});
});
}
});
&#13;
.thing {
width: 200px;
height: 100px;
background: transparent;
position: absolute;
border: 1px solid #666666;
}
.thing span {
display: block;
margin-left: 95px;
margin-top: 40px;
}
.muConnector {
position: absolute;
border-left: 1px dashed red;
z-index: 100;
-webkit-transform-origin: top left;
-moz-transform-origin: top left;
-o-transform-origin: top left;
-ms-transform-origin: top left;
transform-origin: top left;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span>Drag any box...</span>
<div id="a" class='thing' style='left:400px; top: 100px;'>
<span>o</span>
</div>
<div id="b" class='thing' style='left:600px; top: 300px;'>
<span>o</span>
</div>
<div id="c" class='thing' style='left:400px; top: 500px;'>
<span>o</span>
</div>
<div id="d" class='thing' style='left:200px; top: 300px;'>
<span>o</span>
</div>
&#13;
答案 1 :(得分:0)
要通过调整大小和所有内容来解决问题,请使用百分比定位元素,并以百分比形式创建大小。如果您不知道如何使用百分比的位置信息,请使用下面的javascript:
var
window_width = $(window).width(),
window_height = $(window).height(),
unique_name,
parallax_name_list = [],
parallax_positions = [];
var vtg = {
pos: function(obj){
var posType = "offset";
determineObject(obj, posType, window_width, window_height);
},
coord: function(){
detectObjectCoords();
},
}
function determineObject(obj, posType, window_width, window_height){
if (($("#"+obj).length == 0)&&($("."+obj).length == 0)){
throw new Error("VTG_SCRIPT_ERROR: Could not find element '"+obj+"'");
return;
} else if (($("#"+obj).length == 1)&&($("."+obj).length == 1)){
throw new Error("VTG_SCRIPT_ERROR: Classnames and IDs cannot not have the same name.");
return;
} else {
detectObjectType(obj, posType, window_width, window_height);
}
}
function detectObjectType(obj, posType, window_width, window_height){
var object_type;
if ($("#"+obj).length == 1){
var object_type = "id";
positionObject(obj, object_type, posType, window_width, window_height);
} else {
var object_type = "classname";
positionObject(obj, object_type, posType, window_width, window_height);
}
}
function positionObject(obj, type, posType, window_width, window_height){
var
draggable,
pos = posType,
idclass,
type,
dot = ".",
name;
if (type == "id"){
draggable = $("#"+obj).draggable();
idclass = "#";
name = idclass + obj;
unique_name = name;
} else {
draggable = $("."+obj).draggable();
idclass = ".";
name = idclass + obj;
unique_name = name;
}
var
elem = $(name).position(),
elem_top = elem.top/$(window).height() * 100,
elem_left = elem.left/$(window).width() * 100;
if ((isNaN(elem_top))&&(isNaN(elem_left))){
console.log("%cCould not calculate the position of the requested object!","font-weight: bold; color: #CC181E;");
return;
} else {
console.debug("$('"+name+"').css({ position: 'absolute', top: '"+elem_top+"%', left: '"+elem_left+"%'});");
}
}
function detectObjectCoords( ){
var
elm = $(unique_name).position(),
coords_top = elm.top/$(window).height() * 100,
coords_left = elm.left/$(window).width() * 100;
console.clear();
console.log("%cUpdating console","color: #34A953;");
console.debug("$('"+unique_name+"').css({ position: 'absolute', top: '"+coords_top+"%', left: '"+coords_left+"%'});");
return;
}
function error(msg){
throw new Error ("VTG_SCRIPT_ERROR: " + msg);
}
function checkType(name){
var new_name
if ($("#" + name).length == 1){
new_name = "#" + name;
return new_name;
}
else if ($("." + name).length == 1){
new_name = "." + name;
return new_name;
} else {
error("The element could not be found.");
return false;
}
}
function empty(word){
if (word == ""){
return true;
} else {
return false;
}
}
这段代码来自我目前正在开发的框架。它需要jQuery库。要使用它,请输入&gt; vtg.pos("your object class/id");
您应该可以拖动对象,直到刷新页面为止。对位置感到满意后,在控制台中键入vtg.coord();
并复制返回的代码并将代码粘贴到html / js文件中。如果您不确定要复制什么,返回的代码应该类似于:
$(&#39; #your item&#39;)。css({position:&#39; absolute&#39;,top:&#39; 30.841007053291534%&#39;,left:&#39; 42.31259266123054%&#39;});
您可以使用我想要的代码顶部位置
答案 2 :(得分:0)
我仍然不清楚你想要做什么,但也许GoJS简介第二页的第一个图表展示了你想要的东西:http://gojs.net/latest/intro/buildingObjects.html。那个图是现场的!现在该图表不允许用户绘制新注释,但可以在图表的编辑器版本中提供此类功能。
示例还在http://gojs.net/latest/samples/comments.html中演示了不同的评论样式,气球评论。您可以在http://gojs.net找到更多样本。