Animated Gradient Text

Share your advanced PureBasic knowledge/code with the community.
veganisafreak
User
User
Posts: 32
Joined: Mon Jun 02, 2008 6:55 pm
Location: UK

Animated Gradient Text

Post by veganisafreak »

This is my first proper PB program. It isn't really advanced but it's kinda kewl. Hope there are no bugs left. Save the following as "gradient text.pb":

Code: Select all

; Code tested

; Gradient Text Library

; There are procedures to draw animated or still gradient text
; and set its properties like color, speed and direction.
; There are no procedures to retrieve the properties, you
; have to access the global variables directly.

Global GT_SPEED.f = 1.0 ; number of cycles per second, must be > 0.0
Global GT_UPDATE_TIME = 1000 / GT_SPEED ; time taken for one complete cycle
Global GT_PREV_TIME = ElapsedMilliseconds() ; records the last time the text was at phase 0.0
Global GT_DIR = 0 ; scroll direction - 0 means left to right, 1 means right to left

; rgb values of first color in gradient

Global GT_R1 = 30
Global GT_G1 = 30
Global GT_B1 = 238

; rgb values of second color in gradient

Global GT_R2 = 48
Global GT_G2 = 223
Global GT_B2 = 233

; differences in rgb values of the two colors (used to calculate intermediate colors)

Global GT_RDIFF = GT_R2 - GT_R1
Global GT_GDIFF = GT_G2 - GT_G1
Global GT_BDIFF = GT_B2 - GT_B1

; background color

Global GT_BACK_R = 0
Global GT_BACK_G = 0
Global GT_BACK_B = 0

Declare.f Float(i.l)


; Draw gradient text (animated)

Procedure GradientText(x,y,Lit$,cx = 0,cy = 0)
	Protected i,j
	Protected Offset
	Protected Length
	Protected HalfLength.f
	Protected Time
	Protected Elapsed
	Protected Phase.f,Factor.f

  BackColor(RGB(GT_BACK_R,GT_BACK_G,GT_BACK_B))

	Time = ElapsedMilliseconds()
	Elapsed = Time - GT_PREV_TIME

	Phase.f = (Float(Elapsed % GT_UPDATE_TIME) / Float(GT_UPDATE_TIME))
	
	If Elapsed >= GT_UPDATE_TIME
		GT_PREV_TIME = Time - (Elapsed % GT_UPDATE_TIME)
	EndIf

	Length = Len(lit$)

	If cx = 1
		x = x - TextWidth(Lit$) / 2
	EndIf
	
	If cy = 1
		y = y - TextHeight(Lit$) / 2
	EndIf


	HalfLength.f = Float(Length) / 2.0

	For i = 0 To Length - 1
	
		If GT_DIR = 0
      If (i - (Length * Phase.f)) <= 0.0
				j = Length + (i - (Length * Phase.f))
			Else
				j = (i - (Length * Phase.f))
			EndIf
		Else
			j = Int(i + (Length * Phase.f)) % Int(Length)
		EndIf

		If Float(j) / Length >= 0.5
			Factor.f = 1.0 - (j - HalfLength.f) / HalfLength.f		
		Else
			Factor.f = j / HalfLength.f
		EndIf

		FrontColor(RGB(GT_R1 + Factor.f * GT_RDIFF,GT_G1 + Factor.f * GT_GDIFF,GT_B1 + Factor.f * GT_BDIFF))

		DrawText(x + Offset,y,Mid(Lit$,i+1,1))
		Offset = Offset + TextWidth(Mid(Lit$,i+1,1))
	Next
	
	ProcedureReturn 1
EndProcedure


; Old gradient text Procedure, not animated

Procedure GradientTextClassic(x,y,Lit$,cx = 0,cy = 0)
	Protected i
	Protected Offset
	Protected Length
	Protected HalfLength.f
	Protected Factor.f

  BackColor(RGB(GT_BACK_R,GT_BACK_G,GT_BACK_B))

	Length = Len(lit$)

	If cx = 1
		x = x - TextWidth(Lit$) / 2
	EndIf
	
	If cy = 1.
		y = y - TextHeight(Lit$) / 2
	EndIf

	HalfLength.f = Float(Length) / 2

	For i = 0 To Length - 1
		If Float(i) / Length >= 0.5
			Factor.f = 1.0 - (i - HalfLength.f) / HalfLength.f		
		Else
			Factor.f = i / HalfLength.f
		EndIf

		FrontColor(RGB(GT_R1 + Factor.f * GT_RDIFF,GT_G1 + Factor.f * GT_GDIFF,GT_B1 + Factor.f * GT_BDIFF))

		DrawText(x + Offset,y,Mid(Lit$,i+1,1))
		Offset = Offset + TextWidth(Mid(Lit$,i+1,1))
	Next
	
	ProcedureReturn 1
EndProcedure

; Set gradient colors. The first three params make up the first color (red, green blue in that order)
; the last three make up the last color.

Procedure SetGradientTextColor(R1,G1,B1,R2,G2,B2)
	GT_R1 = R1
	GT_G1 = G1
	GT_B1 = B1
	
	GT_R2 = R2
	GT_G2 = G2
	GT_B2 = B2
	
	GT_RDIFF = GT_R2 - GT_R1
	GT_GDIFF = GT_G2 - GT_G1
	GT_BDIFF = GT_B2 - GT_B1
EndProcedure

Procedure SetGradientTextBackColor(R,G,B)
  GT_BACK_R = R
  GT_BACK_G = G
  GT_BACK_B = B
EndProcedure

; Set speed of gradient text (cycles per second, must be > 0.0)

Procedure SetGradientTextSpeed(Speed.f)
	GT_SPEED.f = Speed.f
	GT_UPDATE_TIME = 1000 / GT_SPEED.f
EndProcedure

; Set anim direction - 0 means left to right (default), 1 means right to left

Procedure SetGradientTextDirection(Dir)
	GT_DIR = Dir
EndProcedure

; Synchronises (resets) gradient text to current time

Procedure SyncGradientText()
	GT_PREV_TIME = ElapsedMilliseconds()
EndProcedure

Procedure.f Float(i.l)
  Protected r.f
  !FILD dword [p.v_i]
  !FSTP dword [p.v_r] 
  ProcedureReturn r
EndProcedure
And then save the example in the same folder and run it:

Code: Select all

IncludeFile("gradient text.pb")

#WIDTH = 768
#HEIGHT = 768


window = OpenWindow(0,0,0,#WIDTH,#HEIGHT,"My Window")
InitKeyboard()
If window = 0
  MessageRequester("error","meh",0)
EndIf

If InitSprite() = 0
    MessageRequester("Error", "Can't open screen & sprite enviroment!", 0)
    End
  EndIf

screen = OpenWindowedScreen(window,0,0,#WIDTH,#HEIGHT,0,0,0)

font.l = LoadFont(0,"comic sans ms",40,#PB_Font_Bold)

SetGradientTextBackColor(0,0,0)
SetGradientTextColor(0,0,255,0,255,255)


SetGradientTextSpeed(1.0)
SetGradientTextDirection(0)
SyncGradientText()





Repeat
  ClearScreen(RGB(0,0,0))
  If StartDrawing(ScreenOutput())
    
    DrawingFont(FontID(0))

     GradientText(#WIDTH / 2,#HEIGHT / 2 - TextHeight("[ New Game ]"),"[ New Game ]",1,1)
     GradientText(#WIDTH / 2,#HEIGHT / 2,"[ High Scores ]",1,1)
     GradientText(#WIDTH / 2,#HEIGHT / 2 + TextHeight("[ Quit ]"),"[ Quit ]",1,1)
            
    StopDrawing()
    FlipBuffers()
  EndIf
  event = WindowEvent()
  Select event
    Case #PB_Event_CloseWindow
      End
  EndSelect
  ExamineKeyboard()
Until KeyboardPushed(#PB_Key_All)


End
Apologies if there are any Bad Programming PRactices. It is my first attempt.
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Post by rsts »

Cool :) Very nice effect.

cheers
veganisafreak
User
User
Posts: 32
Joined: Mon Jun 02, 2008 6:55 pm
Location: UK

Post by veganisafreak »

Yay someone liked it. BTW you're free to use it in any games or demos or anythign really. I'd love to see my code used in some bigger project.

PS it has my own Float() function because I ported it from BB and it was behaving oddly but I think maybe that func is unnecessary but I'm not sure...
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Post by Kwai chang caine »

Yeeesss !!! I like it 8)
ImageThe happiness is a road...
Not a destination
Ollivier
Enthusiast
Enthusiast
Posts: 281
Joined: Mon Jul 23, 2007 8:30 pm
Location: FR

Post by Ollivier »

Cool effect!
veganisafreak
User
User
Posts: 32
Joined: Mon Jun 02, 2008 6:55 pm
Location: UK

Post by veganisafreak »

Thanks loads guys you're really inspiring me to write more code! Even tho I'm half falling asleep on my keyboard!!!
nicolaus
Enthusiast
Enthusiast
Posts: 456
Joined: Tue Aug 05, 2003 11:30 pm
Contact:

Post by nicolaus »

I can't compile your code because i have all times a asm error :(
ASM is enabled in the compiler options
Green Snake
User
User
Posts: 10
Joined: Sun Apr 17, 2005 12:11 pm

Post by Green Snake »

Try this:

Code: Select all

Procedure.f Float(i.l) 
  Protected Ar.f 
  !FILD dword [p.v_i] 
  !FSTP dword [p.v_Ar] 
  ProcedureReturn Ar 
EndProcedure

If you use jaPBe: jaPBe replaces r with R.
nicolaus
Enthusiast
Enthusiast
Posts: 456
Joined: Tue Aug 05, 2003 11:30 pm
Contact:

Post by nicolaus »

Green Snake wrote:Try this:

Code: Select all

Procedure.f Float(i.l) 
  Protected Ar.f 
  !FILD dword [p.v_i] 
  !FSTP dword [p.v_Ar] 
  ProcedureReturn Ar 
EndProcedure

If you use jaPBe: jaPBe replaces r with R.
Thanks, now it works. It shows very nice!
Post Reply