1

所以这是我的动画功能:

    function animation(el, isHorizontal, from, to, callback) {
        var start = true === isHorizontal ? from.x : from.y,
            stop = true === isHorizontal ? to.x : to.y,
            intervalId, diff;

        intervalId = setInterval(function () {
            diff = Math.abs(stop - start);
            if (stop < start) {
                if (diff < 4) {
                    start -= diff;
                } else {
                    start -= 4;
                }
            } else {
                if (diff < 4) {
                    start += diff;
                } else {
                    start += 4;
                }
            }
            if (true === isHorizontal) {
                el.style.left = start + 'px';
            } else {
                el.style.top = start + 'px';
            }
            if (start === stop) {
                clearInterval(intervalId);
                callback();
            }
        }, 1);
    }

它在 Chrome 中完美运行,尽管在 Safari 中,动画元素似乎在它们应该停止之前停止了几个像素。

假设我要从左侧移动:8 到左侧:116。在 Safari 中,元素在左侧结束:108,当我打开检查器查看控制台并检查元素上的左侧偏移是否正确时,元素正确地重新定位。

我需要做的就是打开开发者控制台,然后元素跳转到正确的位置。

这么奇怪。

这是我的一些可能相关的 CSS:

.box {
    position: relative;
     }
    .item {
        position: absolute;
        background-position: left top;
        background-repeat: no-repeat;
        background-size: 100% auto;
        -webkit-transform: transform;
    }
4

2 回答 2

1

看起来您的代码没有任何问题,但是 Safari 在应该执行重绘时没有执行(因为当您打开开发人员控制台时问题就消失了)。

如果您将 1 毫秒间隔增加到 50 毫秒,您还会遇到问题吗?

通常有效的一种技巧是通过在动画结束时切换 body 上的虚拟类来强制浏览器重新绘制整个页面:

if (start === stop) {
    jQuery("body").toggleClass("forceRepaint");

    clearInterval(intervalId);
    callback();
}

当然,你可以不用 jQuery 来做到这一点,但它会变得不那么简洁。

此外,如果您使用 requestAnimationFrame() 而不是 setInterval() 来制作这样的动画(以及更好的性能),您很可能会避免这个问题。在旧浏览器中,有几个 polyfill 会退回到 setInterval/setTimeout。

于 2013-08-31T13:18:22.950 回答
0

所以似乎在 Safari 中我必须触发硬件加速,否则 Safari 无法跟上并足够快地重新绘制图像:

    -webkit-transform-style: preserve-3d;
    .item {
        position: absolute;
        background-position: left top;
        background-repeat: no-repeat;
        background-size: 100% auto;
        -webkit-transform-style: preserve-3d;
    }
于 2013-08-31T13:37:15.360 回答