Merge branch 'master' into feature/add-android-themed-icon-support
Merged master
This commit is contained in:
commit
65803c927c
@ -1,5 +1,6 @@
|
||||
{
|
||||
"appName": "Wonderous",
|
||||
"localeSwapButton": "简体中文",
|
||||
"animatedArrowSemanticSwipe": "Explore details about {title}.",
|
||||
"appBarTitleFactsHistory": "Facts and History",
|
||||
"appBarTitleConstruction": "Construction",
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"appName": "Wonderous",
|
||||
"localeSwapButton": "English",
|
||||
"animatedArrowSemanticSwipe": "查看关于{title}的详细信息。",
|
||||
"appBarTitleFactsHistory": "历史与细节",
|
||||
"appBarTitleConstruction": "建造",
|
||||
|
@ -30,8 +30,11 @@ class AppLogic {
|
||||
// Localizations
|
||||
await localeLogic.load();
|
||||
|
||||
// Data load
|
||||
wondersLogic.init();
|
||||
|
||||
// Timeline
|
||||
await timelineLogic.init();
|
||||
timelineLogic.init();
|
||||
|
||||
// Settings
|
||||
await settingsLogic.load();
|
||||
|
@ -1,8 +1,7 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:intl/intl_standalone.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:intl/intl_standalone.dart';
|
||||
import 'package:wonders/common_libs.dart';
|
||||
|
||||
class LocaleLogic {
|
||||
AppLocalizations? _strings;
|
||||
@ -10,6 +9,8 @@ class LocaleLogic {
|
||||
|
||||
bool get isLoaded => _strings != null;
|
||||
|
||||
bool get isEnglish => strings.localeName == 'en';
|
||||
|
||||
Future<void> load() async {
|
||||
final localeCode = await findSystemLocale();
|
||||
Locale locale = Locale(localeCode.split('_')[0]);
|
||||
@ -20,6 +21,13 @@ class LocaleLogic {
|
||||
if (AppLocalizations.supportedLocales.contains(locale) == false) {
|
||||
locale = Locale('en');
|
||||
}
|
||||
settingsLogic.currentLocale.value = locale.languageCode;
|
||||
_strings = await AppLocalizations.delegate.load(locale);
|
||||
}
|
||||
|
||||
Future<void> refreshIfChanged(Locale locale) async {
|
||||
if (_strings?.localeName != locale.languageCode && AppLocalizations.supportedLocales.contains(locale)) {
|
||||
_strings = await AppLocalizations.delegate.load(locale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:wonders/common_libs.dart';
|
||||
import 'package:wonders/logic/common/save_load_mixin.dart';
|
||||
|
||||
class SettingsLogic with ThrottledSaveLoadMixin {
|
||||
@ -7,6 +8,7 @@ class SettingsLogic with ThrottledSaveLoadMixin {
|
||||
|
||||
late final hasCompletedOnboarding = ValueNotifier<bool>(false)..addListener(scheduleSave);
|
||||
late final hasDismissedSearchMessage = ValueNotifier<bool>(false)..addListener(scheduleSave);
|
||||
late final currentLocale = ValueNotifier<String>('en')..addListener(scheduleSave);
|
||||
|
||||
final bool useBlurs = defaultTargetPlatform != TargetPlatform.android;
|
||||
|
||||
@ -23,4 +25,11 @@ class SettingsLogic with ThrottledSaveLoadMixin {
|
||||
'hasDismissedSearchMessage': hasDismissedSearchMessage.value,
|
||||
};
|
||||
}
|
||||
|
||||
Future<void> setLocale(Locale value) async {
|
||||
currentLocale.value = value.languageCode;
|
||||
await localeLogic.refreshIfChanged(value);
|
||||
wondersLogic.init();
|
||||
timelineLogic.init();
|
||||
}
|
||||
}
|
||||
|
@ -3,18 +3,17 @@ import 'package:wonders/logic/common/string_utils.dart';
|
||||
import 'package:wonders/logic/data/timeline_data.dart';
|
||||
|
||||
class TimelineLogic {
|
||||
final List<TimelineEvent> events = [];
|
||||
List<TimelineEvent> events = [];
|
||||
|
||||
Future<void> init() async {
|
||||
events.addAll(GlobalEventsData().globalEvents);
|
||||
|
||||
for (var w in wondersLogic.all) {
|
||||
events.add(
|
||||
TimelineEvent(
|
||||
void init() {
|
||||
events = [
|
||||
...GlobalEventsData().globalEvents,
|
||||
...wondersLogic.all.map(
|
||||
(w) => TimelineEvent(
|
||||
w.startYr,
|
||||
StringUtils.supplant($strings.timelineLabelConstruction, {'{title}': w.title}),
|
||||
),
|
||||
);
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -10,16 +10,7 @@ import 'package:wonders/logic/data/wonders_data/pyramids_giza_data.dart';
|
||||
import 'package:wonders/logic/data/wonders_data/taj_mahal_data.dart';
|
||||
|
||||
class WondersLogic {
|
||||
late List<WonderData> all = [
|
||||
GreatWallData(),
|
||||
PetraData(),
|
||||
ColosseumData(),
|
||||
ChichenItzaData(),
|
||||
MachuPicchuData(),
|
||||
TajMahalData(),
|
||||
ChristRedeemerData(),
|
||||
PyramidsGizaData(),
|
||||
];
|
||||
List<WonderData> all = [];
|
||||
|
||||
final int timelineStartYear = -3000;
|
||||
final int timelineEndYear = 2200;
|
||||
@ -29,4 +20,17 @@ class WondersLogic {
|
||||
if (result == null) throw ('Could not find data for wonder type $value');
|
||||
return result;
|
||||
}
|
||||
|
||||
void init() {
|
||||
all = [
|
||||
GreatWallData(),
|
||||
PetraData(),
|
||||
ColosseumData(),
|
||||
ChichenItzaData(),
|
||||
MachuPicchuData(),
|
||||
TajMahalData(),
|
||||
ChristRedeemerData(),
|
||||
PyramidsGizaData(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,11 @@ class WondersApp extends StatelessWidget {
|
||||
const WondersApp({Key? key}) : super(key: key);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ValueListenableBuilder<String>(
|
||||
valueListenable: settingsLogic.currentLocale,
|
||||
builder: (_, localeCode, __) {
|
||||
return MaterialApp.router(
|
||||
locale: Locale(localeCode),
|
||||
debugShowCheckedModeBanner: false,
|
||||
routerDelegate: appRouter.routerDelegate,
|
||||
routeInformationProvider: appRouter.routeInformationProvider,
|
||||
@ -45,6 +49,8 @@ class WondersApp extends StatelessWidget {
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Create singletons (controllers and services) that can be shared across the app.
|
||||
|
@ -134,6 +134,9 @@ class _Insets {
|
||||
|
||||
@immutable
|
||||
class _Shadows {
|
||||
final textSoft = [
|
||||
Shadow(color: Colors.black.withOpacity(.25), offset: Offset(0, 2), blurRadius: 4),
|
||||
];
|
||||
final text = [
|
||||
Shadow(color: Colors.black.withOpacity(.6), offset: Offset(0, 2), blurRadius: 2),
|
||||
];
|
||||
|
@ -52,9 +52,8 @@ class CollectibleItem extends StatelessWidget with GetItMixin {
|
||||
),
|
||||
)
|
||||
.animate(onPlay: (controller) => controller.repeat())
|
||||
// TODO SB (Aug 17, 2022): Temporarily removed on Jonahs request, due to a bug in Impeller which should be fixed soon. Re-enable when fixed.
|
||||
//.shimmer(delay: 4000.ms, duration: $styles.times.med * 3)
|
||||
.shake(delay: 4000.ms, duration: $styles.times.med * 3, curve: Curves.easeInOutCubic, hz: 4)
|
||||
.shimmer(delay: 4000.ms, duration: $styles.times.med * 3)
|
||||
.shake(curve: Curves.easeInOutCubic, hz: 4)
|
||||
.scale(begin: 1.0, end: 1.1, duration: $styles.times.med)
|
||||
.then(delay: $styles.times.med)
|
||||
.scale(begin: 1.0, end: 1 / 1.1),
|
||||
|
@ -5,7 +5,7 @@ class DiagonalTextPageIndicator extends StatelessWidget {
|
||||
const DiagonalTextPageIndicator({Key? key, required this.current, required this.total}) : super(key: key);
|
||||
final int current;
|
||||
final int total;
|
||||
static const double _fontSize = 32;
|
||||
static const double _fontSize = 26;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -21,10 +21,7 @@ class DiagonalTextPageIndicator extends StatelessWidget {
|
||||
child: Transform.translate(
|
||||
offset: Offset(-_fontSize * .7, 0),
|
||||
child: SizedBox(
|
||||
width: size,
|
||||
height: size,
|
||||
child: Text('0$current',
|
||||
style: textStyle.copyWith(shadows: $styles.shadows.text), textAlign: TextAlign.right)),
|
||||
width: size, height: size, child: Text('0$current', style: textStyle, textAlign: TextAlign.right)),
|
||||
),
|
||||
),
|
||||
ClipPath(
|
||||
@ -38,7 +35,7 @@ class DiagonalTextPageIndicator extends StatelessWidget {
|
||||
opacity: .5,
|
||||
child: Text(
|
||||
'0$total',
|
||||
style: textStyle.copyWith(shadows: $styles.shadows.textStrong),
|
||||
style: textStyle, //.copyWith(shadows: $styles.shadows.textStrong),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
19
lib/ui/common/controls/locale_switcher.dart
Normal file
19
lib/ui/common/controls/locale_switcher.dart
Normal file
@ -0,0 +1,19 @@
|
||||
import 'package:wonders/common_libs.dart';
|
||||
|
||||
class LocaleSwitcher extends StatelessWidget with GetItMixin {
|
||||
LocaleSwitcher({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final locale = watchX((SettingsLogic s) => s.currentLocale);
|
||||
Future<void> handleSwapLocale() async {
|
||||
final newLocale = Locale(locale == 'en' ? 'zh' : 'en');
|
||||
await settingsLogic.setLocale(newLocale);
|
||||
}
|
||||
|
||||
return AppBtn.from(
|
||||
padding: EdgeInsets.symmetric(vertical: $styles.insets.sm, horizontal: $styles.insets.sm),
|
||||
text: $strings.localeSwapButton,
|
||||
onPressed: handleSwapLocale);
|
||||
}
|
||||
}
|
@ -31,11 +31,10 @@ class _ResultsGrid extends StatelessWidget {
|
||||
}
|
||||
|
||||
Widget _buildLanguageMessage(BuildContext context) {
|
||||
bool isEnglish = localeLogic.strings.localeName == 'en';
|
||||
return ValueListenableBuilder<bool>(
|
||||
valueListenable: settingsLogic.hasDismissedSearchMessage,
|
||||
builder: (_, value, __) {
|
||||
if (isEnglish || value) return SizedBox();
|
||||
if (localeLogic.isEnglish || value) return SizedBox();
|
||||
return AppBtn.basic(
|
||||
onPressed: () => settingsLogic.hasDismissedSearchMessage.value = true,
|
||||
semanticLabel: $strings.resultsSemanticDismiss,
|
||||
|
@ -9,7 +9,7 @@ class _CollapsingPullQuoteImage extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
// Start transitioning when we are halfway up the screen
|
||||
final collapseStartPx = context.heightPx * 1;
|
||||
final collapseEndPx = context.heightPx * .35;
|
||||
final collapseEndPx = context.heightPx * .15;
|
||||
const double imgHeight = 430;
|
||||
const double outerPadding = 100;
|
||||
|
||||
|
@ -28,8 +28,7 @@ class _ScrollingContent extends StatelessWidget {
|
||||
final String dropChar = value.substring(0, 1);
|
||||
final textScale = MediaQuery.of(context).textScaleFactor;
|
||||
final double dropCapWidth = StringUtils.measure(dropChar, dropStyle).width * textScale;
|
||||
final bool isEnglish = localeLogic.strings.localeName == 'en'; //TODO EC: Helper method for localLogic.isEnglish?
|
||||
final bool skipCaps = !isEnglish || MediaQuery.of(context).accessibleNavigation;
|
||||
final bool skipCaps = !localeLogic.isEnglish || MediaQuery.of(context).accessibleNavigation;
|
||||
return Semantics(
|
||||
label: value,
|
||||
child: !skipCaps
|
||||
|
@ -14,6 +14,8 @@ class _TitleText extends StatelessWidget {
|
||||
children: [
|
||||
Gap($styles.insets.md),
|
||||
Gap(30),
|
||||
|
||||
/// Sub-title row
|
||||
SeparatedRow(
|
||||
padding: EdgeInsets.symmetric(horizontal: $styles.insets.sm),
|
||||
separatorBuilder: () => Gap($styles.insets.sm),
|
||||
@ -39,14 +41,23 @@ class _TitleText extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
Gap($styles.insets.md),
|
||||
Semantics(sortKey: OrdinalSortKey(0), child: WonderTitleText(data)),
|
||||
|
||||
/// Wonder title text
|
||||
Semantics(
|
||||
sortKey: OrdinalSortKey(0),
|
||||
child: WonderTitleText(data),
|
||||
),
|
||||
Gap($styles.insets.xs),
|
||||
|
||||
/// Region
|
||||
Text(
|
||||
data.regionTitle.toUpperCase(),
|
||||
style: $styles.text.title1,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
Gap($styles.insets.md),
|
||||
|
||||
/// Compass divider
|
||||
ExcludeSemantics(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: $styles.insets.md),
|
||||
@ -61,6 +72,8 @@ class _TitleText extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
Gap($styles.insets.sm),
|
||||
|
||||
/// Date
|
||||
Text(
|
||||
StringUtils.supplant(
|
||||
$strings.titleLabelDate,
|
||||
|
@ -12,6 +12,7 @@ import 'package:wonders/ui/screens/home_menu/home_menu.dart';
|
||||
import 'package:wonders/ui/wonder_illustrations/common/animated_clouds.dart';
|
||||
import 'package:wonders/ui/wonder_illustrations/common/wonder_illustration.dart';
|
||||
import 'package:wonders/ui/wonder_illustrations/common/wonder_illustration_config.dart';
|
||||
import 'package:wonders/ui/wonder_illustrations/common/wonder_title_text.dart';
|
||||
|
||||
part '_vertical_swipe_controller.dart';
|
||||
part 'widgets/_animated_arrow_button.dart';
|
||||
@ -143,7 +144,7 @@ class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateM
|
||||
Stack(children: [
|
||||
/// Foreground gradient-1, gets darker when swiping up
|
||||
BottomCenter(
|
||||
child: _buildSwipeableBgGradient(currentWonder.type.bgColor.withOpacity(.5)),
|
||||
child: _buildSwipeableBgGradient(currentWonder.type.bgColor.withOpacity(.65)),
|
||||
),
|
||||
|
||||
/// Foreground decorators
|
||||
@ -151,13 +152,16 @@ class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateM
|
||||
|
||||
/// Foreground gradient-2, gets darker when swiping up
|
||||
BottomCenter(
|
||||
child: _buildSwipeableBgGradient(currentWonder.type.bgColor.withOpacity(.5)),
|
||||
child: _buildSwipeableBgGradient(currentWonder.type.bgColor.withOpacity(1)),
|
||||
),
|
||||
|
||||
/// Floating controls / UI
|
||||
AnimatedSwitcher(
|
||||
duration: $styles.times.fast,
|
||||
child: RepaintBoundary(
|
||||
key: ObjectKey(currentWonder),
|
||||
child: IgnorePointer(
|
||||
ignoringSemantics: false,
|
||||
child: OverflowBox(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@ -168,14 +172,12 @@ class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateM
|
||||
/// Title Content
|
||||
LightText(
|
||||
child: MergeSemantics(
|
||||
child: Transform.translate(
|
||||
offset: Offset(0, 30),
|
||||
child: Column(
|
||||
children: [
|
||||
/// Page indicator
|
||||
IgnorePointer(
|
||||
child: DiagonalTextPageIndicator(current: _wonderIndex + 1, total: _numWonders),
|
||||
),
|
||||
Gap($styles.insets.sm),
|
||||
|
||||
WonderTitleText(currentWonder, enableShadows: true),
|
||||
Gap($styles.insets.md),
|
||||
AppPageIndicator(
|
||||
count: _numWonders,
|
||||
controller: _pageController,
|
||||
@ -184,11 +186,12 @@ class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateM
|
||||
onDotPressed: _handlePageIndicatorDotPressed,
|
||||
semanticPageTitle: $strings.homeSemanticWonder,
|
||||
),
|
||||
Gap($styles.insets.md),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Gap($styles.insets.xs),
|
||||
),
|
||||
|
||||
/// Animated arrow and background
|
||||
/// Wrap in a container that is full-width to make it easier to find for screen readers
|
||||
@ -218,6 +221,7 @@ class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateM
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
/// Menu Btn
|
||||
TopLeft(
|
||||
@ -306,7 +310,7 @@ class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateM
|
||||
return _swipeController.buildListener(builder: (swipeAmt, isPointerDown, _) {
|
||||
return IgnorePointer(
|
||||
child: FractionallySizedBox(
|
||||
heightFactor: .5,
|
||||
heightFactor: .6,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
@ -314,7 +318,7 @@ class _HomeScreenState extends State<HomeScreen> with SingleTickerProviderStateM
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [
|
||||
fgColor.withOpacity(0),
|
||||
fgColor.withOpacity(fgColor.opacity * .75 + (isPointerDown ? .05 : 0) + swipeAmt * .20),
|
||||
fgColor.withOpacity(.5 + fgColor.opacity * .25 + (isPointerDown ? .05 : 0) + swipeAmt * .20),
|
||||
],
|
||||
stops: const [0, 1],
|
||||
),
|
||||
|
@ -4,6 +4,7 @@ import 'package:wonders/common_libs.dart';
|
||||
import 'package:wonders/logic/data/wonder_data.dart';
|
||||
import 'package:wonders/ui/common/app_backdrop.dart';
|
||||
import 'package:wonders/ui/common/app_icons.dart';
|
||||
import 'package:wonders/ui/common/controls/locale_switcher.dart';
|
||||
import 'package:wonders/ui/screens/home_menu/about_dialog_content.dart';
|
||||
|
||||
class HomeMenu extends StatelessWidget {
|
||||
@ -49,11 +50,23 @@ class HomeMenu extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
|
||||
SafeArea(
|
||||
child: PaddedRow(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: $styles.insets.md,
|
||||
vertical: $styles.insets.sm,
|
||||
),
|
||||
children: [
|
||||
/// Back btn
|
||||
BackBtn.close(
|
||||
bgColor: Colors.transparent,
|
||||
iconColor: $styles.colors.offWhite,
|
||||
).safe(),
|
||||
),
|
||||
Spacer(),
|
||||
LocaleSwitcher()
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
/// Content
|
||||
Positioned.fill(
|
||||
@ -75,7 +88,7 @@ class HomeMenu extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
@ -106,6 +119,9 @@ class HomeMenu extends StatelessWidget {
|
||||
}
|
||||
|
||||
Widget _buildBottomBtns(BuildContext context) {
|
||||
return ValueListenableBuilder(
|
||||
valueListenable: settingsLogic.currentLocale,
|
||||
builder: (_, __, ___) {
|
||||
return SeparatedColumn(
|
||||
separatorBuilder: () => Divider(thickness: 1.5, height: 1).animate().scale(
|
||||
duration: $styles.times.slow,
|
||||
@ -131,6 +147,7 @@ class HomeMenu extends StatelessWidget {
|
||||
.fade(delay: $styles.times.pageTransition + 50.ms)
|
||||
.slide(begin: Offset(0, .1), curve: Curves.easeOut),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _buildGridBtn(BuildContext context, WonderData btnData) {
|
||||
|
@ -19,11 +19,7 @@ class _IntroScreenState extends State<IntroScreen> {
|
||||
static const double _textHeight = 155;
|
||||
static const double _pageIndicatorHeight = 55;
|
||||
|
||||
static List<_PageData> pageData = [
|
||||
_PageData($strings.introTitleJourney, $strings.introDescriptionNavigate, 'camel', '1'),
|
||||
_PageData($strings.introTitleExplore, $strings.introDescriptionUncover, 'petra', '2'),
|
||||
_PageData($strings.introTitleDiscover, $strings.introDescriptionLearn, 'statue', '3'),
|
||||
];
|
||||
static List<_PageData> pageData = [];
|
||||
|
||||
late final PageController _pageController = PageController()..addListener(_handlePageChanged);
|
||||
final ValueNotifier<int> _currentPage = ValueNotifier(0);
|
||||
@ -51,6 +47,13 @@ class _IntroScreenState extends State<IntroScreen> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// Set the page data, as strings may have changed based on locale
|
||||
pageData = [
|
||||
_PageData($strings.introTitleJourney, $strings.introDescriptionNavigate, 'camel', '1'),
|
||||
_PageData($strings.introTitleExplore, $strings.introDescriptionUncover, 'petra', '2'),
|
||||
_PageData($strings.introTitleDiscover, $strings.introDescriptionLearn, 'statue', '3'),
|
||||
];
|
||||
|
||||
// This view uses a full screen PageView to enable swipe navigation.
|
||||
// However, we only want the title / description to actually swipe,
|
||||
// so we stack a PageView with that content over top of all the other
|
||||
|
@ -17,7 +17,7 @@ class WonderTitleText extends StatelessWidget {
|
||||
);
|
||||
bool smallText = [WonderType.christRedeemer, WonderType.colosseum].contains(data.type);
|
||||
if (smallText) {
|
||||
textStyle = textStyle.copyWith(fontSize: 48);
|
||||
textStyle = textStyle.copyWith(fontSize: 56);
|
||||
}
|
||||
|
||||
// First, get a list like: ['the\n', 'great wall']
|
||||
@ -40,13 +40,16 @@ class WonderTitleText extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
List<Shadow> shadows = enableShadows ? $styles.shadows.text : [];
|
||||
return RichText(
|
||||
List<Shadow> shadows = enableShadows ? $styles.shadows.textSoft : [];
|
||||
return Hero(
|
||||
tag: 'wonderTitle-$title',
|
||||
child: RichText(
|
||||
textAlign: TextAlign.center,
|
||||
text: TextSpan(
|
||||
style: textStyle.copyWith(shadows: shadows),
|
||||
children: pieces.map(buildTextSpan).toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -56,17 +56,20 @@ class TajMahalIllustration extends StatelessWidget {
|
||||
alignment: Alignment(0, config.shortMode ? 1 : -.15),
|
||||
child: FractionallySizedBox(
|
||||
widthFactor: config.shortMode ? 1 : 1.7,
|
||||
child: WonderHero(config, 'taj-mg',
|
||||
child: Stack(
|
||||
children: [
|
||||
Image.asset('$assetPath/taj-mahal.png', opacity: anim, fit: BoxFit.cover),
|
||||
WonderHero(
|
||||
config,
|
||||
'taj-mg',
|
||||
child: Image.asset('$assetPath/taj-mahal.png', opacity: anim, fit: BoxFit.cover),
|
||||
),
|
||||
if (!config.shortMode)
|
||||
FractionalTranslation(
|
||||
translation: Offset(0, 1.33),
|
||||
child: Image.asset('$assetPath/pool.png', opacity: anim, fit: BoxFit.cover),
|
||||
),
|
||||
],
|
||||
)),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
@ -1,6 +1,9 @@
|
||||
# 1.9.0
|
||||
- Improved support for dynamic text scaling
|
||||
- Improved performance for blend modes and blurs
|
||||
- Added LocalSwitcher btn in the main Wonders Menu
|
||||
- Request higher preferred FPS for Android devices
|
||||
- Fix rendering issues with Chinese fonts
|
||||
|
||||
# 1.8.0
|
||||
- Initial release
|
Loading…
x
Reference in New Issue
Block a user