From bce606f832579fe820b53acba8e24c2639f1f3d1 Mon Sep 17 00:00:00 2001 From: Alessandro Senese Date: Wed, 28 Aug 2024 14:39:25 +0100 Subject: [PATCH] add and fix support for loops --- .../animations/attention_seeker/bounce.gd | 1 - addons/anima/core/anima_node.gd | 9 +- addons/anima/core/anima_tween.gd | 25 +-- .../declaration/anima_declaration_base.gd | 105 +++++++++++-- .../declaration/anima_declaration_node.gd | 147 ++++++++++++++---- addons/anima/plugin.cfg | 2 +- addons/anima/utils/node_properties.gd | 2 +- 7 files changed, 234 insertions(+), 57 deletions(-) diff --git a/addons/anima/animations/attention_seeker/bounce.gd b/addons/anima/animations/attention_seeker/bounce.gd index b717ea96..0b3bbb00 100644 --- a/addons/anima/animations/attention_seeker/bounce.gd +++ b/addons/anima/animations/attention_seeker/bounce.gd @@ -24,4 +24,3 @@ var KEYFRAMES := { "scale:y": 1.02, }, } - diff --git a/addons/anima/core/anima_node.gd b/addons/anima/core/anima_node.gd index 7c2ed81d..7a7bc0e1 100644 --- a/addons/anima/core/anima_node.gd +++ b/addons/anima/core/anima_node.gd @@ -138,6 +138,7 @@ func clear() -> void: if not is_instance_valid(_anima_tween) or _anima_tween.is_queued_for_deletion(): return + _timer.stop() stop() _anima_tween.clear_animations() @@ -759,7 +760,10 @@ func _maybe_play() -> void: if _loop_times > 0 or _should_loop: if _loop_delay > 0: - await get_tree().create_timer(_loop_delay).timeout + _timer.wait_time = _loop_delay + _timer.start() + + await _timer.timeout _do_play() @@ -786,3 +790,6 @@ func get_animation_data() -> Array: func _play_backwards(time: float) -> void: _anima_tween.seek(time) + +func debug(): + print(get_animation_data()) diff --git a/addons/anima/core/anima_tween.gd b/addons/anima/core/anima_tween.gd index 1d76e6d8..55fcbcc0 100644 --- a/addons/anima/core/anima_tween.gd +++ b/addons/anima/core/anima_tween.gd @@ -31,16 +31,21 @@ func _init(new_name: String = "AnimaTween"): name = new_name func _enter_tree(): - var tree: SceneTree = get_tree() + _create_tween() - if tree: - _tween = tree.create_tween() +func _create_tween(): + var tree = get_tree() - _tween.set_parallel(true) - _tween.pause() + if not tree: + return + + _tween = tree.create_tween() + + _tween.set_parallel(true) + _tween.pause() - _tween.loop_finished.connect(_on_tween_completed) - _tween.finished.connect(_on_tween_completed) + _tween.loop_finished.connect(_on_tween_completed) + _tween.finished.connect(_on_tween_completed) func _exit_tree(): for child in get_children(): @@ -291,9 +296,6 @@ func clear_animations() -> void: _tween.stop() _tween.kill() - if is_inside_tree(): - _enter_tree() - for child in get_children(): child.queue_free() @@ -301,6 +303,9 @@ func clear_animations() -> void: _animation_data.clear() _initial_values.clear() + if is_inside_tree(): + _enter_tree() + func set_visibility_strategy(strategy: int) -> void: for animation_data in _animation_data: _apply_visibility_strategy(animation_data, strategy) diff --git a/addons/anima/core/declaration/anima_declaration_base.gd b/addons/anima/core/declaration/anima_declaration_base.gd index 6bace4d4..42dfa690 100644 --- a/addons/anima/core/declaration/anima_declaration_base.gd +++ b/addons/anima/core/declaration/anima_declaration_base.gd @@ -3,6 +3,7 @@ class_name AnimaDeclarationBase var _data := {} var _is_single_shot := true +var _anima_node: AnimaNode enum PlayAction { PLAY, @@ -11,8 +12,24 @@ enum PlayAction { PLAY_BACKWARDS, PLAY_BACKWARDS_WITH_DELAY, PLAY_BACKWARDS_WITH_SPEED, + LOOP, + LOOP_IN_CIRCLE, + LOOP_IN_CIRCLE_WITH_DELAY, + LOOP_IN_CIRCLE_WITH_SPEED, + LOOP_IN_CIRCLE_WITH_DELAY_AND_SPEED, + LOOP_BACKWARDS, + LOOP_BACKWARDS_WITH_SPEED, + LOOP_BACKWARDS_WITH_DELAY, + LOOP_BACKWARDS_WITH_DELAY_AND_SPEED, + LOOP_WITH_DELAY, + LOOP_WITH_SPEED, + LOOP_TIMES_WITH_DELAY, + LOOP_TIMES_WITH_DELAY_AND_SPEED } +func clear(): + _anima_node.clear() + func get_data() -> Dictionary: return _data @@ -108,24 +125,53 @@ func __get_source(): return null func _do_play(action: PlayAction, param = null) -> AnimaNode: - var anima := Anima.begin(__get_source()).then(_data) - anima.set_single_shot(_is_single_shot) + if _anima_node == null: + _anima_node = Anima.begin(__get_source()).then(_data) + + var single_shot = _is_single_shot if action < PlayAction.LOOP else false + _anima_node.set_single_shot(single_shot) match action: PlayAction.PLAY: - anima.play() + _anima_node.play() PlayAction.PLAY_WITH_DELAY: - anima.play_with_delay(param) + _anima_node.play_with_delay(param) PlayAction.PLAY_WITH_SPEED: - anima.play_with_speed(param) + _anima_node.play_with_speed(param) PlayAction.PLAY_BACKWARDS: - anima.play_backwards() + _anima_node.play_backwards() PlayAction.PLAY_BACKWARDS_WITH_DELAY: - anima.play_backwards_with_delay(param) + _anima_node.play_backwards_with_delay(param) PlayAction.PLAY_BACKWARDS_WITH_SPEED: - anima.play_backwards_with_speed(param) - - return anima + _anima_node.play_backwards_with_speed(param) + PlayAction.LOOP: + _anima_node.loop(param) + PlayAction.LOOP_IN_CIRCLE: + _anima_node.loop_in_circle(param) + PlayAction.LOOP_IN_CIRCLE_WITH_DELAY: + _anima_node.loop_in_circle_with_delay(param) + PlayAction.LOOP_IN_CIRCLE_WITH_SPEED: + _anima_node.loop_in_circle_with_speed(param.speed, param.times) + PlayAction.LOOP_IN_CIRCLE_WITH_DELAY_AND_SPEED: + _anima_node.loop_in_circle_with_delay_and_speed(param.delay, param.speed, param.times) + PlayAction.LOOP_BACKWARDS: + _anima_node.loop_backwards(param) + PlayAction.LOOP_BACKWARDS_WITH_SPEED: + _anima_node.loop_backwards_with_speed(param.speed, param.times) + PlayAction.LOOP_BACKWARDS_WITH_DELAY: + _anima_node.loop_with_delay(param.delay, param.times) + PlayAction.LOOP_BACKWARDS_WITH_DELAY_AND_SPEED: + _anima_node.loop_times_with_delay_and_speed(param.times, param.delay, param.speed) + PlayAction.LOOP_WITH_DELAY: + _anima_node.loop_with_delay(param.delay, param.times) + PlayAction.LOOP_WITH_SPEED: + _anima_node.loop_with_speed(param.speed, param.times) + PlayAction.LOOP_TIMES_WITH_DELAY: + _anima_node.loop_times_with_delay(param.times, param.delay) + PlayAction.LOOP_TIMES_WITH_DELAY_AND_SPEED: + _anima_node.loop_times_with_delay_and_speed(param.times, param.delay, param.speed) + + return _anima_node func play() -> AnimaNode: return _do_play(PlayAction.PLAY) @@ -144,3 +190,42 @@ func play_backwards_with_delay(delay: float) -> AnimaNode: func play_backwards_with_speed(speed: float) -> AnimaNode: return _do_play(PlayAction.PLAY_BACKWARDS_WITH_SPEED, speed) + +func loop(times: int = -1) -> AnimaNode: + return _do_play(PlayAction.LOOP, times) + +func loop_in_circle(times: int = -1) -> AnimaNode: + return _do_play(PlayAction.LOOP_IN_CIRCLE, times) + +func loop_in_circle_with_delay(delay: float, times: int = -1) -> AnimaNode: + return _do_play(PlayAction.LOOP_IN_CIRCLE_WITH_DELAY, times) + +func loop_in_circle_with_speed(speed: float, times: int = -1) -> AnimaNode: + return _do_play(PlayAction.LOOP_IN_CIRCLE_WITH_SPEED, { times = times, speed = speed }) + +func loop_in_circle_with_delay_and_speed(delay: float, speed: float, times: int = -1) -> AnimaNode: + return _do_play(PlayAction.LOOP_IN_CIRCLE_WITH_DELAY_AND_SPEED, { times = times, delay = delay, speed = speed }) + +func loop_backwards(times: int = -1) -> AnimaNode: + return _do_play(PlayAction.LOOP_BACKWARDS, times) + +func loop_backwards_with_speed(speed: float, times: int = -1) -> AnimaNode: + return _do_play(PlayAction.LOOP_BACKWARDS_WITH_SPEED, { times = times, speed = speed }) + +func loop_backwards_with_delay(delay: float, times: int = -1) -> AnimaNode: + return _do_play(PlayAction.LOOP_BACKWARDS_WITH_DELAY, { times = times, delay = delay }) + +func loop_backwards_with_delay_and_speed(delay: float, speed: float, times: int = -1) -> AnimaNode: + return _do_play(PlayAction.LOOP_BACKWARDS_WITH_DELAY_AND_SPEED, { times = times, delay = delay, speed = speed }) + +func loop_with_delay(delay: float, times: int = -1) -> AnimaNode: + return _do_play(PlayAction.LOOP_WITH_DELAY, { times = times, delay = delay }) + +func loop_with_speed(speed: float, times: int = -1) -> AnimaNode: + return _do_play(PlayAction.LOOP_WITH_SPEED, { times = times, speed = speed }) + +func loop_times_with_delay(times: float, delay: float) -> AnimaNode: + return _do_play(PlayAction.LOOP_TIMES_WITH_DELAY, { times = times, delay = delay }) + +func loop_times_with_delay_and_speed(times: int, delay: float, speed: float) -> AnimaNode: + return _do_play(PlayAction.LOOP_TIMES_WITH_DELAY_AND_SPEED, { times = times, delay = delay, speed = speed }) diff --git a/addons/anima/core/declaration/anima_declaration_node.gd b/addons/anima/core/declaration/anima_declaration_node.gd index 2d27cfe1..307f33da 100644 --- a/addons/anima/core/declaration/anima_declaration_node.gd +++ b/addons/anima/core/declaration/anima_declaration_node.gd @@ -1,24 +1,37 @@ class_name AnimaDeclarationNode -var _data: Dictionary +var _data := {} +var _anima_declaration func _init(node: Node = null): + _data.clear() + _data.node = node func _set_data(data: Dictionary) -> void: _data = data +func _clear_data(): + _init(_data.node) + func _create_declaration_for_animation(data: Dictionary) -> AnimaDeclarationForAnimation: var c:= AnimaDeclarationForAnimation.new() + _clear_data() + for key in data: _data[key] = data[key] return c._init_me(_data) func _create_declaration_with_easing(data: Dictionary) -> AnimaDeclarationForProperty: + if _anima_declaration: + _anima_declaration.clear() + var c:= AnimaDeclarationForProperty.new() + _clear_data() + for key in data: _data[key] = data[key] @@ -27,100 +40,168 @@ func _create_declaration_with_easing(data: Dictionary) -> AnimaDeclarationForPro func _create_relative_declaration_with_easing(data: Dictionary) -> AnimaDeclarationForRelativeProperty: var c:= AnimaDeclarationForRelativeProperty.new() + _clear_data() + for key in data: _data[key] = data[key] return c._init_me(_data) - + func anima_animation(animation: String, duration = null) -> AnimaDeclarationForAnimation: - return _create_declaration_for_animation({ animation = animation, duration = duration }) + _anima_declaration = _create_declaration_for_animation({ animation = animation, duration = duration }) + + return _anima_declaration func anima_animation_frames(frames: Dictionary, duration = null) -> AnimaDeclarationForAnimation: - return _create_declaration_for_animation({ animation = frames, duration = duration }) + _anima_declaration = _create_declaration_for_animation({ animation = frames, duration = duration }) + + return _anima_declaration func anima_property(property: String, final_value = null, duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = property, to = final_value, duration = duration }) + _anima_declaration = _create_declaration_with_easing({ property = property, to = final_value, duration = duration }) + + return _anima_declaration func anima_fade_in(duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "opacity", from = 0.0, to = 1.0, duration = duration }) + _anima_declaration = _create_declaration_with_easing({ property = "opacity", from = 0.0, to = 1.0, duration = duration }) + + return _anima_declaration func anima_fade_out(duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "opacity", from = 1.0, to = 0.0, duration = duration }) + _anima_declaration = _create_declaration_with_easing({ property = "opacity", from = 1.0, to = 0.0, duration = duration }) + + return _anima_declaration func anima_position(position: Vector2, duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "position", to = position, duration = duration }) + _anima_declaration = _create_declaration_with_easing({ property = "position", to = position, duration = duration }) + + return _anima_declaration func anima_position3D(position: Vector3, duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "position", to = position, duration = duration }) + _anima_declaration = _create_declaration_with_easing({ property = "position", to = position, duration = duration }) + + return _anima_declaration func anima_position_x(x: float, duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "x", to = x, duration = duration }) + _anima_declaration = _create_declaration_with_easing({ property = "x", to = x, duration = duration }) + + return _anima_declaration func anima_position_y(y: float, duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "y", to = y, duration = duration }) + _anima_declaration = _create_declaration_with_easing({ property = "y", to = y, duration = duration }) + + return _anima_declaration func anima_position_z(z: float, duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "z", to = z, duration = duration }) + _anima_declaration = _create_declaration_with_easing({ property = "z", to = z, duration = duration }) + + return _anima_declaration func anima_relative_position(position: Vector2, duration = null) -> AnimaDeclarationForRelativeProperty: - return _create_relative_declaration_with_easing({ property = "position", to = position, duration = duration, relative = true }) + _anima_declaration = _create_relative_declaration_with_easing({ property = "position", to = position, duration = duration, relative = true }) + + return _anima_declaration func anima_relative_position3D(position: Vector3, duration = null) -> AnimaDeclarationForRelativeProperty: - return _create_relative_declaration_with_easing({ property = "position", to = position, duration = duration, relative = true }) + _anima_declaration = _create_relative_declaration_with_easing({ property = "position", to = position, duration = duration, relative = true }) + + return _anima_declaration func anima_relative_position_x(x: float, duration = null) -> AnimaDeclarationForRelativeProperty: - return _create_relative_declaration_with_easing({ property = "x", to = x, duration = duration, relative = true }) + _anima_declaration = _create_relative_declaration_with_easing({ property = "x", to = x, duration = duration, relative = true }) + + return _anima_declaration func anima_relative_position_y(y: float, duration = null) -> AnimaDeclarationForRelativeProperty: - return _create_relative_declaration_with_easing({ property = "y", to = y, duration = duration, relative = true }) + _anima_declaration = _create_relative_declaration_with_easing({ property = "y", to = y, duration = duration, relative = true }) + + return _anima_declaration func anima_relative_position_z(z: float, duration = null) -> AnimaDeclarationForRelativeProperty: - return _create_relative_declaration_with_easing({ property = "z", to = z, duration = duration, relative = true }) + _anima_declaration = _create_relative_declaration_with_easing({ property = "z", to = z, duration = duration, relative = true }) + + return _anima_declaration func anima_scale(scale: Vector2, duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "scale", to = scale, duration = duration }) + _anima_declaration = _create_declaration_with_easing({ property = "scale", to = scale, duration = duration }) + + return _anima_declaration func anima_scale3D(scale: Vector3, duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "scale", to = scale, duration = duration }) + _anima_declaration = _create_declaration_with_easing({ property = "scale", to = scale, duration = duration }) + + return _anima_declaration func anima_scale_x(x: float, duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "scale:x", to = x, duration = duration }) + _anima_declaration = _create_declaration_with_easing({ property = "scale:x", to = x, duration = duration }) + + return _anima_declaration func anima_scale_y(y: float, duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "scale:y", to = y, duration = duration }) + _anima_declaration = _create_declaration_with_easing({ property = "scale:y", to = y, duration = duration }) + + return _anima_declaration func anima_scale_z(z: float, duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "scale:z", to = z, duration = duration }) + _anima_declaration = _create_declaration_with_easing({ property = "scale:z", to = z, duration = duration }) + + return _anima_declaration func anima_size(size: Vector2, duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "size", to = size, duration = duration }) + _anima_declaration = _create_declaration_with_easing({ property = "size", to = size, duration = duration }) + + return _anima_declaration func anima_size3D(size: Vector3, duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "size", to = size, duration = duration }) + _anima_declaration = _create_declaration_with_easing({ property = "size", to = size, duration = duration }) + + return _anima_declaration func anima_size_x(size: float, duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "size:x", to = size, duration = duration }) + _anima_declaration = _create_declaration_with_easing({ property = "size:x", to = size, duration = duration }) + + return _anima_declaration func anima_size_y(size: float, duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "size:y", to = size, duration = duration }) + _anima_declaration = _create_declaration_with_easing({ property = "size:y", to = size, duration = duration }) + + return _anima_declaration func anima_size_z(size: float, duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "size:z", to = size, duration = duration }) + _anima_declaration = _create_declaration_with_easing({ property = "size:z", to = size, duration = duration }) + + return _anima_declaration func anima_rotate(rotate: float, pivot: int = ANIMA.PIVOT.CENTER, duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "rotate", to = rotate, duration = duration, pivot = pivot }) + _anima_declaration = _create_declaration_with_easing({ property = "rotate", to = rotate, duration = duration, pivot = pivot }) + + return _anima_declaration func anima_rotate3D(rotate: Vector3, duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "rotation", to = rotate, duration = duration }) + _anima_declaration = _create_declaration_with_easing({ property = "rotation", to = rotate, duration = duration }) + + return _anima_declaration func anima_rotate_x(x: float, pivot: int, duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "rotation:x", to = x, duration = duration, pivot = pivot }) + _anima_declaration = _create_declaration_with_easing({ property = "rotation:x", to = x, duration = duration, pivot = pivot }) + + return _anima_declaration func anima_rotate_y(y: float, pivot: int, duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "rotation:y", to = y, duration = duration, pivot = pivot }) + _anima_declaration = _create_declaration_with_easing({ property = "rotation:y", to = y, duration = duration, pivot = pivot }) + + return _anima_declaration func anima_rotate_z(z: float, pivot: int, duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "rotation:z", to = z, duration = duration, pivot = pivot }) + _anima_declaration = _create_declaration_with_easing({ property = "rotation:z", to = z, duration = duration, pivot = pivot }) + + return _anima_declaration func anima_shader_param(param_name: String, to_value, duration = null) -> AnimaDeclarationForProperty: - return _create_declaration_with_easing({ property = "shader_param:" + param_name, to = to_value, duration = duration }) + _anima_declaration = _create_declaration_with_easing({ property = "shader_param:" + param_name, to = to_value, duration = duration }) + + return _anima_declaration + +func clear(): + if _anima_declaration: + _anima_declaration.clear() diff --git a/addons/anima/plugin.cfg b/addons/anima/plugin.cfg index 24511c37..728e8a8b 100644 --- a/addons/anima/plugin.cfg +++ b/addons/anima/plugin.cfg @@ -3,5 +3,5 @@ name="Anima" description="" author="Ceceppa" -version="0.4" +version="0.6" script="anima_plugin.gd" diff --git a/addons/anima/utils/node_properties.gd b/addons/anima/utils/node_properties.gd index 830a45be..33d907a6 100644 --- a/addons/anima/utils/node_properties.gd +++ b/addons/anima/utils/node_properties.gd @@ -26,7 +26,7 @@ static func get_size(node: Node) -> Vector2: return node.get_size() elif node is CanvasModulate: return Vector2.ZERO - elif node is Node2D: + elif node is Node2D and "texture" in node: return node.texture.get_size() * node.scale return Vector2.ZERO