Godot Version
4.3 stable
Question
I have problem with tween beacuse i wanted to create the animation for my gui. I wanted to create the scrool container but the bottom and top elemnts should fade and get’s smaller when i scroll, also i wanted the panels to open and close. the fading and scrooling works great, but i cannot connect the opening and closing the panels with scaling the bottom and top panels, it changes opacity during the animation of opening the panels, but the scale is working only if the opening or clsoing animation finish.
extends ScrollContainer
@onready var v_box_container: VBoxContainer = $VBoxContainer
var fade_distance_top = 110.0
var fade_distance_bottom = 250.0
var min_scale = 0.4
var max_scale = 1.0
func _ready() -> void:
var scrollbar = get_v_scroll_bar()
if scrollbar:
scrollbar.connect("value_changed", Callable(self, "_on_scroll_changed"))
# Perform initial fade
_on_scroll_changed(0)
# Optionally re-check every frame, if you want to handle dynamic changes
func _process(delta: float) -> void:
_on_scroll_changed(0)
func _on_scroll_changed(value: float) -> void:
# Get the viewport pos / size
var viewport_global_pos = self.get_global_position()
var viewport_size = self.get_size()
for panel in v_box_container.get_children():
if panel.has_method("update_fade_and_resize"):
panel.update_viewport(viewport_global_pos, viewport_size)
func update_gui():
_on_scroll_changed(0)
extends Control
@onready var panel_container: Control = $"."
@onready var button: Button = $Button
@onready var program_levels: GridContainer = $Button/ProgramLevels
@onready var texture_rect: TextureRect = $Button/GridContainer/MarginContainer2/TextureRect
@onready var label: Label = $Button/GridContainer/MarginContainer/Label
@export var fade_distance_top: float = 110.0
@export var fade_distance_bottom: float = 250.0
@export var min_scale: float = 0.4
@export var max_scale: float = 1.0
@export var panel_name: String
@export var icon_texture: Texture2D
signal fade_and_resize_updated(alpha: float, scale: float)
signal open_panel_signal()
var viewport_global_pos: Vector2
var viewport_size: Vector2
var panel_global_pos: Vector2
var panel_size: Vector2
var viewport_bottom: float
var alpha: float
var panel_scale: float
var panel_center_y
var distance_top
var distance_bottom
# Track the panel's state
var is_panel_open: bool = false
func _ready():
print("DEBUG: Panel ready")
texture_rect.texture = icon_texture
label.text = panel_name
func _process(delta: float) -> void:
self.update_fade_and_resize()
func _on_button_pressed() -> void:
if is_panel_open:
close_panel()
else:
open_panel()
func open_panel() -> void:
print("Opening panel...")
emit_signal("open_panel_signal")
var tween = create_tween()
tween.set_parallel()
tween.custom_step(0.01)
# Set up animations
tween.tween_property(button, "custom_minimum_size:y", 250, 1.5)
tween.tween_property(self, "custom_minimum_size:y", 250, 1.5)
tween.tween_property(program_levels, "modulate:a", 1.0, 1.5)
tween.tween_property(self, "custom_minimum_size:x", 500, 1.5)
is_panel_open = true
func close_panel() -> void:
print("Closing panel...")
var tween = create_tween()
tween.set_parallel()
# Set up animations
tween.tween_property(button, "custom_minimum_size:x", 500, 0.3)
tween.tween_property(button, "custom_minimum_size:y", 136, 0.3)
tween.tween_property(program_levels, "modulate:a", 0.0, 0.2)
tween.tween_property(self, "custom_minimum_size:x", 500, 0.3)
tween.tween_property(self, "custom_minimum_size:y", 136, 0.3)
is_panel_open = false
func update_viewport(viewport_global_pos: Vector2, viewport_size: Vector2) -> void:
self.viewport_bottom = viewport_global_pos.y + viewport_size.y
self.panel_global_pos = self.get_global_position()
self.panel_size = self.get_size()
self.panel_center_y = panel_global_pos.y + panel_size.y / 2
# Calculate distances to the viewport edges
self.distance_top = panel_center_y - viewport_global_pos.y
self.distance_bottom = viewport_bottom - panel_center_y
# Initialize alpha and scale
self.alpha = 1.0
self.panel_scale = max_scale
# Adjust fade and scale for the top edge
if distance_top < fade_distance_top:
var normalized_distance = clamp(distance_top / fade_distance_top, 0.0, 1.0)
self.alpha = pow(normalized_distance, 2.0) # Quadratic easing
self.panel_scale = lerp(min_scale, max_scale, normalized_distance)
# Adjust fade and scale for the bottom edge
if distance_bottom < fade_distance_bottom:
var normalized_distance = clamp(distance_bottom / fade_distance_bottom, 0.0, 1.0)
self.alpha = min(alpha, pow(normalized_distance, 2.0)) # Quadratic easing
self.panel_scale = lerp(min_scale, max_scale, normalized_distance)
#self.scale = Vector2(self.panel_scale, self.panel_scale)
self.update_fade_and_resize()
func update_fade_and_resize() -> void:
# Animate alpha (fade effect)
var tween = create_tween()
tween.bind_node(self)
tween.set_process_mode(Tween.TWEEN_PROCESS_IDLE)
tween.set_parallel()
# Animate scale (resize effect)
print("NAME: " + str(self.name)
+ " SCALE: " + str(self.panel_scale))
#self.scale = Vector2(self.panel_scale, self.panel_scale)
self.queue_redraw()
#tween.tween_property(self, "scale", Vector2(self.panel_scale, self.panel_scale), 0.1)
tween.parallel().tween_property(self, "modulate:a", alpha, 0.1)
#tween.parallel().tween_property(self, "scale", Vector2(self.panel_scale, self.panel_scale), 0.1)
tween.tween_property(self, "viewport_size", Vector2(self.panel_scale, self.panel_scale), 1.5)
# Emit a signal for external updates
emit_signal("fade_and_resize_updated", alpha, scale)
func _on_open_panel_signal():
var tween = create_tween()
#tween.tween_property(self, "scale:x", 0.5, 1.5)