mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-01-18 17:19:50 +00:00
Make FPS project-specific and store it in the pxo files
This commit is contained in:
parent
05c9ef70d4
commit
031efc0cdb
15
CHANGELOG.md
15
CHANGELOG.md
|
@ -4,10 +4,23 @@ All notable changes to this project will be documented in this file.
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). All the dates are in YYYY-MM-DD format.
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). All the dates are in YYYY-MM-DD format.
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
This update has been brought to you by the contributions of:
|
||||||
|
|
||||||
|
Laurenz Reinthaler (Schweini07)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- The FPS of the project animation is now stored in the pxo file.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- CPU usage has been significantly been lowered when Pixelorama is idle. ([#394](https://github.com/Orama-Interactive/Pixelorama/pull/394))
|
||||||
|
<br><br>
|
||||||
|
|
||||||
## [v0.8.2] - 2020-12-12
|
## [v0.8.2] - 2020-12-12
|
||||||
This update has been brought to you by the contributions of:
|
This update has been brought to you by the contributions of:
|
||||||
|
|
||||||
PinyaColada, Rémi Verschelde (akien-mga), dasimonde, gschwind, AbhinavKDev
|
PinyaColada, Rémi Verschelde (akien-mga), dasimonde, gschwind, AbhinavKDev, Laurenz Reinthaler (Schweini07)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- The lighten/darken tool now has a hue shifting mode. It lets users configure the shift in hue, saturation and value of the new shaded pixels. ([#189](https://github.com/Orama-Interactive/Pixelorama/issues/189))
|
- The lighten/darken tool now has a hue shifting mode. It lets users configure the shift in hue, saturation and value of the new shaded pixels. ([#189](https://github.com/Orama-Interactive/Pixelorama/issues/189))
|
||||||
|
|
|
@ -216,16 +216,16 @@ func export_gif(args: Dictionary) -> void:
|
||||||
match direction:
|
match direction:
|
||||||
AnimationDirection.FORWARD:
|
AnimationDirection.FORWARD:
|
||||||
for i in range(processed_images.size()):
|
for i in range(processed_images.size()):
|
||||||
write_frame_to_gif(processed_images[i], Global.current_project.frames[i].duration * (1 / Global.animation_timeline.fps), exporter, args["export_dialog"])
|
write_frame_to_gif(processed_images[i], Global.current_project.frames[i].duration * (1 / Global.current_project.fps), exporter, args["export_dialog"])
|
||||||
AnimationDirection.BACKWARDS:
|
AnimationDirection.BACKWARDS:
|
||||||
for i in range(processed_images.size() - 1, -1, -1):
|
for i in range(processed_images.size() - 1, -1, -1):
|
||||||
write_frame_to_gif(processed_images[i], Global.current_project.frames[i].duration * (1 / Global.animation_timeline.fps), exporter, args["export_dialog"])
|
write_frame_to_gif(processed_images[i], Global.current_project.frames[i].duration * (1 / Global.current_project.fps), exporter, args["export_dialog"])
|
||||||
AnimationDirection.PING_PONG:
|
AnimationDirection.PING_PONG:
|
||||||
export_progress_fraction = 100 / (processed_images.size() * 2)
|
export_progress_fraction = 100 / (processed_images.size() * 2)
|
||||||
for i in range(0, processed_images.size()):
|
for i in range(0, processed_images.size()):
|
||||||
write_frame_to_gif(processed_images[i], Global.current_project.frames[i].duration * (1 / Global.animation_timeline.fps), exporter, args["export_dialog"])
|
write_frame_to_gif(processed_images[i], Global.current_project.frames[i].duration * (1 / Global.current_project.fps), exporter, args["export_dialog"])
|
||||||
for i in range(processed_images.size() - 2, 0, -1):
|
for i in range(processed_images.size() - 2, 0, -1):
|
||||||
write_frame_to_gif(processed_images[i], Global.current_project.frames[i].duration * (1 / Global.animation_timeline.fps), exporter, args["export_dialog"])
|
write_frame_to_gif(processed_images[i], Global.current_project.frames[i].duration * (1 / Global.current_project.fps), exporter, args["export_dialog"])
|
||||||
|
|
||||||
if OS.get_name() == "HTML5":
|
if OS.get_name() == "HTML5":
|
||||||
Html5FileExchange.save_gif(exporter.export_file_data(), args["export_paths"][0])
|
Html5FileExchange.save_gif(exporter.export_file_data(), args["export_paths"][0])
|
||||||
|
|
|
@ -14,8 +14,8 @@ var current_frame := 0 setget frame_changed
|
||||||
var current_layer := 0 setget layer_changed
|
var current_layer := 0 setget layer_changed
|
||||||
var animation_tags := [] setget animation_tags_changed # Array of AnimationTags
|
var animation_tags := [] setget animation_tags_changed # Array of AnimationTags
|
||||||
var guides := [] # Array of Guides
|
var guides := [] # Array of Guides
|
||||||
|
|
||||||
var brushes := [] # Array of Images
|
var brushes := [] # Array of Images
|
||||||
|
var fps := 6.0
|
||||||
|
|
||||||
var x_symmetry_point
|
var x_symmetry_point
|
||||||
var y_symmetry_point
|
var y_symmetry_point
|
||||||
|
@ -177,6 +177,7 @@ func change_project() -> void:
|
||||||
Global.canvas.grid.isometric_polylines.clear()
|
Global.canvas.grid.isometric_polylines.clear()
|
||||||
Global.canvas.grid.update()
|
Global.canvas.grid.update()
|
||||||
Global.transparent_checker._ready()
|
Global.transparent_checker._ready()
|
||||||
|
Global.animation_timeline.fps_spinbox.value = fps
|
||||||
Global.horizontal_ruler.update()
|
Global.horizontal_ruler.update()
|
||||||
Global.vertical_ruler.update()
|
Global.vertical_ruler.update()
|
||||||
Global.preview_zoom_slider.value = -Global.camera_preview.zoom.x
|
Global.preview_zoom_slider.value = -Global.camera_preview.zoom.x
|
||||||
|
@ -282,6 +283,7 @@ func serialize() -> Dictionary:
|
||||||
"export_directory_path" : directory_path,
|
"export_directory_path" : directory_path,
|
||||||
"export_file_name" : file_name,
|
"export_file_name" : file_name,
|
||||||
"export_file_format" : file_format,
|
"export_file_format" : file_format,
|
||||||
|
"fps" : fps
|
||||||
}
|
}
|
||||||
|
|
||||||
return project_data
|
return project_data
|
||||||
|
@ -352,6 +354,8 @@ func deserialize(dict : Dictionary) -> void:
|
||||||
file_name = dict.export_file_name
|
file_name = dict.export_file_name
|
||||||
if dict.has("export_file_format"):
|
if dict.has("export_file_format"):
|
||||||
file_format = dict.export_file_format
|
file_format = dict.export_file_format
|
||||||
|
if dict.has("fps"):
|
||||||
|
fps = dict.fps
|
||||||
|
|
||||||
|
|
||||||
func name_changed(value : String) -> void:
|
func name_changed(value : String) -> void:
|
||||||
|
|
|
@ -9,7 +9,7 @@ func _draw() -> void:
|
||||||
if frame >= current_project.frames.size():
|
if frame >= current_project.frames.size():
|
||||||
frame = current_project.current_frame
|
frame = current_project.current_frame
|
||||||
|
|
||||||
$AnimationTimer.wait_time = current_project.frames[frame].duration * (1 / Global.animation_timeline.fps)
|
$AnimationTimer.wait_time = current_project.frames[frame].duration * (1 / Global.current_project.fps)
|
||||||
|
|
||||||
if animation_timer.is_stopped():
|
if animation_timer.is_stopped():
|
||||||
frame = current_project.current_frame
|
frame = current_project.current_frame
|
||||||
|
@ -30,6 +30,6 @@ func _on_AnimationTimer_timeout() -> void:
|
||||||
frame = 0
|
frame = 0
|
||||||
|
|
||||||
$AnimationTimer.set_one_shot(true)
|
$AnimationTimer.set_one_shot(true)
|
||||||
$AnimationTimer.wait_time = Global.current_project.frames[frame].duration * (1 / Global.animation_timeline.fps)
|
$AnimationTimer.wait_time = Global.current_project.frames[frame].duration * (1 / Global.current_project.fps)
|
||||||
$AnimationTimer.start()
|
$AnimationTimer.start()
|
||||||
update()
|
update()
|
||||||
|
|
|
@ -149,7 +149,7 @@ func add_animated_preview() -> void:
|
||||||
|
|
||||||
previews.add_child(container)
|
previews.add_child(container)
|
||||||
frame_timer.set_one_shot(true) #The wait_time it can't change correctly if it is playing
|
frame_timer.set_one_shot(true) #The wait_time it can't change correctly if it is playing
|
||||||
frame_timer.wait_time = Global.current_project.frames[animated_preview_current_frame].duration * (1 / Global.animation_timeline.fps)
|
frame_timer.wait_time = Global.current_project.frames[animated_preview_current_frame].duration * (1 / Global.current_project.fps)
|
||||||
frame_timer.start()
|
frame_timer.start()
|
||||||
|
|
||||||
|
|
||||||
|
@ -363,14 +363,14 @@ func _on_FrameTimer_timeout() -> void:
|
||||||
animated_preview_current_frame = 0
|
animated_preview_current_frame = 0
|
||||||
else:
|
else:
|
||||||
animated_preview_current_frame += 1
|
animated_preview_current_frame += 1
|
||||||
frame_timer.wait_time = Global.current_project.frames[(animated_preview_current_frame - 1) % (animated_preview_frames.size())].duration * (1 / Global.animation_timeline.fps)
|
frame_timer.wait_time = Global.current_project.frames[(animated_preview_current_frame - 1) % (animated_preview_frames.size())].duration * (1 / Global.current_project.fps)
|
||||||
frame_timer.start()
|
frame_timer.start()
|
||||||
Export.AnimationDirection.BACKWARDS:
|
Export.AnimationDirection.BACKWARDS:
|
||||||
if animated_preview_current_frame == 0:
|
if animated_preview_current_frame == 0:
|
||||||
animated_preview_current_frame = Export.processed_images.size() - 1
|
animated_preview_current_frame = Export.processed_images.size() - 1
|
||||||
else:
|
else:
|
||||||
animated_preview_current_frame -= 1
|
animated_preview_current_frame -= 1
|
||||||
frame_timer.wait_time = Global.current_project.frames[(animated_preview_current_frame + 1) % (animated_preview_frames.size())].duration * (1 / Global.animation_timeline.fps)
|
frame_timer.wait_time = Global.current_project.frames[(animated_preview_current_frame + 1) % (animated_preview_frames.size())].duration * (1 / Global.current_project.fps)
|
||||||
frame_timer.start()
|
frame_timer.start()
|
||||||
Export.AnimationDirection.PING_PONG:
|
Export.AnimationDirection.PING_PONG:
|
||||||
match pingpong_direction:
|
match pingpong_direction:
|
||||||
|
@ -382,7 +382,7 @@ func _on_FrameTimer_timeout() -> void:
|
||||||
animated_preview_current_frame = 0
|
animated_preview_current_frame = 0
|
||||||
else:
|
else:
|
||||||
animated_preview_current_frame += 1
|
animated_preview_current_frame += 1
|
||||||
frame_timer.wait_time = Global.current_project.frames[(animated_preview_current_frame - 1) % (animated_preview_frames.size())].duration * (1 / Global.animation_timeline.fps)
|
frame_timer.wait_time = Global.current_project.frames[(animated_preview_current_frame - 1) % (animated_preview_frames.size())].duration * (1 / Global.current_project.fps)
|
||||||
frame_timer.start()
|
frame_timer.start()
|
||||||
Export.AnimationDirection.BACKWARDS:
|
Export.AnimationDirection.BACKWARDS:
|
||||||
if animated_preview_current_frame == 0:
|
if animated_preview_current_frame == 0:
|
||||||
|
@ -392,7 +392,7 @@ func _on_FrameTimer_timeout() -> void:
|
||||||
pingpong_direction = Export.AnimationDirection.FORWARD
|
pingpong_direction = Export.AnimationDirection.FORWARD
|
||||||
else:
|
else:
|
||||||
animated_preview_current_frame -= 1
|
animated_preview_current_frame -= 1
|
||||||
frame_timer.wait_time = Global.current_project.frames[(animated_preview_current_frame + 1) % (animated_preview_frames.size())].duration * (1 / Global.animation_timeline.fps)
|
frame_timer.wait_time = Global.current_project.frames[(animated_preview_current_frame + 1) % (animated_preview_frames.size())].duration * (1 / Global.current_project.fps)
|
||||||
frame_timer.start()
|
frame_timer.start()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
extends Panel
|
extends Panel
|
||||||
|
|
||||||
var fps := 6.0
|
|
||||||
var animation_loop := 1 # 0 is no loop, 1 is cycle loop, 2 is ping-pong loop
|
var animation_loop := 1 # 0 is no loop, 1 is cycle loop, 2 is ping-pong loop
|
||||||
var animation_forward := true
|
var animation_forward := true
|
||||||
var first_frame := 0
|
var first_frame := 0
|
||||||
|
@ -8,13 +7,15 @@ var last_frame := 0
|
||||||
|
|
||||||
var timeline_scroll : ScrollContainer
|
var timeline_scroll : ScrollContainer
|
||||||
var tag_scroll_container : ScrollContainer
|
var tag_scroll_container : ScrollContainer
|
||||||
|
var fps_spinbox : SpinBox
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
timeline_scroll = Global.find_node_by_name(self, "TimelineScroll")
|
timeline_scroll = Global.find_node_by_name(self, "TimelineScroll")
|
||||||
tag_scroll_container = Global.find_node_by_name(self, "TagScroll")
|
tag_scroll_container = Global.find_node_by_name(self, "TagScroll")
|
||||||
|
fps_spinbox = find_node("FPSValue")
|
||||||
timeline_scroll.get_h_scrollbar().connect("value_changed", self, "_h_scroll_changed")
|
timeline_scroll.get_h_scrollbar().connect("value_changed", self, "_h_scroll_changed")
|
||||||
Global.animation_timer.wait_time = 1 / fps
|
Global.animation_timer.wait_time = 1 / Global.current_project.fps
|
||||||
|
|
||||||
|
|
||||||
func _h_scroll_changed(value : float) -> void:
|
func _h_scroll_changed(value : float) -> void:
|
||||||
|
@ -230,6 +231,7 @@ func _on_AnimationTimer_timeout() -> void:
|
||||||
$AnimationTimer.stop()
|
$AnimationTimer.stop()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
var fps = Global.current_project.fps
|
||||||
if animation_forward:
|
if animation_forward:
|
||||||
if Global.current_project.current_frame < last_frame:
|
if Global.current_project.current_frame < last_frame:
|
||||||
Global.current_project.current_frame += 1
|
Global.current_project.current_frame += 1
|
||||||
|
@ -299,6 +301,7 @@ func play_animation(play : bool, forward_dir : bool) -> void:
|
||||||
if play:
|
if play:
|
||||||
Global.animation_timer.set_one_shot(true) # The wait_time can't change correctly if it is playing
|
Global.animation_timer.set_one_shot(true) # The wait_time can't change correctly if it is playing
|
||||||
var duration : float = Global.current_project.frames[Global.current_project.current_frame].duration
|
var duration : float = Global.current_project.frames[Global.current_project.current_frame].duration
|
||||||
|
var fps = Global.current_project.fps
|
||||||
Global.animation_timer.wait_time = duration * (1 / fps)
|
Global.animation_timer.wait_time = duration * (1 / fps)
|
||||||
Global.animation_timer.start()
|
Global.animation_timer.start()
|
||||||
animation_forward = forward_dir
|
animation_forward = forward_dir
|
||||||
|
@ -325,8 +328,8 @@ func _on_FirstFrame_pressed() -> void:
|
||||||
|
|
||||||
|
|
||||||
func _on_FPSValue_value_changed(value : float) -> void:
|
func _on_FPSValue_value_changed(value : float) -> void:
|
||||||
fps = float(value)
|
Global.current_project.fps = float(value)
|
||||||
Global.animation_timer.wait_time = 1 / fps
|
Global.animation_timer.wait_time = 1 / Global.current_project.fps
|
||||||
|
|
||||||
|
|
||||||
func _on_PastOnionSkinning_value_changed(value : float) -> void:
|
func _on_PastOnionSkinning_value_changed(value : float) -> void:
|
||||||
|
|
|
@ -23,6 +23,17 @@
|
||||||
[ext_resource path="res://assets/graphics/dark_themes/tools/zoom.png" type="Texture" id=21]
|
[ext_resource path="res://assets/graphics/dark_themes/tools/zoom.png" type="Texture" id=21]
|
||||||
[ext_resource path="res://src/UI/ViewportContainer.gd" type="Script" id=23]
|
[ext_resource path="res://src/UI/ViewportContainer.gd" type="Script" id=23]
|
||||||
|
|
||||||
|
[sub_resource type="ShaderMaterial" id=1]
|
||||||
|
shader = ExtResource( 9 )
|
||||||
|
shader_param/size = 10.0
|
||||||
|
shader_param/color1 = Color( 0.7, 0.7, 0.7, 1 )
|
||||||
|
shader_param/color2 = Color( 1, 1, 1, 1 )
|
||||||
|
shader_param/offset = Vector2( 0, 0 )
|
||||||
|
shader_param/scale = Vector2( 0, 0 )
|
||||||
|
shader_param/rect_size = Vector2( 0, 0 )
|
||||||
|
shader_param/follow_movement = false
|
||||||
|
shader_param/follow_scale = false
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id=2]
|
[sub_resource type="ShaderMaterial" id=2]
|
||||||
shader = ExtResource( 9 )
|
shader = ExtResource( 9 )
|
||||||
shader_param/size = 10.0
|
shader_param/size = 10.0
|
||||||
|
@ -34,18 +45,7 @@ shader_param/rect_size = Vector2( 0, 0 )
|
||||||
shader_param/follow_movement = false
|
shader_param/follow_movement = false
|
||||||
shader_param/follow_scale = false
|
shader_param/follow_scale = false
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id=3]
|
[sub_resource type="StyleBoxFlat" id=3]
|
||||||
shader = ExtResource( 9 )
|
|
||||||
shader_param/size = 10.0
|
|
||||||
shader_param/color1 = Color( 0.7, 0.7, 0.7, 1 )
|
|
||||||
shader_param/color2 = Color( 1, 1, 1, 1 )
|
|
||||||
shader_param/offset = Vector2( 0, 0 )
|
|
||||||
shader_param/scale = Vector2( 0, 0 )
|
|
||||||
shader_param/rect_size = Vector2( 0, 0 )
|
|
||||||
shader_param/follow_movement = false
|
|
||||||
shader_param/follow_scale = false
|
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=1]
|
|
||||||
bg_color = Color( 0.0627451, 0.0627451, 0.0627451, 1 )
|
bg_color = Color( 0.0627451, 0.0627451, 0.0627451, 1 )
|
||||||
expand_margin_top = 6.0
|
expand_margin_top = 6.0
|
||||||
|
|
||||||
|
@ -299,7 +299,7 @@ usage = 0
|
||||||
render_target_update_mode = 3
|
render_target_update_mode = 3
|
||||||
|
|
||||||
[node name="TransparentChecker" parent="CanvasAndTimeline/ViewportAndRulers/HSplitContainer/ViewportandVerticalRuler/ViewportContainer/Viewport" instance=ExtResource( 5 )]
|
[node name="TransparentChecker" parent="CanvasAndTimeline/ViewportAndRulers/HSplitContainer/ViewportandVerticalRuler/ViewportContainer/Viewport" instance=ExtResource( 5 )]
|
||||||
material = SubResource( 2 )
|
material = SubResource( 1 )
|
||||||
|
|
||||||
[node name="Canvas" parent="CanvasAndTimeline/ViewportAndRulers/HSplitContainer/ViewportandVerticalRuler/ViewportContainer/Viewport" instance=ExtResource( 19 )]
|
[node name="Canvas" parent="CanvasAndTimeline/ViewportAndRulers/HSplitContainer/ViewportandVerticalRuler/ViewportContainer/Viewport" instance=ExtResource( 19 )]
|
||||||
|
|
||||||
|
@ -331,7 +331,7 @@ handle_input_locally = false
|
||||||
render_target_update_mode = 3
|
render_target_update_mode = 3
|
||||||
|
|
||||||
[node name="TransparentChecker" parent="CanvasAndTimeline/ViewportAndRulers/HSplitContainer/ViewportContainer2/Viewport" instance=ExtResource( 5 )]
|
[node name="TransparentChecker" parent="CanvasAndTimeline/ViewportAndRulers/HSplitContainer/ViewportContainer2/Viewport" instance=ExtResource( 5 )]
|
||||||
material = SubResource( 3 )
|
material = SubResource( 2 )
|
||||||
|
|
||||||
[node name="CanvasPreview" parent="CanvasAndTimeline/ViewportAndRulers/HSplitContainer/ViewportContainer2/Viewport" instance=ExtResource( 2 )]
|
[node name="CanvasPreview" parent="CanvasAndTimeline/ViewportAndRulers/HSplitContainer/ViewportContainer2/Viewport" instance=ExtResource( 2 )]
|
||||||
|
|
||||||
|
@ -343,7 +343,7 @@ script = ExtResource( 7 )
|
||||||
[node name="AnimationTimeline" parent="CanvasAndTimeline" instance=ExtResource( 18 )]
|
[node name="AnimationTimeline" parent="CanvasAndTimeline" instance=ExtResource( 18 )]
|
||||||
margin_top = 492.0
|
margin_top = 492.0
|
||||||
margin_bottom = 692.0
|
margin_bottom = 692.0
|
||||||
custom_styles/panel = SubResource( 1 )
|
custom_styles/panel = SubResource( 3 )
|
||||||
|
|
||||||
[node name="RightPanel" type="Panel" parent="."]
|
[node name="RightPanel" type="Panel" parent="."]
|
||||||
margin_left = 950.0
|
margin_left = 950.0
|
||||||
|
|
Loading…
Reference in a new issue