| |
| 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 |