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.
Aligning scene nodes while ui sceneView is animately resized
-
@rownn Couple options. notvery clean but can be fine tuned
from scene import * class MyScene1(Scene): ''' unless you plan to make copies of the scene theres no need to override __init__ βΊοΈ setup has everything needed ''' def setup(self): self.background_color= '#eee' self.frm = ShapeNode(parent=self, fill_color='red', stroke_color=None) lbl=LabelNode(text=f'{self.view.frame}', font=('Chalkboard SE', 16), position=Point(self.size[0]/2, self.size[1]-64), color='#00d412', parent=self) def viewSizeHasChanged(self): self.frm.position = (150,self.view.height/2-(500-self.view.height)/2) self.frm.path = ui.Path.rect(0,0,250,450) class MyScene2(Scene): def setup(self): self.background_color= '#eee' self.frm = ShapeNode(parent=self, fill_color='blue', stroke_color=None, anchor_point=(0.0, 1)) self.frm.position = (150, (self.view.height/2-(500-self.view.height)/2)) self.frm.path = ui.Path.rect(0,0,250,450) self.minimized=False self.updateSize=True self.lbl1=LabelNode(text=f'{self.view.frame}', font=('Chalkboard SE', 16), position=Point(self.size[0]/2, self.size[1]-64), color='#00d412', parent=self) self.lbl2=LabelNode(text=f'{self.frm.frame}', font=('Chalkboard SE', 16), position=Point(self.size[0]/2, self.size[1]-32), color='#00d412', parent=self) def Resize(self, node, progress): size= 50 if self.minimized else 450 self.frm.size = (self.frm.size[0], size/progress) def Toggle(self): self.minimized = not self.minimized self.frm.run_action(Action.call(self.Resize, 1.0)) def update(self): #self.frm.size=Size(self.view.width-50, self.view.height-50) self.frm.position= Point(25, self.size[1]-25) self.lbl2.text=f'{self.frm.frame}' def viewSizeHasChanged(self): pass class GUI(ui.View): def __init__(self): self.background_color = '#ddd' self.scales = (1, .25) self.state = True self.separator_H = 10 self.mainView = ui.View(frame=(50, 50, 300, 500), background_color='#fff') self.add_subview(self.mainView) self.mainView2 = ui.View(frame=(350, 50, 300, 500), background_color='#fff') self.add_subview(self.mainView2) self.sn = SceneView() self.sn.frame = self.mainView.bounds self.mainView.add_subview(self.sn) self.sn.scene = MyScene1() self.sn2 = SceneView() self.sn2.frame = self.mainView2.bounds self.mainView2.add_subview(self.sn2) self.sn2.scene = MyScene2() self.btn_1 = ui.Button(name='1', title='1', background_color= '#ddd', corner_radius = 12, action = self.btn_tapped1) self.btn_1.frame = (175, 275, 50, 50) self.add_subview(self.btn_1) self.btn_2 = ui.Button(name='2', title='2', background_color= '#ddd', corner_radius = 12, action = self.btn_tapped2) self.btn_2.frame = (475, 275, 50, 50) self.add_subview(self.btn_2) ''' :ui.View.layout(): now the scene's viewSizeHasChanged() will be called anytime the view is altered including initial display ''' def layout(self): self.sn.scene.viewSizeHasChanged() self.sn2.scene.viewSizeHasChanged() pass def btn_tapped1(self, sender): if sender.name == '1': self.state = (self.state+1)%2 self.animate(self.scales[self.state]) def btn_tapped2(self, sender): self.sn2.scene.Toggle() def animation(): self.mainView2.height = 100 if self.sn2.scene.minimized else 500 self.mainView2.y = 275 if self.sn2.scene.minimized else 50 ui.animate(animation, duration=1.0) def animate(self, H): ''' using Transform with ani ate you can scale, move and rotate the whole sceneView alternatively you can create an Action for the scene to change size while changing the views ''' def animation(): self.mainView.transform = ui.Transform.scale(1, H) ui.animate(animation, duration=0.5) if __name__ == '__main__': GUI().present('fullscreen')
-
@rownn said:
PS: Thought it would be clever to avoid the update method. Isnt it performance-consuming?
i thought this too before but as long as everything inside the update method does not take longer than
self.dt
your good πβΊοΈ -
When you look at the code for scene, there is an _update method that is getting called, that handles the Actions. Then it calla update. So performance wise, I think Actions and update methods are similar.
-
@JonB said:
When you look at the code for scene, there is an _update method that is getting called, that handles the Actions. Then it calla update. So performance wise, I think Actions and update methods are similar.
exactly. in my games ill actually use this to my advantage by staging animations and checks. for example you can move a node with
Action.move_by
and have a check inupdate
to make sure node isnt outside the screen. this insures the move is done before the check. Alternativily you can move your check intoScene.did_evaluate_actions()
only reason i dont use this method is because your check must wait until the action is finished and that could have been too long depending on current check being used.heres an example if anyone wants using all three steps to move the node and rmove it if off screen.
def did_evaluate_actions(self): self.move_node() def move_node(self): self.run_action(Action.move_by(-100, 0, 1.0, TIMING_EASE_IN_OUT)) def update(self): if self.position[0] < -self.size[0]-10: self.run_action(Action.remove())
adding a light rotate at the end and begining would give the rocking of a stop and go effect like in a cartoon. βΊοΈ
-
Hey guys,
amazing again. I think I will study you snippets over a glass of wine this evening :)
-
@rownn said:
Hey guys,
amazing again. I think I will study you snippets over a glass of wine this evening :)
π»
-
-
-
-
Pythonic not Pythonish. ;-) 500+ pages of results!
-
@rownn In my very old Fortan past, I used an integer 1 or 0, thus
flag = 1 - flag
-
@cvp, I vote for your version, which I plain forgot.