A basic example of what I’m trying to do is a digital clock. Is it possible to animate the contents of a Text object? Let’s say there’s a countdown timer on a display, how would I go about actually having it count down?
You could have individual digits that you keyframe animate their visibility/renderability. You can do this by rmb on the with the icons in the outliner window
So if I understand you right I would have all 10 digits in the same location, then animate between them?
Hmm… along those lines, what if I had a UV texture that has the digits and then animate the mapping?
Hi kolink,
here is a script I wrote to do a countdown timer.
Copy the script into the text editor, right click and choose run script. You will then have a new panel on the font properties. The timer counts down the number of seconds chosen, from frame 1.
Needs extending, differing starting frames, output formats… one day.
import bpy
import math
from bpy.props import BoolProperty
def countdown_timer(scene):
# look for all font objects with _timer property
timers = [ob.data for ob in scene.objects if ob.type == 'FONT' and ob.data.is_timer]
for font in timers:
secs = font["timer"]
countdown_frames = secs * scene.render.fps / scene.render.fps_base
frame = countdown_frames - scene.frame_current + 1
if frame < 0:
continue
t = float(frame * scene.render.fps_base ) / float(scene.render.fps)
minutes = t // 60
t %= 60
seconds = math.floor(t)
t = t - seconds
hundreds = math.floor(100 * (t))
font.body = "%02d:%02d:%02d" % (minutes,seconds,hundreds)
return None
def is_timer(self, context):
if self.is_timer:
if "timer" not in self.keys():
self["timer"] = 10 # 10 seconds default
return None
class TimerPanel(bpy.types.Panel):
"""Timer Panel"""
bl_label = "Countdown Timer"
bl_idname = "FONT_PT_timer"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "data"
@classmethod
def poll(cls, context):
return (context.object and context.object.type in {'FONT'} and context.curve)
def draw_header(self, context):
font = context.object.data
self.layout.prop(font, "is_timer", text="")
def draw(self, context):
font = context.object.data
layout = self.layout
if font.is_timer:
row = layout.row()
row.prop(font,'["timer"]', text="Seconds")
def register():
bpy.types.TextCurve.is_timer = BoolProperty(default=False, update=is_timer, description="Make countdown timer")
bpy.app.handlers.frame_change_pre.append(countdown_timer)
bpy.utils.register_class(TimerPanel)
def unregister():
bpy.utils.unregister_class(TimerPanel)
bpy.app.handlers.frame_change_pre.pop()
if __name__ == "__main__":
register()
Thanks batFINGER, that seems to work great!
David
Here is the script with precision.
Animate the timer property using drivers / keyframes etc. This way you can make it go up down.
Prec takes care of the fraction.
import bpy
import math
from bpy.props import BoolProperty
def splittime(secs, prec=2):
t = float(secs)
minutes = t // 60
t %= 60
seconds = math.floor(t)
t = round(t - seconds, prec)
p = 10 ** prec
fraction = math.floor(p * (t))
return (minutes, seconds, fraction % p)
def countdown_timer(scene):
# look for all font objects with _timer property
timers = [ob.data for ob in scene.objects if ob.type == 'FONT' and ob.data.is_timer]
for font in timers:
secs = font["timer"]
try:
fmt = ("!02d:!02d:!0%dd" % font["prec"]).replace("!","%")
font.body = fmt % splittime(secs, prec=font["prec"])
except:
pass
return None
def is_timer(self, context):
if self.is_timer:
if "timer" not in self.keys():
self["timer"] = 0.0
self["prec"] = 2
countdown_timer(context.scene)
return None
class TimerPanel(bpy.types.Panel):
"""Timer Panel"""
bl_label = "Countdown Timer"
bl_idname = "FONT_PT_timer"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "data"
@classmethod
def poll(cls, context):
return (context.object and context.object.type in {'FONT'} and context.curve)
def draw_header(self, context):
font = context.object.data
self.layout.prop(font, "is_timer", text="")
def draw(self, context):
font = context.object.data
layout = self.layout
if font.is_timer:
row = layout.row()
row.prop(font,'["timer"]', text="Seconds")
row = layout.row()
#frow.alert = False
row.prop(font,'["prec"]', text="Prec")
try:
fmt = ("!02d:!02d:!0%dd" % font["prec"]).replace("!","%")
row.label(fmt % splittime(font["timer"], prec=font["prec"]))
except:
row.alert = True
row.label("INVALID FORMAT STRING")
def register():
bpy.types.TextCurve.is_timer = BoolProperty(default=False, update=is_timer, description="Make countdown timer")
bpy.app.handlers.frame_change_post.append(countdown_timer)
bpy.utils.register_class(TimerPanel)
def unregister():
bpy.utils.unregister_class(TimerPanel)
bpy.app.handlers.frame_change_post.pop()
if __name__ == "__main__":
register()
print("Countdown Timer")
Just a quick “Thanks”, batfinger (although I’m having troubles getting the newer version of the script to work).
Sorry for the delayed reply - I thought I was Subscribed to this thread, but apparently I wasn’t. Anyway, this script is awesome, I’m using it right now, and I’m sure I’ll be using it in the future. For whatever my opinion is worth, I encourage you to continue cultivating it and I’m sure it will eventually be very popular.
Thank you!
Just so you know, there is an evolved typing text addon that was created by Bassam Kuradali and is available and demonstrated here: http://www.blendernation.com/2013/01/25/typewriter-blender-addon/
However, it does not feature anything like a counting clock, so this is still very useful!