Skip to content

Instantly share code, notes, and snippets.

@HoraceBury
Last active April 18, 2019 12:20
Show Gist options
  • Save HoraceBury/21c51048d717d49c3f29 to your computer and use it in GitHub Desktop.
Save HoraceBury/21c51048d717d49c3f29 to your computer and use it in GitHub Desktop.
BackSwipe Navigation for Composer
-- swipe library
--[[ Libraries ]]--
local composer = require("composer")
--[[ Fields ]]--
local mainstage = display.getCurrentStage()
local stage = composer.stage
local stagewrap = display.newGroup()
local touchpanel = display.newRect( display.actualContentWidth*.05, display.contentCenterY, display.actualContentWidth*.2, display.contentHeight )
touchpanel.fill = {0,0,0}
touchpanel.isHitTestable = true
touchpanel.alpha = 0
if (composer.isDebug) then
touchpanel.alpha = .1
end
stagewrap:insert( stage )
stagewrap:insert( touchpanel )
composer.backSwipeActive = true
--[[ Extensions ]]--
composer.getCurrentScene = function()
return composer.getScene( composer.getSceneName( "current" ) )
end
composer.getPreviousScene = function()
return composer.getScene( composer.getSceneName( "previous" ) )
end
composer.getOverlayScene = function()
return composer.getScene( composer.getSceneName( "overlay" ) )
end
composer.setPreviousScene = function( sceneName )
composer._previousScene = sceneName
end
--[[ Overrides ]]--
local gotoscene = composer.gotoScene
composer.gotoScene = function( sceneName, options )
composer.backSwipeActive = (options.isBackSwipe or false) and stage.numChildren > 0
touchpanel.isVisible = composer.backSwipeActive
if (sceneName == composer.getSceneName( "previous" )) then
local previousview = composer.getPreviousScene().view
composer.effectList[ options.effect ].to.xStart = previousview.x
end
gotoscene( sceneName, options )
end
--[[ Navigation ]]--
local function prepareBack()
local previous, current = composer.getPreviousScene().view, composer.getCurrentScene().view
previous.alpha = 1
previous.isVisible = true
previous:toFront()
current.alpha = 1
current.isVisible = true
current:toFront()
end
local function touch(e)
local view = stage[ stage.numChildren ]
local under = stage[ stage.numChildren-1 ]
if (composer.backSwipeActive) then
if (e.phase == "began") then
e.target.hasFocus = true
mainstage:setFocus( e.target )
e.target.prev = e
prepareBack()
composer.getCurrentScene():dispatchEvent{ name="swipe", phase="began" }
return true
elseif (e.target.hasFocus) then
if (e.phase == "moved") then
view.x = view.x + (e.x - e.target.prev.x)
if (view.x < 0) then
view.x = 0
end
under.x = -(display.actualContentWidth * .3) + (display.actualContentWidth * .3 * (view.x / display.actualContentWidth))
e.target.prev = e
composer.getCurrentScene():dispatchEvent{ name="swipe", phase="moved" }
else
e.target.hasFocus = false
mainstage:setFocus( nil )
e.target.prev = nil
if (view.x < display.actualContentWidth*.3) then
transition.to( view, { time=250, x=0, onComplete=function()
composer.getCurrentScene():dispatchEvent{ name="swipe", phase="cancelled" }
end } )
else
composer.getCurrentScene():dispatchEvent{ name="swipe", phase="ended" }
end
end
return true
end
return false
else
return false
end
end
touchpanel:addEventListener( "touch", touch )
--[[ Effects ]]--
composer.effectList["iosSlideLeft"] = {
sceneAbove = true,
concurrent = true,
to = {
xStart = display.actualContentWidth,
yStart = 0,
xEnd = 0,
yEnd = 0,
transition = easing.outQuad
},
from = {
xStart = 0,
yStart = 0,
xEnd = -display.actualContentWidth * 0.3,
yEnd = 0,
transition = easing.outQuad
}
}
composer.effectList["iosSlideRight"] = {
sceneAbove = false,
concurrent = true,
to = {
xStart = -display.actualContentWidth * 0.3,
yStart = 0,
xEnd = 0,
yEnd = 0,
transition = easing.outQuad
},
from = {
xStart = 0,
yStart = 0,
xEnd = display.actualContentWidth,
yEnd = 0,
transition = easing.outQuad
}
}
-- load reference to the composer api
local composer = require( "composer" )
-- create a scene object
local scene = composer.newScene()
-- declare scene's display group
local sceneGroup
-- called when the scene module is loaded
function scene:create( event )
-- keep reference to scene's display group
sceneGroup = self.view
end
-- called before and after the scene moves on screen
function scene:show( event )
if (event.phase == "will") then
-- scene is about to move on screen
elseif (event.phase == "did") then
-- scene has moved on screen
end
end
-- called before and after the scene moves off screen
function scene:hide( event )
if (event.phase == "will") then
-- scene is about to move off screen
elseif (event.phase == "did") then
-- scene has moved off screen
end
end
-- scene module is about to be removed from memory
function scene:destroy( event )
sceneGroup = nil
end
-- called when user performs back-swipe navigation
function scene:swipe( event )
if (event.phase == "began") then
-- user start a swipe from screen left
elseif (event.phase == "moved") then
-- user moved the current scene during navigation swipe
elseif (event.phase == "cancelled") then
-- user did not complete the navigation, scene remains on screen
elseif (event.phase == "ended") then
-- user completed navigation swipe, call gotoScene
end
end
-- listen to composer events
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
-- listen for the backswipe events
scene:addEventListener( "swipe", scene )
-- return the scene object from the module
return scene
local composer = require( "composer" )
local buttonlib = {}
local function blocktouch( sceneGroup, col )
local rect = display.newRect( sceneGroup, display.contentCenterX, display.contentCenterY, display.contentWidth, display.contentHeight )
rect.fill = col
rect:addEventListener("tap",function(e) return true end )
rect:addEventListener("touch",function(e) return true end )
return true
end
buttonlib.blocktouch = blocktouch
local function createBackButton( sceneGroup, sceneName )
local group = display.newGroup()
sceneGroup:insert( group )
group.x, group.y = display.contentWidth*.2, display.contentHeight*.2
local text = display.newText{ parent=group, text="BACK", fontSize=30 }
text.fill = {1,1,1}
display.newRect( group, 0, 0, text.width*1.2, text.height*1.2 ).fill = {0,0,0}
text:toFront()
group:addEventListener( "tap", function()
composer.gotoScene( sceneName, { time=500, effect="iosSlideRight", isBackSwipe=true } )
return true
end )
end
buttonlib.createBackButton = createBackButton
local function createMenuButton( sceneGroup, y, text, link, effect, isswipe )
local group = display.newGroup()
sceneGroup:insert( group )
group.x, group.y = display.contentCenterX, display.contentHeight*y
local text = display.newText{ parent=group, text=text, fontSize=40 }
text.fill = {1,1,1}
display.newRect( group, 0, 0, text.width*1.2, text.height*1.2 ).fill = {0,0,0}
text:toFront()
group:addEventListener( "tap", function()
composer.gotoScene( link, { time=500, effect=effect, isBackSwipe=isswipe } )
return true
end )
end
buttonlib.createMenuButton = createMenuButton
return buttonlib
local composer = require( "composer" )
local buttonlib = require( "buttonlib" )
local scene = composer.newScene()
local sceneGroup, animrect
local function showAnimation( sceneName )
animrect = display.newRect( sceneGroup, display.contentWidth*.25, display.contentHeight*.75, 0, 25 )
animrect.fill = {0,0,0}
transition.to( animrect, { time=750, width=display.contentWidth*.5, x=display.contentCenterX, onComplete=function()
composer.gotoScene( sceneName, { time=500, effect="iosSlideLeft", isBackSwipe=true } )
end } )
end
function scene:create( event )
sceneGroup = self.view
sceneGroup.name = "loading1"
buttonlib.blocktouch( sceneGroup, {.8,.8,.8} )
display.newText{ parent=sceneGroup, text="DOWNLOAD...", x=display.contentCenterX, y=display.contentHeight*.3, fontSize=70 }.fill = {0,0,0}
end
function scene:show( event )
if (event.phase == "will") then
elseif (event.phase == "did") then
showAnimation( "page1" )
end
end
function scene:hide( event )
if (event.phase == "will") then
elseif (event.phase == "did") then
animrect:removeSelf()
animrect = nil
end
end
function scene:destroy( event )
sceneGroup = nil
end
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
return scene
local composer = require( "composer" )
local buttonlib = require( "buttonlib" )
local scene = composer.newScene()
local sceneGroup
function scene:create( event )
sceneGroup = self.view
sceneGroup.name = "home"
buttonlib.blocktouch( sceneGroup, {1,1,1} )
display.newText{ parent=sceneGroup, text="HOME", x=display.contentCenterX, y=display.contentHeight*.2, fontSize=70 }.fill = {0,0,0}
buttonlib.createMenuButton( sceneGroup, .4, "Page 1", "page1", "iosSlideLeft", true )
buttonlib.createMenuButton( sceneGroup, .6, "Download", "download", "iosSlideLeft", false )
end
function scene:show( event )
if (event.phase == "will") then
elseif (event.phase == "did") then
end
end
function scene:hide( event )
if (event.phase == "will") then
elseif (event.phase == "did") then
end
end
function scene:destroy( event )
sceneGroup = nil
end
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
return scene
local composer = require( "composer" )
local buttonlib = require( "buttonlib" )
local scene = composer.newScene()
local sceneGroup, animrect
local function showAnimation( sceneName )
animrect = display.newRect( sceneGroup, display.contentWidth*.25, display.contentHeight*.75, 0, 25 )
animrect.fill = {0,0,0}
transition.to( animrect, { time=750, width=display.contentWidth*.5, x=display.contentCenterX, onComplete=function()
composer.gotoScene( sceneName, { time=500, effect="iosSlideLeft", isBackSwipe=true } )
end } )
end
function scene:create( event )
sceneGroup = self.view
sceneGroup.name = "loading1"
buttonlib.blocktouch( sceneGroup, {.8,.8,.8} )
display.newText{ parent=sceneGroup, text="DOWNLOAD...", x=display.contentCenterX, y=display.contentHeight*.3, fontSize=70 }.fill = {0,0,0}
end
function scene:show( event )
if (event.phase == "will") then
elseif (event.phase == "did") then
showAnimation( "page1" )
end
end
function scene:hide( event )
if (event.phase == "will") then
elseif (event.phase == "did") then
animrect:removeSelf()
animrect = nil
end
end
function scene:destroy( event )
sceneGroup = nil
end
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
return scene
display.setDefault( "background", 1, 1, 1 )
local composer = require( "composer" )
--composer.isDebug = true -- uncomment to show the swipe detection bar
require("backswipelib")
composer.gotoScene( "home", { effect="fade", time=250, isBackSwipe=false } )
local composer = require( "composer" )
local buttonlib = require( "buttonlib" )
local scene = composer.newScene()
local sceneGroup
function scene:create( event )
sceneGroup = self.view
sceneGroup.name = "page1"
buttonlib.blocktouch( sceneGroup, {1,.8,.8} )
display.newText{ parent=sceneGroup, text="PAGE 1", x=display.contentCenterX, y=display.contentHeight*.2, fontSize=70 }.fill = {0,0,0}
buttonlib.createMenuButton( sceneGroup, .4, "Page 2", "page2", "iosSlideLeft", true )
buttonlib.createBackButton( sceneGroup, "home" )
end
function scene:show( event )
if (event.phase == "will") then
elseif (event.phase == "did") then
composer.setPreviousScene( "home" )
end
end
function scene:hide( event )
if (event.phase == "will") then
elseif (event.phase == "did") then
end
end
function scene:destroy( event )
sceneGroup = nil
end
function scene:swipe( event )
if (event.phase == "ended") then
composer.gotoScene( "home", { time=500, effect="iosSlideRight" } )
end
end
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
scene:addEventListener( "swipe", scene )
return scene
local composer = require( "composer" )
local buttonlib = require( "buttonlib" )
local scene = composer.newScene()
local sceneGroup
function scene:create( event )
sceneGroup = self.view
sceneGroup.name = "page2"
buttonlib.blocktouch( sceneGroup, {.8,1,.8} )
display.newText{ parent=sceneGroup, text="PAGE 2", x=display.contentCenterX, y=display.contentHeight*.2, fontSize=70 }.fill = {0,0,0}
buttonlib.createMenuButton( sceneGroup, .4, "Page 3", "page3", "iosSlideLeft", true )
buttonlib.createBackButton( sceneGroup, "page1" )
end
function scene:show( event )
if (event.phase == "will") then
elseif (event.phase == "did") then
composer.setPreviousScene( "page1" )
end
end
function scene:hide( event )
if (event.phase == "will") then
elseif (event.phase == "did") then
end
end
function scene:destroy( event )
sceneGroup = nil
end
function scene:swipe( event )
if (event.phase == "ended") then
composer.gotoScene( "page1", { time=500, effect="iosSlideRight", isBackSwipe=true } )
end
end
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
scene:addEventListener( "swipe", scene )
return scene
local composer = require( "composer" )
local buttonlib = require( "buttonlib" )
local scene = composer.newScene()
local sceneGroup
function scene:create( event )
sceneGroup = self.view
sceneGroup.name = "page3"
buttonlib.blocktouch( sceneGroup, {.8,.8,1} )
display.newText{ parent=sceneGroup, text="PAGE 3", x=display.contentCenterX, y=display.contentHeight*.2, fontSize=70 }.fill = {0,0,0}
buttonlib.createBackButton( sceneGroup, "page2" )
end
function scene:show( event )
if (event.phase == "will") then
elseif (event.phase == "did") then
composer.setPreviousScene( "page2" )
end
end
function scene:hide( event )
if (event.phase == "will") then
elseif (event.phase == "did") then
end
end
function scene:destroy( event )
sceneGroup = nil
end
function scene:swipe( event )
if (event.phase == "ended") then
composer.gotoScene( "page2", { time=500, effect="iosSlideRight", isBackSwipe=true } )
end
end
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
scene:addEventListener( "swipe", scene )
return scene
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment