Javascript 为什么动画d3 svg线在IE9中不与轴移动同步,但在IE11和Chrome中同步?
以下是两个JSIDdle: 调用勾号的代码: 调用勾号的代码: 进行测试1:Javascript 为什么动画d3 svg线在IE9中不与轴移动同步,但在IE11和Chrome中同步?,javascript,animation,svg,timer,d3.js,Javascript,Animation,Svg,Timer,D3.js,以下是两个JSIDdle: 调用勾号的代码: 调用勾号的代码: 进行测试1: 使用IE 11或Chrome浏览器打开JSFiddle 1和JSFiddle 2 观察动画svg行 进行测试2: 使用IE9浏览器打开JSFiddle 1和JSFiddle 2 观察动画svg行 在测试1中,我观察到动画svg线的起点与轴移动一起移动,因此它在视觉上看起来是同步的。因此,您将看到一条平滑的动画线 在测试2中,我观察到svg线的起点并没有随着轴的移动而移动,因此它在视觉上看起来是不同步的。因此,您会看到一
自定义tween函数的改进版本
:
我对她的答案做了一些小的调整,用x(t-n+2)代替x(t-n+1)。即使线条不平滑,但至少现在与轴偏移同步:我怀疑问题只是IE9不支持该方法。D3使用requestAnimationFrame(如果可用) 这是有区别的,因为requestAnimationFrame方法将一系列连续调用捆绑到一个“frame”中,并将所有调用传递给相同的时间戳值。如果没有requestAnimationFrame方法,每个转换将获得不同的时间戳,延迟时间取决于浏览器完成上一个任务所用的时间 不幸的是,对于坚持使用过时浏览器的人来说,没有简单的解决方案来解决这个问题 您所能做的就是尽可能提高代码的效率。例如,当前正在创建单独的变换,以按相同的变换量移动每条路径。如果您创建了一个
元素并绘制了其中的所有路径,那么您只需要一个变换和一个转换
var graph = g.append("svg")
.attr("width", width)
.attr("height", height + margin.top + margin.bottom);
var plot = graph.append("g").attr("class", "plot");
var path1 = plot.append("g").append("path")
/* etc for the other paths */
然后在tick()
函数中:
- 重新绘制线时,不要在路径元素上设置任何变换,而是使用清除打印变换
plot.attr("transform", null);
- 将所有路径转换替换为
plot.transition() .duration(duration) .ease("linear") .attr("transform", "translate(" + x(t - n + 1) + ")");
plot.attr("transform", null);
// redraw the axis, without transition
axis.call(xAxis).attr("transform", null);
// slide the line left
plot.transition()
.duration(duration)
.ease("linear")
.attrTween("transform",
function(){
//this function is run for every element
//in the selection (which only has one element).
//create an interpolator function
var inter = d3.interpolateString("translate(0,0)",
"translate(" + x(t - n + 1) + ")");
return function(t) {
//this function is called at every "tick"
//of the transition
//transition the axis
axis.attr("transform", inter(t) );
//return the value to transition the plot
return inter(t);
};
})
.each("end", tick); //loop
还有一个额外的复杂性:x轴
元素已经有了一个transform属性,将其向下移动到图形的底部。我可以每次都重复这个转换,这样转换后的属性看起来像是axis.attr(“transform”,“translate(0,+height+)”+inter(t))代码>。但是,我决定通过为轴使用嵌套的
元素来保持简单:垂直变换应用于外部组,水平变换应用于内部组:
var xAxis = d3.svg.axis().scale(x)
.orient("bottom")
.outerTickSize(0);
var axis = graph.append("g") //outer group handles the vertical transform
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.append("g")
//this nested <g> will be stored in the `axis` variable!
//and therefore will get the horizontal transform attribute
.call(x.axis = xAxis);
var xAxis=d3.svg.axis().scale(x)
.orient(“底部”)
.outerTickSize(0);
var axis=graph.append(“g”)//外部组处理垂直变换
.attr(“类”、“x轴”)
.attr(“变换”、“平移(0)”、“高度+”)
.附加(“g”)
//此嵌套将存储在'axis'变量中!
//因此将获得水平变换属性
.调用(x.axis=xAxis);
请注意,我还将.outerTickSize(0)
添加到轴定义中。这可以防止轴在域的开始和结束处绘制额外的记号标记——外部记号在Y轴的底部显示为一条奇怪的闪烁线,每次重新绘制轴时都会出现,然后随着轴的移动立即消失
另外,如果您的客户仍然感到失望,请冷静、礼貌地提醒他或她IE9是一款过时的浏览器,它不具备最新浏览器生成平滑动画的功能。如果有人想要最新最好的网站,他们需要使用最新最好的浏览器 你的回答让我的一天充满活力,但建议的解决方案在视觉上没有任何区别。IE11 emulator无法模拟该问题。但在真正的IE9版本中,问题确实存在。(我今天将IE11降级为IE9,并验证了问题。我用youtube演示更新了我的问题,这样可以帮助您更好地理解问题。@jhyap:让我知道新版本的外观。令人印象深刻的改进,但在任何路径到达轴末端时都会出现轻微的后移问题。请参阅我为上传的视频2
de>x(t-n+1)
问题。因此,我调整了d3.interpo
plot.attr("transform", null);
// redraw the axis, without transition
axis.call(xAxis).attr("transform", null);
// slide the line left
plot.transition()
.duration(duration)
.ease("linear")
.attrTween("transform",
function(){
//this function is run for every element
//in the selection (which only has one element).
//create an interpolator function
var inter = d3.interpolateString("translate(0,0)",
"translate(" + x(t - n + 1) + ")");
return function(t) {
//this function is called at every "tick"
//of the transition
//transition the axis
axis.attr("transform", inter(t) );
//return the value to transition the plot
return inter(t);
};
})
.each("end", tick); //loop
var xAxis = d3.svg.axis().scale(x)
.orient("bottom")
.outerTickSize(0);
var axis = graph.append("g") //outer group handles the vertical transform
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.append("g")
//this nested <g> will be stored in the `axis` variable!
//and therefore will get the horizontal transform attribute
.call(x.axis = xAxis);