Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 3 of 3
  1. #1
    Senior Coder timgolding's Avatar
    Join Date
    Aug 2006
    Location
    Southampton
    Posts
    1,517
    Thanks
    114
    Thanked 110 Times in 109 Posts

    touch events and preventDefault

    Hi i have a script that seems to work ok on desktops browsers
    To see it you need to download Kinetic JS

    Using this kinetic class as it is i can create this script

    Code:
    
    <head>
        <style>
        div#container
        {
            border:1px solid black;
            width:300px;
            height:410px;
        }
        </style>
        <script src="kinetic-v3.8.3.js">
        </script>
        <script>
        window.onload = function(){
                
                var stage = new Kinetic.Stage("container", 300, 410);
                var shapesLayer = new Kinetic.Layer();
    
                var shape = new Kinetic.Shape({
                        clickable: true,
                        drawFunc: function(){
                            var ctx = this.getContext();
                            
                            ctx.fillStyle='green';
                            ctx.strokeStyle = 'rgba(0, 0, 0, 255)'; 
                            ctx.beginPath();
                            ctx.moveTo(10,20);
                            ctx.lineTo(120, 30);
                            ctx.lineTo(250, 220);
                            ctx.lineTo(10, 20);
                            ctx.stroke();
                            ctx.fill();
                            ctx.closePath();
                        }
                    });
                    
                    shape.on("mousedown", function(){
                        window.alert("shape was clicked");
                    });
                        
                    shapesLayer.add(shape);
                    
                    stage.add(shapesLayer);
                };
        </script>
    </head>
    <body onmousedown="return false;">
        <div id="container">
        </div>
    </body>
    I am trying to get this working on ipad / iphone etc. I had to change the kinetic-v3.8.3.js class to stop it from peventing default touch behaviour, if you open kinetic-v3.8.3.js and comment out any lines that say
    evt.preventDefault(); and save it to kinetic-v3.8.3-mobile.js Then you can get the mobile device version working. Stopping the prevenDefault() method means that the canvas object is a) scrollable and b) resizable.

    Code:
    
    <head>
        <style>
        div#container
        {
            border:1px solid black;
            width:300px;
            height:410px;
        }
        </style>
        <script src="kinetic-v3.8.3-mobile.js">
        </script>
        <script>
        window.onload = function(){
                
                var stage = new Kinetic.Stage("container", 300, 410);
                var shapesLayer = new Kinetic.Layer();
    
                var shape = new Kinetic.Shape({
                        clickable: true,
                        drawFunc: function(){
                            var ctx = this.getContext();
                            
                            ctx.fillStyle='green';
                            ctx.strokeStyle = 'rgba(0, 0, 0, 255)'; 
                            ctx.beginPath();
                            ctx.moveTo(10,20);
                            ctx.lineTo(120, 30);
                            ctx.lineTo(250, 220);
                            ctx.lineTo(10, 20);
                            ctx.stroke();
                            ctx.fill();
                            ctx.closePath();
                        }
                    });
                    
                    shape.on("touchend", function(){
                        window.alert("shape was clicked");
                    });
                        
                    shapesLayer.add(shape);
                    
                    stage.add(shapesLayer);
                };
        </script>
    </head>
    <body ontouchend="return false;">
        <div id="container">
        </div>
    </body>
    It kinda works. You can click the object at the start when page loads and it detects the touchend event. You can also resize and scroll the page up and down. However once i have resized the page or scrolled the touchend event stops working on my ipad. What have i done wrong. Can i allow resizing and scrolling and still detect the touch events?

    Edit:
    In fact is doesn't matter if i do evt.prevenDefault() or not. When i zoom in or move the window the shape stops registering any events. I have to zoom back out to register the click. Why does any zooming / scrolling stop my touch events being registered
    Last edited by timgolding; 05-16-2013 at 11:39 AM.
    You can not say you know how to do something, until you can teach it to someone else.

  • #2
    Senior Coder timgolding's Avatar
    Join Date
    Aug 2006
    Location
    Southampton
    Posts
    1,517
    Thanks
    114
    Thanked 110 Times in 109 Posts
    Although i didn't get any help with this i did think up a solution.

    The solution is to use the standard kinetic js script (no changes). This will automatically preventDefaults(); Then i made my own scripts to mimic the behaviour of zoom and panning functions on touch screens. That way i can zoom the canvas if i register a pinch over the canvas or i can move the screen with window.scrollTo(x, y);

    Here is an example of this.

    Code:
    <!DOCTYPE html>
    <html>
    <head>
        <style>
        div#container
        {
            border:1px solid black;
            width:300px;
            height:410px;
        }
        </style>
        <script src="kinetic-v3.8.3.js">
        </script>
        <script>
        function getDistance(p1, p2) {
                    return Math.sqrt(Math.pow((p2.x - p1.x), 2) + Math.pow((p2.y - p1.y), 2));
                }
        window.onload = function(){
               
                
                
                var lastDist = 0;
                var startScale = 1;
                var pinch = false;
                
                var zoom = 1;
                var pressed = false;
                var stage = new Kinetic.Stage("container", 300, 410);
                var shapesLayer = new Kinetic.Layer();
    
                var shape = new Kinetic.Shape({
                        drawFunc: function(){
                            var ctx = this.getContext();
                            
                            ctx.fillStyle='blue';
                            ctx.strokeStyle = 'rgba(0, 0, 0, 255)'; 
                            ctx.beginPath();
                            ctx.moveTo(10,20);
                            ctx.lineTo(120, 30);
                            ctx.lineTo(250, 220);
                            ctx.lineTo(10, 20);
                            ctx.stroke();
                            ctx.fill();
                            ctx.closePath();
                        }
                        
                    });
                    
                    
                    shape.on("touchend", function(){
                         
                       
                        window.alert("Clicked");
                        
                    });
    
                    
                    
                    
                    stage.on("touchstart", function(e){
                    
                        posX = e.clientX;
                        posY = e.clientY;
                        var touchPos = stage.getTouchPosition();
                        x_1 = touchPos.x;
                        y_1 = touchPos.y;
                    });
    
                    
                    stage.on("touchend", function(){
                        
                        lastDist = 0;
                        x_2 = 0;
                        y_2 = 0;
                        pinch = false;
                    });
                    
                    stage.on("touchmove", function(evt){
                        var touch1 = evt.touches[0];
                        var touch2 = evt.touches[1];
                
                        
                        
                        if(touch1 && touch2) {
                          pinch = true;
                          
                          var dist = getDistance({
                            x: touch1.clientX,
                            y: touch1.clientY
                          }, {
                            x: touch2.clientX,
                            y: touch2.clientY
                          });
                
                          if(!lastDist) {
                            lastDist = dist;
                          }
                
                          var scale = stage.getScale().x * dist / lastDist;
                
                          stage.setScale(scale);
                          stage.draw();
                          lastDist = dist;
                        }
                        else
                        {
                            if(touch1 && !pinch)
                            {
                                x_1 = touch1.clientX;
                                y_1 = touch1.clientY;
                                
                                if(!x_2)
                                {
                                    x_2 = x_1;
                                    y_2 = y_1;
                                }
                                
                                x_diff = x_2 - x_1;
                                y_diff = y_2 - y_1;
                                window.scrollTo(x_2 + x_diff, y_2 + y_diff);
                            }
                        }
                    });
    
                
                    shapesLayer.add(shape);
                    
                    stage.add(shapesLayer);
                    
                                    
                };
        </script>
    </head>
    <body>
        <div id="container">
        </div>
    </body>
    </html>
    Hope this helps someone
    You can not say you know how to do something, until you can teach it to someone else.

  • #3
    Senior Coder timgolding's Avatar
    Join Date
    Aug 2006
    Location
    Southampton
    Posts
    1,517
    Thanks
    114
    Thanked 110 Times in 109 Posts
    You may need to put a white rect in the background so when it zooms you dont see the old object underneath.
    You can not say you know how to do something, until you can teach it to someone else.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •