d3 svg转换在Firefox上有轻微不必要的水平移动

时间:2017-07-02 03:45:09

标签: html d3.js svg

以下有一些SVG方块每秒向上进行一次。在谷歌浏览器中它看起来很好。在Firefox中,正方形左右移动约1个像素,这不是我想要的。

任何人都可以帮忙找出原因吗?

抱歉,这段代码不简单;这是基本的,我可以从一个更长的文件中删除所有不相关的方面。



  <!DOCTYPE html>
    <html>
    <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.9.1/d3.min.js"></script>
    <style type='text/css'>
      .hidden { 
        display: none;
      }
       
      #ticktock {
        position: absolute;
        top: 550px;
        left: 400px;
      }
      svg rect.cell {
        fill: none;
        stroke: steelblue;
      }
 
    </style>
    <script type='text/javascript'>
    document.addEventListener('DOMContentLoaded',function(event) {
 
        var L = 25;
        var maxFacetCount = 8;
    	var state = {
    		nexttick: 0,
    		ticksize: 500,
    		n: -8,
    		nx: 8,
    		wheel: [],
            nfacet: maxFacetCount,
    		init: true,
            ticktock: true
    	};
    
       
    	function update_state(state)
    	{
        if (state.ticktock)
        {
          if (state.wheel.length >= state.nfacet)
            state.wheel.shift();
          state.wheel.push({n: ++state.n });
                 
           }
         
    	}
  
      state.wheel = state.wheel.slice(-1);
 
    	function prepare_view(state)
    	{
    		var width = 60 + (state.nx+0.5)*(L+2);
    		var height = 5 + (state.nfacet+0.5)*L;
    		var svg = d3.select("#wheel-container").append("svg")
    			.attr("width", width)
    			.attr("height", height);
        
             var x1 = L*0.5+5;
    		var wheel = svg.append('g')
    			.attr('id','wheel')
                .attr('transform','translate('+x1+',0)');
 
    	}
    	
    	prepare_view(state);
     	function facet_enter(facets, t)
    	{
    		var facet = facets.append('g');
 
            for (var i = 0; i < state.nx; ++i)
            {
                facet.append('rect')
                      .attr('x',i*L)
                      .attr('y',0)
                      .attr('width',L)
                      .attr('height',L)
                  .attr('class','cell');
            }
    		facet_move(facet, state.init ? null : t);
    	}
    	
    	function facet_move(facet, t)
    	{			
    		(t ? facet.transition(t) : facet)
           .attr('opacity',function(d,i) { 
          		var age = state.n - d.n;
              return age == 0 ? 0 : 1-age/state.nfacet; })
    		   .attr('transform',function(d,i) { return 'translate(0,'+((d.n-state.n+state.nfacet-1)*L)+')'; });
    	}
    	
    	function facet_update(facets, t)
    	{
    		facet_move(facets, t);
    	}
      
    	function update_view(state, ticktock)
    	{
         
    		var wheel = d3.select("#wheel");
    		var facets = wheel.selectAll('g');

        if (state.ticktock)
        {
    		  var t = d3.transition().duration(300);
    		  var upd = facets
      		  .data(state.wheel, function(d,i) { return d.n; });
    		  
    		  upd .call(facet_update, t)
    		   .enter()
    			   
    			  .call(facet_enter, t)
 
    		  upd.exit()
    			  .transition(t)
                     .attr('transform','translate (0,'+(-L)+')')
    			     .remove();
 
    	  }
        else
        {
          // tock
          var t = d3.transition().duration(100);
          var t2 = t.transition().duration(100);

          var upd = facets
      		  .data(state.wheel, function(d,i) { return d.n; });
    		  
    		  upd.call(facet_update, t)
    		   .enter()
    			  .call(facet_enter, t);
 
        }
      }
    	var tmr = d3.timer(function(elapsed) {
    		var do_something = false;
    		while (elapsed >= state.nexttick)
    		{
    			do_something = true;
    			state.nexttick += state.ticksize;
    		}
    		if (do_something && !(d3.select('#pause').property('checked') ))
    		{
          state.ticktock = !state.ticktock;
           
      	  update_state(state);
    			update_view(state);
    			state.init = false;
    		}
    	} );
    });
    </script>
    </head>
    <body>
      <div id='wheel-container' ></div>
    <form class="">
      <input type="checkbox" id="pause" name="pause">pause</input>
    </form>
    <div id='ticktock' class='hidden'></div>
    </body>
    </html>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

看起来浮点舍入错误再次发生。我改为shape-rendering: crispEdges;,然后在其中一个根元素中四舍五入为整数translate,这似乎解决了大部分问题(仍有一点残余的y轴移位)。

是:

             var x1 = L*0.5+5;
            var wheel = svg.append('g')
                .attr('id','wheel')
                .attr('transform','translate('+x1+',0)');

更改为:

             var x1 = Math.round(L*0.5+5);
            var wheel = svg.append('g')
                .attr('id','wheel')
                .attr('transform','translate('+x1+',0)');

  <!DOCTYPE html>
    <html>
    <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.9.1/d3.min.js"></script>
    <style type='text/css'>
      .hidden { 
        display: none;
      }
       
      #ticktock {
        position: absolute;
        top: 550px;
        left: 400px;
      }
      svg rect.cell {
        fill: none;
        stroke: steelblue;
        shape-rendering: crispEdges;
      }
 
    </style>
    <script type='text/javascript'>
    document.addEventListener('DOMContentLoaded',function(event) {
 
        var L = 25;
        var maxFacetCount = 8;
    	var state = {
    		nexttick: 0,
    		ticksize: 500,
    		n: -8,
    		nx: 8,
    		wheel: [],
            nfacet: maxFacetCount,
    		init: true,
            ticktock: true
    	};
    
       
    	function update_state(state)
    	{
        if (state.ticktock)
        {
          if (state.wheel.length >= state.nfacet)
            state.wheel.shift();
          state.wheel.push({n: ++state.n });
                 
           }
         
    	}
  
      state.wheel = state.wheel.slice(-1);
 
    	function prepare_view(state)
    	{
    		var width = 60 + (state.nx+0.5)*(L+2);
    		var height = 5 + (state.nfacet+0.5)*L;
    		var svg = d3.select("#wheel-container").append("svg")
    			.attr("width", width)
    			.attr("height", height);
        
             var x1 = Math.round(L*0.5+5);
    		var wheel = svg.append('g')
    			.attr('id','wheel')
                .attr('transform','translate('+x1+',0)');
 
    	}
    	
    	prepare_view(state);
     	function facet_enter(facets, t)
    	{
    		var facet = facets.append('g');
 
            for (var i = 0; i < state.nx; ++i)
            {
                facet.append('rect')
                      .attr('x',i*L)
                      .attr('y',0)
                      .attr('width',L)
                      .attr('height',L)
                  .attr('class','cell');
            }
    		facet_move(facet, state.init ? null : t);
    	}
    	
    	function facet_move(facet, t)
    	{			
    		(t ? facet.transition(t) : facet)
           .attr('opacity',function(d,i) { 
          		var age = state.n - d.n;
              return age == 0 ? 0 : 1-age/state.nfacet; })
    		   .attr('transform',function(d,i) { return 'translate(0,'+((d.n-state.n+state.nfacet-1)*L)+')'; });
    	}
    	
    	function facet_update(facets, t)
    	{
    		facet_move(facets, t);
    	}
      
    	function update_view(state, ticktock)
    	{
         
    		var wheel = d3.select("#wheel");
    		var facets = wheel.selectAll('g');

        if (state.ticktock)
        {
    		  var t = d3.transition().duration(300);
    		  var upd = facets
      		  .data(state.wheel, function(d,i) { return d.n; });
    		  
    		  upd .call(facet_update, t)
    		   .enter()
    			   
    			  .call(facet_enter, t)
 
    		  upd.exit()
    			  .transition(t)
                     .attr('transform','translate (0,'+(-L)+')')
    			     .remove();
 
    	  }
        else
        {
          // tock
          var t = d3.transition().duration(100);
          var t2 = t.transition().duration(100);

          var upd = facets
      		  .data(state.wheel, function(d,i) { return d.n; });
    		  
    		  upd.call(facet_update, t)
    		   .enter()
    			  .call(facet_enter, t);
 
        }
      }
    	var tmr = d3.timer(function(elapsed) {
    		var do_something = false;
    		while (elapsed >= state.nexttick)
    		{
    			do_something = true;
    			state.nexttick += state.ticksize;
    		}
    		if (do_something && !(d3.select('#pause').property('checked') ))
    		{
          state.ticktock = !state.ticktock;
           
      	  update_state(state);
    			update_view(state);
    			state.init = false;
    		}
    	} );
    });
    </script>
    </head>
    <body>
      <div id='wheel-container' ></div>
    <form class="">
      <input type="checkbox" id="pause" name="pause">pause</input>
    </form>
    <div id='ticktock' class='hidden'></div>
    </body>
    </html>