javascript - 如何在 d3.js 中像这个 gif 一样使圆圈动画连续悬停?

标签 javascript d3.js

我是 d3.js 的新手。这是我非常喜欢的圆圈动画。这有点像无限动画。

enter image description here

我想复制这个动画在d3.js中生成它,但我认为我的知识不够,这段代码是我能够复制动画的最接近的代码。

然后我的想法是,我可以实现鼠标悬停效果,如您在图片中所见。我该怎么做?非常感谢。

这是我的代码,这是我当前的结果:

enter image description here

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();

http://plnkr.co/edit/kz2tbxoS9lsfy2oMDzhY?p=preview

最佳答案

这是学习 d3.transition 功能的好案例。 就像@AndrewReid 的引用资料一样,您的代码已经达到您的预期效果。

在你的代码中(如果我没理解错的话),你直接用更新圆半径的数据产生发射效果,并直接用选择组号控制每个圆的生命周期。

其实可以直接使用d3.transition属性来控制圆圈过渡的生命周期来产生emananting效果。

这里有一些关于 d3.transition 生命周期的阅读 Material :

  1. > A Life of a transition
  2. > Working with Transition

这是我的代码:
在我的实现中,我使用数据来决定发射圆数和 使用 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

关于javascript - 如何在 d3.js 中像这个 gif 一样使圆圈动画连续悬停?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49165250/

相关文章:

d3.js - 在 D3.js 中创建元素 "in memory",就像 jQuery 一样

angular - d3 中的动画折线图

javascript - Gulp/Vinyl-fs - dest 与 src 相同的目录不适用于 gulp-rename

javascript - 为什么在条件中不检查流密封对象类型属性

javascript - 我怎样才能摆脱 jquery 切换中的那些动画?

javascript - 如何覆盖 d3.js 对可渲染元素数量的限制?

javascript - 对于 svg :text element in Firefox 15,宽度似乎始终为零(或 NaN)

json数据的Javascript数据结构

javascript - 向 Meteor.users 添加转换函数?

javascript - 使用 javascript 读取文本框用户输入并插入超链接