ericdrowell / KineticJS

KineticJS is an HTML5 Canvas JavaScript framework that extends the 2d context by enabling canvas interactivity for desktop and mobile applications.
http://www.kineticjs.com
3.98k stars 756 forks source link

CSS Scaling loses touching coordinates #925

Open bernal-pablo opened 10 years ago

bernal-pablo commented 10 years ago

Hi,

I'm trying to CSS scale a KinecticJS canvas that also has some touching shapes. After a simple CSS scale3d transform, everything works fine in my laptop web browser, but in Android or iOS, it doesn't recognize when I touch on the shapes.

It seems that, in iOS or Android, after scaling, the canvas fails to correctly position the coordinates of the touch events. Meaning that, if you touch one of the shapes, the canvas will think that you're touching somewhere else. And in the same way, if you touch the canvas in a position where there are no shapes after scaling but there was a shape before scaling, it will think that you're touching the shape now.

I've tried to make some research on this but I couldn't find a solution for this issue. Is anybody else having this problem or does anybody know of a fix for this?

Thanks!

ghost commented 10 years ago

Hi, I'm facing the same problem, the reason behind this is that the touch coordinate is not scaled with the canvas. Currently I have overriden the _setTouchPosition methode, so that the touch position also be transformed.

bernal-pablo commented 10 years ago

Hi, could you post the specific changes that you applied to the method to make it work? I would very much appreciate it. Thanks!

ghost commented 10 years ago
setZoomLevel: function(zoomLevel){
       this.zoomLevel = zoomLevel;
 },
 getZoomLevel : function(){
      return this.zoomLevel;
 },
_setTouchPosition: function(evt) {
            var touch, touchX, touchY;

            if(evt.touches !== undefined && evt.touches.length === 1) {
                // one finger
                touch = evt.touches[0];

                // get the information for finger #1
                touchX = touch.clientX - this._getContentPosition().left;
                touchY = touch.clientY - this._getContentPosition().top;
                var zLevel = this.getZoomLevel() == undefined ? 1 : this.getZoomLevel();
                this.touchPos = {
                    x: touchX/zLevel,
                    y: touchY/zLevel
                };
            }
}

I have recomputed the touch position using the scale level this way. Maybe there is a better solution.

bernal-pablo commented 10 years ago

It works great, thanks!!