以下有一些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;
答案 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>