Я хочу, чтобы по пути двигалось несколько кругов. Сделал по ссылке здесь
var w = $(window).innerWidth();
var h = $(window).innerHeight();
var svg = d3
.select('.container')
.append('svg')
.attr('width', w)
.attr('height', h);
// FIRST (START) POINT & SECOND (FINISH) POINT ARRAY
var points = [{
x: 0,
y: 0,
r: 5
}, {
x: 700,
y: 100,
r: 5
}];
// ADD GROUP 'G'
var group = svg
.append('g')
.attr('transform', 'translate(20,20)');
// ADD CIRCLE AT START & FINISH AS AN VISUAL ANCHOR
group.selectAll("circle")
.data(points)
.enter()
.append("circle")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.attr("r", function(d) {
return d.r;
});
// DETERMINED THE SUBPATH FOR THE CURVE
var cpx = ((points[1].x - points[0].x)),
cpy = ((points[1].y - points[0].y)) ;
// EMPTY ARRAY
var linesArray = [];
//POPULATE ARRAY WITH RANDOM CURVE SVG
for (let i = 0; i <= 10; i++) { // FOR LOOP UNTUK ISI ARRAY DENGAN KORDINAT GARIS MELENGKUNG
var path = d3.path();
path.moveTo(points[0].x, points[0].y);
path.quadraticCurveTo(Math.random(1) * cpx + points[0].x, Math.random() * cpy + points[0].y, points[1].x, points[1].y);
var l = path.toString();
linesArray.push({
d: l
})
}
// DRAW THE PATH
var mypath = group
.selectAll('path')
.data(linesArray)
.enter()
.append("path")
.attr("d", d => d.d)
.attr("stroke", "firebrick")
.attr("stroke-width", 2)
.attr("fill", "none");
// DRAW THE CIRCLE I WILL ANIMATE
var circle = group
.selectAll('circle')
.data(linesArray)
.enter()
.append("circle")
.attr('id','travel')
.attr("r", 8)
.style("fill", 'steelblue')
.style('opacity', 0.5)
.attr("transform", "translate(" + points[0].x + ","+points[0].y+" )");
// ANIMATE ALONG PATH FUNCTION
function translateAlong(mypath) {
var length = mypath.getTotalLength();
return () => {
return x => {
var p = mypath.getPointAtLength(x * length);
return "translate("+p.x+","+p.y+")";
}
}
}
// ANIMATE THE CIRCLE ALONG PATH
setTimeout(() => {
circle
.each(() => {
d3
.selectAll('#travel')
.transition()
.duration(10000)
.style('fill', 'red')
.attrTween('transform', translateAlong(mypath.node()))
.remove();
})
},0)
<div class='container'></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
Круги, анимированные вместе только на одном пути, не анимированные на другом пути, который я нарисовал.
Я прочитал ответ здесь , и пример прикреплен здесь , но я сбит с толку, когда добавляю свойства index
, как в примере, я получаю сообщение об ошибке Cannot read property 'getTotalLength' of undefined
this - это отредактированная часть со свойствами index
, я сделал переход внутри setTimeout
как функцию
// this part are modified based on reference below
// https://bl.ocks.org/anonymous/f54345ed04e1a66b7cff3ebeef271428/76fc9fbaeed5dfa867fdd57b24c6451346852568
function transitionCircle(pathItem, index) {
circle
.each(() => {
d3
.selectAll('#travel')
.transition()
.duration(10000)
.style('fill', 'red')
.attrTween('transform', translateAlong(mypath.node()[index], index))
.remove();
}) // end each
} // end transitionCircle
setTimeout(() => {
transitionCircle();
},0)// end timeout
function translateAlong(mypath, offset) { //mypath value supposed to be mypath.node()[index] right?
var length = mypath.getTotalLength();
return () => {
return x => {
var p = mypath.getPointAtLength(x * length);
return "translate("+p.x+","+p.y+")";
}
}
} //end function translateAlong()
ссылка https://bl.ocks.org/mbostock/1705868
ОБНОВЛЕНИЕ: Я меняю node () на node (), и он работает в console.log(mypath.nodes()[0])
.
Код .attrTween('transform', translateAlong(mypath.node()[0], index))
также работает, но по-прежнему только анимация в первом пути. когда я изменил [0]
обратно на [index]
, он снова вернет Cannot read property 'getTotalLength' of undefined