Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion

Does anybody have some examples of slowly appearing text?

in Questions Posts: 102

This took me way longer than I expected to. An hour? Maybe two. I'm not very happy with it. But I haven't seen any other examples of this.

function setup()
    local str = [[Hello! This is a test to animate the appearance of text. It is a work in progress.]]
    t = {}
    t[0]=""
    for i = 1, #str do
        t[i] = str:sub(i, i)
        print(t[i])
    end
end

-- function to slowly draw text at x,y every speedth frame
-- feed it an empty table holding a text key and a target array of text (see setup above)
-- use a table for subject because pointers
function slowText(x,y, subject, target, iter, speed)
    local i = iter.i
    local j = i+1
    if target[j] and time % speed == 0 then
        subject.text = subject.text .. table.concat(target, "", i, j)
        iter.i=iter.i+2
    end
    -- This stuff below is graphical, Codea only
    local w = textSize(subject.text)
    pushStyle()
    textWrapWidth(740)
    fontSize(20)
    fill(252)
    font("ArialMT")
    text(subject.text, x + (w/2), y)
    popStyle()
end
-- The draw function gets called once every frame
time = 0
iter = {i=0}
local str={text=""}
function draw()
    time = time + 1
    background(40, 40, 50)
    strokeWidth(5)
    slowText(28,280,str,t,iter,2)
    if time == 59 then time = 0 end
end


Comments

  • dave1707dave1707 Mod
    Posts: 6,331

    @xThomas Here an example. It should be made into a class to be able to display different text at different speeds at the same time.

    function setup()
        textMode(CORNER)
        str ="Hello! This is a test to animate the appearance of text. It is a work in progress."
    end
    
    function draw()
        background(0)
        fill(255)
        slowText(10,300,str,20) -- change 20. Higher value mean slower display.
    end
    
    function slowText(x,y, subject,limit)
        if len==nil or cnt==nil then
            cnt=0
            len=1
        end
        if len<#str then
            if cnt<limit then
                cnt=cnt+1
            else
                len=len+1
                cnt=0
            end
        end
        text(string.sub(subject,1,len),x,y)
    end
    
  • dave1707dave1707 Mod
    edited June 15 Posts: 6,331

    Here is a class version of the above code. More things can be added to the class.

    displayMode(FULLSCREEN)
    supportedOrientations(LANDSCAPE_ANY)
    
    function setup()
        s1=slowText(50,200,20,color(255,0,0),20,"Hello! This is a test to animate the appearance of text. It is a work in progress.")
        s2=slowText(10,400,50,color(0,255,0),50,"Hello! This is a test to animate text, the end.")
    end
    
    function draw()
        background(0)
        s1:draw()
        s2:draw()
    end
    
    slowText = class()
    
    function slowText:init(x,y,limit,col,size,str)
        self.x=x
        self.y=y
        self.col=col
        self.size=size
        self.str=str
        self.limit=limit
        self.len=1
        self.cnt=0    
    end
    
    function slowText:draw()
        pushMatrix()
        fill(self.col)
        fontSize(self.size)
        textMode(CORNER)
        if self.len<#self.str then
            if self.cnt<self.limit then
                self.cnt=self.cnt+1
            else
                self.len=self.len+1
                self.cnt=0
            end
        end
        text(string.sub(self.str,1,self.len),self.x,self.y)
        popMatrix()
    end
    
  • dave1707dave1707 Mod
    edited June 15 Posts: 6,331

    Here's another version where I added more to the class.

    displayMode(FULLSCREEN)
    supportedOrientations(LANDSCAPE_ANY)
    
    function setup()
        s1=slowText(WIDTH/2,200,20,color(255,0,0),20,0,0,"Hello! This is a test to animate the appearance of text. It is a work in progress.")
        s2=slowText(400,HEIGHT/2,50,color(0,255,0),40,45,0,"Hello! This is a test to animate text, work in progress.")
        s3=slowText(WIDTH/2+100,HEIGHT/2,50,color(255,255,0),40,0,.1,"Hello!")
    end
    
    function draw()
        background(0)
        s1:draw()
        s2:draw()
        s3:draw()
    end
    
    slowText = class()
    
    function slowText:init(x,y,limit,col,size,ang,inc,str)
        self.x=x
        self.y=y
        self.col=col
        self.size=size
        self.ang=ang
        self.str=str
        self.inc=inc
        self.limit=limit
        self.len=1
        self.cnt=0    
    end
    
    function slowText:draw()
        pushMatrix()
        fill(self.col)
        fontSize(self.size)
        if self.len<#self.str then
            if self.cnt<self.limit then
                self.cnt=self.cnt+1
            else
                self.len=self.len+1
                self.cnt=0
            end
        end
        translate(self.x,self.y)
        self.ang=self.ang+self.inc
        rotate(self.ang)
        text(string.sub(self.str,1,self.len),0,0)
        popMatrix()
    end
    
  • edited October 3 Posts: 102

    this typewriter function makes it so you write text, standard alignment is left. as you make new lines it makes the old text go towards the top of the screen. note that codea will not draw text if textsize is greater than the sceeen. and this is a very minimal implementation, i made it this way by accident trying to do something else. What I actually wanted to do was different but whatever.

    I think textAlign(LEFT) is bugged a bit, as when you try to draw text on only one line, it doesn't actually do the aligning. You need at least two lines.

    -- typewriter
    
    -- Use this function to perform your initial setup
    function setup()
        print("Hello World!")
    end
    
    local long = [["gagshgjhdghsjgjhfgsgfhjshjfjhgdjhfgjhdgfhjgsjhfgjhhgfhgjdhgfhjdjfhgdjhfgjhdgfjhgdjhfgjhdgfjhgdfjhgejhfgjhdgfjhgdfhjgdjhfghjdgfhjgdjhfgjhgdfjhgejhfgjhgjhrgfjhgrfhjgjhdfgjhgdfjhgjrhfghjrgfjhr\n\nijsgkjgdjkgfhkdgjfjghdkfghkghjgjhgjhghjg^>#^%\#^{%#^%]#{^%#{]%}^*^#[]^*^]{"]]
    -- This function gets called once every frame
    function draw()
        -- This sets a dark background color 
        background(40, 40, 50)
    
        -- This sets the line thickness
        strokeWidth(5)
    
        fill(177)
        fontSize(15)
        font("Inconsolata")
        textWrapWidth(312)
        typewriter('Apple Banana Crayon Dog Eagle Falcon Greens Ohayo')
        typewriter(long, 6, 200,399)
        -- Do your drawing here
    
    end
    
    local textObject = {
        text = "\n",
    
    }
    
    --[[
    Auxilary function for animating text one character at a time. Made for RPG games.
    Tries to align text to the left so that character n is always at the same x,y position
    no matter the string. For this reason please use monospaced fonts.
    The first parameter is the string to animate. The optional second parameter is the 
    speed to draw at in frames per second. (default is 6). Third and fourth determine where
    to draw the text. Always aligns LEFT. 
    
    todo: add align mode
    
    Returns  String of textObject.text if called without first parameter
    ]]
    
    local count = 0
    local time = 0
    function typewriter(characters, fps, x, y)
        if not characters then
            return textObject.text
        else
            characters = '\n'..characters   --keeps first line display correctly
            time = time + 1
            fps = fps or 6
            if time % fps == 0 then count = count + 1 end
            x = x or 0
            y = y or 0
            if textObject.text ~= characters then
                textObject.text = string.sub(characters, 1, count)
                textAlign(LEFT)
                local w,h = textSize(typewriter())
                local wrap = textWrapWidth()
                local x = x + w/2
                local y = y + h/2
    
                text(textObject.text, x, y)
            else
                textAlign(LEFT)
                local w,h = textSize(typewriter())
                local wrap = textWrapWidth()
                local x = x + w/2
                local y = y + h/2
                text(textObject.text, x, y)
            end
        end
    end
    
    function touched(touch)
        if touch then showKeyboard() end
    end
    
    function keyboard( key )
        long = keyboardBuffer()
    end
    
Sign In or Register to comment.