From 181c0a66451313454f2d47e4eb7a61986a9fec5d Mon Sep 17 00:00:00 2001 From: Nordup Date: Sun, 10 Aug 2025 22:26:16 +0700 Subject: [PATCH] onboarding carousel working --- app/scenes/components/onboarding/board.tscn | 119 ++++++++++++++ .../components/onboarding/onboarding.tscn | 152 ++++++++++-------- app/scenes/menu_body/home.tscn | 8 +- app/scenes/menu_body/world.tscn | 4 +- app/scripts/ui/onboarding/board.gd | 37 +++++ app/scripts/ui/onboarding/carousel.gd | 42 +++++ app/scripts/ui/onboarding/onboarding.gd | 21 +-- 7 files changed, 299 insertions(+), 84 deletions(-) create mode 100644 app/scenes/components/onboarding/board.tscn create mode 100644 app/scripts/ui/onboarding/board.gd create mode 100644 app/scripts/ui/onboarding/carousel.gd diff --git a/app/scenes/components/onboarding/board.tscn b/app/scenes/components/onboarding/board.tscn new file mode 100644 index 0000000..ed25b19 --- /dev/null +++ b/app/scenes/components/onboarding/board.tscn @@ -0,0 +1,119 @@ +[gd_scene load_steps=7 format=3 uid="uid://pbsmrx55rb5g"] + +[ext_resource type="LabelSettings" uid="uid://crt4elt055uhg" path="res://assets/styles/text_big.tres" id="1_22o26"] +[ext_resource type="Script" path="res://scripts/ui/onboarding/board.gd" id="1_dxxs8"] +[ext_resource type="FontFile" uid="uid://do40418waa8w3" path="res://assets/fonts/Inter-Regular.otf" id="2_glv2j"] +[ext_resource type="PackedScene" uid="uid://xagbhqfidf2" path="res://scenes/components/round_button.tscn" id="3_xk4gg"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_r2yvw"] +bg_color = Color(0.113725, 0.117647, 0.14902, 1) +corner_radius_top_left = 40 +corner_radius_top_right = 40 +corner_radius_bottom_right = 40 +corner_radius_bottom_left = 40 +shadow_color = Color(0.0584, 0.06128, 0.08, 0.784314) +shadow_size = 6 + +[sub_resource type="LabelSettings" id="LabelSettings_bkr01"] +font = ExtResource("2_glv2j") +font_size = 20 +font_color = Color(0.431373, 0.435294, 0.494118, 1) + +[node name="Board" type="Control" node_paths=PackedStringArray("focus_button")] +custom_minimum_size = Vector2(600, 700) +layout_mode = 3 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -300.0 +offset_top = -350.0 +offset_right = 300.0 +offset_bottom = 350.0 +grow_horizontal = 2 +grow_vertical = 2 +pivot_offset = Vector2(300, 350) +script = ExtResource("1_dxxs8") +focus_button = NodePath("TextureButton") +unfocus_color = Color(1, 1, 1, 0.505882) +unfocus_scale = Vector2(0.8, 0.8) + +[node name="Panel" type="Panel" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_r2yvw") + +[node name="MarginContainer" type="MarginContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 0 +theme_override_constants/margin_top = 24 +theme_override_constants/margin_bottom = 24 + +[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"] +layout_mode = 2 +theme_override_constants/separation = 20 +alignment = 1 + +[node name="Label" type="Label" parent="MarginContainer/VBoxContainer"] +layout_mode = 2 +text = "Gate is not responding" +label_settings = ExtResource("1_22o26") +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="Control" type="Control" parent="MarginContainer/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="Label2" type="Label" parent="MarginContainer/VBoxContainer/Control"] +layout_mode = 2 +offset_top = 293.0 +offset_right = 600.0 +offset_bottom = 346.0 +text = "Reload the page or try +to wait if it responses" +label_settings = SubResource("LabelSettings_bkr01") +horizontal_alignment = 1 + +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 4 +theme_override_constants/separation = 22 + +[node name="Reload" parent="MarginContainer/VBoxContainer/HBoxContainer" instance=ExtResource("3_xk4gg")] +custom_minimum_size = Vector2(90, 26) +layout_mode = 2 +theme_override_colors/font_disabled_color = Color(0.431373, 0.435294, 0.494118, 1) +theme_override_colors/font_color = Color(0.831373, 0.831373, 0.831373, 1) +theme_override_fonts/font = ExtResource("2_glv2j") +theme_override_font_sizes/font_size = 20 +text = "Reload" +icon = null + +[node name="Hide" parent="MarginContainer/VBoxContainer/HBoxContainer" instance=ExtResource("3_xk4gg")] +custom_minimum_size = Vector2(90, 26) +layout_mode = 2 +theme_override_colors/font_disabled_color = Color(0.431373, 0.435294, 0.494118, 1) +theme_override_colors/font_color = Color(0.831373, 0.831373, 0.831373, 1) +theme_override_fonts/font = ExtResource("2_glv2j") +theme_override_font_sizes/font_size = 20 +text = "Wait" +icon = null + +[node name="TextureButton" type="TextureButton" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 diff --git a/app/scenes/components/onboarding/onboarding.tscn b/app/scenes/components/onboarding/onboarding.tscn index 7ff2b43..1ffbd13 100644 --- a/app/scenes/components/onboarding/onboarding.tscn +++ b/app/scenes/components/onboarding/onboarding.tscn @@ -1,20 +1,32 @@ -[gd_scene load_steps=8 format=3 uid="uid://b5tbn17l1pfs1"] +[gd_scene load_steps=11 format=3 uid="uid://b5tbn17l1pfs1"] [ext_resource type="Script" path="res://scripts/ui/onboarding/onboarding.gd" id="1_2xh2a"] -[ext_resource type="StyleBox" uid="uid://bllkg32sc4iam" path="res://assets/styles/panel.stylebox" id="2_mnljw"] -[ext_resource type="LabelSettings" uid="uid://crt4elt055uhg" path="res://assets/styles/text_big.tres" id="3_3pufm"] -[ext_resource type="FontFile" uid="uid://do40418waa8w3" path="res://assets/fonts/Inter-Regular.otf" id="4_bi8o3"] -[ext_resource type="PackedScene" uid="uid://xagbhqfidf2" path="res://scenes/components/round_button.tscn" id="5_tk3ti"] +[ext_resource type="Script" path="res://scripts/ui/onboarding/carousel.gd" id="2_uhwdh"] +[ext_resource type="Shader" uid="uid://dd1axtdlit6no" path="res://shaders/vignette_blur.tres" id="2_vhqmk"] +[ext_resource type="PackedScene" uid="uid://pbsmrx55rb5g" path="res://scenes/components/onboarding/board.tscn" id="3_04ofy"] +[ext_resource type="Resource" uid="uid://crjhix0osmtnf" path="res://resources/ui_events.res" id="3_jta5g"] [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_htqsi"] -bg_color = Color(0, 0, 0, 0.5) +bg_color = Color(0, 0, 0, 0.505882) -[sub_resource type="LabelSettings" id="LabelSettings_bkr01"] -font = ExtResource("4_bi8o3") -font_size = 20 -font_color = Color(0.431373, 0.435294, 0.494118, 1) +[sub_resource type="Curve" id="Curve_gjk4u"] +_data = [Vector2(0, 1), 0.0, -0.118897, 0, 0, Vector2(0.6, 0.686327), -1.65368, -1.65368, 0, 0, Vector2(0.99999, 0.424933), 0.0, 0.0, 0, 0] +point_count = 3 -[node name="Onboarding" type="Control" node_paths=PackedStringArray("root", "skip")] +[sub_resource type="CurveTexture" id="CurveTexture_fomqh"] +curve = SubResource("Curve_gjk4u") + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_hpwdi"] +shader = ExtResource("2_vhqmk") +shader_parameter/UVScale = Vector2(1, 1) +shader_parameter/BlurAmount = 1.0 +shader_parameter/VignetteColor = Color(0.0704, 0.07856, 0.08, 1) +shader_parameter/Vignette = SubResource("CurveTexture_fomqh") + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_2l2ws"] +bg_color = Color(1, 1, 1, 1) + +[node name="Onboarding" type="Control" node_paths=PackedStringArray("root")] top_level = true z_index = 10 layout_mode = 3 @@ -26,7 +38,6 @@ grow_vertical = 2 mouse_filter = 2 script = ExtResource("1_2xh2a") root = NodePath("Root") -skip = NodePath("Root/Popup/MarginContainer/VBoxContainer/HBoxContainer/Hide") [node name="Root" type="Control" parent="."] layout_mode = 1 @@ -37,6 +48,7 @@ grow_horizontal = 2 grow_vertical = 2 [node name="Panel" type="Panel" parent="Root"] +visible = false layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 @@ -46,70 +58,74 @@ grow_vertical = 2 mouse_filter = 2 theme_override_styles/panel = SubResource("StyleBoxFlat_htqsi") -[node name="Popup" type="AspectRatioContainer" parent="Root"] +[node name="VignetteBlur" type="Panel" parent="Root"] +material = SubResource("ShaderMaterial_hpwdi") layout_mode = 1 -anchors_preset = 8 -anchor_left = 0.5 -anchor_top = 0.5 -anchor_right = 0.5 -anchor_bottom = 0.5 -offset_left = -533.0 -offset_top = -356.5 -offset_right = 533.0 -offset_bottom = 356.5 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 -ratio = 1.35 +mouse_filter = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_2l2ws") -[node name="Panel" type="Panel" parent="Root/Popup"] -layout_mode = 2 -theme_override_styles/panel = ExtResource("2_mnljw") +[node name="Carousel" type="Control" parent="Root" node_paths=PackedStringArray("line")] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("2_uhwdh") +ui_events = ExtResource("3_jta5g") +line = NodePath("Line") +tween_duration = 0.3 -[node name="MarginContainer" type="MarginContainer" parent="Root/Popup"] -layout_mode = 2 -mouse_filter = 0 -theme_override_constants/margin_top = 24 -theme_override_constants/margin_bottom = 24 +[node name="Line" type="Control" parent="Root/Carousel"] +layout_mode = 1 +anchors_preset = 14 +anchor_top = 0.5 +anchor_right = 1.0 +anchor_bottom = 0.5 +offset_left = 676.0 +offset_top = -350.0 +offset_right = 756.0 +offset_bottom = 350.0 +grow_horizontal = 2 +grow_vertical = 2 -[node name="VBoxContainer" type="VBoxContainer" parent="Root/Popup/MarginContainer"] +[node name="Board" parent="Root/Carousel/Line" instance=ExtResource("3_04ofy")] layout_mode = 2 -theme_override_constants/separation = 20 +anchors_preset = 0 +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +offset_left = 0.0 +offset_top = 0.0 +offset_right = 600.0 +offset_bottom = 700.0 -[node name="Label" type="Label" parent="Root/Popup/MarginContainer/VBoxContainer"] +[node name="Board2" parent="Root/Carousel/Line" instance=ExtResource("3_04ofy")] layout_mode = 2 -text = "Gate is not responding" -label_settings = ExtResource("3_3pufm") -horizontal_alignment = 1 -vertical_alignment = 1 +anchors_preset = 0 +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +offset_left = 650.0 +offset_top = 0.0 +offset_right = 1250.0 +offset_bottom = 700.0 -[node name="Label2" type="Label" parent="Root/Popup/MarginContainer/VBoxContainer"] +[node name="Board3" parent="Root/Carousel/Line" instance=ExtResource("3_04ofy")] layout_mode = 2 -text = "Reload the page or try -to wait if it responses" -label_settings = SubResource("LabelSettings_bkr01") -horizontal_alignment = 1 - -[node name="HBoxContainer" type="HBoxContainer" parent="Root/Popup/MarginContainer/VBoxContainer"] -layout_mode = 2 -size_flags_horizontal = 4 -theme_override_constants/separation = 22 - -[node name="Reload" parent="Root/Popup/MarginContainer/VBoxContainer/HBoxContainer" instance=ExtResource("5_tk3ti")] -custom_minimum_size = Vector2(90, 26) -layout_mode = 2 -theme_override_colors/font_disabled_color = Color(0.431373, 0.435294, 0.494118, 1) -theme_override_colors/font_color = Color(0.831373, 0.831373, 0.831373, 1) -theme_override_fonts/font = ExtResource("4_bi8o3") -theme_override_font_sizes/font_size = 20 -text = "Reload" -icon = null - -[node name="Hide" parent="Root/Popup/MarginContainer/VBoxContainer/HBoxContainer" instance=ExtResource("5_tk3ti")] -custom_minimum_size = Vector2(90, 26) -layout_mode = 2 -theme_override_colors/font_disabled_color = Color(0.431373, 0.435294, 0.494118, 1) -theme_override_colors/font_color = Color(0.831373, 0.831373, 0.831373, 1) -theme_override_fonts/font = ExtResource("4_bi8o3") -theme_override_font_sizes/font_size = 20 -text = "Wait" -icon = null +anchors_preset = 0 +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +offset_left = 1300.0 +offset_top = 0.0 +offset_right = 1900.0 +offset_bottom = 700.0 diff --git a/app/scenes/menu_body/home.tscn b/app/scenes/menu_body/home.tscn index ea7d79b..3f8f106 100644 --- a/app/scenes/menu_body/home.tscn +++ b/app/scenes/menu_body/home.tscn @@ -180,9 +180,9 @@ size_flags_horizontal = 3 [node name="MaxSizeContainer2" type="MarginContainer" parent="MarginContainer/ScrollContainer/VBoxContainer/HBoxContainer/VBoxContainer"] custom_minimum_size = Vector2(300, 44) layout_mode = 2 -theme_override_constants/margin_left = 393 +theme_override_constants/margin_left = 0 theme_override_constants/margin_top = 0 -theme_override_constants/margin_right = 393 +theme_override_constants/margin_right = 0 theme_override_constants/margin_bottom = 0 script = ExtResource("2_ceb6w") limit = Vector2(720, -1) @@ -199,9 +199,9 @@ custom_minimum_size = Vector2(180, 400) layout_mode = 2 size_flags_horizontal = 3 size_flags_stretch_ratio = 2.0 -theme_override_constants/margin_left = 278 +theme_override_constants/margin_left = 0 theme_override_constants/margin_top = 0 -theme_override_constants/margin_right = 278 +theme_override_constants/margin_right = 0 theme_override_constants/margin_bottom = 0 script = ExtResource("2_ceb6w") limit = Vector2(950, -1) diff --git a/app/scenes/menu_body/world.tscn b/app/scenes/menu_body/world.tscn index 927688a..c1e3119 100644 --- a/app/scenes/menu_body/world.tscn +++ b/app/scenes/menu_body/world.tscn @@ -40,7 +40,7 @@ shader_parameter/show_render = null _data = [Vector2(0.0876494, 0.913189), 0.0, -0.118897, 0, 0, Vector2(0.50996, 0.316361), -1.65368, -1.65368, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0] point_count = 3 -[sub_resource type="CurveTexture" id="CurveTexture_fomqh"] +[sub_resource type="CurveTexture" id="CurveTexture_e4qvr"] curve = SubResource("Curve_rju31") [sub_resource type="ShaderMaterial" id="ShaderMaterial_bspld"] @@ -48,7 +48,7 @@ shader = ExtResource("18_sat0u") shader_parameter/UVScale = Vector2(0.9, 0.9) shader_parameter/BlurAmount = 2.5 shader_parameter/VignetteColor = Color(0.126, 0.1719, 0.18, 1) -shader_parameter/Vignette = SubResource("CurveTexture_fomqh") +shader_parameter/Vignette = SubResource("CurveTexture_e4qvr") [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_axrau"] bg_color = Color(1, 1, 1, 1) diff --git a/app/scripts/ui/onboarding/board.gd b/app/scripts/ui/onboarding/board.gd new file mode 100644 index 0000000..93cac06 --- /dev/null +++ b/app/scripts/ui/onboarding/board.gd @@ -0,0 +1,37 @@ +extends Control +class_name OnboardingBoard + +signal request_focus + +@export var focus_button: TextureButton +@export var unfocus_color: Color +@export var unfocus_scale: Vector2 + +var tween: Tween + + +func _ready() -> void: + focus_button.pressed.connect(func(): request_focus.emit()) + focus_button.visible = false + + +func focus(tween_duration: float) -> void: + if is_instance_valid(tween): tween.stop() + tween = create_tween() + tween.set_parallel(true) + + tween.tween_property(self, "scale", Vector2.ONE, tween_duration).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT) + tween.tween_property(self, "modulate", Color.WHITE, tween_duration).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT) + + focus_button.visible = false + + +func unfocus(tween_duration: float) -> void: + if is_instance_valid(tween): tween.stop() + tween = create_tween() + tween.set_parallel(true) + + tween.tween_property(self, "scale", unfocus_scale, tween_duration).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT) + tween.tween_property(self, "modulate", unfocus_color, tween_duration).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT) + + focus_button.visible = true diff --git a/app/scripts/ui/onboarding/carousel.gd b/app/scripts/ui/onboarding/carousel.gd new file mode 100644 index 0000000..28d1ed2 --- /dev/null +++ b/app/scripts/ui/onboarding/carousel.gd @@ -0,0 +1,42 @@ +extends Control + +@export var ui_events: UiEvents +@export var line: Control +@export var tween_duration: float + +var boards: Array[OnboardingBoard] = [] +var focused_page: int +var tween: Tween + + +func _ready() -> void: + setup_boards() + assert(boards.size() > 0, "Carousel must have at least one board") + + move_line(0) + + +func setup_boards() -> void: + for child in line.get_children(): + boards.append(child as OnboardingBoard) + + for i in range(boards.size()): + boards[i].request_focus.connect(move_line.bind(i)) + + +func move_line(board_index: int) -> void: + var board = boards[board_index] + focused_page = board_index + + var screen_center = ui_events.current_ui_size.x / 2 + var wanted_board_position = screen_center - board.size.x / 2 + var line_position = Vector2(wanted_board_position - board.position.x, line.position.y) + + if is_instance_valid(tween): tween.stop() + tween = create_tween() + tween.tween_property(line, "position", line_position, tween_duration).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT) + + for i in range(boards.size()): + if i == board_index: + boards[i].focus(tween_duration) + else: boards[i].unfocus(tween_duration) diff --git a/app/scripts/ui/onboarding/onboarding.gd b/app/scripts/ui/onboarding/onboarding.gd index 37fce73..ba85a25 100644 --- a/app/scripts/ui/onboarding/onboarding.gd +++ b/app/scripts/ui/onboarding/onboarding.gd @@ -1,26 +1,27 @@ extends Control -@export var root: Control -@export var skip: Button -@export var fade_in: float = 1.0 -@export var fade_out: float = 0.2 - +const INITIAL_DELAY = 1.0 const SHOWN = Color(1, 1, 1, 1) const HIDDEN = Color(1, 1, 1, 0) +@export var root: Control +# @export var skip: Button +@export var fade_in: float = 0.2 +@export var fade_out: float = 0.2 + var tween: Tween func _ready() -> void: - skip.pressed.connect(hide_onboarding) + # skip.pressed.connect(hide_onboarding) visible = true root.hide() root.modulate = HIDDEN root.mouse_filter = Control.MOUSE_FILTER_PASS - await get_tree().create_timer(1.0).timeout - #show_onboarding() + await get_tree().create_timer(INITIAL_DELAY).timeout + show_onboarding() func show_onboarding() -> void: @@ -29,7 +30,7 @@ func show_onboarding() -> void: root.show() if is_instance_valid(tween): tween.stop() - tween = get_tree().create_tween() + tween = create_tween() tween.tween_property(root, "modulate", SHOWN, fade_in) await tween.finished @@ -42,7 +43,7 @@ func hide_onboarding() -> void: root.mouse_filter = Control.MOUSE_FILTER_PASS if is_instance_valid(tween): tween.stop() - tween = get_tree().create_tween() + tween = create_tween() tween.tween_property(root, "modulate", HIDDEN, fade_out) await tween.finished