Here’s where I’ve gotten so far. It occurred to me that the problem I was having with the zoom is that it was calculating the zoom on the fly, whereas what I should have been doing was figuring out my start zoom and end zoom and tweeting between those points, and now I have a buttery smooth zoom between panels on a page.
PageClass = class()
FocusClass = class()
function FocusClass:init(x,y,w,h, bg)
-- you can accept and set parameters here
self.x = x
self.y = y
self.h = h
self.w = w
self.bg = bg or color(255,0) -- default to no background colour ...
end
VERTICAL = 1
HORIZONTAL = 2
function PageClass:addPanel(x,y,w,h)
self.panelCount = self.panelCount + 1
self.panels[self.panelCount] = FocusClass(x,y,w,h)
end
function PageClass:boxOut(x,y,w,h, bg)
-- draw a box around x,y,w,h
bg = bg or color(255, 0, 0, 0)
pushStyle()
stroke(0,0)
strokeWidth(0)
-- break it up into four chunks
popStyle()
end
function PageClass:init(src)
-- parameter src = the source image to add...
self.src = src
-- default focus on the entire page
self.focusX = 0
self.focusY = 0
self.w, self.h = spriteSize(self.src)
self.focusW = self.w
self.focusH = self.h
self.focusHorizontal = self.w > self.h
self.focusZoom = 1
self.viewPortX = 0
self.viewPortY = 0
self.viewPortW = WIDTH
self.viewPortH = HEIGHT
self.panels = {}
self.panelCount = 0
self.animating = false
self.currentPanel = 1
-- create the first panel to cover the whole page
self:addPanel(0,0,self.w,self.h)
end
function PageClass:panelMove(n)
-- known bug, if we travel outside the limits of the panel count (-4, or panelcount+10 say
-- then we loop back to panelcount (if -4) or 1 (if panelcount+10)
if self.animating then
-- stop animating and skip to the next panel.
tween.stop(self.animating)
self.animating = false
end
self.currentPanel = n
if self.currentPanel < 1 then
self.currentPanel = self.panelCount
end
if self.currentPanel > self.panelCount then
self.currentPanel = 1
end
-- now do animation
-- fix the orientation for any animation
self.focusHorizontal = self.panels[self.currentPanel].w > self.panels[self.currentPanel].h
local zoom
if self.focusHorizontal then
zoom = WIDTH / self.panels[self.currentPanel].w
else
zoom = HEIGHT / self.panels[self.currentPanel].h
end
self.animating = tween( 1, self,
{ focusX = self.panels[self.currentPanel].x,
focusY = self.panels[self.currentPanel].y,
focusW = self.panels[self.currentPanel].w,
focusH = self.panels[self.currentPanel].h,
focusZoom = zoom },
tween.easing.In,
function()
self.animating = false
end
)
end
function PageClass:nextPanel()
self:panelMove(self.currentPanel + 1) -- next
end
function PageClass:previousPanel()
self:panelMove(self.currentPanel -1) -- move previous
end
function PageClass:deleteCurrentPanel()
end
function PageClass:draw(x,y)
-- calculate from centre point
self.focusOffsetX = (self.w/2) - (self.focusX+ (self.focusW /2) )
self.focusOffsetY = (self.h/2) - (self.focusY+ (self.focusH / 2))
pushMatrix()
x = x or WIDTH /2
y = y or HEIGHT / 2
-- translate to the screen co-ordinates to display
translate(x,y)
-- zoom in on the image using the calculated zoom
scale(self.focusZoom)
-- now translate the image is centred on the part we want to display
translate(self.focusOffsetX, self.focusOffsetY)
-- now offset the focus of the image
spriteMode(CENTER)
sprite(self.src,0,0)
--Now we draw the panels in for bug hunting...
translate(-1*self.w/2, -1*self.h/2)
pushStyle()
stroke(255, 247, 0, 255)
fill(255, 0, 0, 42)
rect(self.focusX,self.focusY,self.focusW,self.focusH)
for i,v in pairs(self.panels) do
stroke(255, 0, 0, 255)
fill(255, 0, 0, 0)
strokeWidth(5)
rect(v.x, v.y, v.w, v.h)
fontSize(60)
fill(0, 0, 0, 255)
text(i, v.x+v.w/2, v.y+v.h/2)
end
popMatrix()
popMatrix()
end
function PageClass:touched(touch)
-- Codea does not automatically call this method
end
My plan is to add in loading/editing of pages/panels, so I can create animated comics (simple frame to frame animation much like comixology does)