Skip to content

Instantly share code, notes, and snippets.

@alecperkins
Created October 16, 2012 02:31
Show Gist options
  • Save alecperkins/3896953 to your computer and use it in GitHub Desktop.
Save alecperkins/3896953 to your computer and use it in GitHub Desktop.
Experiment with 3-finger-swipe-to-reveal nav
#nav
button item 1
button item 2
button item 3
#panel
h1 ☰ Hello world!
p Swipe with three fingers to the right to reveal the nav panel
p Cras mattis consectetur purus sit amet fermentum. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nulla vitae elit libero, a pharetra augue. Donec id elit non mi porta gravida at eget metus. Etiam porta sem malesuada magna mollis euismod. Nulla vitae elit libero, a pharetra augue.

swipenav

An experiment in detecting three-finger dragging. The styles are still kinda weird on iPhones, but it works okay on iPads.

Prompted by Thibaut Sailly's blog post on a standardized gesture for revealing nav, similar to the three-bar navicon.

Live demo

$('head').append('<meta name="viewport" content="width=device-width">')
last_touch = null
start_time = null
distance = 0
$panel = $('#panel')
$panel.on 'touchstart', (e) ->
e.preventDefault()
# Get the latest touch for calculating the delta, clone because the touch
# will change as it moves.
last_touch = _.clone(_.last(e.originalEvent.touches))
return
$panel.on 'touchmove', (e) ->
# Only do a move if there are 3 touch points.
if e.originalEvent.touches.length is 3
if not start_time?
start_time = new Date()
# Calculate the delta of the change, using only the first touch.
touch = _.find e.originalEvent.changedTouches, (t) ->
t.identifier is last_touch.identifier
last_touch_delta_x = touch.screenX - last_touch.screenX
# Cap the change between 0 and 200.
if last_touch_delta_x > 200
last_touch_delta_x = 200
else if last_touch_delta_x < 0
last_touch_delta_x = 0
distance = last_touch_delta_x
# Set the position of the panel to match the touch delta.
# (This is kind of sluggish. CSS transforms would be better.)
$panel.css
left: last_touch_delta_x
return
$panel.on 'touchend', (e) ->
e.preventDefault()
# Only stop the gesture when all fingers are removed.
if e.originalEvent.touches.length is 0
# If the gesture is fast enough (more like a flick) or over the halfway
# point, fully open the panel.
if new Date() - start_time < 500 and distance > 30 or distance > 100
$panel.animate
left: 200
, 250
# Otherwise, reset the panel, snapping back to 0.
else
$panel.animate
left: 0
, 250
last_touch = null
start_time = null
distance = 0
else
# Ensure there is something to measure if the original last_touch was
# removed from the screen.
last_touch = _.clone(_.last(e.originalEvent.touches))
return
{
"name": "swipetest",
"proto_version": "0.0.4",
"script_libraries": [
"http://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.2/jquery.min.js",
"http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.1/underscore-min.js"
],
"style_libraries": [
]
}
body
overflow: hidden
width: 100%
height: 100%
position: absolute
top: 0
left: 0
#nav
position: absolute
top: 0
left: 0
bottom: 0
width: 100%
background: #555
button
display: block
#panel
min-height: 640px
background: #eee
position: absolute
top: 0
left: 0
bottom: 0
width: 100%
padding: 1em
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment