我是d3.js的新手。这是我喜欢的圈子动画。它就像一个无限的动画。
我想复制这个动画以在d3.js中生成它,但我认为我的知识不足,这段代码是我能够复制动画的最接近的。
然后我的想法是,我可以在图像中看到鼠标悬停效果。我该怎么做?非常感谢你。
这是我的代码,这是我目前的结果:
var width = document.getElementById('circles').offsetWidth-70;
var height =(width/2)+100;
var scale = d3.scale.linear()
.range(["yellow","orange","red"])
.domain([0,60]);
var data = [0,10,20,30,40,50,60];
var svg = d3.select("#circles").append("svg")
.attr("width", width+"px")
.attr("height", height+"px");
//circle orange
svg.append("circle")
.attr("cx",80)
.attr("cy",80)
.attr("r",30)
.attr("fill","orange")
.style("stroke-width","1")
.style("stroke","orange")
.on('mouseover', function(){
d3.select(this).transition().ease("bounce").duration(500).attr("r",32)
})
.on('mouseout', function(){
d3.select(this).transition().ease("bounce").duration(500).attr("r",30)
})
//circle yellow
svg.append("circle")
.attr("cx",80)
.attr("cy",80)
.attr("r",22)
.attr("fill","yellow")
.style("stroke-width","1")
.style("stroke","yellow")
.style("opacity","0.9")
.on('mouseover', function(){
d3.select(this).transition().ease("bounce").duration(500).attr("r",24).style("opacity","1")
})
.on('mouseout', function(){
d3.select(this).transition().ease("bounce").duration(500).attr("r",22).style("opacity","0.9")
})
var circles = svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("r",function(d) { return d; })
.attr("transform","translate(80,80)")
.attr("fill","none")
.style("stroke-width","1")
.style("stroke",function(d) { return scale(d) });
function transition() {
// Update data, max d is 60:
data = data.map(function(d) { return d == 60 ? 0 : d + 10});
var i = 0;
// Grow circles
circles
.data(data)
.filter(function(d) { return d > 0 })
.transition()
//.ease(d3.easeLinear)
.ease("linear")//set the ease here
.attr("r", function(d) { return d; })
.style("stroke", function(d) { return scale(d) })
.style("opacity",function(d) { return d == 60 ? 0 : 1 })
.duration(1000)
//.on("end",function(){if(++i==circles.size()-1) { transition(); } });
.each("end", function (d,i) {
//.on("end", function (d,i) {
if(++i==circles.size()-1) { transition(); }
});
// Reset circles where r == 0
circles
.filter(function(d) { return d == 0 })
.attr("r", 0)
.style("opacity",1)
.style("stroke",function(d) { return scale(d); });
}
transition();
答案 0 :(得分:4)
这是学习 d3.transition 功能的好例子。
就像@AndrewReid的参考资料一样,您的代码已经存在,以达到预期的效果。
在你的代码中(如果我理解正确的话),你直接产生散发效果,数据更新圆半径并直接用选择组编号控制每个圆的生命周期。
实际上,您可以直接使用 d3.transition属性来控制圆形过渡生命周期以产生直观效果。
这里有一些d3.transition生命周期的阅读材料:
这是我的代码:
在我的实现中,我使用数据来决定emananting圈数和
使用transition.on来监听每个完成的转换周期并重置属性。
//DOM.svg is the syntax in observablhq, in browser, replace with your way
const svg = d3.select(DOM.svg(250,250));
const data = Array.from(Array(CircleNumber).keys());
// use this emanating function to control the execution cycles
function emananting(num){
svg.selectAll('circle.emanting')
.transition()
.duration((d,i)=>{
return 2500;
}) // duration to control each circle emananting duration
.delay((d,i)=>{
return i*500;
}) // delay to control between each circle's space
.attr('opacity',0)
.attr('r',50)
.on('end',(d,i,g)=>{
// after each transition end, trigger these codes
d3.select(g[i])
.attr('r', 10)
.attr('opacity',1);
// control flow from listening to the last transition done!
// remove the num < 10 condition , it will be infinite
if (i===5 && num < 2){
console.log(num);
emananting(num+1);
}
});
}
// Here create the center circle body
svg.append('circle')
.classed('CircleBody',true)
.attr('r',10)
.attr('stroke','yellow')
.attr('fill','orange')
.attr('opacity',1)
.attr('cx',125)
.attr('cy',125);
// Here create the emanting circle
svg.selectAll('circle.emanting')
.data(data)
.enter()
.append('circle')
.attr('class','emanting')
.attr('id', (d,i)=>{
return 'number' + i;
})
.attr('r',10)
.attr('stroke','orange')
.attr('fill','none')
.attr('opacity',1)
.attr('cx',125)
.attr('cy',125);
// control flow
emananting(0);
这里有一些关于@observablehq的演示 https://beta.observablehq.com/@weitinglin/demo-how-can-i-make-the-animation-of-a-circle-continous-with-h