1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-01-19 17:49:47 +00:00
Pixelorama/src/Tools/Eraser.gd
Emmanouil Papadeas d2734ab044 Add a basic stabilizer
Not as powerful as other art software, but should be enough for pixel art
2023-12-04 14:55:38 +02:00

145 lines
3.6 KiB
GDScript

extends "res://src/Tools/Draw.gd"
var _last_position := Vector2.INF
var _clear_image: Image
var _changed := false
class EraseOp:
extends Drawer.ColorOp
var changed := false
func process(_src: Color, dst: Color) -> Color:
changed = true
dst.a -= strength
if dst.a <= 0:
dst = Color(0, 0, 0, 0)
return dst
func _init() -> void:
_drawer.color_op = EraseOp.new()
_clear_image = Image.create(1, 1, false, Image.FORMAT_RGBA8)
_clear_image.fill(Color(0, 0, 0, 0))
func get_config() -> Dictionary:
var config := super.get_config()
config["strength"] = _strength
return config
func set_config(config: Dictionary) -> void:
super.set_config(config)
_strength = config.get("strength", _strength)
func draw_start(pos: Vector2i) -> void:
pos = snap_position(pos)
super.draw_start(pos)
if Input.is_action_pressed("draw_color_picker"):
_picking_color = true
_pick_color(pos)
return
_picking_color = false
Global.canvas.selection.transform_content_confirm()
update_mask(_strength == 1)
_changed = false
_drawer.color_op.changed = false
prepare_undo("Draw")
_drawer.reset()
_draw_line = Input.is_action_pressed("draw_create_line")
if _draw_line:
if Global.mirror_view:
# mirroring position is ONLY required by "Preview"
pos.x = (Global.current_project.size.x - 1) - pos.x
_line_start = pos
_line_end = pos
update_line_polylines(_line_start, _line_end)
else:
draw_tool(pos)
_last_position = pos
Global.canvas.sprite_changed_this_frame = true
cursor_text = ""
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"):
_pick_color(pos)
return
if _draw_line:
if Global.mirror_view:
# mirroring position is ONLY required by "Preview"
pos.x = (Global.current_project.size.x - 1) - pos.x
var d := _line_angle_constraint(_line_start, pos)
_line_end = d.position
cursor_text = d.text
update_line_polylines(_line_start, _line_end)
else:
draw_fill_gap(_last_position, pos)
_last_position = pos
cursor_text = ""
Global.canvas.sprite_changed_this_frame = true
func draw_end(pos: Vector2i) -> void:
pos = snap_position(pos)
super.draw_end(pos)
if _picking_color:
return
if _draw_line:
if Global.mirror_view:
# now we revert back the coordinates from their mirror form so that line can be drawn
_line_start.x = (Global.current_project.size.x - 1) - _line_start.x
_line_end.x = (Global.current_project.size.x - 1) - _line_end.x
draw_tool(_line_start)
draw_fill_gap(_line_start, _line_end)
_draw_line = false
commit_undo()
cursor_text = ""
update_random_image()
func _draw_brush_image(image: Image, src_rect: Rect2i, dst: Vector2i) -> void:
_changed = true
if _strength == 1:
var brush_size := image.get_size()
if _clear_image.get_size() != brush_size:
_clear_image.resize(brush_size.x, brush_size.y, Image.INTERPOLATE_NEAREST)
var images := _get_selected_draw_images()
for draw_image in images:
draw_image.blit_rect_mask(_clear_image, image, src_rect, dst)
else:
for xx in image.get_size().x:
for yy in image.get_size().y:
if image.get_pixel(xx, yy).a > 0:
var pos := Vector2i(xx, yy) + dst - src_rect.position
_set_pixel(pos, true)
func _on_Opacity_value_changed(value: float) -> void:
_strength = value / 255
update_config()
save_config()
func update_config() -> void:
super.update_config()
$OpacitySlider.value = _strength * 255
func update_brush() -> void:
super.update_brush()
$ColorInterpolation.visible = false