1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-01-18 17:19:50 +00:00

Add an offset image effect

Some functionality as the move tool, but with more precision, wrap around ability and of course animation.
This commit is contained in:
Emmanouil Papadeas 2023-07-04 03:29:58 +03:00
parent 81c0b49c59
commit 08064098b8
8 changed files with 172 additions and 3 deletions

View file

@ -148,6 +148,16 @@ msgstr ""
msgid "Resize Canvas"
msgstr ""
msgid "Offset Image"
msgstr ""
msgid "Offset:"
msgstr ""
#. Found in the Offset Image dialog. It's a checkbox that, if enabled, wraps around the image if pixels go out of canvas bounds.
msgid "Wrap around:"
msgstr ""
msgid "Centralize Image"
msgstr ""

View file

@ -25,6 +25,7 @@ enum ViewMenu {
enum WindowMenu { WINDOW_OPACITY, PANELS, LAYOUTS, MOVABLE_PANELS, ZEN_MODE, FULLSCREEN_MODE }
enum ImageMenu {
RESIZE_CANVAS,
OFFSET_IMAGE,
SCALE_IMAGE,
CROP_IMAGE,
FLIP,

View file

@ -1,7 +1,7 @@
class_name ImageEffect
extends ConfirmationDialog
# Parent class for all image effects
# Methods that have "pass" are meant to be replaced by the inherited Scripts
## Parent class for all image effects
## Methods that have "pass" are meant to be replaced by the inherited scripts
enum { SELECTED_CELS, FRAME, ALL_FRAMES, ALL_PROJECTS }

View file

@ -0,0 +1,24 @@
shader_type canvas_item;
uniform sampler2D selection;
uniform vec2 offset = vec2(0.0); // In pixels
uniform bool wrap_around = false;
void fragment() {
vec4 original_color = texture(TEXTURE, UV);
vec4 selection_color = texture(selection, UV);
vec2 uv = UV - (offset * TEXTURE_PIXEL_SIZE); // Offset the uv by an amount of pixels
if (wrap_around) {
uv = fract(uv);
}
vec4 output = texture(TEXTURE, uv);
// Cut original selected content
original_color.a = 0.0 * step(0.5, selection_color.a) + original_color.a * step(selection_color.a, 0.5);
output.a = min(step(uv.x, 1.0) * step(0.0, uv.x), output.a); // Remove left and right edges
output.a = min(step(uv.y, 1.0) * step(0.0, uv.y), output.a); // Remove up and bottom edges
selection_color = texture(selection, uv);
COLOR = mix(original_color, output, selection_color.a);
}

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=14 format=2]
[gd_scene load_steps=15 format=2]
[ext_resource path="res://src/UI/Dialogs/ImageEffects/FlipImageDialog.tscn" type="PackedScene" id=1]
[ext_resource path="res://src/UI/Dialogs/ImageEffects/InvertColorsDialog.tscn" type="PackedScene" id=2]
@ -6,6 +6,7 @@
[ext_resource path="res://src/UI/Dialogs/ImageEffects/DropShadowDialog.tscn" type="PackedScene" id=4]
[ext_resource path="res://src/UI/Dialogs/ImageEffects/GradientMapDialog.tscn" type="PackedScene" id=5]
[ext_resource path="res://src/UI/Dialogs/ImageEffects/Posterize.tscn" type="PackedScene" id=6]
[ext_resource path="res://src/UI/Dialogs/ImageEffects/OffsetImage.tscn" type="PackedScene" id=7]
[ext_resource path="res://src/UI/Dialogs/ImageEffects/ResizeCanvas.tscn" type="PackedScene" id=8]
[ext_resource path="res://src/UI/Dialogs/ImageEffects/RotateImage.tscn" type="PackedScene" id=9]
[ext_resource path="res://src/UI/Dialogs/ImageEffects/ShaderEffect.tscn" type="PackedScene" id=10]
@ -17,6 +18,10 @@
[node name="ImageEffects" type="Control"]
mouse_filter = 2
[node name="OffsetImage" parent="." instance=ExtResource( 7 )]
margin_right = 376.0
margin_bottom = 370.0
[node name="ScaleImage" parent="." instance=ExtResource( 14 )]
margin_bottom = 127.0

View file

@ -0,0 +1,54 @@
extends ImageEffect
enum Animate { OFFSET_X, OFFSET_Y }
var shader: Shader = preload("res://src/Shaders/OffsetPixels.gdshader")
var wrap_around := false
onready var offset_sliders := $VBoxContainer/OffsetOptions/OffsetSliders as ValueSliderV2
func _ready() -> void:
var sm := ShaderMaterial.new()
sm.shader = shader
preview.set_material(sm)
# Set as in the Animate enum
animate_panel.add_float_property(
"Offset X", $VBoxContainer/OffsetOptions/OffsetSliders.get_sliders()[0]
)
animate_panel.add_float_property(
"Offset Y", $VBoxContainer/OffsetOptions/OffsetSliders.get_sliders()[1]
)
func _about_to_show() -> void:
offset_sliders.min_value = -Global.current_project.size
offset_sliders.max_value = Global.current_project.size
._about_to_show()
func commit_action(cel: Image, project: Project = Global.current_project) -> void:
var offset_x := animate_panel.get_animated_value(commit_idx, Animate.OFFSET_X)
var offset_y := animate_panel.get_animated_value(commit_idx, Animate.OFFSET_Y)
var offset := Vector2(offset_x, offset_y)
var selection_tex := ImageTexture.new()
if selection_checkbox.pressed and project.has_selection:
selection_tex.create_from_image(project.selection_map, 0)
var params := {"offset": offset, "wrap_around": wrap_around, "selection": selection_tex}
if !confirmed:
for param in params:
preview.material.set_shader_param(param, params[param])
else:
var gen := ShaderImageEffect.new()
gen.generate_image(cel, shader, params, project.size)
yield(gen, "done")
func _on_OffsetSliders_value_changed(_value: Vector2) -> void:
update_preview()
func _on_WrapCheckBox_toggled(button_pressed: bool) -> void:
wrap_around = button_pressed
update_preview()

View file

@ -0,0 +1,71 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://src/UI/Dialogs/ImageEffects/ImageEffectParent.tscn" type="PackedScene" id=1]
[ext_resource path="res://src/UI/Nodes/ValueSliderV2.tscn" type="PackedScene" id=2]
[ext_resource path="res://src/UI/Dialogs/ImageEffects/OffsetImage.gd" type="Script" id=3]
[node name="OffsetImage" instance=ExtResource( 1 )]
window_title = "Offset Image"
script = ExtResource( 3 )
[node name="VBoxContainer" parent="." index="3"]
margin_bottom = 344.0
[node name="AspectRatioContainer" parent="VBoxContainer" index="1"]
margin_bottom = 224.0
[node name="Preview" parent="VBoxContainer/AspectRatioContainer" index="0"]
margin_left = 80.0
margin_right = 280.0
margin_bottom = 200.0
[node name="OffsetOptions" type="GridContainer" parent="VBoxContainer" index="2"]
margin_top = 228.0
margin_right = 360.0
margin_bottom = 308.0
columns = 2
[node name="OffsetLabel" type="Label" parent="VBoxContainer/OffsetOptions" index="0"]
margin_top = 19.0
margin_right = 178.0
margin_bottom = 33.0
size_flags_horizontal = 3
text = "Offset:"
[node name="OffsetSliders" parent="VBoxContainer/OffsetOptions" index="1" instance=ExtResource( 2 )]
margin_left = 182.0
margin_right = 360.0
size_flags_horizontal = 3
min_value = Vector2( -64, -64 )
max_value = Vector2( 64, 64 )
allow_greater = true
allow_lesser = true
show_ratio = true
suffix_x = "px"
suffix_y = "px"
[node name="WrapLabel" type="Label" parent="VBoxContainer/OffsetOptions" index="2"]
margin_top = 61.0
margin_right = 178.0
margin_bottom = 75.0
size_flags_horizontal = 3
text = "Wrap around:"
[node name="WrapCheckBox" type="CheckBox" parent="VBoxContainer/OffsetOptions" index="3"]
margin_left = 182.0
margin_top = 56.0
margin_right = 360.0
margin_bottom = 80.0
mouse_default_cursor_shape = 2
size_flags_horizontal = 3
text = "On"
[node name="OptionsContainer" parent="VBoxContainer" index="3"]
margin_top = 312.0
margin_bottom = 336.0
[node name="AnimateDialog" parent="." index="4"]
margin_bottom = 344.0
[connection signal="value_changed" from="VBoxContainer/OffsetOptions/OffsetSliders" to="." method="_on_OffsetSliders_value_changed"]
[connection signal="toggled" from="VBoxContainer/OffsetOptions/WrapCheckBox" to="." method="_on_WrapCheckBox_toggled"]

View file

@ -273,6 +273,7 @@ func _setup_image_menu() -> void:
# Order as in Global.ImageMenu enum
var image_menu_items := [
"Resize Canvas",
"Offset Image",
"Scale Image",
"Crop Image",
"Mirror Image",
@ -650,6 +651,9 @@ func image_menu_id_pressed(id: int) -> void:
Global.ImageMenu.SCALE_IMAGE:
_popup_dialog(Global.control.get_node("Dialogs/ImageEffects/ScaleImage"))
Global.ImageMenu.OFFSET_IMAGE:
_popup_dialog(Global.control.get_node("Dialogs/ImageEffects/OffsetImage"))
Global.ImageMenu.CENTRALIZE_IMAGE:
DrawingAlgos.centralize()