免费手绘时iOS SVG滞后

时间:2015-12-23 21:44:17

标签: javascript jquery ios performance svg

我正在为我们的用户写一个简单的绘图“事物”。它使用SVG。所有用户都有iPad,4s或Air 2s。我正在测试2(第二代, Air 2)。所有iPad都运行iOS 9.2并使用Safari。

当在SVG元素上徒手绘制时,存在很大的滞后。在第二代它是“几乎可以容忍”,在4s它是“令人难以置信的痛苦”。不确定Air 2s,但如果它按照4s的方式进行缩放,我会说它现在“杀了我”。有趣的是更好的硬件如何滞后,但我想它可能与增加的分辨率有关,但仍然......

我能做些什么来改善表现吗?在绘制准备好的形状(矩形,线条(路径)和椭圆)时,滞后也是显而易见的,但这是我们可以忍受的东西。

这是我用来绑定事件处理程序(使用jQuery)进行徒手绘制的代码。

Floor.bindFreeHand = function (e) {
    e.preventDefault();
    var sPB, d, p1, segments;
    Floor._jElement.off(EventTypes.pointerDown + " " + EventTypes.pointerUp).on(EventTypes.pointerDown, function (e) {
        var pI1 = PointerInfo.parse(e);
        sPB = new SvgPathsBuilder();
        d = sPB.moveTo(pI1.x, pI1.y).d();
        p1 = Svg.path(d).attr({
            "fill": "none",
            "stroke": Floor._color,
            "stroke-linecap": "round",
            "stroke-linejoin": "round",
            "stroke-opacity": Floor._opacity,
            "stroke-width": Floor._width
        });
        segments = p1.element.pathSegList;
        Floor._sElement.add(p1);
        Floor._jElement.on(EventTypes.pointerMove, function (e) {
            e.preventDefault();
            e.stopPropagation();
            segments.appendItem(p1.element.createSVGPathSegLinetoAbs(e.offsetX, e.offsetY));
            //var pI2 = PointerInfo.parse(e);
            //d = sPB.lineTo(pI2.x, pI2.y).d();
            //p1.attr("d", d);
        });
    }).on(EventTypes.pointerUp, function (e) {
        Floor._jElement.off(EventTypes.pointerMove);
    });
};

这是PointerInfoEventTypes个对象:

var PointerInfo = (function () {
    function PointerInfo(x, y) {
        this.x = x;
        this.y = y;
    }
    PointerInfo.parse = function (e) {
        var x = e.offsetX - 2, y = e.offsetY - 1;
        return new PointerInfo(x, y);
    };
    return PointerInfo;
})();

var EventTypes = (function () {
    function EventTypes() {
    }
    EventTypes.touch = EventTypes.touch || ("ontouchstart" in window);
    EventTypes.pointerDown = EventTypes.touch ? "touchstart" : "mousedown";
    EventTypes.pointerMove = EventTypes.touch ? "touchmove" : "mousemove";
    EventTypes.pointerUp = EventTypes.touch ? "touchend" : "mouseup";
    EventTypes.pointerLeave = EventTypes.touch ? "touchleave" : "mouseout";
    return EventTypes;
})();

所有这些都是从TypeScript编译而来的。

1 个答案:

答案 0 :(得分:1)

我花了两天的时间把它弄清楚并禁用了页面上的其他所有内容以及其他每个脚本都被加载了。事实证明,导致滞后的是CSS。正在绘制的SVG元素具有通过渐变创建的背景图案,看起来像网格。显然,随着路径在touchmove上更新,元素的布局无效,Safari正在不断地重新绘制它。

因此,故事的寓意是iOS Safari中的性能问题并非始终归功于JavaScript。花哨的CSS效果也有助于它,特别是如果它们所依赖的元素被不断地操纵。

<强>更新

使用Chrome 48,您无法再设置路径的细分受众群,因为该API已弃用并已删除。现在的解决方案是在指针移动时不断更新d属性。从我的测试来看,即使在iPad第二代等旧设备上也没有明显的性能损失。