Transforms
Transforms are used in order to turn adisplayable intoanother displayable. There are several kinds of transforms, and various ways tocreate them. The built-in transforms are used to control where an image isplaced on the screen, while user-defined transforms can cause more complexeffects, like motion, zoom, rotation, up to complex color effects.
Transforms can be applied to images by passing them to theat clause of theshow or scene statements. The following applies theright transform to theeileenhappy image:
showeileenhappyatright
Multiple transforms can be applied by separating them with commas. Thesetransforms are applied from left-to-right.
showeileenhappyathalfsize,right
Applying transforms to displayables in Python
There are several ways to apply transformt to displayabled in Python:
The most universal and most recommended way is
At(d,t)(see below). Itworks with all transforms.d(child=t)works with allATL transforms.t(d)works with allPython transforms, as wellas with ATL transforms that don't have any positional parameters.
- At(d,*args)
Given a displayabled, applies each of the transforms inargsto it. The transforms are applied in left-to-right order, so thatthe outermost transform is the rightmost argument.
transformbirds_transform:xpos-200linear10xpos800pause20repeatimagebirds=At("birds.png",birds_transform)
Note
The resulting value may not be able to be displayed, if there remainsparameters of the transform that have not been given a value, as can be thecase with transforms defined using theTransform Statement.
Note
The resulting value may still be a transform that can be applied to yetanother displayable (overriding its previous child) ; that's the case withATL transforms which are still usable as transforms even when having theirchild set.
Built-in Transforms
Ren'Py ships with a number of transforms defined by default. These transformsposition things on the screen. Here's a depiction of where each built-intransform will position an image.
+-----------------------------------------------------------+ |topleft, reset top topright| | | | | | | | | | truecenter | | | | | | | | |offscreenleft|left center, default right|offscreenright +-----------------------------------------------------------+
Theoffscreenleft andoffscreenright transforms position imagesoff the edges of the screen. These transforms can be used to move things offthe screen (remember to hide them afterwards, to ensure that they do not consumeresources).
The transforms are:
- center
Centers horizontally, and aligns to the bottom of the screen.
- default
Centers horizontally, and aligns to the bottom of the screen. This can beredefined via
config.default_transformto change the defaultplacement of images shown with the show or scene statements.
- left
Aligns to the bottom-left corner of the screen.
- offscreenleft
Places the displayable off the left side of the screen, aligned to thebottom of the screen.
- offscreenright
Places the displayable off the right side of the screen, aligned to thebottom of the screen.
- reset
Resets the transform to the default values of each property, removing anyproperites set before it.
- right
Aligns to the bottom-right corner of the screen.
- top
Centers horizontally, and aligns to the top of the screen.
- topleft
Aligns to the top-left corner of the screen.
- topright
Aligns to the top-right corner of the screen.
- truecenter
Centers both horizontally and vertically.
ATL - Animation and Transformation Language
The Animation and Transformation Language (ATL) is a high-level language whichcan create animations, move displayables across the screen, set their position,apply transformations, and more. These can be changed over time, and in responseto events.
ATL transform objects, which are created using theTransform Statementdown below, are displayables and can be used as such (even though they will betransparent when their child displayable is not set) : they can be passed to ascreen'sAdd element, or to aShow expressionstatement, or to therenpy.show() function.
Ren'Py script statements
There are three Ren'Py script statements which can include ATL code.
Transform Statement
Thetransform statement creates a new transform. The syntax is:
atl_transform ::= "transform"qualname( "("parameters")" )? ":"atl_block
The transform statement is run atinit time. The transformmay take a list of parameters, which works much the same way as a Pythonfunction definition, except that several kinds of parameters are currentlyforbidden, though they may be allowed in the future:
Positional-only parameters
Keyword-only parameters without a default value
Variadic positional parameters (
*args)Variadic keyword parameters (
**kwargs)
The created object cannot be used as a transform until and unless all itsparameters have been given a value.
See also :ATL curry and partial parameter passing
qualname, the name of the transform, must be a set of dot-separated Pythonidentifiers. The transform created by the ATL block will be bound to that name,within the providedstore if one was provided.
transformleft_to_right:xalign0.linear2xalign1.repeattransformariana.left:xalign.3transformanimated_ariana_disp:"ariana"pause1."ariana_reverse"pause1.repeat
The created object is both a transform and a displayable, but as opposed to theimage statement, it is created as a variable (or a constant), rather than inthe namespace ofimages.
Image Statement with ATL Block
The second way to include ATL code in a script is as part of animagestatement. As its inline counterpart, it binds an image name(which may contain spaces) to the given transform. As there is no way to supplywith parameters, it's only useful if the transform defines an animation. Thesyntax is:
atl_image ::= "image"image_name":"atl_block
imageanimated_ariana_img:"ariana"pause1."ariana_reverse"pause1.repeat
Scene and Show Statements with ATL Block
The final way to use ATL is as part of ashow or scenestatement. This wraps the image that's being shown inside an ATL transformationwhich is created on the fly and applied to the image. The syntax is:
atl_show ::=stmt_show":"atl_blockatl_scene ::=stmt_scene":"atl_block
showeileenhappy:xalign1.scenebgwashington:zoom2.
ATL Syntax and Statements
ATL statements may be inline, or make up a block within the ATL block in whichit is written. With some exceptions described in the relevant statements, thestatements in an ATL block are executed in order, from top to bottom.
If an ATL statement requires an expression to be evaluated, such evaluationoccurs when the transform is first executed (that is when using ashowstatement, or displaying the transform as part of a screen), and not when theparticular ATL statement is executed.
The following are the ATL statements.
Inline Contains Statement
The inline contains statement takes a single expression evaluating to adisplayable.
atl_contains ::= "contains"simple_expressionThis statement sets (or replaces) the child of the current ATL transform to thevalue of the expression, making it useful for animation.
transforman_animation:"1.png"pause2"2.png"pause2repeatimagemove_an_animation:containsan_animation# If we didn't use contains, we'd still be looping# and would never reach here.xalign0.0linear1.0yalign1.0
TheDisplayable Statement is less explicit and bears ambiguity withthe transform expression statement, but it allows for atransition to be used for replacing the child. Thisstatement can be particularly useful when an ATL transform wishes to contain,rather than include, a second ATL transform.
Number Statement
The number statement consists of a simple expression evaluating to an integer orfloating-point number. It can optionally be preceded by the keyword "pause".
atl_number ::= "pause"?simple_expressionIt is used as a number of seconds to pause execution for.
imageatlexample:# Displays logo_base.pngcontains"logo_base.png"# Pause for 1.0 seconds.pause1.0# Show logo_bw.png, with a dissolve."logo_bw.png"withDissolve(0.5,alpha=True)# Pause for 3 seconds3repeat
Properties Statement
This statement sets one or more transform properties to a new value.
atl_properties ::=atl_property+atl_property ::=transform_propertysimple_expression
The statement first gives a series (at least one) of property names, eachfollowed by the new value to set it to. SeeList of Transform Properties for alist of transform properties, their meaning and the values they take.
transformrightoid:xalign.9transformariana.left:xanchor.3xpos100
Interpolation Statement
The interpolation statement is the main way of getting smoothly animatedtransformations.
atl_interp ::= ((warpersimple_expression) | ("warp"simple_expressionsimple_expression)) (atl_interp_target+ | (":"atl_interp_target+ ))
atl_interp_target ::= (atl_property+ ("knot"simple_expression)* ) |atl_transform_expression| "clockwise" | "counterclockwise" | ("circles"simple_expression)
Some sample interpolations:
showlogobase:# Show the logo at the upper right side of the screen.xalign1.0yalign0.0# Take 1.0 seconds to move things back to the left.linear1.0xalign0.0# Take 1.0 seconds to move things to the location specified in the# truecenter transform. Use the ease warper to do this.ease1.0truecenter# Set the location to circle around.anchor(0.5,0.5)# Use circular motion to bring us to spiral out to the top of# the screen. Take 2 seconds to do so.linear2.0yalign0.0clockwisecircles3# Use a spline motion to move us around the screen.linear2.0align(0.5,1.0)knot(0.0,.33)knot(1.0,.66)# Changes xalign and yalign at the same time.linear2.0xalign1.0yalign1.0# The same thing, using a block.linear2.0:xalign1.0yalign1.0
The first part of the interpolation is used to select a function that time-warpsthe interpolation. That means, a function that maps linear time to non-lineartime, seeWarpers for more information about that. Selecting a warper caneither be done by giving the name of a registered warper, or by giving thekeyword "warp" followed by an expression giving a warping function.
In either case, it's followed by a number giving the number of seconds the interpolation should take.
transformbuiltin_warper:xpos0ease5xpos520initpython:defmy_warper(t):returnt**4.4definemy_warpers=[my_warper]transformaccessed_as_function:xpos0warpmy_warpers[0]5xpos520warpmy_warper3xpos100
The interpolation will persist for the given amount of time, and at least oneframe.
WhenTransform Properties are given, the value each is given is the valueit will be set to at the end of the interpolation statement. This can be tweakedin several ways:
If the value is followed by one or more knots, then spline motion is used. Thestarting point is the value of the property at the start of the interpolation,the end point is the given value, and the knots are used to control thespline. A quadratic curve is used for a single knot, Bezier is used when thereare two and Catmull-Rom is used for three or more knots. In the former twocases, the knot or knots are simply control nodes. For Catmull-Rom, the firstand last knot are control nodes (often outside the displayed path) and theother knots are points the path passes through.
If the interpolation statement contains a "clockwise" or "counterclockwise"clause, circular motion is used. In that case, Ren'Py will compare the startand end locations (which are set by
pos,align,angleandradius, ...) and figure out the polar coordinatecenter (which isaround). Ren'Py will then compute the number ofdegrees it will take to go from the start angle to the end angle, in thespecified direction of rotation. If the circles clause is given, Ren'Py willensure that the appropriate number of circles will be made.Otherwise, the value is linearly interpolated between the start and endlocations.
It is also possible to interpolate aTransform Expression Statement,which should in this case be an ATL transform containing only a singleproperties statement. The properties from the transform will be processed as ifthey were written directly in this interpolation.
A warper may be followed by a colon (:). In that case, it may be followed by oneor more lines, in an indented block, containing the clauses described above.This lets you break an interpolation of many different things up into severallines.
Pass Statement
atl_pass ::= "pass"
Thepass statement is a simple statement that causes nothing to happen : ano-op. This can be used when there's a desire to separate statements, like whentwo sets of choice statements (see below) would otherwise be back-to-back. Itcan also be useful when the syntax requires a block to be created but you needit to be empty, for example to make one of the choice blocks not do anything.
Repeat Statement
Therepeat statement is a simple statement that causes the block containingit to resume execution from the beginning.
atl_repeat ::= "repeat" (simple_expression)?If the expression is present, then it is evaluated to give an integer number oftimes the block will execute. (So a block ending withrepeat2 will executeat most twice in total, andrepeat1 does not repeat.)
The repeat statement must be the last statement in a block:
showlogobase:xalign0.0linear1.0xalign1.0linear1.0xalign0.0repeat
Block Statement
Theblock statement simply contains a block of ATL statements.
atl_block_stmt ::= "block" ":"atl_blockThis can be used to group statements that will repeat:
showlogobase:alpha0.0xalign0.0yalign0.0linear1.0alpha1.0block:linear1.0xalign1.0linear1.0xalign0.0repeat
Parallel Statement
Theparallel statement defines a set of ATL blocks to execute in parallel.
atl_parallel ::= ("parallel" ":"atl_block)+Parallel statements are greedily grouped into a parallel set when more thanone parallel block appears consecutively in a block. The set of all parallelblocks are then executed simultaneously. The parallel statement terminates whenthe last block terminates.
The blocks within a set should be independent of each other, and manipulatedifferentTransform Properties. When two blocks change the same property,the result is undefined.
showlogobase:parallel:xalign0.0linear1.3xalign1.0linear1.3xalign0.0repeatparallel:yalign0.0linear1.6yalign1.0linear1.6yalign0.0repeat
Choice Statement
Thechoice statement defines one of a set ofpotential choices. Ren'Py will pick one of the choices in the set, andexecute the ATL block associated with it, and then continue execution afterthe last choice in the choice set.
atl_choice ::= ("choice" (simple_expression)? ":"atl_block)+Choice statements are greedily grouped into a choice set when more than onechoice statement appears consecutively in a block. If thesimple_expressionis supplied, it is a floating-point weight given to that block, otherwise 1.0is assumed.
imageeileenrandom:choice:"eileen happy"choice:"eileen vhappy"choice:"eileen concerned"pause1.0repeat
Thepass statement can be useful in order to break several sets of choiceblocks into several choice statements, or to make an empty choice block.
Animation Statement
Theanimation statement must be the first statement in an ATL block, andtells Ren'Py that the block uses the animation timebase.
atl_animation ::= "animation"
As compared to the normal showing timebase, the animation timebase starts whenan image or screen with the same tag is shown. This is generally used to haveone image replaced by a second one at the same apparent time. For example:
imageeileenhappymoving:animation"eileen happy"xalign0.0linear5.0xalign1.0repeatimageeileenvhappymoving:animation"eileen vhappy"xalign0.0linear5.0xalign1.0repeatlabelstart:showeileenhappymovingpauseshoweileenvhappymovingpause
This example will cause Eileen to change expression when the first pausefinishes, but will not cause her position to change, as both animations sharethe same animation time, and hence will place her sprite in the same place.Without the animation statement, the position would reset when the playerclicks.
On Statement
Theon statement defines an event handler.
atl_on ::= "on"name(","name)* ":"atl_block
on blocks are greedily grouped into a single statement. On statement canhandle a single event name, or a comma-separated list of event names.
This statement is used to handle events. When an event is handled, handling ofany other event ends and handing of the new event immediately starts. When anevent handler ends without another event occurring, thedefault event isproduced (unless thedefault event is already being handled).
Execution of the on statement will never naturally end. (But it can be endedby the time statement, or an enclosing event handler.)
See the event statement for a way to produce arbitrary events, and seeExternal events for a list of naturally-produced events.
showlogobase:onshow:alpha0.0linear.5alpha1.0onhide:linear.5alpha0.0transformpulse_button:onhover,idle:linear.25zoom1.25linear.25zoom1.0
Transform Expression Statement
This statement includes another ATL transform as part of the current ATL block.
atl_transform_expression ::=simple_expressionThis only applies if the ATL transform hasnot been supplied a child (seethe top of the page for how to do that), otherwise it will be interpreted as aDisplayable Statement. The contents of the provided ATL transformare included at the location of this statement.
transformmove_right:linear1.0xalign1.0imageatlexample:# Display logo_base.png"logo_base.png"# Run the move_right transform.move_right
Displayable Statement
The displayable statement consists of a simple Python expression evaluating toadisplayable, optionally followed by a with clausecontaining a second simple expression.
atl_displayable ::=simple_expression("with"simple_expression)?
It is used to set or replace the child of the transform when the statementexecutes.
If awith clause is present, the second expression is evaluated as atransition, and the transition is applied between the oldchild and the new child. Be careful in that not all transitions will work inthis situation, notablyDict Transitions andmove- andease- transitions.
imageatlexample:# Displays logo_base.png"logo_base.png"# Pause for 1.0 seconds.1.0# Show logo_bw.png, with a dissolve."logo_bw.png"withDissolve(0.5,alpha=True)
Warning
If passing any child-less transform is pointless as it will make thetransform transparent and ineffective, passing child-less ATL transforms maybe interpreted as aTransform Expression Statement, which willyield different results.
If the expression evaluates to an ATL transformwith a child, the executionof this ATL block will only continue after the includee's ATL code runs.
Contains Block Statement
The contains block, like itsinline counterpart, sets the child of thetransform but in a different way.
atl_counts ::= "contains" ":"atl_blockOne or more contains blocks will be greedily grouped together inside a singlecontains statement, wrapped inside aFixed(), and set as the child of thetransform.
Each block should define a displayable to use, otherwise an error will occur.The contains statement executes instantaneously, without waiting for thechildren to complete.
imagetestdouble:contains:"logo.png"xalign0.0linear1.0xalign1.0repeatcontains:"logo.png"xalign1.0linear1.0xalign0.0repeat
Function Statement
Thefunction statement allows ATL to use Python code.
atl_function ::= "function"simple_expressionThe functions have the same signature as those used withTransform():
The first argument is a transform object.Transform Properties can beset as attributes on this object.
The second argument is the shown timebase, the number of seconds since thefunction began executing.
The third argument is the animation timebase, which is the number ofseconds something with the same tag has been on the screen.
If the function returns a number, it will be called again after that number ofseconds has elapsed. (0 seconds means to call the function as soon aspossible.) If the function returns None, control will pass to the next ATLstatement.
This function should not have side effects other than changing the transformobject in the first argument, and may be called at any time with any value aspart of prediction.
Note thatfunction is not a transform property, and that it doesn't have theexact same behavior asTransform()'sfunction parameter.
initpython:defslide_vibrate(trans,st,at,/):ifst>1.0:trans.xalign=1.0trans.yoffset=0returnNoneelse:trans.xalign=sttrans.yoffset=random.randrange(-10,11)return0labelstart:showlogobase:functionslide_vibratepause1.0repeat
Time Statement
Thetime statement is a control statement.
atl_time ::= "time"simple_expressionIt contains a single expression, which is evaluated to give a time expressed asseconds from the start of execution of the containing block. When the time givenin the statement is reached, the following statement begins to execute. Thistransfer of control occurs even if a previous statement is still executing, andcauses any such prior statement to immediately terminate.
Time statements are implicitly preceded by a pause statement with an infinitetime. This means that if control would otherwise reach the time statement, itwaits until the time statement would take control.
When there are multiple time statements in a block, they must strictlyincrease in order.
imagebackgrounds:"bg band"xoffset0block:linear1xoffset10linear1xoffset0repeat# control would never exit this blocktime2.0xoffset0"bg whitehouse"time4.0"bg washington"
Event Statement
Theevent statement is a simple statement that causes an event with thegiven name to be produced.
atl_event ::= "event"nameWhen an event is produced inside a block, the block is checked to see if anevent handler for the given name exists. If it does, control is transferredto the event handler. Otherwise, the event propagates to any containing eventhandler.
External events
The following events are triggered automatically within an ATL transform:
startA pseudo-event, triggered on entering an
onstatement, if no event ofhigher priority has happened.showTriggered when the transform is shown using the show or scene statement, andno image with the given tag exists.
replaceTriggered when transform is shown using the
showstatement, replacing animage with the given tag.hideTriggered when the transform is hidden using the
hidestatement or itsPython equivalent.Note that this isn't triggered when the transform is eliminated via theScene Statement or exiting theContexts it exists in, such aswhen exiting the game menu.
replacedTriggered when the transform is replaced by another. The image will notactually hide until the ATL block finishes.
hover,idle,selected_hover,selected_idle,insensitive,selected_insensitiveTriggered when a button containing this transform, or a button contained bythis transform, enters the named state.
ATL curry and partial parameter passing
An ATL transform defined using theTransform Statement can have itsparameters set at different times. When calling an ATL transform like afunction, the resulting value is still a transform, and the parameters that werepassed a value are treated as though the value is the new default value of theparameter.
For example:
transformscreamer(child,screamee,wait_time=2,flash_time=.1):childpausewait_timescreameepauseflash_timechild# doing this doesn't raise an error (it would if it were a Python function)defineshorter_screamer=screamer(wait_time=1)defineeileen_excited_screamer=screamer(screamee="eileen excited",flash_time=.2)labelstart:showhhannahhhappyatscreamer(screamee="hhannahh surprised",wait_time=1.5)"Here is one way"showeileenvhappyateileen_excited_screamer"Here is another"showpatriciasadateileen_excited_screamer(screamee="patricia wow")"And you can also do this"
Note that theshorter_screamer transform, just as thescreamertransform, cannot be used directly likeshoweileenatscreamer, since theirscreamee parameters do not have a value.
Note also that, like labels and screens, the default values of the parameters ofa transform directly created by theTransform Statement will be evaluatedat the time when the transform iscalled, not at the time when it isdefined.
However, the transform resulting from calling another transform (such asshorter_screamer in the example above, or also the transform applied topatricia) has all the default values of its parameters already evaluated,whether they come from the evaluation of the default values in the originaltransform (such asshorter_screamer'sflash_time parameter, orpatricia's transform'swait_time parameter), or from values passed to it in acall earlier in the line (such asshorter_screamer'swait_timeparameter, or patricia's transform'sscreamee andflash_time parameters).
Special Child Parameter
If an ATL transform has a parameter named "child" and that parameter receives avalue,regardless of the kind of parameter or the way it receives a value(by a positional argument or by keyword, and even if the parameter ispositional-only or keyword-only, and defaulted or required), then in parallelthe child of the transform is set to the value of the parameter.
Note that the default value of the parameter doesn't count, the parameter has toreceive a value from the outside.
Conversely, when that ATL transform is used as a transform, thechild=keyword argument will be passed, and so in addition to setting the child, if aparameter is there to receive it (excluding positional-only parameters, since itis passed by keyword), it will have the child's value when the transformexecutes.
For example, this enables to swap between the supplied child and anotherdisplayable:
transformlucy_jump_scare(child):# the child is implicitly set as the child of the transformpause5# Jump scare"lucy mad"pause.2# Go back to the original childchild
It can also be used to place the original child inside acontains block:
transformmarquee(width,height=1.0,duration=2.0,child=None):xcenter0.5ycenter0.5crop(0,0,0.5,500)contains:childxanchor0.0xpos1.0lineardurationxanchor1.0xpos0.0
Theold_widget andnew_widget keyword-able parameters (meaning that theyshould not be positional-only) have a special use as part ofATL Transitions.
Warpers
A warper is a function that can change the amount of time an interpolationstatement considers to have elapsed. They are defined as functions from t to t',where t and t' are floating point numbers, with t ranging from 0.0 to 1.0 overthe given amount of time. (If the statement has 0 duration, then t is 1.0 whenit runs.) t' should start at 0.0 and end at 1.0, but can be greater or less. Thefollowing warpers are defined by default.
pausePause, then jump to the new value. If
t==1.0,t'=1.0. Otherwise,t'=0.0.linearLinear interpolation.
t'=teaseStart slow, speed up, then slow down.
t'=.5-math.cos(math.pi*t)/2.0easeinStart fast, then slow down.
t'=math.cos((1.0-t)*math.pi/2.0)easeoutStart slow, then speed up.
t'=1.0-math.cos(t*math.pi/2.0)
In addition, most of Robert Penner's easing functions are supported. Tomake the names match those above, the functions have been renamedsomewhat. Graphs of these standard functions can be found athttps://easings.net/.
Ren'Py Name | easings.net Name |
|---|---|
ease_back | easeInOut_back |
ease_bounce | easeInOut_bounce |
ease_circ | easeInOut_circ |
ease_cubic | easeInOut_cubic |
ease_elastic | easeInOut_elastic |
ease_expo | easeInOut_expo |
ease_quad | easeInOut_quad |
ease_quart | easeInOut_quart |
ease_quint | easeInOut_quint |
easein_back | easeOut_back |
easein_bounce | easeOut_bounce |
easein_circ | easeOut_circ |
easein_cubic | easeOut_cubic |
easein_elastic | easeOut_elastic |
easein_expo | easeOut_expo |
easein_quad | easeOut_quad |
easein_quart | easeOut_quart |
easein_quint | easeOut_quint |
easeout_back | easeIn_back |
easeout_bounce | easeIn_bounce |
easeout_circ | easeIn_circ |
easeout_cubic | easeIn_cubic |
easeout_elastic | easeIn_elastic |
easeout_expo | easeIn_expo |
easeout_quad | easeIn_quad |
easeout_quart | easeIn_quart |
easeout_quint | easeIn_quint |
These warpers can be accessed in the_warper read-only module, which containsthe functions listed above. It is useful for things in Ren'Py which take atime-warping function, such asDissolve(), which you can use like:
withDissolve(1,time_warp=_warper.easein_quad)
New warpers can be defined using therenpy.atl_warper decorator, in apythonearly block. It should be placed in a file that is parsed before any filethat uses the warper. This looks like:
pythonearlyhide:@renpy.atl_warperdeflinear(t):returnt
Replacing Transforms
When an ATL transform, a built-in transform or a transform defined using theTransform class is replaced by another transform of these categories,the properties of the outgoing transform are inherited by the incomingtransform. That inheritance doesn't apply for other kinds of transforms.
When theshow statement has multiple transforms in theat list, the transforms are matched from last to first, until one list runsout. For example:
showeileenhappyata,b,c"Dialogue !"showeileenhappyatd,e
Thec transform will be replaced bye, theb transform will bereplaced byd, and nothing replaces thea transform.
At the moment of replacement, if both transforms are of suitable kinds, thevalues of the properties of the old transform are copied to the new transform.If the old transform was animated, the current intermediate value is inherited.For example:
transformbounce:linear3.0xalign1.0linear3.0xalign0.0repeattransformheadright:linear15xalign1.0labelexample:showeileenhappyatbouncepauseshoweileenhappyatheadrightpause
In this example, the image will bounce from left to right and back until theplayer clicks. When that happens, thexalign property of thebouncetransform will be used to initialize thexalign property of theheadright transform, and so the image will move from where it was when theplayer first clicked.
The position properties (xpos,ypos,xanchor,yanchor, and properties setting them such asxalign orradius/angle) have a special rule for inheritance : a valueset in the child will override a value set in the parent. That is because adisplayable may have only one position, and a position that is actively settakes precedence.
Finally, when ashow statement does not include anat clause, the sametransforms are used, so no inheritance is necessary. To reset all transformproperties, hide and then show the displayable again. To break the animationsapplied to a displayable (but keep the position), you can use:
showeileenhappyatsome_animation"Wow, so this is what antigravity feels like !"showeileen:pass"But I'm happy when it settles down."
The Transform Class
One equivalent to to the simplest ATL transforms is the Transform class.
- classTransform(child=None,*,function=None,reset=False,**properties)
Creates a transform which applies operations such as cropping, rotation,scaling or alpha-blending to its child. A transform object has fieldscorresponding to thetransform properties,which it applies to its child.
- child
The child the transform applies to.
- reset
If True, the transform will reset properties to their default valueswhen it is shown, rather than inheriting those properties from thetransforms it replaces.
- function(trans:Transform,st:float,at:float,/)→int|None
If not None, this function will be called when the transform isrendered, with three positional arguments:
The transform object.
The shown timebase, in seconds.
The animation timebase, in seconds.
The function should return a delay, in seconds, after which it will becalled again, or None to be called again at the start of the nextinteraction.
This function should not have side effects other than changing theTransform object in the first argument, and may be called at any timewith any value as a part of prediction.
Additional keyword arguments are values that transform properties are setto. These particular transform properties will be set each time thetransform is drawn, and so may not be changed after the Transform object iscreated. Fields corresponding to other transform properties, however, can beset and changed afterwards, either within the function passed as thefunction parameter, or immediately before calling the
update()method.- hide_request
This attribute is set to true when the function is called, to indicatethat the transform is being hidden.
- hide_response
If
hide_requestis true, this can be set to false to prevent thetransform from being hidden.
- original_child
This is the child Displayable that was set when the transform was created,before any calls to set_child. This may be None if no child was during creation.
- set_child(child)
Call this method with a newchild to change the child of thistransform.
- update()
This should be called when a transform property field is updated outsideof the function passed as thefunction argument, to ensure that thechange takes effect.
Callables as transforms
Finally, simple Python callables can be used as transforms. These callablesshould take a singledisplayable as an argument, andreturn a new Displayable. For example:
initpython:# this transform uses the right and left transformsdefright_or_left(d):ifswitch:returnAt(d,right)else:returnAt(d,left)
That means that certain builtins which take a displayable and return a displayable,such asFlatten(), are also transforms and can be used as such.