@tool extends MarginContainer class_name CardVisualiser signal clicked(c: CardVisualiser) const MAX_ROT = 15 const ZOOM_SCALE = 1.2 const MARGIN = 25 var wanted_rot : Vector2 = Vector2.ZERO var real_rot : Vector2 = Vector2.ZERO var is_ready = false @export var card_width : int = 250 : set(v): card_width = v if is_ready : update() @export var small_mode : bool = true : set(v): var old = small_mode small_mode = v if is_ready and old != small_mode : update() @export var interactive_small_mode : bool = true @export var interactive_zoom : bool = false @export var down_arrow : bool = true : set(v): var old = down_arrow down_arrow = v if is_ready and old != down_arrow : update() @export var card_info : CardInfo = null : set(v): var old = card_info card_info = v if is_ready and old != card_info: update() @export_tool_button("Update", "Callable") var update_action = update var updated_on_last_frame = false func _input(event): if event.is_action_pressed("action") and is_mouse_over(): clicked.emit(self) func _ready(): %SubViewportContainer.material = %SubViewportContainer.material.duplicate() update() is_ready = true func _process(_d): var center_relative_mouse_position = (get_local_mouse_position() - size/2) / size if is_mouse_over(): wanted_rot = center_relative_mouse_position * MAX_ROT if interactive_small_mode: small_mode = false if interactive_zoom: scale = scale.lerp(Vector2.ONE * ZOOM_SCALE, 0.2) else: wanted_rot = Vector2.ZERO if interactive_small_mode: small_mode = true if interactive_zoom: scale = scale.lerp(Vector2.ONE, 0.2) real_rot = real_rot.lerp(wanted_rot, 0.1) %SubViewportContainer.material.set_shader_parameter("y_rot", - real_rot.x) %SubViewportContainer.material.set_shader_parameter("x_rot", real_rot.y) %Card.custom_minimum_size.x = card_width %CardContainer.size = Vector2.ZERO %SubViewport.size = %CardContainer.size %SubViewportContainer.size = %SubViewport.size size = %SubViewportContainer.size - (Vector2.ONE * MARGIN * 2) func is_mouse_over() -> bool: var center_relative_mouse_position = (get_local_mouse_position() - size/2) / size return ( abs(center_relative_mouse_position.x) < 0.5 and abs(center_relative_mouse_position.y) < 0.5 ) func update(): if card_info: %Card.info = card_info %Card.small_mode = small_mode %Card.down_arrow = down_arrow %Card.update() updated_on_last_frame = true