2
$\begingroup$

I try to make an animated graph like the one below (the value changes according to the post's lenght). I need about ten poles to be animated. I suppose that using drivers may be a good solution, but I don't know how to achieve it. Thanks in advance. enter image description here enter image description here

$\endgroup$
3
$\begingroup$

There are two techniques for animating text.

The first technique is to have a vast number of text objects whose hide_render property (the camera icon in the outliner) is keyframed so that each only shows up in the rendered scene for the appropriate frame or frames.

The other is to use a frame_change_pre handler (python) to change the body of the text curve.

Here is a modified version of the example from Garrett's answer to How can I make dynamic text in an animation?

import bpy

scene = bpy.context.scene

def recalculate_text(scene):
    obj = bpy.data.objects['Text']
    bar = bpy.data.objects['Cube']
    obj.data.body = "h=%.1f" % bar.dimensions[2]
    obj.location[2] = bar.dimensions[2] + bar.location[2] + 0.2

bpy.app.handlers.frame_change_pre.append(recalculate_text)

(I modified the default cube by moving its origin to the bottom of the cube, and animated its Z size property).

You would have to put this python script in a text buffer and run it. If you want it to automatically run every time blender loads the file you should give the text buffer a name ending in .py and click the Register checkbox for that text buffer. This also means you will have to load the .blend file Trusted (either using the Reload Trusted button, or by invoking blender with the -y flag).

The other technique of having a swarm of text curves whose visibility is animated is demonstrated at http://web.purplefrog.com/~thoth/blender/python-cookbook/data-graph.html . Here is a relevant excerpt:

def setVisibility(obj, f1, f2):

    if not f2 is None:
        obj.keyframe_insert(data_path='hide', frame= bpy.context.scene.frame_end+10)
    obj.keyframe_insert(data_path='hide_render', frame=f1)
    obj.keyframe_insert(data_path='hide', frame=f1)
    obj.hide = True
    obj.hide_render = True
    obj.keyframe_insert(data_path='hide', frame=0)
    obj.keyframe_insert(data_path='hide_render', frame=0)
    if not f2 is None:
        obj.keyframe_insert(data_path='hide', frame=f2)
        obj.keyframe_insert(data_path='hide_render', frame=f2)


def makeText(text, loc, f1, f2):
    curve = bpy.data.curves.new("label", 'FONT')
    curve.body = text
    o1 = bpy.data.objects.new("label", curve)
    bpy.context.scene.objects.link(o1)
    o1.location = loc
    if not f1 is None:
        setVisibility(o1, f1, f2)
    o1.parent = bpy.data.objects["font folder"]

    curve.materials.append(bpy.data.materials["text"])

    return o1


def make2Text(text1, text2, loc, f1, f2):
    o1 = makeText(text1, loc, f1, f2)
    o2 = makeText(text2, loc, f1, f2)
    o1.data.align = 'RIGHT'

    return (o1, o2)

# animating text by creating hundreds of individual text objects that pop in and out
f1 = -1
for i,xy  in enumerate(data):
    f2 = frameForX(i, len(data), f0, f9)
    f3 = frameForX(i+1, len(data), f0, f9)
    if (i+1 >= len(data)):
        f3 = None
    if (f2>f1):
        make2Text("x=%d,"%xy[0], "y=%.1f"%xy[1], [4,6,1], f2, f3)
    f1 = f2
|improve this answer|||||
$\endgroup$
  • $\begingroup$ Thanks for the solutions @Mutant Bob! I'll check out all of them. $\endgroup$ – Paul Gonet Jun 22 '15 at 17:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.