在Internet Explorer中,d3.js动画无法正常播放

3
我有一个使用d3.js制作的动画,在所有其他浏览器中都表现得非常好,但在IE浏览器中却有问题。希望实现的效果是它在增长和缩小时始终处于中心位置,然后无限循环。我在jsfiddle上制作了一个示例。问题在于,在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的版本将会是... - epascarello
版本是IE 11。其他版本可能也会发生这种情况。 - 655321
1
顺便说一句,我不确定为什么IE在DOM检查器中显示变换属性的简化版本而不是您分配的值,但这似乎不会影响任何事情 - scale(10,10)scale(10)意思完全相同! - AmeliaBR
1个回答

3
问题似乎在于IE忽略了<use>元素上的宽度和高度属性。相比之下,请查看这个版本的代码,我已经删除了这些属性(还有动画),你会得到其他浏览器中与IE一样的偏离位置。这是一个错误,并且我以前从未遇到过。也找不到关于它们bug报告网站的任何信息。在此期间,你可能需要准备一个更简单的示例并进行错误报告,同时以下是解决方法: <use>元素的宽度和高度属性作用于被引用的图形,将其缩放到该大小,仅当被引用的图形是带有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浏览器不仅忽略了width和height属性,而且应用了100%的默认值 - 这意味着它会在应用任何变换之前将引用的SVG缩放到与父SVG相同的大小(例如,在您的示例中为500px宽度和高度)。

因此,为了使所有浏览器都能良好地工作,您需要(a)使用width和height属性告诉其他浏览器缩放到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);

这是一种相对绕弯的方法,用于实现规范的浏览器,但您可以在它们和IE中获得所需的结果。

http://jsfiddle.net/U9L7w/6/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接