This example modifies my own
draw with nearest neighbor snap
to draw polyline using snap to chosen point.
To make snap active, circle area around desired target point should be hovered by cursor position.
This example was created to examine feasibility of such idea.
Unfortunately, choosing between densely distributed points in some cases is almost impossible.
Going closer to desired points may not help, if area around other point in close proximity is hovered already.
Sometimes it is necessary to approach to desired point from some alternate direction so as not to activate other attraction areas.
To make this example feasible, I had to decrease distance tolerance to 10 (comparing to 20 in previous case).
-
-
Save Krzysztof-FF/f256cd1aef376c754934564e8595a208 to your computer and use it in GitHub Desktop.
SVG Snap - draw utilizing plain hover snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset = "utf-8"> | |
<title> SVG Snap - draw utilizing plain hover snap </title> | |
<style> | |
.point { | |
fill: #999; | |
stroke: # fff; | |
pointer-events: none; | |
} | |
.circle { | |
fill: white; | |
fill-opacity: 0; | |
stroke: lightgrey; | |
stroke-opacity: 0.5; | |
pointer-events: all; | |
} | |
.point.selected { | |
fill: red; | |
fill-opacity: 1; | |
} | |
.circle.selected { | |
stroke: red; | |
} | |
</style> | |
<body> | |
<script src = "http://d3js.org/d3.v3.min.js"></script> | |
<script> | |
var width = 960, | |
height = 500; | |
var RADIUS = 10; | |
var data = d3.range(400).map(function () { | |
return [Math.random() * width, Math.random() * height]; | |
}); | |
var svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height) | |
.on("mousemove", function (d) { | |
var xy = d3.mouse(d3.selectAll('svg')[0][0]); | |
svg.select("#pt") | |
.attr("cx", xy[0]) | |
.attr("cy", xy[1]); | |
mousemoved(); | |
}) | |
.on("click", function (d) { | |
sel = svg.select('.selected'); | |
if (sel.empty()) { | |
sel = svg.select("#pt"); | |
} | |
if (!sel.empty()) { | |
var x = sel.attr("cx"); | |
var y = sel.attr("cy"); | |
svg.select("#pt") | |
.attr("cx", x) | |
.attr("cy", y); | |
mousemoved(); | |
poly.attr("points", poly.attr("points") + " " + x + "," + y); | |
} | |
}); | |
svg.append("circle") | |
.attr("id", "pt") | |
.attr("r", 3) | |
.attr("cx", width / 2) | |
.attr("cy", height / 2) | |
.style("fill", "yellow"); | |
var mouseCircle = svg.append("circle").classed("mouse", true) | |
.attr({ | |
r: RADIUS, | |
fill: "none", | |
stroke: "#555" | |
}); | |
var poly = svg.append("polyline") | |
.attr({ | |
points: width / 2 + "," + height / 2 + " " + width / 2 + "," + height / 2, | |
fill: "none", | |
stroke: "gray" | |
}); | |
var point = svg.selectAll(".point") | |
.data(data) | |
.enter().append("circle") | |
.attr("class", "point") | |
.attr("cx", function (d) { | |
return d[0]; | |
}) | |
.attr("cy", function (d) { | |
return d[1]; | |
}) | |
.attr("r", 3); | |
svg.selectAll(".point").each(function(d) { | |
var sibling = this.nextSibling; | |
var target = d3.select(this); | |
svg.insert("circle", function() { return sibling; }) | |
.attr("class", "circle") | |
.attr("cx", function () { | |
return target.attr("cx"); | |
}) | |
.attr("cy", function () { | |
return target.attr("cy"); | |
}) | |
.attr("r", RADIUS) | |
.on("mouseover", function() { | |
d3.select(this).classed("selected", true); | |
d3.select(this.previousSibling).classed("selected", true); | |
mouseCircle.attr("stroke", "blue"); | |
}) | |
.on("mouseout", function() { | |
d3.select(this).classed("selected", false); | |
d3.select(this.previousSibling).classed("selected", false); | |
mouseCircle.attr("stroke", "gray"); | |
}) | |
; | |
}); | |
function mousemoved() { | |
pt = svg.select('#pt'); | |
var x = +pt.attr('cx'), | |
y = +pt.attr('cy'); | |
mouseCircle.attr({ | |
cx: x, | |
cy: y | |
}); | |
var pp = poly.attr("points"); | |
pp = pp.substring(0, pp.lastIndexOf(" ")) + " " + x + "," + y; | |
poly.attr("points", pp); | |
} | |
mousemoved(); | |
</script> | |
<body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment