Slide menu

I’ve searched the forums for this, but I can’t think what it’s called, so haven’t found what I need - apologies if it’s already out there!

I need to make a sliding menu - similar to the level selectors in Blast Monkey, Cavern Drake, Angry Birds… It’s not for a game but for a different app I’m producing for a client.

Any ideas if there’s a tutorial or block of sample code out there?

Cheers
Steve
[import]uid: 45932 topic_id: 12484 reply_id: 312484[/import]

something like this,

[lua]local menus = {}
local num = 7
local xPosHandler = {}
local function handleTouch(e)
local phase = e.phase
local t = e.target
if “began” == phase then
for i=1,num do
xPosHandler[i] = e.x - menus[i].x
end
display.getCurrentStage():setFocus(t)
t.isFocus = true
elseif “moved” == phase and t.isFocus then
for i=1,num do
menus[i].x = e.x - xPosHandler[i]
end
elseif “ended” == phase then
display.getCurrentStage():setFocus(nil)
t.isFocus = false

end
end
for i=1,num do
menus[i] = display.newRect(0,0,100,100)
menus[i].x = i * 150
menus[i].y = 160
menus[i].myName = i
menus[i]:addEventListener(“touch”,handleTouch)
end[/lua] [import]uid: 12482 topic_id: 12484 reply_id: 45600[/import]

one more,

[lua]local centerPos = display.newRect(0,0,120,120)
centerPos.x = 240
centerPos.y = 160
centerPos:setFillColor(0,255,0,200)
local menus = {}
local num = 7
local xPosHandler = {}
local function handleTouch(e)
local phase = e.phase
local t = e.target
if “began” == phase then
for i=1,num do
xPosHandler[i] = e.x - menus[i].x
end
display.getCurrentStage():setFocus(t)
t.isFocus = true
elseif “moved” == phase and t.isFocus then
for i=1,num do
menus[i].x = e.x - xPosHandler[i]
end
elseif “ended” == phase then
display.getCurrentStage():setFocus(nil)
t.isFocus = false
for i=1,num do
if menus[i].x > 240 - 80 and menus[i].x < 240 + 80 then
diff = menus[i].x - 240
end
end

for i=1,num do
transition.to(menus[i],{x = menus[i].x - diff,time = 500})
end

end
end
for i=1,num do
menus[i] = display.newRect(0,0,100,100)
menus[i].x = 90 + i * 150
menus[i].y = 160
menus[i].myName = i
menus[i]:addEventListener(“touch”,handleTouch)
end[/lua]
see it width 320*480 in config with landscape mode

:slight_smile: [import]uid: 12482 topic_id: 12484 reply_id: 45603[/import]

Thanks hgvyas123! That’s really helpful.

I’ll give these a try and let you know if I have any probs!

S [import]uid: 45932 topic_id: 12484 reply_id: 45609[/import]

sure

:slight_smile: [import]uid: 12482 topic_id: 12484 reply_id: 45731[/import]

Perfect, thank you for the example. [import]uid: 38820 topic_id: 12484 reply_id: 46423[/import]

How is it possible to only “mask/show” the area inside the green rectangle, so outside the green rectangle the white rectangle are invisible/hidden? [import]uid: 71536 topic_id: 12484 reply_id: 46454[/import]

Wow thank you very much! really good example [import]uid: 58067 topic_id: 12484 reply_id: 46537[/import]

@timwills :- this will give some idea
and thanks to all for saying me thanks :slight_smile:
[lua]local centerPos = display.newRect(0,0,120,120)
centerPos.x = 240
centerPos.y = 160
centerPos:setFillColor(0,255,0,200)

local menus = {}
local num = 7
local xPosHandler = {}
local function handleTouch(e)
local phase = e.phase
local t = e.target
if “began” == phase then
for i=1,num do
xPosHandler[i] = e.x - menus[i].x
end
display.getCurrentStage():setFocus(t)
t.isFocus = true
elseif “moved” == phase and t.isFocus then
for i=1,num do
menus[i].x = e.x - xPosHandler[i]
menus[i].alpha = 0.3
if menus[i].x > 240 - 80 and menus[i].x < 240 + 80 then
menus[i].alpha = 1
end
end
elseif “ended” == phase then
display.getCurrentStage():setFocus(nil)
t.isFocus = false

for i=1,num do
menus[i].alpha = 0.3
if menus[i].x > 240 - 80 and menus[i].x < 240 + 80 then
diff = menus[i].x - 240
menus[i].alpha = 1
end
end

for i=1,num do
transition.to(menus[i],{x = menus[i].x - diff,time = 500})
end

end
end

for i=1,num do
menus[i] = display.newRect(0,0,100,100)
menus[i].x = 90 + i * 150
menus[i].y = 160
menus[i].myName = i
menus[i]:addEventListener(“touch”,handleTouch)
menus[i].alpha = 0.3
if menus[i].x == 240 then
menus[i].alpha = 1
end
end[/lua] [import]uid: 12482 topic_id: 12484 reply_id: 46571[/import]

@ hgvyas123 - very nice! Thanks! :slight_smile:

Jay
[import]uid: 9440 topic_id: 12484 reply_id: 46573[/import]

welcome always happy for inspiration see :slight_smile: [import]uid: 12482 topic_id: 12484 reply_id: 46574[/import]

@ hgvyas123 - Thanks very much for your example!

I looked at the example. Great thinking,thanks! But technically there’s no clipping/masking, but a rectangle object pops in when it’s close to the center, while the rest are set to hidden objects.

Is this the way to go when making a enterFrame mini imagescroller that is also draggable/slidable?
ps. So far, thanks for the help, Corona is really great! [import]uid: 71536 topic_id: 12484 reply_id: 46606[/import]

mini imagescroller ??? [import]uid: 12482 topic_id: 12484 reply_id: 46613[/import]

I’m sorry, english isn’t my native language. Maybe imagescarousel or imagesslider is a better word for it?

See it as an imageslider where you can slide through your images with slide gestures. Plus arrow-buttons to the left and the right of the rectangle that have a “tap”-event on it.

So your example was great, but the images sort of pop-in and pop-out.

My question is: Is it possible to create a clipping mask to the centerPos Rectangle, so the pop-in/pop-out doesn’t occur while the rest of the screen around the rectangle can be filled with other objects. Like this it becomes sort of a widget.

I found a javascript look-alike for the question I have, only without the slide/drag event: javascript example

You see that the images are in a sort of clipping mask.
[import]uid: 71536 topic_id: 12484 reply_id: 46646[/import]

You don’t have to do any clipping, just look where the alpha is being set to 0.3 and change that to 0. Now the objects on the left/right of center won’t show up, but you can still swipe through the list.

Jay
[import]uid: 9440 topic_id: 12484 reply_id: 46720[/import]

@ J. A. Whye - Thanks for the help!
I already tried to set a dynamic mask, so there’s no popping-in and out (alpha 1/0) of the rectangle and that actually works. Although I think my code can be optimized and written better.

In my example you’ll see that I insert a mask, that should be a 200x200 rectangle, but it shows a 1000x200 rectangle.

Can anybody take a look at it and make suggestions/optimizations?

Here’s my example:
[lua]local deviceWidth, deviceHeight, widthRatio, heightRatio

deviceWidth = display.contentWidth
deviceHeight = display.contentHeight

– Set ratiovalues for procentual calculations
widthRatio = math.floor(deviceWidth/100)
heightRatio = math.floor(deviceHeight/100)

– Set white background
local background = display.newRect(0,0,deviceWidth,deviceHeight)

– SET UP MASK ----------------
local dynamicMask = display.newGroup();
local maskBg = display.newRect(display.screenOriginX,display.screenOriginY,deviceWidth,deviceHeight)
maskBg:setFillColor(255,255,255)
dynamicMask:insert(maskBg);
local maskBoxX = display.contentCenterX
local maskBoxY = display.contentCenterY + (heightRatio*10)
local maskBox = display.newRect(0,0, 200,200)
maskBox.x = 0
maskBox.y = maskBoxY
dynamicMask:insert(maskBox);
maskBox:setFillColor(0,0,0);
display.save (dynamicMask, “tmp.jpg”, system.TemporaryDirectory)
maskBox:removeSelf()
local mask = graphics.newMask( “tmp.jpg”, system.TemporaryDirectory )
– /SET UP MASK ----------------

local menus = {}
local num = 7
local xPosHandler = {}
diff = 0
local function handleTouch(e)
local phase = e.phase
local t = e.target
if “began” == phase then
for i=1,num do
xPosHandler[i] = e.x - menus[i].x
end
display.getCurrentStage():setFocus(t)
t.isFocus = true
elseif “moved” == phase and t.isFocus then
for i=1,num do
menus[i].x = e.x - xPosHandler[i]
end
elseif “ended” == phase then
display.getCurrentStage():setFocus(nil)
t.isFocus = false
for i=1,num do
if menus[i].x > 240 - 80 and menus[i].x < 240 + 80 then
diff = menus[i].x - 240
end
end

for i=1,num do
transition.to(menus[i],{x = menus[i].x - diff,time = 500})
end

end
end

for i=1,num do
menus[i] = display.newRect(0,0,100,100)
menus[i]:setFillColor(0,100,100,200)
menus[i].x = maskBoxX + (i-1) * 150
menus[i].y = maskBoxY
menus[i].myName = i
menus[i]:addEventListener(“touch”,handleTouch)
end

thisMainRect = display.newRect(display.screenOriginX,display.screenOriginY,1280,deviceHeight)
thisMainRect:setFillColor(0,255,255);
thisMainRect:setMask(nil)
thisMainRect:setMask(mask)[/lua] [import]uid: 71536 topic_id: 12484 reply_id: 46724[/import]

An update about setting the alpha – I actually changed the original code so the alpha is set using a transition.to with a time=200. So the objects quickly fade in and out instead of popping.

Just that little tweak gives the whole thing a more polished feel, I think.

Jay [import]uid: 9440 topic_id: 12484 reply_id: 46726[/import]

@timwils :-

can i ask why are you using such hard method why display.save , setMask there is no need of that the js example which you had shown me is very easy and also something similar to example give here you just have to change that example if you are going to use a lot of images else it will be fine with some little modification. like the example i had give with the starting one more, put this line at the end

local rect =display.newRect(0,0,100,320)
rect:setFillColor(0)

local rect1 =display.newRect(380,0,100,320)
rect1:setFillColor(0)

@J. A. Whye (cpm guy)

where you had update sorry i can’t find that

:slight_smile: [import]uid: 12482 topic_id: 12484 reply_id: 46762[/import]

@ hgvyas123 - Thanks for the suggestion!

It’s indeed probably the best solution to just put 2 rectangles with the same color as the background at the point where I wanted to “mask” them out :slight_smile:
I think I will go for this suggestion.

It’s als good to know that there’s not some simple widget or function to create a viewport from a vectorobject/displayobject where everything placed in that object only shows if they’re in the viewport. In html it’s easy (example), so I thought that it would be just as easy with Corona :o)

[import]uid: 71536 topic_id: 12484 reply_id: 46781[/import]

HI
Try to use and modify slideView from sample projects. Works great. [import]uid: 13156 topic_id: 12484 reply_id: 50223[/import]