Skip to content

Instantly share code, notes, and snippets.

@tlfrd
Last active September 13, 2019 10:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tlfrd/d9a284b2536dc9b734917068cc86d0a8 to your computer and use it in GitHub Desktop.
Save tlfrd/d9a284b2536dc9b734917068cc86d0a8 to your computer and use it in GitHub Desktop.
Guess The Ratio II
license: mit

An updated version of Guess The Ratio.

TODO:

  • Experiment with voronoi vs. large (hidden) mouseover circles
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
.drag-dot {
cursor: -webkit-grab;
}
.outer-line {
stroke-linecap: round;
}
</style>
</head>
<body>
<script>
var margin = {top: 50, right: 100, bottom: 50, left: 100};
var width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var defs = svg.append("defs");
var filter = defs.append("filter")
.attr("id", "glow");
filter.append("feGaussianBlur")
.attr("class", "blur")
.attr("stdDeviation", 0.75)
.attr("result","coloredBlur");
var feMerge = filter.append("feMerge");
feMerge.append("feMergeNode")
.attr("in","coloredBlur");
feMerge.append("feMergeNode")
.attr("in","SourceGraphic");
var dragbehaviour = d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended);
var config = {
radius: 13,
strokeWidth: 4
};
var dots = [
{position: "lowest", x: width / 4, colour: d3.interpolateMagma(0.25)},
{position: "median", x: width / 2, colour: d3.interpolateMagma(0.5)},
{position: "highest", x: width * 3 / 4, colour: d3.interpolateMagma(0.75)}
];
var outerLine = svg.append("line")
.attr("class", "outer-line")
.attr("x1", 0)
.attr("x2", width)
.attr("y1", height / 2)
.attr("y2", height / 2)
.style("stroke", "#e0e0e0")
.style("stroke-width", config.strokeWidth + 1);
var innerLine = svg.append("line")
.attr("class", "inner-line")
.attr("x1", dots[0].x)
.attr("x2", dots[dots.length - 1].x)
.attr("y1", height / 2)
.attr("y2", height / 2)
.style("stroke", "#ee8476")
.style("stroke-width", config.strokeWidth + 3);
var dotGroup = svg.append("g");
var bgDots = dotGroup.selectAll("circle")
.data(dots)
.enter().append("circle")
.attr("cx", d => d.x)
.attr("cy", height / 2)
.attr("r", config.radius)
.style("fill", "white");
var dragDots = dotGroup.selectAll("circle.drag-dot")
.data(dots)
.enter().append("circle")
.attr("class", "drag-dot")
.attr("cx", d => d.x)
.attr("cy", height / 2)
.attr("r", config.radius)
.style("stroke", d => d.colour)
.style("fill", d => d.colour)
.style("fill-opacity", 0.5)
.style("stroke-width", config.strokeWidth)
.call(dragbehaviour)
.on("mouseover", function() {
addGlow(d3.select(this));
})
.on("mouseout", function() {
if (!glowing) removeGlow(d3.select(this));
});
debugger;
dotGroup.selectAll("circle").sort(function(a, b) {
if (a.x > b.x) return 1;
if (a.x < b.x) return -1;
return 0;
});
/* Drag functions */
var glowing = false;
function dragstarted() {
addGlow(d3.select(this));
glowing = true;
}
function dragged(data, i) {
var minX, maxX;
if (data.position == "lowest") {
minX = 0;
maxX = dots[i + 1].x - config.strokeWidth;
} else if (data.position == "median") {
minX = dots[i - 1].x + config.strokeWidth;
maxX = dots[i + 1].x - config.strokeWidth;
} else {
minX = dots[i - 1].x + config.strokeWidth;
maxX = width;
}
d3.select(this)
.attr("cx", d => d.x = Math.max(minX, Math.min(maxX, d3.event.x)));
bgDots
.attr("cx", d => d.x);
innerLine
.attr("x1", dots[0].x)
.attr("x2", dots[dots.length - 1].x);
}
function dragended() {
removeGlow(d3.select(this));
glowing = false;
}
/* Glow/change colour functions */
function addGlow(selection) {
selection
.style("filter", "url(#glow)")
.style("stroke", "black");
}
function removeGlow(selection) {
selection
.style("filter", "none")
.style("stroke", d => d.colour);
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment