Skip to content

Commit

Permalink
Page transitions (#206)
Browse files Browse the repository at this point in the history
Close: #184
  • Loading branch information
jpnurmi committed Sep 15, 2022
1 parent 7fd68bc commit 85d0b8e
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 12 deletions.
15 changes: 3 additions & 12 deletions lib/src/themes/common_themes.dart
Expand Up @@ -3,6 +3,7 @@ import 'package:flutter/services.dart';
import 'package:yaru_colors/yaru_colors.dart';
import 'package:yaru/src/text/text_theme.dart';
import 'package:yaru/src/themes/constants.dart';
import 'package:yaru/src/themes/page_transitions.dart';

// AppBar

Expand Down Expand Up @@ -241,16 +242,6 @@ RadioThemeData _getRadioThemeData(Color primaryColor, Brightness brightness) {
);
}

const _desktopPageTransitionsBuilder = CupertinoPageTransitionsBuilder();

const _pageTransitionTheme = PageTransitionsTheme(
builders: {
TargetPlatform.linux: _desktopPageTransitionsBuilder,
TargetPlatform.macOS: _desktopPageTransitionsBuilder,
TargetPlatform.windows: _desktopPageTransitionsBuilder,
},
);

/// Helper function to create a new Yaru light theme
ThemeData createYaruLightTheme({
required ColorScheme colorScheme,
Expand All @@ -259,7 +250,7 @@ ThemeData createYaruLightTheme({
bool? useMaterial3 = true,
}) {
return ThemeData(
pageTransitionsTheme: _pageTransitionTheme,
pageTransitionsTheme: YaruPageTransitionsTheme.horizontal,
useMaterial3: useMaterial3,
tabBarTheme: TabBarTheme(labelColor: colorScheme.onSurface),
dialogTheme: _dialogThemeLight,
Expand Down Expand Up @@ -307,7 +298,7 @@ ThemeData createYaruDarkTheme({
bool? useMaterial3 = true,
}) {
return ThemeData(
pageTransitionsTheme: _pageTransitionTheme,
pageTransitionsTheme: YaruPageTransitionsTheme.horizontal,
useMaterial3: useMaterial3,
tabBarTheme: TabBarTheme(labelColor: Colors.white.withOpacity(0.8)),
dialogTheme: _dialogThemeDark,
Expand Down
151 changes: 151 additions & 0 deletions lib/src/themes/page_transitions.dart
@@ -0,0 +1,151 @@
import 'package:flutter/material.dart';

class YaruPageTransitionsTheme extends PageTransitionsTheme {
const YaruPageTransitionsTheme._({required super.builders});

/// Horizontal slide and fade page transitions.
///
/// This page transitions theme is best suited for applications using a
/// horizontal navigation pattern, such as classic desktop wizards or master-
/// detail applications in portrait mode.
static const horizontal = YaruPageTransitionsTheme._(
builders: {
TargetPlatform.linux: _horizontalBuilder,
TargetPlatform.macOS: _horizontalBuilder,
TargetPlatform.windows: _horizontalBuilder,
},
);

/// Vertical slide and fade page transitions.
///
/// This page transitions theme is best suited for applications using a
/// vertical navigation pattern, such as master-detail applications in
/// landscape mode.
static const vertical = YaruPageTransitionsTheme._(
builders: {
TargetPlatform.linux: _verticalBuilder,
TargetPlatform.macOS: _verticalBuilder,
TargetPlatform.windows: _verticalBuilder,
},
);

static const _horizontalBuilder = _YaruHorizontalPageTransitionsBuilder();
static const _verticalBuilder = _YaruVerticalPageTransitionsBuilder();
}

class _YaruHorizontalPageTransitionsBuilder extends PageTransitionsBuilder {
const _YaruHorizontalPageTransitionsBuilder();

@override
Widget buildTransitions<T>(
PageRoute<T>? route,
BuildContext? context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) {
return _YaruHorizontalPageTransitions(
animation: animation,
secondaryAnimation: secondaryAnimation,
child: child,
);
}
}

class _YaruHorizontalPageTransitions extends StatelessWidget {
_YaruHorizontalPageTransitions({
required Animation<double> animation,
required Animation<double> secondaryAnimation,
required this.child,
}) : _position = animation.drive(_tween.chain(_fastOutSlowInTween)),
_secondaryPosition = secondaryAnimation
.drive(_secondaryTween.chain(_fastOutSlowInTween)),
_opacity = animation.drive(_easeInTween),
_secondaryOpacity = secondaryAnimation.drive(_easeInTween);

static final _tween = Tween(begin: const Offset(0.2, 0.0), end: Offset.zero);
static final _secondaryTween =
Tween(begin: Offset.zero, end: const Offset(-0.2, 0.0));
static final _fastOutSlowInTween = CurveTween(curve: Curves.fastOutSlowIn);
static final _easeInTween = CurveTween(curve: Curves.easeIn);

final Animation<Offset> _position, _secondaryPosition;
final Animation<double> _opacity, _secondaryOpacity;
final Widget child;

@override
Widget build(BuildContext context) {
final textDirection = Directionality.of(context);
return SlideTransition(
position: _secondaryPosition,
textDirection: textDirection,
child: FadeTransition(
opacity: ReverseAnimation(_secondaryOpacity),
child: SlideTransition(
position: _position,
textDirection: textDirection,
child: FadeTransition(opacity: _opacity, child: child),
),
),
);
}
}

class _YaruVerticalPageTransitionsBuilder extends PageTransitionsBuilder {
const _YaruVerticalPageTransitionsBuilder();

@override
Widget buildTransitions<T>(
PageRoute<T>? route,
BuildContext? context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) {
return _YaruVerticalPageTransitions(
animation: animation,
secondaryAnimation: secondaryAnimation,
child: child,
);
}
}

class _YaruVerticalPageTransitions extends StatelessWidget {
_YaruVerticalPageTransitions({
required Animation<double> animation,
required Animation<double> secondaryAnimation,
required this.child,
}) : _position = animation.drive(_tween.chain(_fastOutSlowInTween)),
_secondaryPosition = secondaryAnimation
.drive(_secondaryTween.chain(_fastOutSlowInTween)),
_opacity = animation.drive(_easeInTween),
_secondaryOpacity = secondaryAnimation.drive(_easeOutTween);

static final _tween = Tween(begin: const Offset(0.0, 0.1), end: Offset.zero);
static final _secondaryTween =
Tween(begin: Offset.zero, end: const Offset(0.0, 0.0));
static final _fastOutSlowInTween = CurveTween(curve: Curves.fastOutSlowIn);
static final _easeInTween = CurveTween(curve: Curves.easeIn);
static final _easeOutTween = CurveTween(curve: Curves.easeOutExpo);

final Animation<Offset> _position, _secondaryPosition;
final Animation<double> _opacity, _secondaryOpacity;
final Widget child;

@override
Widget build(BuildContext context) {
final textDirection = Directionality.of(context);
return SlideTransition(
position: _secondaryPosition,
textDirection: textDirection,
child: FadeTransition(
opacity: ReverseAnimation(_secondaryOpacity),
child: SlideTransition(
position: _position,
textDirection: textDirection,
child: FadeTransition(opacity: _opacity, child: child),
),
),
);
}
}
1 change: 1 addition & 0 deletions lib/yaru.dart
Expand Up @@ -5,6 +5,7 @@ export 'package:yaru/src/themes/extensions.dart';
export 'package:yaru/src/themes/high_contrast.dart';
export 'package:yaru/src/themes/kubuntu.dart';
export 'package:yaru/src/themes/lubuntu.dart';
export 'package:yaru/src/themes/page_transitions.dart';
export 'package:yaru/src/themes/ubuntu_budgie.dart';
export 'package:yaru/src/themes/ubuntu_mate.dart';
export 'package:yaru/src/themes/ubuntu_studio.dart';
Expand Down

0 comments on commit 85d0b8e

Please sign in to comment.