Last active
April 22, 2020 13:12
-
-
Save rannerboy/e84a75d7e17265d077a0b72a039209c1 to your computer and use it in GitHub Desktop.
Corona SDK slideshow module - Swiping objects left and right
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[ | |
Example of using the slideshow module | |
Creates a number of large circles as the main display groups used by the slideshow example | |
Also creates thumbnails that will be updated by callbacks from the slidehow module | |
Markus Ranner 2016 | |
--]] | |
local slideshow = require("slideshow") | |
display.setStatusBar(display.HiddenStatusBar) | |
--[[ | |
Create circles of random colors to use as slideshow objects | |
--]] | |
local function createSlideshowObjects(numberOfObjects) | |
local objects = {} | |
for i = 1, numberOfObjects do | |
--[[ | |
Each slideshow object is added to its own display group. | |
This is not really necessary in this example, but shows that the slideshow works with display groups which will be the most likely use case | |
--]] | |
local group = display.newGroup() | |
local circle = display.newCircle(0, 0, 200) | |
-- Save the fill color as a property to be able to retrieve it later for the thumbnails | |
circle.fillColor = { math.random(), math.random(), math.random(), 1 } | |
circle:setFillColor(unpack(circle.fillColor)) | |
group:insert(circle) | |
objects[#objects + 1] = group | |
end | |
return objects | |
end | |
--[[ | |
Create and return a display group containing a thumbnail for each of the slideshow objects | |
--]] | |
function createThumbnails(slideshowObjects) | |
local group = display.newGroup() | |
local thumbSize = 30 | |
local thumbMargin = 10 | |
for i = 1, #slideshowObjects do | |
-- Since we added the slideshow objects to a display group, we get the first (only) object of the group here to find out its color | |
local obj = slideshowObjects[i][1] | |
local thumb = display.newCircle((i - 1) * (thumbSize + thumbMargin), 0, thumbSize / 2, thumbSize / 2) | |
thumb:setFillColor(unpack(obj.fillColor)) | |
thumb:setStrokeColor(1, 1, 1, 1.0) | |
thumb.strokeWidth = 0 | |
thumb.anchorX = 0 | |
-- Setup a tap handler for each thumb that will quick jump to selected object index | |
thumb:addEventListener("tap", function() | |
local disableTransition = false | |
slideshow.showObjectAtIndex(i, disableTransition) | |
end) | |
group:insert(thumb) | |
end | |
group.x = display.contentCenterX - (#slideshowObjects / 2 * (thumbSize + thumbMargin)) | |
group.y = display.contentHeight - 100 | |
return group | |
end | |
math.randomseed( os.time() ) | |
-- Setup the objects and thumbnails to use for the slideshow | |
local slideshowObjects = createSlideshowObjects(9) | |
local thumbnailsGroup = createThumbnails(slideshowObjects) | |
local function updateThumbnails(selectedObjectIndex) | |
-- Highlight the stroke of the selected object's corresponding thumbnail | |
for i = 1, thumbnailsGroup.numChildren do | |
local thumb = thumbnailsGroup[i] | |
if (i == selectedObjectIndex) then | |
thumb.strokeWidth = 3 | |
else | |
thumb.strokeWidth = 0 | |
end | |
end | |
end | |
--[[ | |
Start the slideshow | |
This example shows all the customizable parameters, but all the parameters are optional | |
--]] | |
local slideshowParams = { | |
startIndex = 5, | |
transitionEffect = easing.outCubic, | |
transitionEffectTimeMs = 250, | |
y = display.contentCenterY - 100, | |
swipeSensitivityPixels = 50, | |
onChange = updateThumbnails, | |
} | |
slideshow.init(slideshowObjects, slideshowParams) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[ | |
Corona SDK slideshow module | |
Handles a number of display objects/groups, displaying only one at a time. | |
Allows user to swipe left/right to change displayed object. | |
Uses callbacks to update other parts of the program when a new object is displayed. | |
Markus Ranner 2016 | |
--]] | |
-- State | |
local _slideshowObjects | |
local _currentObjectIndex | |
local _transitionEffectTimeMs | |
local _transitionEffect | |
local _swipeSensitivityPixels | |
local _onChange | |
local function showObject(objectIndex, disableTransition) | |
local objectToShow = _slideshowObjects[objectIndex] | |
-- Update current object index and make a callback if selected object has changed | |
if(_currentObjectIndex ~= objectIndex) then | |
_currentObjectIndex = objectIndex | |
if (_onChange) then | |
_onChange(_currentObjectIndex) | |
end | |
end | |
-- Transition all slideshow objects into place | |
for i = 1, #_slideshowObjects do | |
local object = _slideshowObjects[i] | |
local x = _slideshowObjects[i].originalPosition.x - ((objectIndex - 1) * display.contentWidth) | |
-- If transition has been disabled, update position immediately | |
if (disableTransition) then | |
object.x = x | |
else | |
transition.to(object, { | |
x = x, | |
time = _transitionEffectTimeMs, | |
transition = _transitionEffect, | |
}) | |
end | |
end | |
end | |
local function handleSwipe( event ) | |
local swipedObject = event.target | |
local swipeDistanceX = event.x - event.xStart | |
if (event.phase == "began") then | |
-- Set a focus flag on the object, so that we don't handle touch events that weren't started on the same object | |
swipedObject.hasFocus = true | |
-- This redirects all futre touch events to the swiped object, even when touch moves outside of its bounds | |
display.getCurrentStage():setFocus( swipedObject ) | |
elseif ( event.phase == "moved" ) then | |
if (swipedObject.hasFocus) then | |
-- Move all objects according to swipe gesture | |
for i = 1, #_slideshowObjects do | |
local object = _slideshowObjects[i] | |
local offsetX = -((_currentObjectIndex - 1) * display.contentWidth) | |
local x = object.originalPosition.x + offsetX + swipeDistanceX | |
object.x = x | |
end | |
end | |
elseif( event.phase == "ended" ) then | |
-- Reset touch event focus | |
swipedObject.hasFocus = false | |
display.getCurrentStage():setFocus( nil ) | |
-- Calculate which object to show next, preventing swiping too far left or right | |
local nextObjectIndex = _currentObjectIndex | |
if((swipeDistanceX >= _swipeSensitivityPixels) and (_currentObjectIndex > 1)) then | |
nextObjectIndex = _currentObjectIndex - 1 | |
elseif((swipeDistanceX <= -_swipeSensitivityPixels) and (_currentObjectIndex < #_slideshowObjects)) then | |
nextObjectIndex = _currentObjectIndex + 1 | |
end | |
-- Finally, show the selected object in the slideshow | |
showObject(nextObjectIndex) | |
elseif( event.phase == "cancelled" ) then | |
-- Reset touch event focus | |
swipedObject.hasFocus = false | |
display.getCurrentStage():setFocus( nil ) | |
end | |
return true | |
end | |
local function showObjectAtIndex(objectIndex, disableTransition) | |
showObject(objectIndex, disableTransition) | |
end | |
local function init( slideshowObjects, params ) | |
if (not params) then | |
params = {} | |
end | |
-- Set initial state for slideshow component | |
_transitionEffect = params.transitionEffect or easing.outCirc | |
_transitionEffectTimeMs = params.transitionEffectTimeMs or 200 | |
_slideshowObjects = slideshowObjects | |
_swipeSensitivityPixels = params.swipeSensitivityPixels or 100 | |
_onChange = params.onChange or nil | |
local y = params.y or display.contentCenterY | |
-- Position each slideshow object and setup a touch handler for each one | |
for i = 1, #slideshowObjects do | |
local obj = slideshowObjects[i] | |
-- Set initial position for every slideshow object | |
obj.x = display.contentCenterX + ((i - 1) * display.contentWidth) | |
obj.y = y | |
-- For display groups, we need to set the anchorChildren property to true to correctly position the child objects | |
obj.anchorChildren = true | |
-- The originalPosition will be used to position all slideshow objects correctly while swiping | |
obj.originalPosition = { x = obj.x , y = obj.y } | |
obj:addEventListener( "touch", handleSwipe ) | |
end | |
-- Show selected start object | |
local startIndex = params.startIndex or 1 | |
local disableTransition = true | |
showObject(startIndex, disableTransition) | |
end | |
local function cleanUp() | |
_slideshowObjects = nil | |
_currentObjectIndex = nil | |
end | |
return { | |
init = init, | |
cleanUp = cleanUp, | |
showObjectAtIndex = showObjectAtIndex, | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment