Skip to content

Instantly share code, notes, and snippets.

@max-l
Last active December 11, 2018 03:42
Show Gist options
  • Save max-l/cda07bafcf7970e724b3aa00aefe9a02 to your computer and use it in GitHub Desktop.
Save max-l/cda07bafcf7970e724b3aa00aefe9a02 to your computer and use it in GitHub Desktop.
sink3
license: mit
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<style>
path {fill: none;stroke: #000;stroke-width: 3px;}
circle {fill: steelblue;stroke: #fff;stroke-width: 1px;}
sink {}
</style>
</head>
<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("body")
.append("svg")
.attr("width", 400)
.attr("height", 600)
.attr("class", "sink")
const topLeft = [75,120]
const rightBottom = [170,200]
const radius = 5
const stepDistance = 1
const redrawInterval = 40
var data = [];
const faucet = [[71, 64],[119, 95],[130, 139]];
const tub = [[75, 120],[75, 200],[170, 200], [170,120]];
const path = svg.append("path")
.data([faucet])
.attr("d", d3.line().curve(d3.curveCardinal))
svg.append("path")
.data([tub])
.attr("d", d3.line())
const translateAlong = path => {
const l = path.getTotalLength() ;
return (d, i, a) => t => {
const p = path.getPointAtLength(t * l)
return `translate(${p.x},${p.y})`;
};
}
const initPoints = (pointCount) => {
const rnd = d3.randomUniform(1, 10)
d3.range(pointCount).map(i=> {
data.push({
id: i, x:topLeft[0], y:topLeft[1],
slope: rnd() / 10,
x_dir: 1,y_dir: 1,
state:0
})
})
}
initPoints(5)
const rndDelay = d3.randomUniform(500, 1500)
redraw(data);
d3.interval(() => redraw(update(data)), redrawInterval)
function redraw(data){
var circle = svg.selectAll("circle")
.data(data)
circle.enter().append("circle")
.attr("r", radius)
/*
.transition()
.ease(d3.easeQuad)
.delay(rndDelay)
.duration(2000)
.attrTween("transform", translateAlong(path.node()))
.on("end", d => {
const lastP = faucet[2]
d.state = 1
d.x = lastP[0]
d.y = lastP[1]
console.log("a1",[d.x,d.y])
}) */
.attr("cx", d => d.x)
.attr("cy", d => d.y)
circle.filter(d => d.state == 0)
.attr("r", radius)
.attr("cx", d => d.x)
.attr("cy", d => {
console.log("a2",[d.x,d.y])
return d.y
})
}
const update = data =>
data.map(d => calcPointB(d, stepDistance, d.slope))
const calcPointB = (p, d, m) => {
const getDir = (coord, dir, maxCood, minCoord) =>
(Math.ceil(coord) <= minCoord - radius) ? 1 :
(Math.ceil(coord) >= maxCood - radius) ? -1 : dir
const sqrt = Math.sqrt
const pow2 = a=>Math.pow(a, 2)
p.x_dir = getDir(p.x, p.x_dir, rightBottom[0], topLeft[0]);
p.y_dir = getDir(p.y, p.y_dir, rightBottom[1], topLeft[1]);
p.x = p.x +
(d * sqrt(1 / (1 + pow2(m))) * p.x_dir)
p.y = p.y +
(m * d * sqrt(1 / (1 + pow2(m))) * p.y_dir);
return p;
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment