78 lines
2.1 KiB
GDScript
78 lines
2.1 KiB
GDScript
class_name TypewriterReveal
|
|
extends RefCounted
|
|
|
|
const DEFAULT_CHARACTERS_PER_SECOND: float = 28.0
|
|
const MIN_CHARACTERS_PER_SECOND: float = 12.0
|
|
const MAX_CHARACTERS_PER_SECOND: float = 60.0
|
|
const ACTIVE_TWEEN_META: StringName = &"typewriter_reveal_active_tween"
|
|
|
|
static var _characters_per_second: float = DEFAULT_CHARACTERS_PER_SECOND
|
|
|
|
|
|
static func set_characters_per_second(value: float) -> void:
|
|
_characters_per_second = clampf(
|
|
value,
|
|
MIN_CHARACTERS_PER_SECOND,
|
|
MAX_CHARACTERS_PER_SECOND,
|
|
)
|
|
|
|
|
|
static func get_characters_per_second() -> float:
|
|
return _characters_per_second
|
|
|
|
|
|
static func start(
|
|
label: Label,
|
|
characters_per_second: float = -1.0,
|
|
) -> float:
|
|
if label == null:
|
|
return 0.0
|
|
cancel(label, false)
|
|
var character_count: int = label.get_total_character_count()
|
|
if character_count <= 0:
|
|
label.visible_characters = -1
|
|
return 0.0
|
|
label.visible_characters = 0
|
|
var resolved_characters_per_second := (
|
|
characters_per_second
|
|
if characters_per_second > 0.0
|
|
else _characters_per_second
|
|
)
|
|
var duration := float(character_count) / resolved_characters_per_second
|
|
var reveal_tween := label.create_tween()
|
|
label.set_meta(ACTIVE_TWEEN_META, reveal_tween)
|
|
reveal_tween.tween_property(
|
|
label,
|
|
"visible_characters",
|
|
character_count,
|
|
duration,
|
|
).from(0).set_trans(Tween.TRANS_LINEAR)
|
|
reveal_tween.finished.connect(
|
|
_on_reveal_finished.bind(label, reveal_tween),
|
|
CONNECT_ONE_SHOT,
|
|
)
|
|
return duration
|
|
|
|
|
|
static func cancel(label: Label, reveal_all: bool = true) -> void:
|
|
if label == null:
|
|
return
|
|
var reveal_tween: Tween
|
|
if label.has_meta(ACTIVE_TWEEN_META):
|
|
reveal_tween = label.get_meta(ACTIVE_TWEEN_META) as Tween
|
|
if reveal_tween != null and reveal_tween.is_valid():
|
|
reveal_tween.kill()
|
|
if label.has_meta(ACTIVE_TWEEN_META):
|
|
label.remove_meta(ACTIVE_TWEEN_META)
|
|
if reveal_all:
|
|
label.visible_characters = -1
|
|
|
|
|
|
static func _on_reveal_finished(label: Label, reveal_tween: Tween) -> void:
|
|
if label == null or not is_instance_valid(label):
|
|
return
|
|
if (
|
|
label.has_meta(ACTIVE_TWEEN_META)
|
|
and label.get_meta(ACTIVE_TWEEN_META) == reveal_tween
|
|
):
|
|
label.remove_meta(ACTIVE_TWEEN_META)
|