Zoom in and out / scaling

Hello all,

I have a small problem as when I’m scaling up my scene (secenegroup) to have a zoom effect (either by xScale or transition.scaleTo) it doesn’t do it from center…

I’ve tried to setup some anchors but it appears having no effect even by setting up the myGroup.anchorChildren = true

I suppose it should be an automatic way to keep everything centered “as is” when zooming in or out, no?
Any help?

Would help if you provide sample code.

If the objects seem to move after applying a scale factor to the group, instead of staying in place (assuming this is what you’re expecting), then the group itself is probably not centered in the screen.

Thus, set the display group position at center of screen, insert your objects and position them accordingly inside this group, then apply the scale factor.

Hello, thanks for answering.

Here is basically what happens :
In my scene I have :

function scene:create( event )
local sceneGroup = self.view
bla bla bla
at some point I have the following listener :
choicebk:addEventListener( “tap”, clicaction )

With the following function:

function clicaction( event )
event.target.parent.xScale = 1.80
event.target.parent.yScale = 1.45
end

This should result in my Scenegroup to be displayed “bigger”, but as you have said, I have nowhere somehting forcing it to be centered… At the moment the scene is indeed bigger but centered on the upper left part of the original screen instead of the middle.

How do I do the “center” thing for the scenegroup?

Thanks in advance :slight_smile:

That’s the easy part. :slightly_smiling_face:
The group has x and y properties, same as any display object.

There are 2 approaches:

  1. If you want to use self.view as the “master group” then you can do:
function scene:create( event )
  local sceneGroup = self.view
    sceneGroup.x = display.contentCenterX
    sceneGroup.y = display.contentCenterY
end

or

  1. Alternatively, you can create your own “master group” on top of your composer scene, insert this group inside composer’s self.view, and do all your manipulation on that group; you would also insert all your objects in this master group:
local masterGroup = display.newGroup()
...
function scene:create( event )
  local sceneGroup = self.view
    sceneGroup:insert(masterGroup)
    masterGroup.x = display.contentCenterX
    masterGroup.y = display.contentCenterY
end

Because you are moving the display group (whichever you choose) from its original location at (0,0) you will need to reposition all of your objects as well.

Also, keep in mind that your group’s 0,0 will be in the center of the screen, thus to position your objects closer to the left side of the screen you’ll need to assign negative values for x, and likewise negative values for y in order to move closer to the top of the screen.

Hi,

Thanks for the answer. I gave a try to both solutions but nothing really worked …
I still need to do :
event.target.parent.x = display.contentCenterX-850
event.target.parent.y = display.contentCenterY-340

to “replace” the scene group in the middle of the screen ( aproximately …).
I don’t catch what is going wrong there, and why when streching or schrinkink an object should “move it” on the screen…

Not sure if you mean with or without scaling applied, but I will assume it’s not…

Assuming default project settings for alignment in config.lua, display.contentCenterX and Y are always in the center of the screen. If you assign those values to an object then that object will be in the center (again, assuming default anchoring for said object).

For a group, if you center it, and you want any of its child also in the center then the coordinates for the child must be 0,0 and not display.contentCenterX/Y. In other words, the child sits relative to the parent (group).

event.target.parent is a reference to the display group the object is currently in.

You may need to play around a bit with display groups to understand how they work; for this try creating a single group, insert a single object, and move them both around separately to see the results. :slightly_smiling_face:

Under myGroup.anchorChildren = true, try adding:

myGroup.anchorX = .5
myGroup.anchorY = .5

Thanks for both answers.

Still not working :pensive: i have position issue, zoom issues… Nothing good came out after trying a lot of different ways.
Even puting in config. Lua the Centre command didn’t make it.

Is anyone having a code sample working to zoom on display center (the whole scene being zoomed in)?
Just to let me figure what goes wrong.

Just writing here in case someone has a link, but I remember @roaminggamer having written a zoom in/out sample project at some point. It’s probably in his GitHub profile.

@XeduR, I took a look and it might be buried somewhere in a sub directory in his repositories. I have a copy, but it uses his SSK lib which introduces other things in the code.

@Loky31 , this is as simple as it can get:

-- main.lua
local masterGroup = display.newGroup()
	masterGroup.x = display.contentCenterX
	masterGroup.y = display.contentCenterY
	

local topLeftRect = display.newRect(masterGroup, -50,-50,25,25)
	topLeftRect:setFillColor(1,0,0)
local topRightRect = display.newRect(masterGroup, 50,-50,25,25)
	topRightRect:setFillColor(0,1,0)
local bottonLeftRect = display.newRect(masterGroup, -50,50,25,25)
	bottonLeftRect:setFillColor(0,0,1)

local bottonRightRect = display.newRect(masterGroup, 50,50,25,25)
	bottonRightRect:setFillColor(1,1,0)
local centerRect = display.newRect(masterGroup, 0,0,25,25)
	centerRect:setFillColor(0,1,1)


local function onTouchEvent(event)
	local phase = event.phase
	local target = event.target
	
	if phase == "began" then
		if target.id == "in" then
			masterGroup.xScale = masterGroup.xScale + 0.1
			masterGroup.yScale = masterGroup.yScale + 0.1
			
		elseif target.id == "out" then
			masterGroup.xScale = masterGroup.xScale - 0.1
			masterGroup.yScale = masterGroup.yScale - 0.1
		end
	end
end

local button_zoomIn = display.newRect(200,280,25,25)
	button_zoomIn:setFillColor(0.5)
	button_zoomIn.label = display.newText("+", button_zoomIn.x, button_zoomIn.y)
	button_zoomIn.id = "in"
	button_zoomIn:addEventListener("touch", onTouchEvent)
	
local button_zoomOut = display.newRect(280,280,25,25)
	button_zoomOut:setFillColor(0.5)
	button_zoomOut.label = display.newText("-", button_zoomOut.x, button_zoomOut.y)
	button_zoomOut.id = "out"
	button_zoomOut:addEventListener("touch", onTouchEvent)

It’s effectively what we would consider a “zoom” effect. If this is not the effect you’re looking for (which I also thought possible), then what you might be looking for is scaling each object individually and not the display group itself.

2 Likes

here is an example

main.lua (63 Bytes)
scene.lua (1.0 KB)

That is exactly what I’m looking for…

The weird thing is that when applying this to my scenegroup , I got it moving from it’s starting position for no obvious reason.

I will dig into that because I should somewhere do something wrong I suppose…

Thanks, straight to the point. Exactly what I do not manage to achieve once my scene totally populated :frowning:

Trying to put together all you provided, I discovered something that might be a solid lead…

as soon as I want to put something like (tried it for scenegroup directly or a master group over the scene group, or a simple group):
Group.x = display.contentCenterX
Group.y = display.contentCenterY

I have my whole scene moved to the down right. Like if my top left angle was moved to the very center of the screen. That’s clearly point out a problem in my sceneGroup / scene.

Hum I found where something goes wrong !!!

In fact when you have setup your group like :
group = display.newGroup()
group.x = display.contentCenterX
group.y = display.contentCenterY

after, all elements you put there should not have something like :

background.x = display.contentCenterX
background.y = display.contentCenterY

but
background.x = 0
background.y = 0

I have everything in the first format all over my code LOL
I had absolutely no trouble until this zoom thing…
Anyone could explain me the logic behind? And what is the very difference between the two synthaxes?

The point is that when you place an object in a group, its coordinates become relative. Those. these are coordinates in the group, not on the screen.

It is better to read about it here.
https://docs.coronalabs.com/guide/graphics/group.html

Imagine a rectangle being drawn that exactly encompasses every object in the group. That is the size and relative position of your object group. Groups do not default to anchoring at the middle ( 0.5, 0.5 ) like objects do. They default to ( 0, 0 ) which is the upper, left-hand corner. That’s why you need to anchor the children and then set the anchor to the middle.

I’ve been trough the documentation already uqite some times but seems like either I get it wrong either it is not handy at all…

not sure of what you mean there “That’s why you need to anchor the children and then set the anchor to the middle.”.
If it is to do
object.anchorX= 0.5
object.anchorY= 0.5
and
myGroup.anchorChildren = true^
I already tried it… unsuccessfully.
Maybe I did it wrong, or wrong order.
I obviously missing some principles there as I struggle on this with no comparison to other stuff…

You need to anchor the group, not the objects:

myGroup.anchorChildren = true
myGroup.anchorX = .5
myGroup.anchorY = .5

Is the scenegroup having some particularities? Do I need to switch to a brand new group all my objects in order to this ?

Because that still does not the trick. Now I have the zoom on the right bottom side quarter of the image…
Getting crazy with that, I gave a try to pinch gesture tonight… still no joy for me as I still have this anchoring problem and it doesn’t zoom where I want to, and even worse I didn’t manage the scrollview to work.

In any case many thanks for the time spent on my stupidity…