How to make a scrolling carousel

I need to create a horizontal scrollview with a list of tappable items. It must scroll infinitely to the left or right. Has anyone done anything like this in Corona or know of any good algorithms?
[import]uid: 52127 topic_id: 15067 reply_id: 315067[/import]

there is some code on the Code Exchange if you look for it of a carousel.

cheers,

?:slight_smile: [import]uid: 3826 topic_id: 15067 reply_id: 55823[/import]

Couldn’t find it. I don’t need any 3d effects. I just want a simple horizontal scroll view that loops infinitely. Seems impossible with Corona. scrollview.lua only does vertical scroll views. [import]uid: 52127 topic_id: 15067 reply_id: 55911[/import]

Convert it to horizontal then? [import]uid: 87611 topic_id: 15067 reply_id: 55922[/import]

This is doable, but not with widget.scrollView. You have to roll you’re own.

I’ll try and whip something up tonight to demo this.

[import]uid: 19626 topic_id: 15067 reply_id: 55923[/import]

[lua]local objects = {}
objects[1] = {}
objects[1].fileName = “images/one.png”
objects[1].name = “One”
objects[2] = {}
objects[2].fileName = “images/two.png”
objects[2].name = “Two”
objects[3] = {}
objects[3].fileName = “images/three.png”
objects[3].name = “Three”
objects[4] = {}
objects[4].fileName = “images/four.png”
objects[4].name = “Four”
objects[5] = {}
objects[5].fileName = “images/five.png”
objects[5].name = “Five”
objects[6] = {}
objects[6].fileName = “images/six.png”
objects[6].name = “Six”
objects[7] = {}
objects[7].fileName = “images/seven.png”
objects[7].name = “Seven”

local currentItem = 1
local images = {}
local showCurrentItems

local localGroup = display.newGroup()

local background = display.newRect(0,0,display.contentWidth,display.contentHeight)
background:setFillColor(0,0,0)

localGroup:insert(background)

local function tappedOnItem(event)
print(event.name)
local target = event.target
print("You tapped on " … target.myName)
if target.idx ~= currentItem then
currentItem = target.idx
showCurrentItems(currentItem, #images)
end
return true
end

for i = 1, #objects do
images[i] = display.newImageRect(objects[i].fileName,96,96)
images[i].isVisible = false
images[i].alpha = 1.0
images[i].xScale = 1.0
images[i].yScale = 1.0
images[i].myName = objects[i].name
images[i]:addEventListener(“tap”, tappedOnItem)
images[i].idx = i
localGroup:insert(images[i])
end

showCurrentItems = function(currentItem, totalItems)
local firstLeft = currentItem - 1
if firstLeft < 1 then
firstLeft = totalItems – firstLeft will be 0 if we are currently on #1, so wrap it around to the last item
end
local secondLeft = currentItem - 2
if secondLeft < 1 then
secondLeft = totalItems + secondLeft – secondLeft can be 0 or -1, so adding it to totalItems will generate totalItems or totalItems - 1
end
local firstRight = currentItem + 1
if firstRight > totalItems then
firstRight = 1
end
local secondRight = currentItem + 2
if secondRight > totalItems then
secondRight = secondRight - totalItems
end

for i = 1, totalItems do
images[i].isVisible = false
end

images[currentItem].x = display.contentWidth / 2
images[currentItem].y = display.contentHeight / 2
images[currentItem].alpha = 1.0
images[currentItem].xScale = 1.0
images[currentItem].yScale = 1.0
images[currentItem].isVisible = true

images[firstLeft].x = display.contentWidth / 2 - 90
images[firstLeft].y = display.contentHeight / 2
images[firstLeft].alpha = 0.75
images[firstLeft].xScale = 0.75
images[firstLeft].yScale = 0.75
images[firstLeft].isVisible = true

images[firstRight].x = display.contentWidth / 2 + 90
images[firstRight].y = display.contentHeight / 2
images[firstRight].alpha = 0.75
images[firstRight].xScale = 0.75
images[firstRight].yScale = 0.75
images[firstRight].isVisible = true

images[secondLeft].x = display.contentWidth / 2 - 160
images[secondLeft].y = display.contentHeight / 2
images[secondLeft].alpha = 0.5
images[secondLeft].xScale = 0.5
images[secondLeft].yScale = 0.5
images[secondLeft].isVisible = true

images[secondRight].x = display.contentWidth / 2 + 160
images[secondRight].y = display.contentHeight / 2
images[secondRight].alpha = 0.5
images[secondRight].xScale = 0.5
images[secondRight].yScale = 0.5
images[secondRight].isVisible = true
end

showCurrentItems(currentItem,#images)

local function touchHandler(event)
if event.phase == “ended” then
local dx = event.x - event.xStart
if dx > 50 then
currentItem = currentItem + 1
if currentItem > #images then
currentItem = 1
end
showCurrentItems(currentItem, #images)
elseif dx < -50 then
currentItem = currentItem - 1
if currentItem < 1 then
currentItem = #images
end
showCurrentItems(currentItem,#images)
end
end
end

localGroup:addEventListener(“touch”, touchHandler)[/lua] [import]uid: 19626 topic_id: 15067 reply_id: 55945[/import]

Interesting. Your code works, but it’s not scrollable. I need to be able to swipe/drag through the list. Like UIScrollView in iOS. [import]uid: 52127 topic_id: 15067 reply_id: 55948[/import]

http://developer.anscamobile.com/code/enhanced-springboard-slidephoto-viewer

Just convert this, I’ve set the functionality up in my game, check what slide group its on and if its the last in the array make it move from the right of the screen. If you don’t understand check out how the 3d carousel works. You could probably even convert that one in the code exchange to 2d. [import]uid: 87611 topic_id: 15067 reply_id: 55950[/import]

@Lewis.Elliot.92,
I would definitely use that if I needed a paged slider. I need a true scrollview though, that you can swipe through with one swipe, with deceleration like in native iOS and Android scrollviews. [import]uid: 52127 topic_id: 15067 reply_id: 55953[/import]

I guess I didn’t get what you were trying to accomplish. While I didn’t put in any animation, it does demonstrate how to setup a queue of items that endlessly loop as you swipe through them.

This can be easily adapted to full screen images, only showing the current item.

If you’re looking for like an endless background, that’s pretty easy to do too.
[import]uid: 19626 topic_id: 15067 reply_id: 55955[/import]