-
21 Apr 2012 5:40 AM #1
Extending Ext.Button for better UX and responsive tap
Extending Ext.Button for better UX and responsive tap
GT.FixedButton
==============
This extends the Ext.Button in Sencha Touch 2.0 for a different, more iOS like user experience. As the name suggests this works well for buttons that are fixed and not in a scrollable container. It might also work with buttons in a scrollable container but haven't tested yet.
Code and Example
===============
The code is here: https://github.com/roycyang/sencha-touch-extensions
An example is here: http://roycyang.github.com/sencha-touch-extensions/example
Screen Shot 2012-04-24 at 10.17.49 AM.png
The Problem
===============
Currently, Ext.Button has the following rules:
1. The button fires on the tap event. This is not optimal because the user needs to tap the button and release it exactly on the same pixel, or else the tap event doesn't fire. There is a thread about using moveThrottle (http://www.sencha.com/forum/showthre...t=movethrottle) to give the tap event a tolerance:
But this code messes with the other touch events, making the carousel and all scrolling look choppy. Even if that choppiness was acceptable, a 3px or 5px tolerance still isn't good enough. Some users are "sloppy" tappers.Code:Ext.application({ eventPublishers: { touchGesture: { moveThrottle: 3 } }, // ... });
2. When you touch a button, the press state is added. Only when you let go (touchend), does the press state disappear. Even if you touch the button and drag your finger off, the press state remains. There is a fundamental flaw in the logic in that when the user sees the "press state" activated, they would expect the button to be "tapped" when they let go.
The Alternative
===============
This attempts to solve the issues by doing the following:
1. The tap zone is now larger than the button itself. This is done using a tapmask and is inspired by SunboX and Lim Chee Aun's post: http://cheeaun.com/blog/2012/03/how-...b-app#the-feel
2. Upon press, the tap zone is doubled.
3. The tap event is tied to touchstart and touchend. If you touch the button and then release and are still on tap zone, it will fire the tap event. The user can now be as "sloppy" as they want and there is a now a buffer zone around the button.
4. The press state is also tied to touchmove. If you activate the button press and then move your finger off the button, the press state disappears and the tap event won't fire.
Getting Started
===============
To use this, add the following to your app.js:
From there, you will have access to the fixed button by using:Code:Ext.Loader.setPath({ 'GT': 'GT' });
Code:requires: ['GT.FixedButton'] //... xtype: 'fixedbutton' // these are default, only add if you are changing tapMask: null, // change to true to see the zone, good for debugging tapOverflowTop: 10, // in pixels tapOverflowBottom: 10, // in pixels tapOverflowLeft: 10, // in pixels tapOverflowRight: 10 // in pixels
-
22 Apr 2012 2:11 AM #2
Looks very interesting. I'm building an app that uses several fixed buttons so this would fit in great. However, I don't see a download link anywhere for the package.
-
22 Apr 2012 5:41 AM #3
-
22 Apr 2012 11:15 PM #4
Nice work!
Sencha should change this in the framework.
-
23 Apr 2012 5:54 AM #5
After testing in iOS, it appears that there is a bug in the touch targets, which I've submitted here: http://www.sencha.com/forum/showthre...s-wrong-in-iOS
The jist is that when you listen to the touchmove event:
What is returned should be what you're currently "touching" but always returns the first thing you touched which means there is no information on what you touched when you release.Code:touchmove: function(event, target){ console.log('target should be: ' + target.id) }
In Chrome/Safari, it displays the correct behavior hence the example works in chrome but isn't 100% in iOS yet.
-
24 Apr 2012 12:45 AM #6
Really nice, would be cool if this worked as overwrite of default Sencha Buttons.
Who is interested in the iOS Button behavior, Lim Chee Aun did a really nice write on this:
http://cheeaun.com/blog/2012/03/how-...b-app#the-feel
greetings Sunny
-
24 Apr 2012 3:54 AM #7
Great read! Definitely given me the inspiration to extend this some more to override the touchmove bug and create a touchend 50px "ring" around the button instead.
I'll work on making those dimensions configurable. That also solves a big issue in that it's hard to hit a small target on a smartphone. I've always used padding and an image to fake a larger initial tap area. I'll see about creating a mask that is a smaller "ring" around a button.
-
24 Apr 2012 6:04 AM #8
I've incorporated the latest changes so now the example is using a tapmask. Still need to tie it to x/y coordinates instead of the element itself due to the sencha bug. But it works great in Chrome/Safari. Check it out:
http://roycyang.github.com/sencha-to...sions/example/
-
24 Apr 2012 1:43 PM #9
This is a HUGE improvement to how the buttons behave in ST2. Thanks!
-
24 Apr 2012 4:49 PM #10
Thanks for the feedback guys.
Updated FixedButton so that it's tied to X/Y coordinates so it now works in iOS. I'm assuming it will also work in Android/Blackberry as the code is pretty standard. Essentially when you tap a button, I record the offsets and height and width and then compare that to the x/y coordinates on touchmove and touchend.
One caveat is that this will unfortunately NOT work in a scrolling container as the scrolling changes the X/Y coordinate calculation. There needs to be a lot more logic and deeper integration into ST2 for this to work successfully in scrolling containers. Based on SunboX's post, we could port this UI over to be a good disclosure icon for a list but that's another day!


Reply With Quote