Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Scripter for Scene and other updates
-
@mikael , I hope you dont mind all my replies....
But I did the below code, just testing. I have got some things wrong, but its ok. But the attempt was to try to make objects within a view a little self describing. Maybe its a very bad idea, but even bad ideas lead to good ideas sometimes :). My example only tries this with one label. But i can see many different ways to approach this. Maybe each obj as a custom class with a std method name like animate_view for example and then the main view could call the animate_view methods in the correct sequence.
Oh well food for thought! I am guessing you have sort of workflow as you say you have used Scripter in multiple projects you have been working on lately.import ui from scripter import * def move_offscreen_x(obj): if obj.frame.max_x: obj.x = -(obj.x + obj.frame.max_x) def mk_header_panel(w, h, hm=0, vm=0, **kwargs): h = ui.View(width=w, height=h, **kwargs) lb = ui.Label(frame=h.bounds, text='••• Altered Carbon •••', alignment=ui.ALIGN_CENTER, alpha=1) lb.font = ('Arial Rounded MT Bold', 48) h.add_subview(lb) ''' Just an idea, maybe a bad one! The idea is within the object creation, define the script func as well as the params. I have not thought this out. I just wanted to try... This example, does not work 100% because the text is aleady rendered in the view. ''' h.script = reveal_text h.params = {'view': lb, 'duration': 2} return h class CardA(ui.View): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.header = None self.cv = ui.View(frame=self.bounds.inset(12, 12), bg_color='purple', border_width=.5, corner_radius=12, flex='WH' ) self.add_subview(self.cv) self.make_view() def make_view(self): header = mk_header_panel(self.width, 150, bg_color='deeppink') self.cv.add_subview(header) self.header = header move_offscreen_x(self.header) self.card_reveal_script() @script def card_reveal_script(self): slide_value(self.cv, attribute='x', end_value=6, target=None, start_value=-self.width, duration=.3, delta_func=None, ease_func='easeIn', current_func=None, map_func=None, side_func=None) yield slide_value(self.header, attribute='x', end_value=0, target=None, start_value=self.width, duration=1, delta_func=None, ease_func='easeIn', current_func=None, map_func=None, side_func=None) yield ''' Just trying something different here! See if our object has a script attr, if it does we assume it has a param attr also. Another assumption(does not need to be an assumption) is that the params dict contains a key called view. Its popped of the dict, then rest of the dict is passed as the **kwargs to the obj.script func/method ''' if self.header.script: v = self.header.params.pop('view') self.header.script(v, **self.header.params) yield if __name__ == '__main__': f = (0, 0, 600, 800) c = CardA(frame=f) c.present('sheet')
-
@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 useease_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.
fly_in
,appear
and 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_subview
and running the animation. Not providing the parent would mean that the view would get presented instead.Thus,
fade_in(view)
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 :)
-
@Phuket2, yes,
fade_in
orfly_in
are 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>
@script
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.