diff --git a/README.md b/README.md index 49e86ca..5a21056 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,7 @@ optional arguments: --min-distance DISTANCE min distance by km for track filter --with-animation add amimation to the poster + --animation-time amimation duration (default 30s) Heatmap Type Options: --heatmap-center LAT,LNG diff --git a/gpxtrackposter/circular_drawer.py b/gpxtrackposter/circular_drawer.py index e2f0944..aa8ce50 100644 --- a/gpxtrackposter/circular_drawer.py +++ b/gpxtrackposter/circular_drawer.py @@ -274,7 +274,11 @@ def _draw_circle_segment( if self.poster.with_animation: path.add( svgwrite.animate.Animate( - "opacity", dur="30s", values=values, keyTimes=key_times, repeatCount="indefinite" + "opacity", + dur=f"{self.poster.animation_time}s", + values=values, + keyTimes=key_times, + repeatCount="indefinite", ) ) g.add(path) diff --git a/gpxtrackposter/cli.py b/gpxtrackposter/cli.py index ecdd3b1..b20bc2a 100755 --- a/gpxtrackposter/cli.py +++ b/gpxtrackposter/cli.py @@ -199,6 +199,13 @@ def main() -> None: action="store_true", help="If the `poster` contains animation or not", ) + args_parser.add_argument( + "--animation-time", + dest="animation_time", + type=int, + default=30, + help="Animation show time", + ) for _, drawer in drawers.items(): drawer.create_args(args_parser) @@ -238,6 +245,7 @@ def main() -> None: p.set_athlete(args.athlete) p.set_title(args.title if args.title else p.translate("MY TRACKS")) p.set_with_animation(args.with_animation) + p.set_animation_time(args.animation_time) p.special_distance = { "special_distance": args.special_distance * Units().km, diff --git a/gpxtrackposter/github_drawer.py b/gpxtrackposter/github_drawer.py index 0e2e3d2..160bb87 100644 --- a/gpxtrackposter/github_drawer.py +++ b/gpxtrackposter/github_drawer.py @@ -92,6 +92,9 @@ def draw(self, dr: svgwrite.Drawing, g: svgwrite.container.Group, size: XY, offs rect_x = 10.0 dom = (2.6, 2.6) # add every day of this year for 53 weeks and per week has 7 days + animate_index = 1 + year_count = self.poster.year_tracks_date_count_dict[year] + key_times = utils.make_key_times(year_count) for _i in range(54): rect_y = offset.y + year_size + 2 for _j in range(7): @@ -113,8 +116,24 @@ def draw(self, dr: svgwrite.Drawing, g: svgwrite.container.Group, size: XY, offs color = special_color str_length = utils.format_float(self.poster.m2u(length)) date_title = f"{date_title} {str_length} {km_or_mi}" + # tricky for may cause animate error + if animate_index < len(key_times) - 1: + animate_index += 1 rect = dr.rect((rect_x, rect_y), dom, fill=color) + if self.poster.with_animation: + values = ( + ";".join(["0"] * animate_index) + ";" + ";".join(["1"] * (len(key_times) - animate_index)) + ) + rect.add( + svgwrite.animate.Animate( + "opacity", + dur=f"{self.poster.animation_time}s", + values=values, + keyTimes=";".join(key_times), + repeatCount="1", + ) + ) rect.set_desc(title=date_title) g_year.add(rect) github_rect_day += datetime.timedelta(1) diff --git a/gpxtrackposter/poster.py b/gpxtrackposter/poster.py index e8ba098..1be5947 100644 --- a/gpxtrackposter/poster.py +++ b/gpxtrackposter/poster.py @@ -74,6 +74,7 @@ def __init__(self) -> None: self.tracks_drawer: typing.Optional["TracksDrawer"] = None self._trans: typing.Optional[typing.Callable[[str], str]] = None self.with_animation = False + self.animation_time: int = 30 self.set_language(None, None) def set_language(self, language: typing.Optional[str], localedir: typing.Optional[str]) -> None: @@ -129,6 +130,9 @@ def set_title(self, title: str) -> None: def set_with_animation(self, with_animation: bool) -> None: self.with_animation = with_animation + def set_animation_time(self, animation_time: int) -> None: + self.animation_time = animation_time + def set_tracks(self, tracks: typing.List[Track]) -> None: """Associate the set of tracks with this poster.