ie浏览器中损坏的d3.js动画

Broken d3.js animation in Internet Explorer

本文关键字:d3 js 动画 损坏 浏览器 ie      更新时间:2023-09-26

我有一个d3.js动画,在所有其他浏览器中工作出色,除了资源管理器。期望的效果是它在增长和收缩时处于中心位置,然后再次循环,无限循环。我在这里做了一个记号。问题是动画会离开屏幕并失去屏幕中间的中心点。

之后,比较IE11和Chrome中的DOM中的svg,我看到IE11中的scale()只有一个值"scale(x)"而不是两个"scale(x, y)"。我相信这只是众多问题之一。

var duration = 5000;
var start = 50,
startScale = 1,
endScale = 10,
startTranslate = 225,
endTranslate = 0;
var startTrans = "scale(" + startScale + "," + startScale + ")translate(" + startTranslate + "," + startTranslate + ")",
endTrans = "scale(" + endScale + "," + endScale + ") translate(" + endTranslate + "," + endTranslate + ")";
d3.select("#slider_td").append("input")
    .attr("type", "range")
    .attr("id", "slider")
    .attr("min", 3000)
    .attr("max", 7000)
    .attr("value", duration)
    .on("change", function () {
    duration = this.value;
    d3.select("#_rb").property("value", d3.round(duration / 1000));
});
var svg = d3.select("#animation_td").append("svg")
    .attr("width", 500)
    .attr("height", 500)
    .style("background-color", "#ADD9F7");
svg.append("use")
    .attr("xlink:href", "#Livello_1")
    .attr("width", start)
    .attr("height", start)
    .attr("transform", startTrans)
    .call(transition, startTrans, endTrans);
svg.append("circle")
    .attr("cx", 250)
    .attr("cy", 730)
    .attr("r", 350)
    .style("fill", "#99CC00")
    .style("stroke", "white");
function transition(element, start, end) {
    element.transition()
        .duration(duration)
        .attr("transform", end)
        .each("end", function () {
        d3.select(this).call(transition, end, start);
    });
}

问题似乎是IE忽略了<use>元素的宽度和高度属性。

作为比较,看看这个版本的小提琴,我已经删除了这些属性(和动画)-你会得到相同的偏离中心的定位在其他浏览器中,就像在IE中。

这是一个bug,一个我还没有遇到的bug。我在他们的bug报告网站上也找不到任何东西。

你可能想把一个更简单的例子放在一起,并做一个错误报告,同时这里有一个解决方案:

<use>元素上的width和height属性的作用是将引用的图形缩放到该尺寸。只有当引用的图形是带有viewBox属性的<symbol><svg>时,它才有效果。

因此,我的第一个猜测是,你应该能够通过(a)删除<use>元素的宽度和高度属性,以及(b)添加一个额外的缩放因子来自己进行调整:
var basicScale = 50/557.8,   
    //50px is the desired width
    //557.8px is the width and height of the original graphic
    startScale = 1,
    endScale = 10,
    startTranslate = 225,
    endTranslate = 0;
var startTrans = "scale(" + startScale + ") translate(" 
                  + startTranslate + "," + startTranslate + ") scale(" 
                  + basicScale + ")",
    endTrans = "scale(" + endScale + ") translate(" 
                  + endTranslate + "," + endTranslate + ") scale(" 
                  + basicScale + ")";
http://jsfiddle.net/U9L7w/5/

不幸的是,虽然上面的例子是一个显著的改进,但它并不完全正确——太阳和山在IE中不是一个在另一个的中心,即使它们在Firefox和Chrome中使用完全相同的代码。

似乎IE不只是忽略的宽度和高度属性,它应用一个默认值100% -这意味着它缩放引用的SVG是相同的大小作为父SVG (500px的宽度和高度在你的例子)应用任何转换之前。

因此,为了在所有浏览器中都能很好地工作,您需要(a)告诉其他浏览器使用宽度和高度属性缩放到100%,然后(b)在创建新的缩放因子时将该缩放因子考虑在内:

/* To adjust for a lack of IE support for width and height on <use>, 
   add in an extra scale transform.  For other browsers,  
   set the 100% width and height explicitly on the <use> element   
   to match IE's behaviour.
*/
var basicScale = 50/500,  
    //50px is the desired width
    //500px is the width and height of the referencing graphic
    startScale = 1,
    endScale = 10,
    startTranslate = 225,
    endTranslate = 0;
var startTrans = "scale(" + startScale + ") translate(" 
                  + startTranslate + "," + startTranslate + ") scale(" 
                  + basicScale + ")",
    endTrans = "scale(" + endScale + ") translate(" 
                  + endTranslate + "," + endTranslate + ") scale(" 
                  + basicScale + ")";
/* ... */
svg.append("use")
    .attr("xlink:href", "#Livello_1")
    .attr("width", "100%")
    .attr("height", "100%")
    .attr("transform", startTrans)
    .call(transition, startTrans, endTrans);
http://jsfiddle.net/U9L7w/6/

对于正确实现规范的浏览器来说,这是获得最终结果的一种相当迂回的方式,但是您在它们和IE中都获得了所需的结果。