Built with blockbuilder.org
forked from tomshanley's block: fresh block
license: mit |
Built with blockbuilder.org
forked from tomshanley's block: fresh block
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<style> | |
body { margin:0;top:0;right:0;bottom:0;left:0; } | |
</style> | |
</head> | |
<body> | |
<script> | |
console.clear() | |
let height = 800 | |
let width = height | |
let margin = 50 | |
let sineData = d3.range(0, 101).map(function(k) { | |
let freq = 0.05 | |
var value = [freq * k * Math.PI, Math.sin(freq * k * Math.PI)]; | |
return value; | |
}); | |
let sineX = d3.scaleLinear() | |
.domain([-1, 1]) | |
.range([0, width]) | |
let sineY = d3.scaleLinear() | |
.domain(d3.extent(sineData, function(d) { | |
return d[0] | |
})) | |
.range([0, height]) | |
let line = d3.line() | |
.x(function(d) { | |
return sineX(d[1]); | |
}) | |
.y(function(d) { | |
return sineY(d[0]); | |
}) | |
.curve(d3.curveLinear) | |
var svg = d3.select("body").append("svg") | |
.attr("width", width + margin + margin) | |
.attr("height", height + margin + margin) | |
var g = svg.append('g') | |
.attr('transform', 'translate(' + margin + ',' + margin + ')') | |
var sinePath = g.append('path') | |
.datum(sineData) | |
.attr('d', line) | |
.style('stroke', 'black') | |
.style('stroke-width', 1) | |
.style('fill', 'none') | |
let n = 150 | |
let circleData = d3.range(0, n).map(function(k) { return k }) | |
let node = sinePath.node() | |
let pathLength = Math.floor(node.getTotalLength()) | |
console.log(pathLength) | |
let r = 10 | |
var circleX = function(i){ | |
return node.getPointAtLength(i).x | |
} | |
var circleY = function(i){ | |
return node.getPointAtLength(i).y | |
} | |
let circleID = 0 | |
let prevCircleX = circleX(0) | |
let prevCircleY = circleY(0) | |
g.append('circle') | |
.attr('id', 'circle-' + circleID) | |
.attr("cx", prevCircleX ) | |
.attr("cy", prevCircleY ) | |
for (var l = 1; l < pathLength; l++) { | |
let thisCircleX = circleX(l) | |
let thisCircleY = circleY(l) | |
let sideX = Math.abs(thisCircleX - prevCircleX) | |
let sideY = Math.abs(thisCircleY - prevCircleY) | |
let hyp = Math.sqrt((sideX * sideX) + (sideY * sideY)) | |
if (hyp > (r * 2)) { | |
prevCircleX = thisCircleX | |
prevCircleY = thisCircleY | |
g.append('circle') | |
.attr('id', 'circle-' + l) | |
.attr("cx", prevCircleX ) | |
.attr("cy", prevCircleY ) | |
} | |
} | |
g.selectAll('circle') | |
.style('fill', 'grey') | |
.style('opacity', 0.5) | |
.attr('r', 10) | |
</script> | |
</body> |