mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-01-31 07:29:49 +00:00
Add a basic stabilizer
Not as powerful as other art software, but should be enough for pixel art
This commit is contained in:
parent
1b22e75034
commit
d2734ab044
|
@ -1465,6 +1465,10 @@ msgstr ""
|
|||
msgid "Dynamics"
|
||||
msgstr ""
|
||||
|
||||
#. Found in the Dynamics options menu. A stabilizer is a feature that, when enabled, helps artists create smooth lines as they draw.
|
||||
msgid "Stabilizer"
|
||||
msgstr ""
|
||||
|
||||
#. Found in the Dynamics options menu. Pressure refers to tablet pen pressure.
|
||||
msgid "Pressure"
|
||||
msgstr ""
|
||||
|
|
|
@ -9,6 +9,8 @@ var vertical_mirror := false
|
|||
var pixel_perfect := false
|
||||
|
||||
# Dynamics
|
||||
var stabilizer_enabled := false
|
||||
var stabilizer_value := 16
|
||||
var dynamics_alpha: int = Dynamics.NONE
|
||||
var dynamics_size: int = Dynamics.NONE
|
||||
var pen_pressure := 1.0
|
||||
|
|
|
@ -6,6 +6,7 @@ var kname: String
|
|||
var tool_slot: Tools.Slot = null
|
||||
var cursor_text := ""
|
||||
var _cursor := Vector2i(Vector2.INF)
|
||||
var _stabilizer_center := Vector2.ZERO
|
||||
|
||||
var _draw_cache: Array[Vector2i] = [] ## For storing already drawn pixels
|
||||
@warning_ignore("unused_private_class_variable")
|
||||
|
@ -54,6 +55,7 @@ func update_config() -> void:
|
|||
|
||||
|
||||
func draw_start(pos: Vector2i) -> void:
|
||||
_stabilizer_center = pos
|
||||
_draw_cache = []
|
||||
is_moving = true
|
||||
Global.current_project.can_undo = false
|
||||
|
@ -260,6 +262,17 @@ func _snap_to_guide(
|
|||
return snap_to
|
||||
|
||||
|
||||
func _get_stabilized_position(normal_pos: Vector2) -> Vector2:
|
||||
if not Tools.stabilizer_enabled:
|
||||
return normal_pos
|
||||
var difference := normal_pos - _stabilizer_center
|
||||
var distance := difference.length() / Tools.stabilizer_value
|
||||
var angle := difference.angle()
|
||||
var pos := _stabilizer_center + Vector2(distance, distance) * Vector2.from_angle(angle)
|
||||
_stabilizer_center = pos
|
||||
return pos
|
||||
|
||||
|
||||
func _get_draw_rect() -> Rect2i:
|
||||
if Global.current_project.has_selection:
|
||||
return Global.current_project.selection_map.get_used_rect()
|
||||
|
|
|
@ -318,7 +318,7 @@ func _draw_tool(pos: Vector2) -> PackedVector2Array:
|
|||
|
||||
# Bresenham's Algorithm
|
||||
# Thanks to https://godotengine.org/qa/35276/tile-based-line-drawing-algorithm-efficiency
|
||||
func draw_fill_gap(start: Vector2, end: Vector2) -> void:
|
||||
func draw_fill_gap(start: Vector2i, end: Vector2i) -> void:
|
||||
if Global.mirror_view:
|
||||
# Even brushes are not perfectly centred and are offsetted by 1 px so we add it
|
||||
if int(_stroke_dimensions.x) % 2 == 0:
|
||||
|
|
|
@ -66,11 +66,12 @@ func draw_start(pos: Vector2i) -> void:
|
|||
cursor_text = ""
|
||||
|
||||
|
||||
func draw_move(pos: Vector2i) -> void:
|
||||
func draw_move(pos_i: Vector2i) -> void:
|
||||
var pos := _get_stabilized_position(pos_i)
|
||||
pos = snap_position(pos)
|
||||
super.draw_move(pos)
|
||||
if _picking_color: # Still return even if we released Alt
|
||||
if Input.is_action_pressed("draw_color_picker"):
|
||||
if Input.is_action_pressed(&"draw_color_picker"):
|
||||
_pick_color(pos)
|
||||
return
|
||||
|
||||
|
|
|
@ -131,11 +131,12 @@ func draw_start(pos: Vector2i) -> void:
|
|||
cursor_text = ""
|
||||
|
||||
|
||||
func draw_move(pos: Vector2i) -> void:
|
||||
func draw_move(pos_i: Vector2i) -> void:
|
||||
var pos := _get_stabilized_position(pos_i)
|
||||
pos = snap_position(pos)
|
||||
super.draw_move(pos)
|
||||
if _picking_color: # Still return even if we released Alt
|
||||
if Input.is_action_pressed("draw_color_picker"):
|
||||
if Input.is_action_pressed(&"draw_color_picker"):
|
||||
_pick_color(pos)
|
||||
return
|
||||
|
||||
|
|
|
@ -12,9 +12,10 @@ func draw_start(pos: Vector2i) -> void:
|
|||
_last_position = pos
|
||||
|
||||
|
||||
func draw_move(pos: Vector2i) -> void:
|
||||
func draw_move(pos_i: Vector2i) -> void:
|
||||
if selection_node.arrow_key_move:
|
||||
return
|
||||
var pos := _get_stabilized_position(pos_i)
|
||||
pos = snap_position(pos)
|
||||
super.draw_move(pos)
|
||||
if !_move:
|
||||
|
@ -28,8 +29,6 @@ func draw_end(pos: Vector2i) -> void:
|
|||
if selection_node.arrow_key_move:
|
||||
return
|
||||
pos = snap_position(pos)
|
||||
if !_move:
|
||||
_draw_points.append(pos)
|
||||
super.draw_end(pos)
|
||||
|
||||
|
||||
|
|
|
@ -40,9 +40,10 @@ func draw_start(pos: Vector2i) -> void:
|
|||
_last_position = pos
|
||||
|
||||
|
||||
func draw_move(pos: Vector2i) -> void:
|
||||
func draw_move(pos_i: Vector2i) -> void:
|
||||
if selection_node.arrow_key_move:
|
||||
return
|
||||
var pos := _get_stabilized_position(pos_i)
|
||||
pos = snap_position(pos)
|
||||
super.draw_move(pos)
|
||||
if !_move:
|
||||
|
@ -56,8 +57,6 @@ func draw_end(pos: Vector2i) -> void:
|
|||
if selection_node.arrow_key_move:
|
||||
return
|
||||
pos = snap_position(pos)
|
||||
if !_move:
|
||||
_draw_points.append_array(draw_tool(pos))
|
||||
super.draw_end(pos)
|
||||
|
||||
|
||||
|
|
|
@ -237,11 +237,12 @@ func draw_start(pos: Vector2i) -> void:
|
|||
cursor_text = ""
|
||||
|
||||
|
||||
func draw_move(pos: Vector2i) -> void:
|
||||
func draw_move(pos_i: Vector2i) -> void:
|
||||
var pos := _get_stabilized_position(pos_i)
|
||||
pos = snap_position(pos)
|
||||
super.draw_move(pos)
|
||||
if _picking_color: # Still return even if we released Alt
|
||||
if Input.is_action_pressed("draw_color_picker"):
|
||||
if Input.is_action_pressed(&"draw_color_picker"):
|
||||
_pick_color(pos)
|
||||
return
|
||||
|
||||
|
|
|
@ -153,3 +153,11 @@ func _on_SizeMin_value_changed(value: float) -> void:
|
|||
func _on_SizeMax_value_changed(value: float) -> void:
|
||||
Tools.brush_size_max = int(value)
|
||||
dynamics_changed.emit()
|
||||
|
||||
|
||||
func _on_enable_stabilizer_toggled(toggled_on: bool) -> void:
|
||||
Tools.stabilizer_enabled = toggled_on
|
||||
|
||||
|
||||
func _on_stabilizer_value_value_changed(value: float) -> void:
|
||||
Tools.stabilizer_value = value
|
||||
|
|
|
@ -45,7 +45,6 @@ gradient = SubResource("3")
|
|||
gradient = SubResource("3")
|
||||
|
||||
[node name="Global Tool Options" type="PanelContainer"]
|
||||
custom_minimum_size = Vector2(0, 36)
|
||||
offset_left = 1.0
|
||||
offset_right = 195.0
|
||||
offset_bottom = 50.0
|
||||
|
@ -147,12 +146,38 @@ texture = ExtResource("6")
|
|||
|
||||
[node name="DynamicsPanel" type="PopupPanel" parent="."]
|
||||
canvas_item_default_texture_filter = 0
|
||||
size = Vector2i(300, 334)
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="DynamicsPanel"]
|
||||
offset_left = 4.0
|
||||
offset_top = 4.0
|
||||
offset_right = 186.0
|
||||
offset_bottom = 288.0
|
||||
offset_left = 8.0
|
||||
offset_top = 8.0
|
||||
offset_right = 292.0
|
||||
offset_bottom = 326.0
|
||||
|
||||
[node name="StabilizerContainer" type="HBoxContainer" parent="DynamicsPanel/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="EnableStabilizer" type="CheckButton" parent="DynamicsPanel/VBoxContainer/StabilizerContainer"]
|
||||
layout_mode = 2
|
||||
mouse_default_cursor_shape = 2
|
||||
text = "Stabilizer"
|
||||
|
||||
[node name="StabilizerValue" type="TextureProgressBar" parent="DynamicsPanel/VBoxContainer/StabilizerContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 2
|
||||
mouse_default_cursor_shape = 2
|
||||
theme_type_variation = &"ValueSlider"
|
||||
min_value = 1.0
|
||||
max_value = 64.0
|
||||
value = 16.0
|
||||
allow_greater = true
|
||||
nine_patch_stretch = true
|
||||
stretch_margin_left = 3
|
||||
stretch_margin_top = 3
|
||||
stretch_margin_right = 3
|
||||
stretch_margin_bottom = 3
|
||||
script = ExtResource("5")
|
||||
|
||||
[node name="DynamicsOptions" type="GridContainer" parent="DynamicsPanel/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
@ -412,6 +437,8 @@ offset_bottom = 23.0
|
|||
[connection signal="toggled" from="ScrollContainer/CenterContainer/GridContainer/Vertical" to="." method="_on_Vertical_toggled"]
|
||||
[connection signal="toggled" from="ScrollContainer/CenterContainer/GridContainer/PixelPerfect" to="." method="_on_PixelPerfect_toggled"]
|
||||
[connection signal="pressed" from="ScrollContainer/CenterContainer/GridContainer/Dynamics" to="." method="_on_Dynamics_pressed"]
|
||||
[connection signal="toggled" from="DynamicsPanel/VBoxContainer/StabilizerContainer/EnableStabilizer" to="." method="_on_enable_stabilizer_toggled"]
|
||||
[connection signal="value_changed" from="DynamicsPanel/VBoxContainer/StabilizerContainer/StabilizerValue" to="." method="_on_stabilizer_value_value_changed"]
|
||||
[connection signal="value_changed" from="DynamicsPanel/VBoxContainer/LimitContainer/AlphaMin" to="." method="_on_AlphaMin_value_changed"]
|
||||
[connection signal="value_changed" from="DynamicsPanel/VBoxContainer/LimitContainer/AlphaMax" to="." method="_on_AlphaMax_value_changed"]
|
||||
[connection signal="value_changed" from="DynamicsPanel/VBoxContainer/LimitContainer/SizeMin" to="." method="_on_SizeMin_value_changed"]
|
||||
|
|
Loading…
Reference in a new issue