Search code examples
coronasdk

why won't this Corona SDK code work for centering view based on touch point?


Any suggestions re how to fix the code I have below to make it work? I want to be able to position the moveableGroup after a zoom in or out (i.e. click or double-click) such that the point clicked will be moved to the centre of the cross-hairs in the fixedGroup. I'm getting muddled up getting it right noting the use of group zoom, moves etc.

display.setStatusBar( display.HiddenStatusBar )
system.setTapDelay( 0.3 )

local function moveableMapTouchListener( event )
    local moveableView = event.target
    if event.phase == "began" then
        moveableView.markX = moveableView.x    -- store x location of object
        moveableView.markY = moveableView.y    -- store y location of object
    elseif event.phase == "moved" then
        local x = (event.x - event.xStart) + moveableView.markX
        local y = (event.y - event.yStart) + moveableView.markY
        moveableView.x, moveableView.y = x, y    -- move object based on calculations above
    elseif event.phase == "ended" then
    end

    return true
end

local function moveableViewTapListener(event) 
    local moveableView = event.target

    -- Calculate Scale Ratio
    local scaleRatio 
    if event.numTaps == 1 then
        -- Single Tap
        scaleRatio = 0.8
    elseif event.numTaps == 2 then
        scaleRatio = 1/0.8
    end

    -- Note Pivot Point (where user clicked) and current Centre
    local pivotXLocal, pivotYLocal =  event.target:contentToLocal( event.x, event.y )
    local centreX, centreY = -moveableView.x, -moveableView.y

    -- Scale Image
    moveableView:scale(scaleRatio, scaleRatio)

    -- ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    -- Move to Centre Around Pivot Point  *** HOW TO DO THIS ??? - THIS DOESN'T WORK ***
    local pivotXContent, pivotYContent =  event.target:localToContent( pivotXLocal, pivotYLocal )
    local zeroXContent, zeroYContent =  event.target:localToContent( 0,0 )
    moveableView.x, moveableView.y = pivotXContent - zeroXContent, pivotYContent - zeroYContent
    -- ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

    return true
end

---------------------------------
-- Implementation
---------------------------------

-- Moveable Group
local moveableGroup = display.newGroup()
local internalContents = display.newRect(moveableGroup, 50,80,  300,300)
internalContents.strokeWidth = 3
internalContents:setFillColor  ( 1, 0.5 ,1, 0.5 )
internalContents:setStrokeColor( 0, 0, 1, 1 )

-- Fixedup Group (with crosshairs)
local mainFixedGroup = display.newGroup()
local _w, _h = 0.8 * display.contentWidth, 0.8 * display.contentHeight
local myRectangle = display.newRect(mainFixedGroup, 0, 0,  _w, _h )
myRectangle.strokeWidth = 3
myRectangle:setFillColor  ( 1, 0 ,0, 0 )
myRectangle:setStrokeColor( 0, 0, 1, 1 )
-- Cross Haris
local crossHari1 = display.newLine(mainFixedGroup, -_w/2, -_h/2, _w/2, _h/2 )
crossHari1:setStrokeColor(  0, 0, 1, 1  )
crossHari1.strokeWidth = 1
local crossHari2 = display.newLine(mainFixedGroup, -_w/2, _h/2, _w/2, -_h/2 )
crossHari2:setStrokeColor(  0, 0, 1, 1  )
crossHari2.strokeWidth = 1
mainFixedGroup.x, mainFixedGroup.y = display.contentWidth/2, display.contentHeight/2

-- Insert Moveable Group into Fixed Group
mainFixedGroup:insert(moveableGroup)
moveableGroup.x = -50
moveableGroup.y = -50

-- Add Listeners (to move / scale the moveable Group)
moveableGroup:addEventListener( "touch", moveableMapTouchListener )
moveableGroup:addEventListener( "tap", moveableViewTapListener)

Solution

  • this seems to fix it:

    display.setStatusBar( display.HiddenStatusBar )
    system.setTapDelay( 0.3 )
    
    local function showPoint(parent, x, y)
        local myCircle = display.newCircle(parent, x,y, 8 )
        myCircle:setFillColor( 0.5,0,1 )
        myCircle.strokeWidth = 0
    end
    
    local function moveableMapTouchListener( event )
        local moveableView = event.target
        if event.phase == "began" then
            moveableView.markX = moveableView.x    -- store x location of object
            moveableView.markY = moveableView.y    -- store y location of object
        elseif event.phase == "moved" then
            local x = (event.x - event.xStart) + moveableView.markX
            local y = (event.y - event.yStart) + moveableView.markY
            moveableView.x, moveableView.y = x, y    -- move object based on calculations above
        elseif event.phase == "ended" then
        end
    
        return true
    end
    
    local function moveableViewTapListener(event) 
        local moveableView = event.target
    
        -- Calculate Scale Ratio
        local scaleRatio 
        if event.numTaps == 1 then
            -- Single Tap
            scaleRatio = 0.8
        elseif event.numTaps == 2 then
            scaleRatio = 1/0.8
        end
    
        -- -- Note Pivot Point (where user clicked) and current Centre
        -- local pivotXLocal, pivotYLocal =  event.target:contentToLocal( event.x, event.y )
        -- local centreX, centreY = -moveableView.x, -moveableView.y
    
         -- Note Pivot Point (where user clicked) and current Centre
        local pivotXL, pivotYL =  moveableView:contentToLocal( event.x, event.y )
        local myCircle = display.newCircle(moveableView, pivotXL, pivotYL, 8 )
        myCircle:setFillColor( 0.5,0,1 )
        myCircle.strokeWidth = 0
    
    
        -- Scale Image
        moveableView:scale(scaleRatio, scaleRatio)
    
        -- ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    
        local ox, oy = moveableView.parent:contentToLocal( display.contentWidth/2, display.contentHeight/2 )
        local txc, tyc = moveableView:localToContent(myCircle.x, myCircle.y)
        local tx, ty = moveableView.parent:contentToLocal( txc, tyc)
        showPoint(moveableView.parent, ox, oy)
        local dx, dy = tx-ox, ty-oy
        moveableView.x, moveableView.y = moveableView.x - dx, moveableView.y - dy
    
        -- -- Move to Centre Around Pivot Point  *** HOW TO DO THIS ??? - THIS DOESN'T WORK ***
        -- local pivotXContent, pivotYContent =  event.target:localToContent( pivotXLocal, pivotYLocal )
        -- local zeroXContent, zeroYContent =  event.target:localToContent( 0,0 )
        -- moveableView.x, moveableView.y = pivotXContent - zeroXContent, pivotYContent - zeroYContent
        -- ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
    
        return true
    end
    
    ---------------------------------
    -- Implementation
    ---------------------------------
    
    -- Moveable Group
    local moveableGroup = display.newGroup()
    local internalContents = display.newRect(moveableGroup, 50,80,  300,300)
    internalContents.strokeWidth = 3
    internalContents:setFillColor  ( 1, 0.5 ,1, 0.5 )
    internalContents:setStrokeColor( 0, 0, 1, 1 )
    
    -- Fixedup Group (with crosshairs)
    local mainFixedGroup = display.newGroup()
    local _w, _h = 0.8 * display.contentWidth, 0.8 * display.contentHeight
    local myRectangle = display.newRect(mainFixedGroup, 0, 0,  _w, _h )
    myRectangle.strokeWidth = 3
    myRectangle:setFillColor  ( 1, 0 ,0, 0 )
    myRectangle:setStrokeColor( 0, 0, 1, 1 )
    -- Cross Haris
    local crossHari1 = display.newLine(mainFixedGroup, -_w/2, -_h/2, _w/2, _h/2 )
    crossHari1:setStrokeColor(  0, 0, 1, 1  )
    crossHari1.strokeWidth = 1
    local crossHari2 = display.newLine(mainFixedGroup, -_w/2, _h/2, _w/2, -_h/2 )
    crossHari2:setStrokeColor(  0, 0, 1, 1  )
    crossHari2.strokeWidth = 1
    mainFixedGroup.x, mainFixedGroup.y = display.contentWidth/2, display.contentHeight/2
    
    -- Insert Moveable Group into Fixed Group
    mainFixedGroup:insert(moveableGroup)
    moveableGroup.x = -50
    moveableGroup.y = -50
    moveableGroup:rotate( 45 )
    
    
    -- Add Listeners (to move / scale the moveable Group)
    moveableGroup:addEventListener( "touch", moveableMapTouchListener )
    moveableGroup:addEventListener( "tap", moveableViewTapListener)