Is it possible to do per-character animation on text? I’m creating a lot of animated titles and want to create animations similar to this:
I’m aware that I could create a Text node for each character but given that I’m creating a lot of titles it would be much quicker if I could animate the text from the input of a single Text node.
The last animation can be done with a simple expression on the text node. The first one is a bit more tricky (if you don’t want to use multiple text nodes), maybe a Python plug exists(?)
Thanks, I’ll look into using an expression for the first example.
I may make a feature request as it would be good if there was a general way to do any sort of animation on a per character basis (e.g. this in After Effects https://www.youtube.com/watch?v=b1_p2qQf_Ts )
I’m attempting to replicate the typewriter text in the last animation using expression and I’m having a bit of trouble. I have two Text nodes. One with the original text and another Text node with the following expression:
originalText = original.text.get()
output = " "
while frame < len(originalText):
output=output+originalText[frame]
ret = output
And in the python console I have this
ERROR: while executing script:
ret = app1.new.text.expression0(15,0)
Python error:
Python exception: local variable 'ret' referenced before assignment
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "<string>", line 22 in expression0
UnboundLocalError: local variable 'ret' referenced before assignment
I tried it in Python3 (swapped out frame for a counter) and it worked.
Hello, your expression will result in an infinite loop, maybe you are going to make expression like this? (If I understood correctly)
originalText = original.text.get()
output = " "
ptr = 0
for i in range(frame, len(originalText)):
if frame<len(originalText):
ptr=frame
else:
ptr=len(originalText)
output+=originalText[ptr]
ret = output
Results in (assuming original.text = “ASDF”):
0-th frame: AAAA.
1-st frame: SSS
2-nd frame: DD
3-rd+ frame: F
I’m trying to make a typewriter text effect with each letter in a word appearing one by one. I’m still learning Python and your example really helped! Here’s how I adapted it to make it work
originalText = original.text.get()
output = " "
ptr = 0
slowFac = 4
for i in range(frame/slowFac, len(originalText)+1):
if frame/slowFac < len(originalText):
ptr=frame/slowFac
else:
ptr=len(originalText)
ret = originalText[0:ptr]
It disappears once the text is typed but it’s a start!
You might consider using Retime node (set speed to 1/4) instead of slowFactor, it will make things easier and gives you more control over animation.
Just saying…
I did actually try adding a Retime node after the text node but it doesn’t do anything. In fact the animation disappears once I add a Retime node and change a setting. A possible bug?
@hellocatfood, same problem here - odd static results. Maybe, Natron’s Retime node messes the value of the frame variable. However, Reverse input works ok, changing the Speed is not ok.
How much to change the speed of the input clip. To determine which input frame is taken at a given time, the speed is integrated from the beginning of the source frame range to the given time, so that speed can be animated to locally accelerate (speed > 1), decelerate (speed < 1) or reverse (speed < 0) the source clip. Note that this is is not the same as the speed parameter of the Nuke Retime node, which just multiplies the speed value at the current time by the time to obtain the source frame number.
I think the problem is there, it should just multiply to get the value of frame.
Retime works well, and if speed is a constant, integrating a constant from 0 to t is the same thing as multiplying it by t.
This is another bug, please file an issue on github and attach the project file.
These two modifications work (Constant is just black and transparent):
I know this is video is titled links, but this is building a typewrite style expression where one can put any text into a separate text node/field and the expression that links to the field will type it out over time.
Hmm, not positive, but I think the reason you might have been having issues with the count pause is it looks like you were using integers, which would restrict one to time units of 1 as the minimum. If a floating point value like 1.1 had been used, then the pause time should, in theory, have been more controllable.