Last active
September 23, 2025 12:54
-
-
Save PlugFox/ccc3d742a3c551bcb2ecb9b57a2bd34e to your computer and use it in GitHub Desktop.
Google Play and App Store logos
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * Google Play and App Store logos | |
| * https://gist.github.com/PlugFox/ccc3d742a3c551bcb2ecb9b57a2bd34e | |
| * https://dartpad.dev?id=ccc3d742a3c551bcb2ecb9b57a2bd34e | |
| * Mike Matiunin <[email protected]>, 23 September 2025 | |
| */ | |
| // ignore_for_file: curly_braces_in_flow_control_structures | |
| import 'dart:async'; | |
| import 'dart:math' as math; | |
| import 'dart:ui' as ui hide Size; | |
| import 'package:flutter/foundation.dart'; | |
| import 'package:flutter/material.dart'; | |
| import 'package:flutter/services.dart' show HapticFeedback; | |
| import 'package:flutter/rendering.dart' show BoxHitTestResult; | |
| void main() => runZonedGuarded<void>( | |
| () => runApp(const App()), | |
| (error, stackTrace) => print(error), // ignore: avoid_print | |
| ); | |
| /// {@template app} | |
| /// App widget. | |
| /// {@endtemplate} | |
| class App extends StatelessWidget { | |
| /// {@macro app} | |
| const App({super.key}); | |
| static void showSnackbar(BuildContext context, String message) => | |
| ScaffoldMessenger.maybeOf(context) | |
| ?..clearSnackBars() | |
| ..showSnackBar( | |
| SnackBar(content: Text(message), duration: Duration(seconds: 5)), | |
| ); | |
| @override | |
| Widget build(BuildContext context) => MaterialApp( | |
| title: 'Google Play & App Store', | |
| home: Scaffold( | |
| appBar: AppBar( | |
| title: const Text('Google Play & App Store'), | |
| centerTitle: true, | |
| ), | |
| body: SafeArea( | |
| child: Padding( | |
| padding: EdgeInsets.all(24.0), | |
| child: Center( | |
| child: SizedBox( | |
| height: 52.0, | |
| child: Builder( | |
| builder: (context) => Row( | |
| mainAxisSize: MainAxisSize.min, | |
| mainAxisAlignment: MainAxisAlignment.center, | |
| crossAxisAlignment: CrossAxisAlignment.start, | |
| spacing: 16.0, | |
| children: <Widget>[ | |
| Expanded( | |
| child: GetAppStoreLogo( | |
| label: 'Скачать в', // 'Download on the' | |
| tooltip: 'Открыть в App Store', // 'Download on the App Store' | |
| onTap: () { | |
| HapticFeedback.mediumImpact().ignore(); | |
| showSnackbar(context, 'Открыть в App Store'); | |
| }, | |
| ), | |
| ), | |
| Expanded( | |
| child: GetGooglePlayLogo( | |
| label: 'ПОЛУЧИТЬ В', // 'GET IT ON' | |
| tooltip: 'Открыть в Google Play', // 'Get it on Google Play' | |
| onTap: () { | |
| HapticFeedback.mediumImpact().ignore(); | |
| showSnackbar(context, 'Открыть в Google Play'); | |
| }, | |
| ), | |
| ), | |
| ], | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ); | |
| } | |
| /// {@template get_app_store_logo} | |
| /// GetAppStoreLogo widget. | |
| /// {@endtemplate} | |
| class GetAppStoreLogo extends StatelessWidget implements PreferredSizeWidget { | |
| /// {@macro get_app_store_logo} | |
| const GetAppStoreLogo({ | |
| this.label, | |
| this.tooltip, | |
| this.onTap, | |
| super.key, // ignore: unused_element | |
| }); | |
| /// The size of the logo. | |
| static const Size size = Size(180, 52); | |
| static final double targetAspectRatio = size.width / size.height; | |
| @override | |
| Size get preferredSize => size; | |
| /// Called when the user taps this button. | |
| final VoidCallback? onTap; | |
| /// The label of the button. | |
| /// For example: 'Download on the' | |
| final String? label; | |
| /// The tooltip of the button. | |
| /// For example: 'Download on the App Store' | |
| final String? tooltip; | |
| static Widget _wrapWithTooltip({required Widget child, String? tooltip}) { | |
| if (tooltip case String message when message.isNotEmpty) | |
| return Tooltip(message: message, child: child); | |
| return child; | |
| } | |
| @override | |
| Widget build(BuildContext context) => Center( | |
| child: SizedBox.fromSize( | |
| size: size, | |
| child: LayoutBuilder( | |
| builder: (context, constraints) { | |
| if (constraints.smallest.shortestSide < 24) | |
| return const SizedBox.shrink(); | |
| final boxAspectRatio = constraints.maxWidth / constraints.maxHeight; | |
| // If aspect ratio is too low, display only the logo. | |
| // otherwise, display the full button with text. | |
| if (boxAspectRatio < targetAspectRatio * 0.7) { | |
| return Center( | |
| child: AspectRatio( | |
| aspectRatio: 1.0, | |
| child: Material( | |
| color: Colors.transparent, | |
| type: MaterialType.button, | |
| borderRadius: BorderRadius.circular(12.0), | |
| elevation: 4.0, | |
| child: Ink( | |
| decoration: ShapeDecoration( | |
| color: Colors.black, | |
| shape: RoundedRectangleBorder( | |
| borderRadius: BorderRadius.circular(12.0), | |
| ), | |
| ), | |
| child: InkWell( | |
| onTap: onTap, | |
| borderRadius: BorderRadius.circular(12.0), | |
| child: _wrapWithTooltip( | |
| tooltip: tooltip, | |
| child: const Padding( | |
| padding: EdgeInsets.all(8.0), | |
| child: Center(child: AppStoreLogo()), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ); | |
| } else { | |
| return FittedBox( | |
| fit: BoxFit.contain, | |
| alignment: Alignment.center, | |
| child: SizedBox.fromSize( | |
| size: size, | |
| child: Material( | |
| color: Colors.transparent, | |
| type: MaterialType.button, | |
| borderRadius: BorderRadius.circular(12.0), | |
| elevation: 4.0, | |
| child: Ink( | |
| decoration: ShapeDecoration( | |
| color: Colors.black, | |
| shape: RoundedRectangleBorder( | |
| borderRadius: BorderRadius.circular(12.0), | |
| ), | |
| ), | |
| child: InkWell( | |
| onTap: onTap, | |
| borderRadius: BorderRadius.circular(12.0), | |
| child: _wrapWithTooltip( | |
| tooltip: tooltip, | |
| child: Padding( | |
| padding: const EdgeInsets.symmetric( | |
| horizontal: 12.0, | |
| vertical: 6.0, | |
| ), | |
| child: Row( | |
| mainAxisSize: MainAxisSize.min, | |
| mainAxisAlignment: MainAxisAlignment.center, | |
| crossAxisAlignment: CrossAxisAlignment.center, | |
| children: <Widget>[ | |
| const SizedBox( | |
| height: 32.0, | |
| child: AppStoreLogo(), | |
| ), | |
| const SizedBox(width: 12.0), | |
| Expanded( | |
| child: Column( | |
| mainAxisSize: MainAxisSize.max, | |
| mainAxisAlignment: MainAxisAlignment.center, | |
| crossAxisAlignment: | |
| CrossAxisAlignment.stretch, | |
| children: <Widget>[ | |
| Text( | |
| label ?? 'Download on the', | |
| textAlign: TextAlign.start, | |
| style: const TextStyle( | |
| color: Colors.white, | |
| fontSize: 10.0, | |
| letterSpacing: 1.1, | |
| fontWeight: FontWeight.w600, | |
| height: 1.0, | |
| overflow: TextOverflow.visible, | |
| ), | |
| ), | |
| const SizedBox(height: 2.0), | |
| const Text( | |
| 'App Store', | |
| textAlign: TextAlign.start, | |
| style: TextStyle( | |
| color: Colors.white, | |
| fontSize: 18.0, | |
| fontWeight: FontWeight.w700, | |
| height: 1.0, | |
| overflow: TextOverflow.visible, | |
| ), | |
| ), | |
| ], | |
| ), | |
| ), | |
| ], | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ); | |
| } | |
| }, | |
| ), | |
| ), | |
| ); | |
| } | |
| /// {@template app_store_logo} | |
| /// AppStoreLogo widget. | |
| /// {@endtemplate} | |
| class AppStoreLogo extends LeafRenderObjectWidget | |
| implements PreferredSizeWidget { | |
| /// {@macro app_store_logo} | |
| const AppStoreLogo({super.key}); | |
| /// The size of the logo. | |
| static const Size size = Size(27.8, 33.2); | |
| @override | |
| Size get preferredSize => size; | |
| @override | |
| RenderObject createRenderObject(BuildContext context) => | |
| AppStoreLogoRenderObject().._targetSize = size; | |
| @override | |
| void updateRenderObject( | |
| BuildContext context, | |
| covariant AppStoreLogoRenderObject renderObject, | |
| ) { | |
| if (renderObject case AppStoreLogoRenderObject object | |
| when object._targetSize != size) { | |
| renderObject | |
| .._targetSize = size | |
| ..markNeedsLayout(); | |
| } | |
| } | |
| } | |
| @internal | |
| class AppStoreLogoRenderObject extends RenderBox { | |
| AppStoreLogoRenderObject(); | |
| Size _targetSize = Size.zero; | |
| double _scale = .0; | |
| @override | |
| bool get isRepaintBoundary => false; | |
| @override | |
| bool get alwaysNeedsCompositing => false; | |
| @override | |
| bool get sizedByParent => false; | |
| @override | |
| Size computeDryLayout(BoxConstraints constraints) => | |
| constraints.constrain(_targetSize); | |
| @override | |
| void performLayout() { | |
| final size = super.size = computeDryLayout(constraints); | |
| _scale = math.min( | |
| size.width / AppStoreLogo.size.width, | |
| size.height / AppStoreLogo.size.height, | |
| ); | |
| } | |
| @override | |
| bool hitTestSelf(Offset position) => true; | |
| @override | |
| bool hitTestChildren(BoxHitTestResult result, {required Offset position}) => | |
| false; | |
| @override | |
| void paint(PaintingContext context, Offset offset) { | |
| final scale = _scale; | |
| final canvas = context.canvas..save(); | |
| if (scale < .01) { | |
| // No need to paint if the scale is too small. | |
| return; | |
| } else if (scale < 1.0) { | |
| // Move the logo to the center of the box. | |
| canvas.translate( | |
| offset.dx + (size.width - AppStoreLogo.size.width * scale) / 2, | |
| offset.dy + (size.height - AppStoreLogo.size.height * scale) / 2, | |
| ); | |
| } else if (scale == 1.0) { | |
| // Move the logo to the center of the box. | |
| canvas.translate(offset.dx, offset.dy); | |
| } else { | |
| // Move the center of the logo to the center of the box. | |
| canvas.translate( | |
| offset.dx + (size.width - AppStoreLogo.size.width * scale) / 2, | |
| offset.dy + (size.height - AppStoreLogo.size.height * scale) / 2, | |
| ); | |
| } | |
| canvas | |
| // ..clipRect(Offset.zero & size) | |
| ..scale(scale, scale) | |
| ..drawPicture(_$logoPicture) | |
| ..restore(); | |
| } | |
| static final ui.Picture _$logoPicture = () { | |
| final recorder = ui.PictureRecorder(); | |
| final canvas = Canvas(recorder); | |
| const size = AppStoreLogo.size; | |
| final path_0 = Path(); | |
| path_0.moveTo(size.width * 0.8354143, size.height * 0.5211500); | |
| path_0.cubicTo( | |
| size.width * 0.8340286, | |
| size.height * 0.3979176, | |
| size.width * 0.9617821, | |
| size.height * 0.3379647, | |
| size.width * 0.9676214, | |
| size.height * 0.3351735, | |
| ); | |
| path_0.cubicTo( | |
| size.width * 0.8952714, | |
| size.height * 0.2509421, | |
| size.width * 0.7831286, | |
| size.height * 0.2394332, | |
| size.width * 0.7437179, | |
| size.height * 0.2385156, | |
| ); | |
| path_0.cubicTo( | |
| size.width * 0.6495321, | |
| size.height * 0.2306009, | |
| size.width * 0.5581714, | |
| size.height * 0.2835185, | |
| size.width * 0.5101893, | |
| size.height * 0.2835185, | |
| ); | |
| path_0.cubicTo( | |
| size.width * 0.4612536, | |
| size.height * 0.2835185, | |
| size.width * 0.3873679, | |
| size.height * 0.2392803, | |
| size.width * 0.3077386, | |
| size.height * 0.2405803, | |
| ); | |
| path_0.cubicTo( | |
| size.width * 0.2052679, | |
| size.height * 0.2418421, | |
| size.width * 0.1094050, | |
| size.height * 0.2892156, | |
| size.width * 0.05682857, | |
| size.height * 0.3627794, | |
| ); | |
| path_0.cubicTo( | |
| size.width * -0.05167571, | |
| size.height * 0.5127765, | |
| size.width * 0.02924771, | |
| size.height * 0.7332029, | |
| size.width * 0.1332029, | |
| size.height * 0.8544471, | |
| ); | |
| path_0.cubicTo( | |
| size.width * 0.1852046, | |
| size.height * 0.9138265, | |
| size.width * 0.2459689, | |
| size.height * 0.9801265, | |
| size.width * 0.3255036, | |
| size.height * 0.9777941, | |
| ); | |
| path_0.cubicTo( | |
| size.width * 0.4033143, | |
| size.height * 0.9752324, | |
| size.width * 0.4323786, | |
| size.height * 0.9381824, | |
| size.width * 0.5262786, | |
| size.height * 0.9381824, | |
| ); | |
| path_0.cubicTo( | |
| size.width * 0.6193179, | |
| size.height * 0.9381824, | |
| size.width * 0.6466107, | |
| size.height * 0.9777941, | |
| size.width * 0.7277250, | |
| size.height * 0.9763029, | |
| ); | |
| path_0.cubicTo( | |
| size.width * 0.8112357, | |
| size.height * 0.9752324, | |
| size.width * 0.8638107, | |
| size.height * 0.9166559, | |
| size.width * 0.9139929, | |
| size.height * 0.8567412, | |
| ); | |
| path_0.cubicTo( | |
| size.width * 0.9740857, | |
| size.height * 0.7886824, | |
| size.width * 0.9982214, | |
| size.height * 0.7216559, | |
| size.width * 0.9991786, | |
| size.height * 0.7182147, | |
| ); | |
| path_0.cubicTo( | |
| size.width * 0.9972143, | |
| size.height * 0.7176794, | |
| size.width * 0.8369964, | |
| size.height * 0.6688529, | |
| size.width * 0.8354143, | |
| size.height * 0.5211500, | |
| ); | |
| path_0.close(); | |
| final paint0Fill = Paint()..style = PaintingStyle.fill; | |
| paint0Fill.color = Colors.white; | |
| canvas.drawPath(path_0, paint0Fill); | |
| final path_1 = Path(); | |
| path_1.moveTo(size.width * 0.6821893, size.height * 0.1587568); | |
| path_1.cubicTo( | |
| size.width * 0.7240393, | |
| size.height * 0.1169656, | |
| size.width * 0.7526714, | |
| size.height * 0.06010971, | |
| size.width * 0.7447250, | |
| size.height * 0.002412682, | |
| ); | |
| path_1.cubicTo( | |
| size.width * 0.6841500, | |
| size.height * 0.004553853, | |
| size.width * 0.6084000, | |
| size.height * 0.03586853, | |
| size.width * 0.5647786, | |
| size.height * 0.07674206, | |
| ); | |
| path_1.cubicTo( | |
| size.width * 0.5261821, | |
| size.height * 0.1127597, | |
| size.width * 0.4917071, | |
| size.height * 0.1717950, | |
| size.width * 0.5006143, | |
| size.height * 0.2273126, | |
| ); | |
| path_1.cubicTo( | |
| size.width * 0.5686571, | |
| size.height * 0.2313656, | |
| size.width * 0.6385179, | |
| size.height * 0.1998979, | |
| size.width * 0.6821893, | |
| size.height * 0.1587568, | |
| ); | |
| path_1.close(); | |
| final paint1Fill = Paint()..style = PaintingStyle.fill; | |
| paint1Fill.color = Colors.white; | |
| canvas.drawPath(path_1, paint1Fill); | |
| return recorder.endRecording(); | |
| }(); | |
| } | |
| /// {@template get_google_play_logo} | |
| /// GetGooglePlayLogo widget. | |
| /// {@endtemplate} | |
| class GetGooglePlayLogo extends StatelessWidget implements PreferredSizeWidget { | |
| /// {@macro get_google_play_logo} | |
| const GetGooglePlayLogo({ | |
| this.label, | |
| this.tooltip, | |
| this.onTap, | |
| super.key, // ignore: unused_element | |
| }); | |
| /// The size of the logo. | |
| static const Size size = Size(180, 52); | |
| static final double targetAspectRatio = size.width / size.height; | |
| @override | |
| Size get preferredSize => size; | |
| /// Called when the user taps this button. | |
| final VoidCallback? onTap; | |
| /// The label of the button. | |
| /// For example: 'GET IT ON' | |
| final String? label; | |
| /// The tooltip of the button. | |
| /// For example: 'Download on Google Play' | |
| final String? tooltip; | |
| static Widget _wrapWithTooltip({required Widget child, String? tooltip}) { | |
| if (tooltip case String message when message.isNotEmpty) | |
| return Tooltip(message: message, child: child); | |
| return child; | |
| } | |
| @override | |
| Widget build(BuildContext context) => Center( | |
| child: SizedBox.fromSize( | |
| size: size, | |
| child: LayoutBuilder( | |
| builder: (context, constraints) { | |
| if (constraints.smallest.shortestSide < 24) | |
| return const SizedBox.shrink(); | |
| final boxAspectRatio = constraints.maxWidth / constraints.maxHeight; | |
| // If aspect ratio is too low, display only the logo. | |
| // otherwise, display the full button with text. | |
| if (boxAspectRatio < targetAspectRatio * 0.7) { | |
| return Center( | |
| child: AspectRatio( | |
| aspectRatio: 1.0, | |
| child: Material( | |
| color: Colors.transparent, | |
| type: MaterialType.button, | |
| borderRadius: BorderRadius.circular(12.0), | |
| elevation: 4.0, | |
| child: Ink( | |
| decoration: ShapeDecoration( | |
| color: Colors.black, | |
| shape: RoundedRectangleBorder( | |
| borderRadius: BorderRadius.circular(12.0), | |
| ), | |
| ), | |
| child: InkWell( | |
| onTap: onTap, | |
| borderRadius: BorderRadius.circular(12.0), | |
| child: _wrapWithTooltip( | |
| tooltip: tooltip, | |
| child: const Padding( | |
| padding: EdgeInsets.all(8.0), | |
| child: Center(child: GooglePlayLogo()), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ); | |
| } else { | |
| return FittedBox( | |
| fit: BoxFit.contain, | |
| alignment: Alignment.center, | |
| child: SizedBox.fromSize( | |
| size: size, | |
| child: Material( | |
| color: Colors.transparent, | |
| type: MaterialType.button, | |
| borderRadius: BorderRadius.circular(12.0), | |
| elevation: 4.0, | |
| child: Ink( | |
| decoration: ShapeDecoration( | |
| color: Colors.black, | |
| shape: RoundedRectangleBorder( | |
| borderRadius: BorderRadius.circular(12.0), | |
| ), | |
| ), | |
| child: InkWell( | |
| onTap: onTap, | |
| borderRadius: BorderRadius.circular(12.0), | |
| child: _wrapWithTooltip( | |
| tooltip: tooltip, | |
| child: Padding( | |
| padding: const EdgeInsets.symmetric( | |
| horizontal: 12.0, | |
| vertical: 6.0, | |
| ), | |
| child: Row( | |
| mainAxisSize: MainAxisSize.min, | |
| mainAxisAlignment: MainAxisAlignment.center, | |
| crossAxisAlignment: CrossAxisAlignment.center, | |
| children: <Widget>[ | |
| const SizedBox( | |
| height: 32.0, | |
| child: GooglePlayLogo(), | |
| ), | |
| const SizedBox(width: 12.0), | |
| Expanded( | |
| child: Column( | |
| mainAxisSize: MainAxisSize.min, | |
| mainAxisAlignment: MainAxisAlignment.center, | |
| crossAxisAlignment: | |
| CrossAxisAlignment.stretch, | |
| children: <Widget>[ | |
| Text( | |
| label ?? 'GET IT ON', | |
| textAlign: TextAlign.start, | |
| style: const TextStyle( | |
| color: Colors.white, | |
| fontSize: 10.0, | |
| letterSpacing: 1.1, | |
| fontWeight: FontWeight.w600, | |
| height: 1.0, | |
| overflow: TextOverflow.visible, | |
| ), | |
| ), | |
| const SizedBox(height: 2.0), | |
| const Text( | |
| 'Google Play', | |
| textAlign: TextAlign.start, | |
| style: TextStyle( | |
| color: Colors.white, | |
| fontSize: 18.0, | |
| fontWeight: FontWeight.w700, | |
| height: 1.0, | |
| overflow: TextOverflow.visible, | |
| ), | |
| ), | |
| ], | |
| ), | |
| ), | |
| ], | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ); | |
| } | |
| }, | |
| ), | |
| ), | |
| ); | |
| } | |
| /// {@template google_play_logo} | |
| /// GooglePlayLogo widget. | |
| /// {@endtemplate} | |
| class GooglePlayLogo extends LeafRenderObjectWidget | |
| implements PreferredSizeWidget { | |
| /// {@macro google_play_logo} | |
| const GooglePlayLogo({super.key}); | |
| /// The size of the logo. | |
| static const Size size = Size(31.0, 33.4); | |
| @override | |
| Size get preferredSize => size; | |
| @override | |
| RenderObject createRenderObject(BuildContext context) => | |
| GooglePlayLogoRenderObject().._targetSize = size; | |
| @override | |
| void updateRenderObject( | |
| BuildContext context, | |
| covariant GooglePlayLogoRenderObject renderObject, | |
| ) { | |
| if (renderObject case GooglePlayLogoRenderObject object | |
| when object._targetSize != size) { | |
| renderObject | |
| .._targetSize = size | |
| ..markNeedsLayout(); | |
| } | |
| } | |
| } | |
| @internal | |
| class GooglePlayLogoRenderObject extends RenderBox { | |
| GooglePlayLogoRenderObject(); | |
| Size _targetSize = Size.zero; | |
| double _scale = .0; | |
| @override | |
| bool get isRepaintBoundary => false; | |
| @override | |
| bool get alwaysNeedsCompositing => false; | |
| @override | |
| bool get sizedByParent => false; | |
| @override | |
| Size computeDryLayout(BoxConstraints constraints) => | |
| constraints.constrain(_targetSize); | |
| @override | |
| void performLayout() { | |
| final size = super.size = computeDryLayout(constraints); | |
| _scale = math.min( | |
| size.width / GooglePlayLogo.size.width, | |
| size.height / GooglePlayLogo.size.height, | |
| ); | |
| } | |
| @override | |
| bool hitTestSelf(Offset position) => true; | |
| @override | |
| bool hitTestChildren(BoxHitTestResult result, {required Offset position}) => | |
| false; | |
| @override | |
| void paint(PaintingContext context, Offset offset) { | |
| final scale = _scale; | |
| final canvas = context.canvas..save(); | |
| if (scale < .01) { | |
| // No need to paint if the scale is too small. | |
| return; | |
| } else if (scale < 1.0) { | |
| // Move the logo to the center of the box. | |
| canvas.translate( | |
| offset.dx + (size.width - GooglePlayLogo.size.width * scale) / 2, | |
| offset.dy + (size.height - GooglePlayLogo.size.height * scale) / 2, | |
| ); | |
| } else if (scale == 1.0) { | |
| // Move the logo to the center of the box. | |
| canvas.translate(offset.dx, offset.dy); | |
| } else { | |
| // Move the center of the logo to the center of the box. | |
| canvas.translate( | |
| offset.dx + (size.width - GooglePlayLogo.size.width * scale) / 2, | |
| offset.dy + (size.height - GooglePlayLogo.size.height * scale) / 2, | |
| ); | |
| } | |
| canvas | |
| // ..clipRect(Offset.zero & size) | |
| ..scale(scale, scale) | |
| ..drawPicture(_$logoPicture) | |
| ..restore(); | |
| } | |
| static final ui.Picture _$logoPicture = () { | |
| final recorder = ui.PictureRecorder(); | |
| final canvas = Canvas(recorder); | |
| const size = GooglePlayLogo.size; | |
| final path_0 = Path(); | |
| path_0.moveTo(size.width * 0.03102691, size.height * 0.02351362); | |
| path_0.cubicTo( | |
| size.width * 0.01871931, | |
| size.height * 0.03527088, | |
| size.width * 0.01159669, | |
| size.height * 0.05357618, | |
| size.width * 0.01159669, | |
| size.height * 0.07728206, | |
| ); | |
| path_0.lineTo(size.width * 0.01159669, size.height * 0.9228559); | |
| path_0.cubicTo( | |
| size.width * 0.01159669, | |
| size.height * 0.9465618, | |
| size.width * 0.01871931, | |
| size.height * 0.9648676, | |
| size.width * 0.03102691, | |
| size.height * 0.9766235, | |
| ); | |
| path_0.lineTo(size.width * 0.03406469, size.height * 0.9792059); | |
| path_0.lineTo(size.width * 0.5532875, size.height * 0.5055647); | |
| path_0.lineTo(size.width * 0.5532875, size.height * 0.4943824); | |
| path_0.lineTo(size.width * 0.03406469, size.height * 0.02074165); | |
| path_0.lineTo(size.width * 0.03102691, size.height * 0.02351362); | |
| path_0.close(); | |
| final paint0Fill = Paint()..style = PaintingStyle.fill; | |
| paint0Fill.shader = ui.Gradient.linear( | |
| Offset(size.width * 0.5071875, size.height * 0.9316618), | |
| Offset(size.width * -17.42741, size.height * 0.2701871), | |
| [ | |
| const Color(0xff00A0FF), | |
| const Color(0xff00A1FF), | |
| const Color(0xff00BEFF), | |
| const Color(0xff00D2FF), | |
| const Color(0xff00DFFF), | |
| const Color(0xff00E3FF), | |
| ], | |
| [0, 0.0066, 0.2601, 0.5122, 0.7604, 1], | |
| ); | |
| canvas.drawPath(path_0, paint0Fill); | |
| final path_1 = Path(); | |
| path_1.moveTo(size.width * 0.7261062, size.height * 0.6635441); | |
| path_1.lineTo(size.width * 0.5532219, size.height * 0.5055853); | |
| path_1.lineTo(size.width * 0.5532219, size.height * 0.4944029); | |
| path_1.lineTo(size.width * 0.7263156, size.height * 0.3364412); | |
| path_1.lineTo(size.width * 0.7301906, size.height * 0.3384971); | |
| path_1.lineTo(size.width * 0.9351750, size.height * 0.4449353); | |
| path_1.cubicTo( | |
| size.width * 0.9936781, | |
| size.height * 0.4751412, | |
| size.width * 0.9936781, | |
| size.height * 0.5248471, | |
| size.width * 0.9351750, | |
| size.height * 0.5552441, | |
| ); | |
| path_1.lineTo(size.width * 0.7301906, size.height * 0.6614912); | |
| path_1.lineTo(size.width * 0.7261062, size.height * 0.6635441); | |
| path_1.close(); | |
| final paint1Fill = Paint()..style = PaintingStyle.fill; | |
| paint1Fill.shader = ui.Gradient.linear( | |
| Offset(size.width * 1.011353, size.height * 0.4999412), | |
| Offset(size.width * -0.2451384, size.height * 0.4999412), | |
| [ | |
| const Color(0xffFFE000), | |
| const Color(0xffFFBD00), | |
| const Color(0xffFFA500), | |
| const Color(0xffFF9C00), | |
| ], | |
| [0, 0.4087, 0.7754, 1], | |
| ); | |
| canvas.drawPath(path_1, paint1Fill); | |
| final path_2 = Path(); | |
| path_2.moveTo(size.width * 0.7302344, size.height * 0.6614765); | |
| path_2.lineTo(size.width * 0.5532656, size.height * 0.4999824); | |
| path_2.lineTo(size.width * 0.03100587, size.height * 0.9766324); | |
| path_2.cubicTo( | |
| size.width * 0.05043625, | |
| size.height * 0.9952706, | |
| size.width * 0.08212156, | |
| size.height * 0.9975176, | |
| size.width * 0.1181541, | |
| size.height * 0.9788794, | |
| ); | |
| path_2.lineTo(size.width * 0.7302344, size.height * 0.6614765); | |
| path_2.close(); | |
| final paint2Fill = Paint()..style = PaintingStyle.fill; | |
| paint2Fill.shader = ui.Gradient.linear( | |
| Offset(size.width * 0.6340031, size.height * 0.4121882), | |
| Offset(size.width * -29.01119, size.height * -48.48235), | |
| [const Color(0xffFF3A44), const Color(0xffC31162)], | |
| [0, 1], | |
| ); | |
| canvas.drawPath(path_2, paint2Fill); | |
| final path_3 = Path(); | |
| path_3.moveTo(size.width * 0.7302344, size.height * 0.3385029); | |
| path_3.lineTo(size.width * 0.1181541, size.height * 0.02110312); | |
| path_3.cubicTo( | |
| size.width * 0.08212156, | |
| size.height * 0.002654603, | |
| size.width * 0.05043625, | |
| size.height * 0.004900853, | |
| size.width * 0.03100587, | |
| size.height * 0.02354056, | |
| ); | |
| path_3.lineTo(size.width * 0.5532656, size.height * 0.5000000); | |
| path_3.lineTo(size.width * 0.7302344, size.height * 0.3385029); | |
| path_3.close(); | |
| final paint3Fill = Paint()..style = PaintingStyle.fill; | |
| paint3Fill.shader = ui.Gradient.linear( | |
| Offset(size.width * -10.04578, size.height * 1.257968), | |
| Offset(size.width * 0.3122012, size.height * 0.8574147), | |
| [ | |
| const Color(0xff32A071), | |
| const Color(0xff2DA771), | |
| const Color(0xff15CF74), | |
| const Color(0xff06E775), | |
| const Color(0xff00F076), | |
| ], | |
| [0, 0.0685, 0.4762, 0.8009, 1], | |
| ); | |
| canvas.drawPath(path_3, paint3Fill); | |
| return recorder.endRecording(); | |
| }(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment