gpt4 book ai didi

javascript - 在 svg 路径中​​动态绘制箭头不起作用

转载 作者:行者123 更新时间:2023-11-28 04:36:06 26 4
gpt4 key购买 nike

var Belay = (function () {
var settings = {
strokeColor: '#fff',
strokeWidth: 2,
opacity: 1,
fill: 'none',
animate: true,
animationDirection: 'right',
animationDuration: .75
};
var me = {};

me.init = function (initObj) {
if (initObj) {
$.each(initObj, function (index, value) {
//TODO validation on settings
settings[index] = value;
});
}
}

me.set = function (prop, val) {
//TODO validate
settings[prop] = val;
}

me.on = function (el1, el2) {
var $el1 = $(el1);
var $el2 = $(el2);
if ($el1.length && $el2.length) {
var svgheight, p, svgleft, svgtop, svgwidth

var el1pos = $(el1).offset();
var el2pos = $(el2).offset();

var el1H = $(el1).outerHeight();
var el1W = $(el1).outerWidth();

var el2H = $(el2).outerHeight();
var el2W = $(el2).outerWidth();

var node1X = Math.round(el1pos.left + el1W);
var node2X = Math.round(el2pos.left);
var overlapping = node1X >= node2X;

var svgwidth = Math.abs(node2X - node1X);
var svgleft = Math.min(node1X, node2X);

var node1Y = Math.round(el1pos.top + el1H / 2);
var node2Y = Math.round(el2pos.top + el1H / 2);

var svgheight = Math.abs(node1Y - node2Y);
var svgtop = Math.min(node1Y, node2Y);

var pt1x = node1X - svgleft;
var pt1y = node1Y - svgtop + settings.strokeWidth;
var pt2x = node2X - svgleft;
var pt2y = node2Y - svgtop + settings.strokeWidth;

// cpt is the length of the control point vector
// variew with distance netween boxes
var cpt = Math.round(svgwidth * Math.min(svgheight / 300, 1));

if (overlapping) {
// Need to widen the svg because otherwise the bezier control
// points (and hence the curve) will extend outside it.
svgleft -= cpt;
svgwidth += 2 * cpt;
pt1x += cpt;
pt2x += cpt;
}

// Build the path decription
p = "M" + pt1x + "," + pt1y +
" L" + (pt1x + pt2x) / 8 + "," + pt1y +
" L" + (pt1x + pt2x) / 8 + "," + pt2y //+
" L" + (pt2x) / 1.03 + "," + pt2y +
" L" + (pt2x) / 1.03 + "," + (pt2y - 5) +
" L" + pt2x + "," + pt2y +
" L" + (pt2x) / 1.03 + "," + (pt2y + 5) +
" L" + (pt2x) / 1.03 + "," + pt2y;

//ugly one-liner
$ropebag = $('#ropebag').length ? $('#ropebag') : $('body').append($("<div id='ropebag' />")).find('#ropebag');

var svgnode = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
var defs = document.createElementNS('http://www.w3.org/2000/svg', "defs");
var marker = document.createElementNS('http://www.w3.org/2000/svg', "marker");
var path = document.createElementNS('http://www.w3.org/2000/svg', "path");

marker.setAttributeNS(null,"id","arrow");
marker.setAttributeNS(null,"markerWidth","13");
marker.setAttributeNS(null,"markerHeight","13");
marker.setAttributeNS(null,"refX","2");
marker.setAttributeNS(null,"refY","7");
marker.setAttributeNS(null,"markerUnits","userSpaceOnUse");
path.setAttributeNS(null,"d","M2,2 L2,13 L8,7 L2,2");

marker.appendChild(path);
defs.appendChild(marker);

var newpath = document.createElementNS('http://www.w3.org/2000/svg', "path");
newpath.setAttributeNS(null, "d", p);
newpath.setAttributeNS(null, "stroke", settings.strokeColor);
newpath.setAttributeNS(null, "stroke-width", settings.strokeWidth);
newpath.setAttributeNS(null, "opacity", settings.opacity);
newpath.setAttributeNS(null, "fill", settings.fill);
newpath.setAttributeNS(null, "marker-end", "url(#arrow)");

svgnode.appendChild(newpath);
svgnode.appendChild(defs);

$(svgnode).css({
left: svgleft,
top: svgtop - settings.strokeWidth,
position: 'absolute',
width: svgwidth,
height: svgheight + settings.strokeWidth * 2,
minHeight: '20px',
'pointer-events': 'none'
});
$ropebag.append(svgnode);
if (settings.animate) {
// THANKS to http://jakearchibald.com/2013/animated-line-drawing-svg/
var pl = newpath.getTotalLength();
// Set up the starting positions
newpath.style.strokeDasharray = pl + ' ' + pl;

if (settings.animationDirection == 'right') {
newpath.style.strokeDashoffset = pl;
} else {
newpath.style.strokeDashoffset = -pl;
}

// Trigger a layout so styles are calculated & the browser
// picks up the starting position before animating
// WON'T WORK IN IE. If you want that, use requestAnimationFrame to update instead of CSS animation
newpath.getBoundingClientRect();
newpath.style.transition = newpath.style.WebkitTransition = 'stroke-dashoffset ' + settings.animationDuration + 's ease-in-out';
// Go!
newpath.style.strokeDashoffset = '0';
}
}
}

me.off = function () {
$("#ropebag").empty();
}

return me;
}());


/*********************** Custom JavaScript **********************************/


$(document).ready(function () {


$(".draggable").draggable({
drag: function (event, ui) {
Belay.off();
drawConnectors();
}
});



function drawConnectors() {
$(".parent").each(function () {
var theID = this.id;
$("." + theID).each(function (i, e) {
var rand = Math.random() * .7 + .3;
Belay.set('animationDuration', rand)
Belay.on($("#" + theID), e)
});
})
}

$(window).resize(function () {
Belay.off();
drawConnectors();
});

Belay.init({
strokeWidth: 1
});
Belay.set('strokeColor', '#999');
drawConnectors();
});
.row{
margin-top:2in;
}

.box{
border:1px solid #ccc;
padding:10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js"></script>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet"/>

<body>
<div class="row">
<div class="col-md-4">
<div class="pull-left ">
<div class="parent draggable box" id="parent1">Left drag</div>
</div>

<div class="pull-right">
<div class="child parent1 draggable box">Right drag</div>
</div>
</div>
</div>
</body>

嗨,按照这个例子 how-to-change-the-lines-between-two-points-from-curved-to-straight-lines-with-on如何动态地在路径末尾绘制箭头

有人可以告诉我在代码中添加标记结尾有什么问题

var Belay = (function () 
{
var settings = {
strokeColor: 'red',
strokeWidth: 2,
opacity: 1,
fill: 'none',
animate: true,
animationDirection: 'right',
animationDuration: .75
};
var me = {};

me.init = function (initObj) {
if (initObj) {
$.each(initObj, function (index, value) {
//TODO validation on settings
settings[index] = value;
});
}
}

me.set = function (prop, val) {
//TODO validate
settings[prop] = val;
}

me.on = function (el1, el2) {
var $el1 = $(el1);
var $el2 = $(el2);
if ($el1.length && $el2.length) {
var svgheight, p, svgleft, svgtop, svgwidth

var el1pos = $(el1).offset();
var el2pos = $(el2).offset();

var el1H = $(el1).outerHeight();
var el1W = $(el1).outerWidth();

var el2H = $(el2).outerHeight();
var el2W = $(el2).outerWidth();

var node1X = Math.round(el1pos.left + el1W);
var node2X = Math.round(el2pos.left);
var overlapping = node1X >= node2X;

var svgwidth = Math.abs(node2X - node1X);
var svgleft = Math.min(node1X, node2X);

var node1Y = Math.round(el1pos.top + el1H / 2);
var node2Y = Math.round(el2pos.top + el1H / 2);

var svgheight = Math.abs(node1Y - node2Y);
var svgtop = Math.min(node1Y, node2Y);

var pt1x = node1X - svgleft;
var pt1y = node1Y - svgtop + settings.strokeWidth;
var pt2x = node2X - svgleft;
var pt2y = node2Y - svgtop + settings.strokeWidth;

// cpt is the length of the control point vector
// variew with distance netween boxes
var cpt = Math.round(svgwidth * Math.min(svgheight / 300, 1));

if (overlapping) {
// Need to widen the svg because otherwise the bezier control
// points (and hence the curve) will extend outside it.
svgleft -= cpt;
svgwidth += 2 * cpt;
pt1x += cpt;
pt2x += cpt;
}

p = "M" + pt1x + "," + pt1y +
" L" + (pt1x + pt2x) / 8 + "," + pt1y +
" L" + (pt1x + pt2x) / 8 + "," + pt2y +
" L" + (pt2x) / 1.03 + "," + pt2y +
" L" + (pt2x) / 1.03 + "," + (pt2y - 5) +
" L" + pt2x + "," + pt2y +
" L" + (pt2x) / 1.03 + "," + (pt2y + 5) +
" L" + (pt2x) / 1.03 + "," + pt2y;

//ugly one-liner
$ropebag = $('#ropebag').length ? $('#ropebag') : $('body').append($("<div id='ropebag' />")).find('#ropebag');

var svgnode = document.createElementNS('http://www.w3.org/2000/svg', 'svg');

//try
var defs = document.createElementNS('http://www.w3.org/2000/svg', "defs");
var marker = document.createElementNS('http://www.w3.org/2000/svg', "marker");
var path = document.createElementNS('http://www.w3.org/2000/svg', "path");

marker.setAttributeNS(null,"id","arrow");
marker.setAttributeNS(null,"markerWidth",10);
marker.setAttributeNS(null,"markerHeight",10);
marker.setAttributeNS(null,"refX",0);
marker.setAttributeNS(null,"refY",5);
marker.setAttributeNS(null,"viewbox","0 0 10 10");
marker.setAttributeNS(null,"orient","auto");
marker.setAttributeNS(null,"markerUnits","strokeWidth");

path.setAttributeNS(null,"d","M 0 0 L 10 5 L 0 10");
////try
marker.appendChild(path);
defs.appendChild(marker);

var newpath = document.createElementNS('http://www.w3.org/2000/svg', "path");
newpath.setAttributeNS(null, "d", p);
newpath.setAttributeNS(null, "stroke", settings.strokeColor);
newpath.setAttributeNS(null, "stroke-width", settings.strokeWidth);
newpath.setAttributeNS(null, "opacity", settings.opacity);
newpath.setAttributeNS(null, "fill", settings.fill);
newpath.setAttributeNS(null, "marker-end", "url(#arrow)");

newpath.appendChild(defs);


svgnode.appendChild(newpath);
//for some reason, adding a min-height to the svg div makes the lines appear more correctly.
$(svgnode).css({
left: svgleft,
top: svgtop - settings.strokeWidth,
position: 'absolute',
width: svgwidth,
height: svgheight + settings.strokeWidth * 2,
minHeight: '20px',
'pointer-events': 'none'
});
$ropebag.append(svgnode);
if (settings.animate) {
// THANKS to http://jakearchibald.com/2013/animated-line-drawing-svg/
var pl = newpath.getTotalLength();
// Set up the starting positions
newpath.style.strokeDasharray = pl + ' ' + pl;

if (settings.animationDirection == 'right') {
newpath.style.strokeDashoffset = pl;
} else {
newpath.style.strokeDashoffset = -pl;
}

// Trigger a layout so styles are calculated & the browser
// picks up the starting position before animating
// WON'T WORK IN IE. If you want that, use requestAnimationFrame to update instead of CSS animation
newpath.getBoundingClientRect();
newpath.style.transition = newpath.style.WebkitTransition = 'stroke-dashoffset ' + settings.animationDuration + 's ease-in-out';
// Go!
newpath.style.strokeDashoffset = '0';
}
}
}

me.off = function ()
{
$("#ropebag").empty();
}

return me;
} ());

function drawConnectors()
{

}

最佳答案

您似乎没有将 newpath 附加到任何内容。

此外,您还将 defs 附加到 newpath。我不确定这是否有效(我从未尝试过)。你应该避免这样做。将 defs 附加到 SVG。

关于javascript - 在 svg 路径中​​动态绘制箭头不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44195693/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com