Mon Nov 06, 2023 12:46 am
#!/usr/bin/env python
# slide-into-place-ani.py
# Created by TT
# Just thought this would be interesting, to create animation that slides into place with different layers from different angles and from different angles
#
# License: GPLv3
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY# without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# To view a copy of the GNU General Public License
# visit: http://www.gnu.org/licenses/gpl.html
#
#
# ------------
#| Change Log |
# ------------
# Rel 1: Initial release
from gimpfu import *
#import random
import math
def ease_in_out(t):
"""Ease-in-out function: acceleration until halfway, then deceleration"""
return 2*t*t if t < 0.5 else 1 - pow(-2*t + 2, 2) / 2
def python_slide_into_place_ani(image,layer,slideframes,framearray,anglearray,distancearray,fadearray):
# pdb.gimp_image_undo_group_start(image)
# pdb.gimp_context_push()
#YOUR CODE BEGINS=======================
slideframes = int(slideframes)
new_image = pdb.gimp_image_new(image.width,image.height,RGB)
pdb.gimp_display_new(new_image)
linkedlayers = []
visible = []
positions = []
for l in image.layers:
if pdb.gimp_item_get_linked(l) == TRUE:
linkedlayers.append(l)
visible.append(pdb.gimp_item_get_visible(l))
positions.append(pdb.gimp_image_get_item_position(image,l))
linkedlayers.reverse()
visible.reverse()
positions.reverse()
#hide all linked layers so it doesn't affect our animation layers
for l in linkedlayers:
pdb.gimp_item_set_visible(l,FALSE)
framearray = [int(x) for x in framearray.split(',')]
anglearray = [int(x) for x in anglearray.split(',')]
distancearray = [int(x) for x in distancearray.split(',')]
fadearray = [int(x) for x in fadearray.split(',')]
framearray.reverse()
anglearray.reverse()
distancearray.reverse()
fadearray.reverse()
frames = max(framearray)+slideframes
for j in range(0,frames):
removelayers = []
#pdb.gimp_message("NEW FRAME")
for i in range(0,len(linkedlayers)):
linkedlayer = linkedlayers[i]
thisframe = j-framearray[i]
if thisframe >= 0 and thisframe <= slideframes:
t = float(thisframe)/slideframes
elif thisframe < 0:
t = 0
else:
t = 1;
#pdb.gimp_message(t)
mindist = 0; maxdist = distancearray[i];
dist = maxdist + (mindist-maxdist) * ease_in_out(t)
opacity = 0 + (1.0) * ease_in_out(t)
#text_layer = pdb.gimp_text_fontname(image,None,0,0,word,-1,TRUE,size,0,fontname)
new_layer = pdb.gimp_layer_new_from_drawable(linkedlayer,image)
pdb.gimp_image_insert_layer(image,new_layer,None,positions[i])
pdb.gimp_item_set_linked(new_layer,FALSE)
pdb.gimp_item_set_visible(new_layer,TRUE)
angle = anglearray[i]
rad = angle/360.0*2*math.pi
ix = math.cos(rad) * dist
iy = math.sin(rad) * dist
#auto crop to make it layer to content
#pdb.plug_in_autocrop_layer(image,new_layer)
#pdb.gimp_layer_scale(new_layer,new_layer.width*size/100.0,new_layer.height*size/100.0,TRUE)
offsetx,offsety = pdb.gimp_drawable_offsets(new_layer)
pdb.gimp_layer_set_offsets(new_layer,offsetx+ix,offsety+iy)
if (fadearray[i] == 1):
pdb.gimp_layer_set_opacity(new_layer,opacity * 100)
removelayers.append(new_layer) #add it so we can remove it when we're done
visible_layer = pdb.gimp_layer_new_from_visible(image,new_image,'frame')
pdb.gimp_image_insert_layer(new_image,visible_layer,None,0)
for rl in removelayers:
pdb.gimp_image_remove_layer(image,rl)
#set it back to whatever visibility it was
for i in range(0,len(linkedlayers)):
l = linkedlayers[i]
v = visible[i]
pdb.gimp_item_set_visible(l,v)
#YOUR CODE ENDS ========================
# pdb.gimp_context_pop()
# pdb.gimp_image_undo_group_end(image)
pdb.gimp_displays_flush()
#return
register(
"python_fu_slide_into_place_ani",
"Slide Into Place Animation",
"Slide Into Place Animation",
"TT",
"TT",
"Nov 5, 2023",
"<Image>/Python-Fu/Slide Into Place Ani...",
"*", # Create a new image, don't work on an existing one
[
#INPUT BEGINS
(PF_INT, "frames", "Frames per Slide:", 10),
(PF_STRING, "framearray", "Start Sliding-In Frame Array (1st is for frame):", "1,5,10,20,1"),
(PF_STRING, "anglearray", "Sliding-In From Angle Array:", "0,45,90,180,270"),
(PF_STRING, "distancearray","Sliding-In From Distance Array:","100,200,300,400,150"),
(PF_STRING, "fadearray","Sliding-In Fade Array(1:fade,0:no-fade:","1,1,1,1,0"),
#INPUT ENDS
],
[],
python_slide_into_place_ani)
main()
# Below is all the example input types for INPUTS for the plug-in which can be cut and pasted into #INPUT BEGINS section and edited to taste
# (PF_INT, "p0", "_INT:", 0), # PF_INT8, PF_INT16, PF_INT32 similar but no difference in Python.
# (PF_FLOAT, "p02", "_FLOAT:", 3.141),
# (PF_STRING, "p03", "_STRING:", "foo"), # alias PF_VALUE
# (PF_TEXT, "p04", "TEXT:", "bar"),
# # PF_VALUE
# # Pick one from set of choices
# (PF_OPTION,"p1", "OPTION:", 0, ["0th","1st","2nd"]), # initially 0th is choice
# (PF_RADIO, "p16", "RADIO:", 0, (("0th", 1),("1st",0))), # note bool indicates initial setting of buttons
# # PF_RADIO is usually called a radio button group.
# # SLIDER, ADJUSTMENT types require the extra parameter of the form (min, max, step).
# (PF_TOGGLE, "p2", "TOGGLE:", 1), # initially True, checked. Alias PF_BOOL
# # PF_TOGGLE is usually called a checkbox.
# (PF_SLIDER, "p3", "SLIDER:", 0, (0, 100, 10)),
# (PF_SPINNER, "p4", "SPINNER:", 21, (1, 1000, 50)), # alias PF_ADJUSTMENT
# # Pickers ie combo boxes ie choosers from lists of existing Gimp objects
# (PF_COLOR, "p14", "_COLOR:", (100, 21, 40) ), # extra param is RGB triple
# # PF_COLOUR is an alias by aussie PyGimp author lol
# (PF_IMAGE, "p15", "IMAGE:", None), # should be type gimp.image, but None works
# (PF_FONT, "p17", "FONT:", 0),
# (PF_FILE, "p18", "FILE:", 0),
# (PF_BRUSH, "p19", "BRUSH:", 0),
# (PF_PATTERN, "p20", "PATTERN:", 0),
# (PF_GRADIENT, "p21", "GRADIENT:", 0),
# (PF_PALETTE, "p22", "PALETTE:", 0),
# (PF_LAYER, "p23", "LAYER:", None),
# (PF_CHANNEL, "p24", "CHANNEL:", None), # ??? Usually empty, I don't know why.
# (PF_DRAWABLE, "p25", "DRAWABLE:", None),
# # Mostly undocumented, but work
# (PF_VECTORS, "p26", "VECTORS:", None),
# (PF_FILENAME, "p27", "FILENAME:", 0),
# (PF_DIRNAME, "p28", "DIRNAME:", 0)
# # PF_REGION might work but probably of little use. See gimpfu.py.
Mon Nov 06, 2023 11:12 am
Mon Nov 06, 2023 11:15 am
Sat Nov 18, 2023 5:24 pm
Sun Nov 19, 2023 1:59 pm
Sun Nov 19, 2023 5:36 pm