Scripter for Scene and other updates
At the beginning of this year, Pythonista 3.2 brought support for ui.View.update, and thus made Scripter available for everyone.
I have been using Scripter for UI animations in about every one of my projects for the past months, have been happy with its efficiency and stability, and thus wanted to just promote it a bit more.
Here are some recent updates to the tool:
- Scrolling banner view
- Scripter in scene animations
- Scripter for long-running tasks and polling
Scrolling banner view
c = ScrollingBannerLabel( text='Happy Pythonista 3.2 *****', text_color='green', font=('Futura', 24), initial_delay=0.5, scrolling_speed=50)
Simple utility view, handy for news ticker type use cases, with an adjustable initial delay and scrolling speed:
Scripter for Scene Nodes
Turned out that it was very easy to enable Scripter in Scenes. Whereas on the UI side I would consider Scripter 'essential' (providing functionality that is not really there otherwise), for Scenes it is 'nice to have', or available if you want to use the same syntax in both UI and Scenes.
Here's an example:
from scripter import * from scene import * class MyScene (Scene): @script # setup can be a script def setup(self): self.background_color = 'black' s = self.ship = SpriteNode( 'spc:PlayerShip1Orange', alpha=0, scale=2, position=self.size/2, parent=self) yield 1.0 pulse(self, 'white') s = self.ship show(s, duration=2.0) scale_to(s, 1, duration=2.0) yield wobble(s) yield move_by(s, 0, 100) yield fly_out(s, 'up') yield l = LabelNode( text='Tap anywhere', position=self.size/2, parent=self) reveal_text(l) yield 2.0 hide(l) @script # touch events can be scripts def touch_began(self, touch): target = Vector(touch.location) vector = target - self.ship.position rotate_to(self.ship, vector.degrees-90) yield move_to(self.ship, *target, duration=0.7, ease_func=sinusoidal) run(MyScene())
Long-running task, polling etc.
This is not an update to Scripter, just an expansion of my understanding on what it can be useful for.
As Scripter has a lot parallels to things like asyncio, it can also be used to run long-running computations without freezing the UI and without threads, or to implement polling for some conditions.
These require that you can insert a
yieldstatement somewhere in your computation or loop, so calling long-running third party functions is not really an option.
@Phuket2, thanks for pointing out the error. It is fixed in the repo.
I will get back to the other points soon.
@mikael , thanks! Rotating examples working now. Maybe its not a big deal, but in the demo, maybe some of the btns like 'roll to' should have the button's enable property set to False until its finished animating. Look its a small issue, But more than likely in an implementation you would want this behaviour.
Ok, sir @Phuket2!
First of all, a big thank you for all the ideas and feedback.
Regarding the ease functions, in the current version all functions are available as functions, i.e. can be found with autocomplete. Support for the string arguments was retained for backwards compatibility only.
Thus, instead of
ease_func='easeIn', just use
ease_func=ease_in. Function names are the same as in the reference graphic.
Regarding the demos not stopping if you click another button - yes, but I was too lazy to implement it. Also, you can get some crazy fun effects with the current setup.
appearand other similar PowerPoint-type "view introduction" functions do seem like a good idea. The challenge there is that in order to be animated, the view needs to in the view hierarchy, and thus you suddenly need to care where the view 'starts', not just where you want it to end up.
To avoid this, we could have the intro functions take an additional view as a parent view, then the function could take care of placing the view suitably before calling
add_subviewand running the animation. Not providing the parent would mean that the view would get presented instead.
would fade the root view into visibility, while
fly_in(child, 'from_left', 100, 100, parent=view)
would bring in a child view, after having added it as a subview.
This would be in line with the rest of the Scripter API, but would not really support the "view manages itself" philosophy.
Have you gone further with your experiment?
@mikael , thanks for the update. It appears that maybe you haven't pushed the last update to the repo. Last update appears to be the corrections for the rotation.
Yes I understand your comments about self animating views (so to speak). Over the last few days I haven't had much time to experiment all though I do some stuff each day. But look for whatever reason, animations scare the hell out of me :) Just a mental block about the math. Eg. Easy for me to get confused. So its slow going for me. But, I am going to stick at it. The prospect of being able to construct views like this and other View animations on this site is exciting to me.
Anyway, I will keep working on it. I have always been a little suprised that some of these more tantalising animations/transitions views have not shown up in Pythonista apps. Aka the feeling you are using a very polished native app. Its not a criticism, I just think its not a real focus for a lot of Python programmers (UI). Maybe I need to be burnt at the stake for that comment :)
fly_inare not implemented yet, they were just examples for the discussion, to get a feel for how the API would look and whether they would really match what you were looking for.
In terms of the finished look that you get with a little bit of animation here and there, I obviously agree.
@mikael , ok no problems. I just misunderstood your post. I started having problems yesterday (I think after I updated to 11.2.5) about script not being defined. Strange, the trace back is below. I didn't have much time to found out the cause. The only thing i can think of is how I copied the Scripter code into Pythonista (I did a drag and drop copy from a clone of the repo in Working Copy). I am not really sure. Anyway, I am not really reporting it here as I need to try more things first.
Anyway, when I come across this issue, I was just going to make a view that used your wobble script to wobble a ui.Button at regular interval (to draw attention to it). I was just interested to see how this all would work out. I.e the containing view having and update method as well as calling the script on the container views update fire. I assume it would work.
As far as I can see there is no way for a script to re-animate given a duration/pause(maybe I am wrong) but I think its an interesting point, as some elements in a ui, you would like them to continue to animate forever, but with a pause between the animations so its not over the top. Even better the pause could have a ease function. Anyway, I am just talking giving my ideas. I dont expect anything from you, its your project.
I come from the dummies side of things, meaning the less I need to know about using a Lib the better. But I do understand that libs are also written with a certain expectation that the user of the Lib/module has a degree of understanding of some primitives core to the lib.
Traceback (most recent call last):
File "/private/var/mobile/Containers/Shared/AppGroup/3533032E-E336-4C25-BBC4-112A6BF2AF75/Pythonista3/Documents/site-packages-3/scripter/scripter-demo.py", line 90, in <module>
NameError: name 'script' is not defined
@Phuket2, for what it is worth, I am running 11.2.5, and I do not get the error.
For the repeating wiggle, I would do:
@script def notice(view): while True: wobble(view) yield 5
Could also use different wait times, and could use the ease functions to calculate each wait.
@mikael, thanks for your reply. As regards to the error I am having, I am pretty sure somehow I have corrupted something. But at the moment my home internet is on and off like a yoyo :( Its cable issues in the streets. So its not so easy to do app downloads etc to reset. I will have to wait until they sort it out, again!
I like your example notice! But it really does illustrates something. How you intend your lib to be used. I know its going to seem stupid, but the name of the Lib does says it all. I didn't really get that somehow. I was looking at your lib more from a macro point of view rather than a micro POV.
I am not sure I have explained that clearly or not. But as I say, I will keep trying to get my head around it. In terms of doing animated views vrs PowerPoint slides concept. One could say they are they same or very similar(but they are not). I think the great thing is that your lib/module can support either direction. At least I think that...
@Phuket2, I hear you. I think the approach here is to ”script” and publish the most generalized scripts as ”macros”, but unless you sort of internalize the basic ”philosophy of yielding”, it is very difficult to get the best out of the lib.