2

我之前有一个基于 HTML5 画布的应用程序,我最近转换为使用 Kinetic JS。我可以通过简单地在包含的 div 上使用 overflow: auto 在桌面浏览器和 IOS 中启用滚动。由于转换为使用 Kinetic 滚动不再适用于移动/iPad 设备。

尽管我有点卡住了,但我尝试了几种不同的方法来解决这个问题。首先,我尝试使用 touchscroll,但由于各种原因这对我不起作用(尽管库导致其他问题,但事情确实滚动了)。接下来,我尝试将 -webkit-overflow-scrolling: touch 选项添加到我的 div 样式中,尽管这似乎没有任何效果。

是否有滚动大于可视区域/div 的 Kinetic JS 画布的标准方法?

这是一个例子。如果您在 IOS 设备(iPad、iPhone 等)上查看示例,您会注意到顶部画布不会在 div 内滚动,而底部画布会滚动。

http://jsfiddle.net/blueshirts/uERVq/26/

<!-- KineticJS canvase, won't scroll on IOS devices. -->
<div id="container" style="overflow: auto; width: 400px; height: 400px; background-    color: gray">
</div>

<br/>

<!-- Vanilla HTML5 Canvas, does scroll on IOS devices. -->
<div id="canvasContainer"
     style="width: 400px; height: 400px; overflow: auto; background-color: red">
    <canvas id="vanillaCanvas"
            width="800" height="600">
    </canvas> 
</div>

// Create a stage instance that is larger than its parent div.
var stage = new Kinetic.Stage({
    container: 'container',
    width: 800,
    height: 600
});

// Create a layer.
var layer = new Kinetic.Layer();

// Add some text...
var text = new Kinetic.Text({
    text: "KineticJS generated Canvas that won't scroll to IOS touches...",
    x: 0,
    y: 0,
    fontSize: 12,
    fontFamily: 'Calibri',
    textFill: 'Black'                
});
layer.add(text);

// Add a rectangle to the layer so you can see if the content scrolls.
var rect = new Kinetic.Rect({
    x: 50,
    y: 50,
    width: 200,
    height: 100,
    fill: "yellow",
    stroke: "black",
    strokeWidth: 7
});
layer.add(rect);

// Add the layer to the stage.
stage.add(layer);


// Create a "vanilla" canvas instance and draw the same rectangle on it.
var canvas = document.getElementById('vanillaCanvas');
var context = canvas.getContext('2d');

context.beginPath();
context.rect(50, 50, 200, 100);
context.fillStyle = 'yellow';
context.fill();
context.lineWidth = 7;
context.strokeStyle = 'black';
context.stroke();

编辑:

可能是错误的,但在我看来,这个问题是由 Kinetic 在 Stage 类中注册 touchmove 事件(和其他事件)引起的。在它运行的处理程序中, preventDefault 似乎阻止移动浏览器执行其默认滚动行为。如果“我”已经注册了 touchmove 事件,这可能是可取的。如果 Kinetic 没有注册和处理我不感兴趣的事件,那就太好了。

 _touchmove: function(evt) {
     this._setUserPosition(evt);
     var dd = Kinetic.DD;
     evt.preventDefault();

我可以在这里演示这个问题:http: //jsfiddle.net/blueshirts/P9RaT/28/

4

4 回答 4

1

我认为这是 Kinetic JS 中的一个基本错误。如果我知道是这种情况,我就不会开始使用动力学 JS 来着手一个雄心勃勃的项目,因为它甚至不能做基础。

由于 Kinetic 团队没有任何回应,我将切换到 bug 较少的库,如 fabric.js。

于 2014-06-26T09:41:31.743 回答
0

我在 iPad/iPhone 上使用 KineticJS 创建的地图滚动时遇到了同样的问题。

这对我有用:stage.setListening(false);

我在这里找到了这个解决方案:

https://github.com/ericdrowell/KineticJS/pull/510

于 2014-09-27T01:09:11.227 回答
0

不确定我是否喜欢这个选项,尽管它比使用许多滚动库之一要好。我可以通过扩展默认 Stage 类并仅在我不在移动设备上时执行 evt.preventDefault() 来解决此问题。虽然到目前为止似乎符合我的用法,但不确定这可能会造成什么不良影响。如果有更简单的方法来修改默认行为,那就太好了。

Kinetic.Global.extend(MyStage, Kinetic.Stage);
function MyStage(mobile, config) {
    this.mobile = mobile;
    this._initStage(config);
}
MyStage.prototype._touchstart = function(evt) {
    this._setUserPosition(evt);
    if (this.mobile) {
        evt.preventDefault();
    }
    var obj = this.getIntersection(this.getUserPosition());

    if(obj && obj.shape) {
        var shape = obj.shape;
        this.tapStart = true;
        shape._handleEvent('touchstart', evt);
    }

    /*
                         * init stage drag and drop
                         */
    if(Kinetic.DD && this.attrs.draggable) {
        this._initDrag();
    }
}
MyStage.prototype._touchmove = function(evt) { // Override the default touchmove handler.
    this._setUserPosition(evt);
    var dd = Kinetic.DD;
    if (this.mobile) {
        evt.preventDefault();
    }
    var obj = this.getIntersection(this.getUserPosition());
    if(obj && obj.shape) {
        var shape = obj.shape;
        shape._handleEvent('touchmove', evt);
    }

    // start drag and drop
    if(dd) {
        dd._startDrag(evt);
    }
}
于 2012-11-22T04:15:10.740 回答
0

我可能不完全理解这个问题,但为什么不直接在舞台上添加 'draggable: true'

// Create a stage instance that is larger than its parent div.
var stage = new Kinetic.Stage({
    container: 'container',
    width: 800,
    height: 600,
    draggable: true
});

我正在使用同样的方法,我的画布是视口大小的几倍,并且使用“可拖动:真”我可以滚动画布图像。

于 2014-01-09T04:27:19.237 回答