IE中的SVG路径线动画

3
我在网页上有一些路径动画,它们在除IE10/11以外的所有浏览器中都可以正常工作。然而,我在其他页面上有一些更简单的动画,使用了基本相同的代码,只是少用了一些,它们似乎没问题。
我认为这可能与IE相关的性能瓶颈有关。
如果您在IE10/11中查看http://codepen.io/jhealey5/pen/YXzbYY,您会发现SVG出现了故障或未完全呈现的问题。我无法确定具体问题所在。
来自codepen的相关JS代码:
    var cfg = {
            easing: [0.165, 0.84, 0.44, 1],
            duration: 1200,
            delay: 500,
            layerDelay: 7000,
            width: 28,
            positioning: true,
            colors: [
                    '#027CA5',
                    '#75B5C6',
                    '#00FFD0',
                    '#00B994',
                    '#BEF5FE'
            ]
    }

    $('.shape-layer').each(function(i) {
            var $this = $(this);

            setTimeout(function() {
                    var $paths = $this.find('path');

                    strokeSetup($paths);
                    strokeOut($paths);

            }, cfg.layerDelay * i);
    });

    function strokeSetup($el) {
            $el.each(function(i) {
                    var $this = $(this),
                            pLen = Math.ceil($this.get(0).getTotalLength());

                    $this.css({
                            'stroke-dasharray': pLen,
                            'stroke-dashoffset': pLen,
                            'stroke-width': cfg.width
                    });
            });
    }

    function strokeOut($el) {
            var pathCount = $el.length,
                    iterationCount = pathCount;

            $el.each(function(i) {
                    var $this = $(this),
                            pLen = Math.ceil($this.get(0).getTotalLength()),
                            color = cfg.colors[getRandom(0, cfg.colors.length)];

                    setTimeout(function() {
                            $this.css({
                                    'stroke': color
                            });

                            if (cfg.positioning) {
                                    var side = ['top', 'bottom', 'left', 'right'],
                                            cssO = {};

                                    $this.parent().css({
                                            top: 'auto',
                                            bottom: 'auto',
                                            left: 'auto',
                                            right: 'auto'
                                    });

                                    cssO[side[getRandom(0, 1)]] = getRandom(0, 40) + '%';

                                    var firstPos = cssO[Object.keys(cssO)[0]],
                                            sideAmount = (parseInt(firstPos) < 20) ? 100 : 20;

                                    cssO[side[getRandom(2, 3)]] = getRandom(0, sideAmount) + '%';

                                    $this.parent().css(cssO);
                            }

                            $this.velocity({
                                    'stroke-dashoffset': 0,
                            }, {
                                    duration: cfg.duration,
                                    easing: cfg.easing
                            });

                            if (!--iterationCount) {
                                    strokeIn($el);
                            }
                    }, cfg.delay * i);
            });

    }

    function strokeIn($el) {
            var pathCount = $el.length,
                    iterationCount = pathCount;

            $el.each(function(i) {
                    var $this = $(this),
                            pLen = Math.ceil($this.get(0).getTotalLength());

                    setTimeout(function() {

                            $this.velocity({
                                    'stroke-dashoffset': pLen
                            }, {
                                    duration: cfg.duration,
                                    easing: cfg.easing
                            });

                            if (!--iterationCount) {
                                    strokeOut($el);
                            }
                    }, cfg.delay * i);
            });
    }

    function getRandom(min, max) {
            return Math.floor(Math.random() * (max - min + 1)) + min;
    }

这个在IE上的表现看起来像是重新绘制错误。看起来 IE 没有正确计算重绘区域。也许这与你复杂的超时重叠安排有关。你可以通过只在IE上运行一个破折号偏移动画来解决问题。 - Paul LeBeau
1个回答

2
您可能已经知道,所有版本的Internet Explorer都不支持SMIL。路径/笔画等的动画是SMIL的内容。即使通过JavaScript也无法实现。而且jQuery与SVG DOM不完全兼容。尽管此操作是通过CSS SVG属性进行的,但通过CSS实现的SVG“动画”并不理想。
SMIL正在逐渐消失并将被弃用,这就是为什么我建议花更多时间使用像Snap.svg(ie9 +)或Raphaël(ie6 +)这样的库,个人更倾向于Snap。
无论如何,关于您制作的这个动画呢?
从明智的专业角度来看,在您的情况下,这不是渐进增强的场景。这意味着您应该通过将SVG动画转换为视频、gif或静态图像,并将其用作IE浏览器的回退方式来进行补偿。例如,通过modernizr或其他方式。
每个浏览器中的每个页面都必须完全相同是完全错误的。我认为对于那些在此场景中缺少功能的用户,静态jpg图像已足够。
我时刻注意到的另一件事是,在涉及SVG时,Internet Explorer在不同版本中“破坏”了兼容性。

1
我使用相同的技术在网站的其他页面上对类似路径形状进行动画处理,它们都能正常工作。只有这个页面有更复杂的动画效果无法正常工作。我完全同意,如果我找不到解决方案,我将退回到图像,就像!Modernizr.svg或移动设备上一样。 - evu
说实话,我很少使用CSS进行SVG动画。我并不完全确定IE浏览器对通过SVG使用CSS进行动画的支持情况以及不同版本之间的差异。我知道可能会有更具体的答案。顺便说一句,在我的“Android Chrome”浏览器上效果非常棒。 ;) - frontsideup
1
@Undefined OP在这里没有使用SMIL动画。这只是普通的手动CSS操作。 - Paul LeBeau
@PaulLeBeau 我明白。但说实话,使用CSS来动画化SVG应该因为很多原因而停止。这种动画可能会使5-10%的用户感到疏远,除非有解决方法。在我看来,这并不是必要的,但我相信其他人可能会持不同意见。Edge也不支持过时的SMIL。我们可以通过Web Animations Polyfill或类似Raphael、Snap和GSAP的库来使用新的动画API“Web Animations API”。但是,jQuery并不是一个专门用于DOM/Canvas/SVG等动画库,它只是一个通用的库。 - frontsideup

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