Closed subsoap closed 3 years ago
Could this be achieved using the truncate() and characters() functions?
@britzl most likely if truncate allowed per word truncation
Added per word truncation in 5.9.0
How would you do this?
I can't set the previous node invisible, nor can I delete it because of the way truncate works. I can set their color.w to 0 I think. It would be more convenient to fade in one word at a time, but that's a different look. timer.delay seems like the wrong tool for this problem too.
I created an example of one way of solving this: https://github.com/britzl/defold-richtext/blob/master/example/example.gui_script#L246-L283
Take a look and see if you have any suggestions on how to improve it.
This seems like the right solution!
WoW's interface was done in Lua. I wonder if their quest text used a similar technique? :)
Here are some visual / timer changes only. The timer.delay calls should be saved in a table which can then be canceled for each? If you click back before it finishes the script errors over a deleted node. Could add an event for clicking while fading to instantly show all text.
The improvement to the example in general is also good!
local function create_fade_in_example()
local long_text = [[
This is a text that should fade in character by character. This text is long to make it easier to see the visual effect.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis porta eu ligula in varius.
Vestibulum fringilla rhoncus vestibulum. Nullam rutrum diam eu quam volutpat, ut laoreet massa suscipit.
Nulla id eleifend erat. Donec commodo quam nec posuere efficitur. Vestibulum a justo ex.
Vestibulum facilisis, felis id semper scelerisque, magna metus pretium felis, vel fermentum ipsum mauris a quam.
]]
local settings = { position = vmath.vector3(20, 900, 0), align = richtext.ALIGN_LEFT, width = 640 }
local words = richtext.create(long_text, "Roboto-Regular", settings)
local fade_duration = 0.44
local fade_delay = 0.022
coroutine.wrap(function()
-- disable all words
for i=1,#words do
gui.set_enabled(words[i].node, false)
end
-- iterate over words and fade them in character by character
for i=1,#words do
local word = words[i]
-- split into individual characters and fade in
local characters = richtext.characters(word)
for i,char in ipairs(characters) do
fade_in(char.node, go.EASING_INOUTSINE, fade_duration, (i - 1) * fade_delay)
end
-- start a timer to delete the individual characters and re-enable original word
local max_delay = (#characters - 1) * fade_delay
timer.delay(fade_duration + max_delay, false, function()
for _,char in ipairs(characters) do
gui.delete_node(char.node)
end
gui.set_enabled(word.node, true)
end)
fade_delay = fade_delay
fade_duration = fade_duration
-- wait before dealing with the next word
delay(max_delay)
end
end)()
return words
end
Yeah, this was a fairly quick test to see if this approach works. You need to keep track of the words and characters and timer so that it's possible to do cleanup.
Why do you set the delay and duration like this: ?
fade_delay = fade_delay
fade_duration = fade_duration
Why do you set the delay and duration like this: ?
I have no idea! 🤪 Must have been testing something and did something weird, or maybe happened from a multiple cursor being active without noticing.
https://www.twitch.tv/finestko/clip/PrettiestPopularToadSquadGoals
An effect some visual novels has which looks nice.