I would like help to correct my code to click the marker circle element to pause or resume transition of this element along the line. My code moves marker along a line and I can
To check if the circle is moving in the click function use d3.active(), which...
... returns null if there is no such active transition on the specified node.
Like this:
.on('click', function(d, i) {
if (d3.active(this)) {
marker.transition();
setTimeout(function() {
pauseValues.lastTime = pauseValues.currentTime;
}, 100);
} else {
transition();
}
});
Here is your code with that change:
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-array.v1.min.js"></script>
<script src="https://d3js.org/d3-geo.v1.min.js"></script>
<script src="https://d3js.org/d3-queue.v3.min.js"></script>
<style type="text/css">
body {
font-family: "Helvetica Neue", Helvetica, sans-serif;
color: red;
}
button {
position: absolute;
top: 15px;
left: 10px;
background: #004276;
padding-right: 26px;
border-radius: 2px;
cursor: pointer;
}
circle {
fill: steelblue;
stroke: pink;
stroke-width: 3px;
}
.point {
fill: green;
}
.line {
fill: none;
stroke: red;
stroke-width: 4;
stroke-dasharray: 4px, 8px;
}
</style>
<body>
<button>Start</button>
<script>
var w = 960,
h = 500;
var duration = 10000;
var svg = d3.select("body").append("svg")
.attr("width", w)
.attr("height", h);
var line = d3.line()
.x(function(d) {
return (d)[0];
})
.y(function(d) {
return (d)[1];
});
var data = [
[480, 200],
[580, 400],
[680, 100],
[780, 300],
[180, 300],
[280, 100],
[380, 400]
];
//path to animate
var linepath = svg.append("path")
.data([data])
.attr("d", line)
.attr('class', 'line')
.attr("d", function(d) {
return line(d)
});
var points = svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("r", 7)
.attr("transform", function(d) {
return "translate(" + (d) + ")";
})
.attr("class", "point");
var pauseValues = {
lastTime: 0,
currentTime: 0
};
var marker = svg.append("circle")
.attr("r", 19)
.attr("transform", "translate(" + (data[0]) + ")")
.on('click', function(d, i) {
if (d3.active(this)) {
marker.transition();
setTimeout(function() {
pauseValues.lastTime = pauseValues.currentTime;
}, 100);
} else {
transition();
}
});
function transition() {
marker.transition()
.duration(duration - (duration * pauseValues.lastTime))
.attrTween("transform", translateAlong(linepath.node()))
.on("end", function() {
pauseValues = {
lastT: 0,
currentT: 0
};
transition()
});
}
function translateAlong(path) {
var l = path.getTotalLength();
return function(d, i, a) {
return function(t) {
t += pauseValues.lastTime;
var p = path.getPointAtLength(t * l);
pauseValues.currentTime = t;
return "translate(" + p.x + "," + p.y + ")";
};
};
}
d3.select('button').on('click', function(d, i) {
var self = d3.select(this);
if (self.text() == "Pause") {
self.text('Start');
marker.transition()
.duration(0);
setTimeout(function() {
pauseValues.lastTime = pauseValues.currentTime;
}, 100);
} else {
self.text('Pause');
transition();
}
});
</script>
</body>