Skip to content
This repository was archived by the owner on Mar 31, 2020. It is now read-only.

Commit 9747c1e

Browse files
committed
Performance enhancments on animations
1 parent 6d8fc22 commit 9747c1e

File tree

4 files changed

+55
-49
lines changed

4 files changed

+55
-49
lines changed

Pipfile.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
if __name__ == "__main__":
44
root = App()
5-
# root.protocol('WM_DELETE_WINDOW', root.cleanup)
5+
root.protocol('WM_DELETE_WINDOW', root.cleanup)
66
root.mainloop()

src/animate.py

Lines changed: 46 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
import tkinter as tk
44
import operator
55
import time
6-
from typing import NamedTuple, Callable, TypeVar, Generator, Tuple
6+
import math
7+
from typing import NamedTuple, Callable, TypeVar, Generator
78
from enum import Enum
89
from dataclasses import dataclass
9-
from functools import partialmethod, partial
10+
from functools import partialmethod
1011

1112

1213
class Coord(NamedTuple):
@@ -60,18 +61,18 @@ def midpoint(self, other: Coord) -> Coord:
6061
"""
6162
return (self + other) / 2
6263

63-
def distance(self, other: Coord) -> int:
64+
def distance(self, other: Coord) -> float:
6465
"""
65-
The Manhattan distance between `self` and `other`.
66+
The distance between `self` and `other`.
6667
6768
param:
6869
other: Coord -- THe point to consider.
6970
7071
return:
7172
int -- A numeric representation of the distance between two points.
7273
"""
73-
dist = map(abs, other - self)
74-
return sum(dist)
74+
diff = other - self
75+
return math.hypot(*diff)
7576

7677
__add__ = partialmethod(__apply, operator.add)
7778
__sub__ = partialmethod(__apply, operator.sub)
@@ -126,32 +127,26 @@ class Animater:
126127
```
127128
"""
128129
_motions = set()
129-
fps = 60
130130

131131
def __init__(self, canvas: tk.Canvas):
132132
self.canvas = canvas
133133

134134
def start(self):
135135
while self._motions:
136-
complete = self.run(self._motions.copy())
137-
self._motions -= complete
138-
time.sleep(1/self.fps)
139-
140-
def run(self, frame):
141-
done = set()
142-
for motion in frame:
143-
if not self.running:
144-
break
136+
print(self._motions)
137+
self.run()
138+
139+
def run(self):
140+
for motion in self._motions.copy():
145141
try:
146-
next(motion)()
142+
move = next(motion)
143+
move()
147144
self.canvas.update()
148145
except StopIteration:
149-
done.add(motion)
150-
self.canvas.update()
151-
return done
146+
self._motions.remove(motion)
152147

153148
def add(self, motion: Motion):
154-
self._motions.add(iter(motion))
149+
self._motions.add(motion.start())
155150

156151
def add_motion(self, id: int, end: Coord, **kwargs):
157152
motion = Motion(self.canvas, id, end, **kwargs)
@@ -180,28 +175,43 @@ def start(self) -> Generator[Callable]:
180175
"""
181176
The entry point for generating move commands.
182177
"""
183-
def frame(increment: Coord, count: int = 1):
184-
for _ in range(count):
185-
move(*increment)
186-
self.canvas.master.update_idletasks()
178+
self.time = time.time()
179+
self.start = self.current
180+
self.distance = self.start.distance(self.end)
181+
self.speed = self.speed ** 3
182+
while self.current != self.end:
183+
yield self.move
184+
185+
def move(self):
186+
self.canvas.move(self.id, *self.increment)
187+
self.canvas.update_idletasks()
187188

188-
start = self.current
189-
steps = round(start.distance(self.end) / self.speed)
190-
frames = round(steps / self.speed)
191-
increment = (self.end - start) / steps
189+
@property
190+
def time(self):
191+
return time.time() - self._time
192192

193-
for _ in range(frames):
194-
yield partial(frame, increment, round(steps / frames))
195-
buffer = self.end - self.current
196-
yield partial(frame, buffer)
193+
@time.setter
194+
def time(self, val):
195+
self._time = val
197196

198197
@property
199-
def move(self):
200-
return partial(self.canvas.move, self.id)
198+
def increment(self):
199+
mult = (self.time * self.speed) / self.distance
200+
point = (self.end - self.start) * mult + self.start
201+
202+
if point.distance(self.end) > self.journey:
203+
return self.end - self.current
204+
else:
205+
return point - self.current
206+
201207

202208
@property
203209
def current(self):
204-
return Coord(*self.canvas.coords(self.id)[:2])
210+
return Coord(*self.canvas.coords(self.id))
211+
212+
@property
213+
def journey(self):
214+
return self.current.distance(self.end)
205215

206216
def __iter__(self):
207217
return self.start()
@@ -214,7 +224,3 @@ def __hash__(self):
214224

215225
def __eq__(self):
216226
return isinstance(self, type(other)) and self.__key() == other.__key()
217-
218-
219-
class BounceBall(Motion):
220-

src/view.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@
1010

1111

1212
class Window(widget.PrimaryCanvas):
13-
animation_speed = 4
13+
animation_speed = 10
1414
current = None
1515
views = {}
1616

1717
def init(self):
1818
self.animater = Animater(self)
1919

2020
def __coord(self, id):
21-
return Coord(*self.coords(id)[:2])
21+
return Coord(*self.coords(id))
2222

2323
def __set(self, view: View, coord: Coord):
2424
wid = view.draw(coord, anchor='nw')

0 commit comments

Comments
 (0)