Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent slow firing of touch start when the event remains still

Edit

I'm essentially trying to create the Mario style jump, so as you touch / mousedown on the body I have an object that starts travelling up, but when you let go this acceleration stops. This means I can't use FastClick as I'm looking for touchstart, touchend events, not a single click event.

~

I'm trying to respond to a touchstart event on mobile in browser. At the moment I'm using these two listeners:

document.body.addEventListener('touchstart', function(e) {
  e.preventDefault();
  space_on();
  return false;
}, false);

document.body.addEventListener('touchend', function(e) {
  e.preventDefault();
  space_off();
  return false;
}, false);

I'm essentially trying to emulate something I've had working really well where I use keydown and keyup events to make a box jump and fall respectively.

The issue I'm having is that a touch start, if you don't swipe, is actually delaying for a short while. Either that, or a calculation is making me lose framerate.

I'm already using fastclick and that isn't effecting this (probably because it was never meant to fire on touchstart listeners). You can see what I mean here:

https://www.youtube.com/watch?v=8GgjSFgtmFk

I swipe 3 times and the box jumps immediately, and then I click 3 times and you can see (especially on the second one) it loses framerate a little bit or is delayed. Here is another, possibly clearer example: https://www.youtube.com/watch?v=BAPw1M2Yfig

There is a demo here:

http://codepen.io/EightArmsHQ/live/7d851f0e1d3a274b57221dac9aebc16a/

Just please bear in mind that you'll need to either be on a phone or touch device or emulate touches in chrome.

Can anyone help me lose the framerate drop or delay that is experienced on a touchstart that doesn't turn into a swipe?

like image 312
Djave Avatar asked Oct 14 '16 08:10

Djave


1 Answers

You should not write your animation loop using setInterval.

Try to replace it with requestAnimationFrame, like this:

  function render() {
    ctx.fillStyle = 'rgba(255,255,255,0.8)';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    draw_rects();
    move();
    fall();
    move_scenery();
    move_jumper();
    jumper.y += jumper.vy;
    requestAnimationFrame(render);
  }

  $(window).load(function() {
    requestAnimationFrame(render);
  });

Like I've done in this pen.

Now your render function is called as soon as the browser is ready to render a new frame. Note that this implementation doesn't use your fps variable, so your frame rate now depends on the browser/device speed. I tested the pen I've edited on my phone and now the animation is way smoother but the scenery is moving too fast (for me at least).

If you want a constant frame rate you can throttle it as explained, for example, here.

Note that you really don't need Fastclick because you aren't binding any click event in your code.

like image 62
Gab Avatar answered Oct 02 '22 01:10

Gab