skia2/resources/slides.lua
2014-10-12 19:05:52 -07:00

320 lines
8.6 KiB
Lua

function make_paint(size, color)
local paint = Sk.newPaint();
paint:setAntiAlias(true)
paint:setSubpixelText(true)
paint:setTextSize(size)
paint:setColor(color)
return paint
end
function find_paint(paints, style)
if not style then
style = "child"
end
local paint = paints[style]
return paint
end
function draw_node(canvas, node, x, y, paints)
if node.text then
local paint = find_paint(paints, node.style)
canvas:drawText(node.text, x, y, paint)
end
if node.draw then
node.draw(canvas)
end
end
function drawSlide(canvas, slide, template, paints)
draw_node(canvas, slide, template.title.x, template.title.y, paints)
if slide.children then
local x = template.child.x
local y = template.child.y
local dy = template.child.dy
for i = 1, #slide.children do
draw_node(canvas, slide.children[i], x, y, paints)
y = y + dy
end
end
end
function slide_transition(prev, next, is_forward)
local rec = {
proc = function(self, canvas, drawSlideProc)
if self:isDone() then
drawSlideProc(canvas)
return nil
end
canvas:drawImage(self.prevImage, self.curr_x, 0)
canvas:drawImage(self.nextImage, self.curr_x + 640, 0)
self.curr_x = self.curr_x + self.step_x
return self
end
}
if is_forward then
rec.prevImage = prev
rec.nextImage = next
rec.curr_x = 0
rec.step_x = -15
rec.isDone = function (self) return self.curr_x <= -640 end
else
rec.prevImage = next
rec.nextImage = prev
rec.curr_x = -640
rec.step_x = 15
rec.isDone = function (self) return self.curr_x >= 0 end
end
return rec
end
function fade_slide_transition(prev, next, is_forward)
local rec = {
prevImage = prev,
nextImage = next,
proc = function(self, canvas, drawSlideProc)
if self:isDone() then
drawSlideProc(canvas)
return nil
end
canvas:drawImage(self.prevImage, self.prev_x, 0, self.prev_a)
canvas:drawImage(self.nextImage, self.next_x, 0, self.next_a)
self:step()
return self
end
}
if is_forward then
rec.prev_x = 0
rec.prev_a = 1
rec.next_x = 640
rec.next_a = 0
rec.isDone = function (self) return self.next_x <= 0 end
rec.step = function (self)
self.next_x = self.next_x - 20
self.next_a = (640 - self.next_x) / 640
self.prev_a = 1 - self.next_a
end
else
rec.prev_x = 0
rec.prev_a = 1
rec.next_x = 0
rec.next_a = 0
rec.isDone = function (self) return self.prev_x >= 640 end
rec.step = function (self)
self.prev_x = self.prev_x + 20
self.prev_a = (640 - self.prev_x) / 640
self.next_a = 1 - self.prev_a
end
end
return rec
end
--------------------------------------------------------------------------------------
gTemplate = {
title = { x = 10, y = 64, textSize = 64 },
child = { x = 40, y = 120, dy = 50, textSize = 40 },
}
gPaints = {}
gPaints.title = make_paint(gTemplate.title.textSize, { a=1, r=0, g=0, b=0 } )
gPaints.child = make_paint(gTemplate.child.textSize, { a=.75, r=0, g=0, b=0 } )
gRedPaint = Sk.newPaint()
gRedPaint:setAntiAlias(true)
gRedPaint:setColor{a=1, r=1, g=0, b=0 }
gSlides = {
{ text = "Title1", style="title", color = { a=1, r=1, g=0, b=0 },
children = {
{ text = "bullet 1", style = "child" },
{ text = "bullet 2", style = "child" },
{ text = "bullet 3", style = "child" },
{ draw = function (canvas)
canvas:drawOval({left=300, top=300, right=400, bottom=400}, gRedPaint)
end },
},
transition = fade_slide_transition
},
{ text = "Title2", style="title", color = { a=1, r=0, g=1, b=0 },
children = {
{ text = "bullet uno", style = "child" },
{ text = "bullet 2", style = "child" },
{ text = "bullet tres", style = "child" },
},
transition = slide_transition
},
{ text = "Title3", style="title",
children = {
{ text = "bullet 1", style = "child", },
{ text = "bullet 2", style = "child", color = { r=0, g=0, b=1 } },
{ text = "bullet 3", style = "child" },
}
}
}
--------------------------------------------------------------------------------------
function tostr(t)
local str = ""
for k, v in next, t do
if #str > 0 then
str = str .. ", "
end
if type(k) == "number" then
str = str .. "[" .. k .. "] = "
else
str = str .. tostring(k) .. " = "
end
if type(v) == "table" then
str = str .. "{ " .. tostr(v) .. " }"
else
str = str .. tostring(v)
end
end
return str
end
-- animation.proc is passed the canvas before drawing.
-- The animation.proc returns itself or another animation (which means keep animating)
-- or it returns nil, which stops the animation.
--
local gCurrAnimation
gSlideIndex = 1
function next_slide()
local prev = gSlides[gSlideIndex]
gSlideIndex = gSlideIndex + 1
if gSlideIndex > #gSlides then
gSlideIndex = 1
end
spawn_transition(prev, gSlides[gSlideIndex], true)
end
function prev_slide()
local prev = gSlides[gSlideIndex]
gSlideIndex = gSlideIndex - 1
if gSlideIndex < 1 then
gSlideIndex = #gSlides
end
spawn_transition(prev, gSlides[gSlideIndex], false)
end
gSurfaceFactory = function (w, h) return Sk.newRasterSurface(w, h) end
function spawn_transition(prevSlide, nextSlide, is_forward)
local transition
if is_forward then
transition = prevSlide.transition
else
transition = nextSlide.transition
end
if not transition then
return
end
local surf = gSurfaceFactory(640, 480)
local canvas = surf:getCanvas()
canvas:clear()
drawSlide(canvas, prevSlide, gTemplate, gPaints)
local prevImage = surf:newImageSnapshot()
canvas:clear()
drawSlide(canvas, nextSlide, gTemplate, gPaints)
local nextImage = surf:newImageSnapshot()
gCurrAnimation = transition(prevImage, nextImage, is_forward)
end
--------------------------------------------------------------------------------------
function spawn_rotate_animation()
gCurrAnimation = {
angle = 0,
angle_delta = 5,
pivot_x = 320,
pivot_y = 240,
proc = function (self, canvas, drawSlideProc)
if self.angle >= 360 then
drawSlideProc(canvas)
return nil
end
canvas:translate(self.pivot_x, self.pivot_y)
canvas:rotate(self.angle)
canvas:translate(-self.pivot_x, -self.pivot_y)
drawSlideProc(canvas)
self.angle = self.angle + self.angle_delta
return self
end
}
end
function spawn_scale_animation()
gCurrAnimation = {
scale = 1,
scale_delta = .95,
scale_limit = 0.2,
pivot_x = 320,
pivot_y = 240,
proc = function (self, canvas, drawSlideProc)
if self.scale < self.scale_limit then
self.scale = self.scale_limit
self.scale_delta = 1 / self.scale_delta
end
if self.scale > 1 then
drawSlideProc(canvas)
return nil
end
canvas:translate(self.pivot_x, self.pivot_y)
canvas:scale(self.scale, self.scale)
canvas:translate(-self.pivot_x, -self.pivot_y)
drawSlideProc(canvas)
self.scale = self.scale * self.scale_delta
return self
end
}
end
function onDrawContent(canvas)
local drawSlideProc = function(canvas)
drawSlide(canvas, gSlides[gSlideIndex], gTemplate, gPaints)
end
if gCurrAnimation then
gCurrAnimation = gCurrAnimation:proc(canvas, drawSlideProc)
return true
else
drawSlideProc(canvas)
return false
end
end
function onClickHandler(x, y)
return false
end
local keyProcs = {
n = next_slide,
p = prev_slide,
r = spawn_rotate_animation,
s = spawn_scale_animation,
}
function onCharHandler(uni)
local proc = keyProcs[uni]
if proc then
proc()
return true
end
return false
end