Browse Source
Merge pull request 'fix/download' (#20) from fix/download into develop
Merge pull request 'fix/download' (#20) from fix/download into develop
Reviewed-on: https://git.nwhco.ir/amirreza.chegini/hade_hoda_flutter/pulls/20pull/21/head
78 changed files with 453 additions and 569 deletions
-
BINassets/images/loading.png
-
0assets/svg/bubble_chat_left.svg
-
0assets/svg/bubble_chat_right.svg
-
0assets/svg/button.svg
-
0assets/svg/button_2.svg
-
0assets/svg/button_3.svg
-
0assets/svg/close_btn.svg
-
0assets/svg/correct.svg
-
0assets/svg/done.svg
-
0assets/svg/done_rounded.svg
-
0assets/svg/facebook.svg
-
0assets/svg/hand_point.svg
-
0assets/svg/home.svg
-
0assets/svg/instagram.svg
-
0assets/svg/lang.svg
-
0assets/svg/language.svg
-
0assets/svg/location.svg
-
0assets/svg/music.svg
-
0assets/svg/music_off.svg
-
0assets/svg/music_on.svg
-
0assets/svg/new_horizon.svg
-
0assets/svg/play.svg
-
0assets/svg/theme.svg
-
0assets/svg/unmusic.svg
-
0assets/svg/whatsapp.svg
-
0assets/svg/wrong.svg
-
0assets/svg/youtube.svg
-
78lib/common_ui/resources/my_assets.dart
-
4lib/common_ui/theme/my_theme.dart
-
2lib/core/constants/my_constants.dart
-
23lib/core/middlewares/my_middlewares.dart
-
12lib/core/routers/my_routes.dart
-
2lib/core/widgets/about_us_dialog/about_us_dialog.dart
-
50lib/core/widgets/animations/rotation_anim.dart
-
2lib/core/widgets/answer_box/styles/picture_box.dart
-
2lib/core/widgets/button/my_button.dart
-
4lib/core/widgets/confetti/my_confetti.dart
-
2lib/core/widgets/error/error_state.dart
-
2lib/core/widgets/hadith_dialog/hadith_dialog.dart
-
6lib/core/widgets/images/my_image.dart
-
2lib/core/widgets/showcase/question_showcase.dart
-
59lib/features/download/data/datasource/download_datasource.dart
-
16lib/features/download/data/repository_impl/download_repository_impl.dart
-
1lib/features/download/domain/repository/download_repository.dart
-
4lib/features/download/domain/usecases/get_images_usecase.dart
-
4lib/features/download/domain/usecases/loading_stream_usecase.dart
-
31lib/features/download/presentation/bloc/download_bloc.dart
-
1lib/features/download/presentation/bloc/download_event.dart
-
17lib/features/download/presentation/ui/download_page.dart
-
16lib/features/home/presentation/bloc/home_bloc.dart
-
2lib/features/home/presentation/ui/home_page.dart
-
78lib/features/intro/data/datasource/intro_datasource.dart
-
34lib/features/intro/data/repository_impl/intro_repository_impl.dart
-
9lib/features/intro/domain/repository/intro_repository.dart
-
12lib/features/intro/domain/usecases/loading_stream_usecase.dart
-
70lib/features/intro/presentation/bloc/intro_bloc.dart
-
1lib/features/intro/presentation/bloc/intro_event.dart
-
84lib/features/intro/presentation/ui/intro_page.dart
-
136lib/features/intro/presentation/ui/widgets/intro_loading_widget.dart
-
1lib/features/language/presentation/bloc/language_bloc.dart
-
2lib/features/language/presentation/ui/language_page.dart
-
14lib/features/level/presentation/bloc/level_bloc.dart
-
4lib/features/level/presentation/bloc/level_event.dart
-
37lib/features/level/presentation/ui/level_page.dart
-
22lib/features/level/presentation/ui/widgets/bottom_path.dart
-
2lib/features/level/presentation/ui/widgets/hint_level_widget.dart
-
14lib/features/level/presentation/ui/widgets/level_widget.dart
-
14lib/features/question/presentation/bloc/question_bloc.dart
-
1lib/features/question/presentation/ui/question_page.dart
-
60lib/features/question/presentation/ui/screens/diamond_screen.dart
-
44lib/features/question/presentation/ui/screens/question_screen.dart
-
2lib/features/question/presentation/ui/widgets/glassy_button.dart
-
2lib/features/question/presentation/ui/widgets/left_blob.dart
-
2lib/features/question/presentation/ui/widgets/question_stepper.dart
-
2lib/features/question/presentation/ui/widgets/right_blob.dart
-
15lib/init_bindings.dart
-
12pubspec.lock
-
6pubspec.yaml
|
After Width: 156 | Height: 174 | Size: 8.2 KiB |
@ -0,0 +1,23 @@ |
|||||
|
import 'dart:async'; |
||||
|
|
||||
|
import 'package:flutter/material.dart'; |
||||
|
import 'package:go_router/go_router.dart'; |
||||
|
import 'package:hadi_hoda_flutter/core/constants/my_constants.dart'; |
||||
|
import 'package:hadi_hoda_flutter/core/routers/my_routes.dart'; |
||||
|
import 'package:hadi_hoda_flutter/core/utils/local_storage.dart'; |
||||
|
|
||||
|
class MyMiddlewares { |
||||
|
static const MyMiddlewares _i = MyMiddlewares._internal(); |
||||
|
const MyMiddlewares._internal(); |
||||
|
factory MyMiddlewares() => _i; |
||||
|
|
||||
|
static FutureOr<String?> intro(BuildContext context, GoRouterState state) { |
||||
|
final String? firstDownload = LocalStorage.readData( |
||||
|
key: MyConstants.firstDownload); |
||||
|
if (firstDownload != 'true') { |
||||
|
return Routes.languagePage; |
||||
|
} else { |
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,50 @@ |
|||||
|
import 'package:flutter/material.dart'; |
||||
|
|
||||
|
class RotationAnim extends StatefulWidget { |
||||
|
const RotationAnim({super.key, required this.child}); |
||||
|
|
||||
|
final Widget child; |
||||
|
|
||||
|
@override |
||||
|
State<RotationAnim> createState() => _RotationAnimState(); |
||||
|
} |
||||
|
|
||||
|
class _RotationAnimState extends State<RotationAnim> |
||||
|
with SingleTickerProviderStateMixin { |
||||
|
late AnimationController _controller; |
||||
|
late Animation<double> _animation; |
||||
|
|
||||
|
@override |
||||
|
void initState() { |
||||
|
super.initState(); |
||||
|
_controller = AnimationController( |
||||
|
vsync: this, |
||||
|
duration: Duration(seconds: 20), |
||||
|
); |
||||
|
_animation = Tween<double>( |
||||
|
begin: 0, |
||||
|
end: 20, |
||||
|
).animate(CurvedAnimation(parent: _controller, curve: Curves.linear)); |
||||
|
|
||||
|
_controller.repeat(); |
||||
|
} |
||||
|
|
||||
|
@override |
||||
|
void dispose() { |
||||
|
_controller.dispose(); |
||||
|
super.dispose(); |
||||
|
} |
||||
|
|
||||
|
@override |
||||
|
Widget build(BuildContext context) { |
||||
|
return AnimatedBuilder( |
||||
|
animation: _controller, |
||||
|
child: widget.child, |
||||
|
builder: (context, child) => RotationTransition( |
||||
|
turns: _animation, |
||||
|
alignment: Alignment.center, |
||||
|
child: child, |
||||
|
), |
||||
|
); |
||||
|
} |
||||
|
} |
||||
@ -1,10 +1,10 @@ |
|||||
import 'package:hadi_hoda_flutter/features/download/domain/entities/download_entity.dart'; |
import 'package:hadi_hoda_flutter/features/download/domain/entities/download_entity.dart'; |
||||
import 'package:hadi_hoda_flutter/features/download/domain/repository/download_repository.dart'; |
import 'package:hadi_hoda_flutter/features/download/domain/repository/download_repository.dart'; |
||||
|
|
||||
class LoadingStreamAudioUseCase { |
|
||||
|
class LoadingStreamUseCase { |
||||
final IDownloadRepository repository; |
final IDownloadRepository repository; |
||||
|
|
||||
const LoadingStreamAudioUseCase(this.repository); |
|
||||
|
const LoadingStreamUseCase(this.repository); |
||||
|
|
||||
Stream<DownloadEntity> call() { |
Stream<DownloadEntity> call() { |
||||
return repository.loadingStream(); |
return repository.loadingStream(); |
||||
@ -1,5 +1,6 @@ |
|||||
sealed class DownloadEvent { |
sealed class DownloadEvent { |
||||
const DownloadEvent(); |
const DownloadEvent(); |
||||
} |
} |
||||
|
class GetImagesEvent extends DownloadEvent {} |
||||
class GetAudiosEvent extends DownloadEvent {} |
class GetAudiosEvent extends DownloadEvent {} |
||||
class SaveLevelsEvent extends DownloadEvent {} |
class SaveLevelsEvent extends DownloadEvent {} |
||||
@ -1,78 +0,0 @@ |
|||||
import 'dart:async'; |
|
||||
import 'dart:io'; |
|
||||
|
|
||||
import 'package:flutter_archive/flutter_archive.dart'; |
|
||||
import 'package:hadi_hoda_flutter/core/constants/my_api.dart'; |
|
||||
import 'package:hadi_hoda_flutter/core/constants/my_constants.dart'; |
|
||||
import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart'; |
|
||||
import 'package:hadi_hoda_flutter/core/network/http_request.dart'; |
|
||||
import 'package:hadi_hoda_flutter/core/utils/local_storage.dart'; |
|
||||
import 'package:hadi_hoda_flutter/core/utils/storage_path.dart'; |
|
||||
import 'package:hadi_hoda_flutter/features/download/domain/entities/download_entity.dart'; |
|
||||
|
|
||||
abstract class IIntroDatasource { |
|
||||
Future<void> getImages(); |
|
||||
Stream<DownloadEntity> loadingStream(); |
|
||||
} |
|
||||
|
|
||||
class IntroDatasourceImpl implements IIntroDatasource { |
|
||||
final IHttpRequest httpRequest; |
|
||||
final StreamController<DownloadEntity> streamController = StreamController<DownloadEntity>.broadcast(); |
|
||||
|
|
||||
IntroDatasourceImpl(this.httpRequest); |
|
||||
|
|
||||
@override |
|
||||
Future<void> getImages() async { |
|
||||
final String filePath = '${StoragePath.documentDir.path}/images.zip'; |
|
||||
|
|
||||
if (LocalStorage.readData(key: MyConstants.downloadedImage) != 'true') { |
|
||||
await httpRequest.download( |
|
||||
urlPath: MyApi.images, |
|
||||
savePath: filePath, |
|
||||
onReceive: (count, total) { |
|
||||
streamController.add(DownloadEntity( |
|
||||
count: count / 1, |
|
||||
total: total / 1, |
|
||||
percent: (count / total) * 100, |
|
||||
)); |
|
||||
}, |
|
||||
).then((value) async { |
|
||||
await LocalStorage.saveData( |
|
||||
key: MyConstants.downloadedImage, |
|
||||
value: 'true', |
|
||||
); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
try{ |
|
||||
if (LocalStorage.readData(key: MyConstants.extractedImage) != 'true') { |
|
||||
final File file = File(filePath); |
|
||||
final Directory directory = Directory('${StoragePath.documentDir.path}/'); |
|
||||
await ZipFile.extractToDirectory( |
|
||||
zipFile: file, |
|
||||
destinationDir: directory, |
|
||||
onExtracting: (zipEntry, progress) { |
|
||||
return ZipFileOperation.includeItem; |
|
||||
}, |
|
||||
).then((value) async { |
|
||||
await Future.wait([ |
|
||||
LocalStorage.saveData( |
|
||||
key: MyConstants.extractedImage, |
|
||||
value: 'true', |
|
||||
), |
|
||||
file.delete(recursive: true), |
|
||||
]); |
|
||||
}); |
|
||||
} else { |
|
||||
streamController.add(DownloadEntity(percent: 50)); |
|
||||
await Future.delayed(Duration(milliseconds: 150)); |
|
||||
streamController.add(DownloadEntity(percent: 100)); |
|
||||
} |
|
||||
} catch (e){ |
|
||||
throw MyException(errorMessage: '$e'); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@override |
|
||||
Stream<DownloadEntity> loadingStream() => streamController.stream; |
|
||||
} |
|
||||
@ -1,34 +0,0 @@ |
|||||
import 'package:flutter/foundation.dart'; |
|
||||
import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart'; |
|
||||
import 'package:hadi_hoda_flutter/core/params/no_params.dart'; |
|
||||
import 'package:hadi_hoda_flutter/core/utils/data_state.dart'; |
|
||||
import 'package:hadi_hoda_flutter/features/download/domain/entities/download_entity.dart'; |
|
||||
import 'package:hadi_hoda_flutter/features/intro/data/datasource/intro_datasource.dart'; |
|
||||
import 'package:hadi_hoda_flutter/features/intro/domain/repository/intro_repository.dart'; |
|
||||
|
|
||||
class IntroRepositoryImpl implements IIntroRepository { |
|
||||
final IIntroDatasource datasource; |
|
||||
|
|
||||
const IntroRepositoryImpl(this.datasource); |
|
||||
|
|
||||
@override |
|
||||
Future<DataState<NoParams, MyException>> getImages() async { |
|
||||
try { |
|
||||
await datasource.getImages(); |
|
||||
return DataState.success(NoParams()); |
|
||||
} on MyException catch (e) { |
|
||||
return DataState.error(e); |
|
||||
} catch (e) { |
|
||||
if (kDebugMode) { |
|
||||
rethrow; |
|
||||
} else { |
|
||||
return DataState.error(MyException(errorMessage: '$e')); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@override |
|
||||
Stream<DownloadEntity> loadingStream() { |
|
||||
return datasource.loadingStream(); |
|
||||
} |
|
||||
} |
|
||||
@ -1,9 +0,0 @@ |
|||||
import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart'; |
|
||||
import 'package:hadi_hoda_flutter/core/params/no_params.dart'; |
|
||||
import 'package:hadi_hoda_flutter/core/utils/data_state.dart'; |
|
||||
import 'package:hadi_hoda_flutter/features/download/domain/entities/download_entity.dart'; |
|
||||
|
|
||||
abstract class IIntroRepository { |
|
||||
Future<DataState<NoParams, MyException>> getImages(); |
|
||||
Stream<DownloadEntity> loadingStream(); |
|
||||
} |
|
||||
@ -1,12 +0,0 @@ |
|||||
import 'package:hadi_hoda_flutter/features/download/domain/entities/download_entity.dart'; |
|
||||
import 'package:hadi_hoda_flutter/features/intro/domain/repository/intro_repository.dart'; |
|
||||
|
|
||||
class LoadingStreamUseCase { |
|
||||
final IIntroRepository repository; |
|
||||
|
|
||||
const LoadingStreamUseCase(this.repository); |
|
||||
|
|
||||
Stream<DownloadEntity> call() { |
|
||||
return repository.loadingStream(); |
|
||||
} |
|
||||
} |
|
||||
@ -1,64 +1,44 @@ |
|||||
import 'dart:async'; |
|
||||
|
|
||||
import 'package:bloc/bloc.dart'; |
import 'package:bloc/bloc.dart'; |
||||
|
import 'package:flutter/cupertino.dart'; |
||||
import 'package:go_router/go_router.dart'; |
import 'package:go_router/go_router.dart'; |
||||
import 'package:hadi_hoda_flutter/core/constants/my_constants.dart'; |
|
||||
import 'package:hadi_hoda_flutter/core/params/no_params.dart'; |
|
||||
|
import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart'; |
||||
import 'package:hadi_hoda_flutter/core/routers/my_routes.dart'; |
import 'package:hadi_hoda_flutter/core/routers/my_routes.dart'; |
||||
import 'package:hadi_hoda_flutter/core/status/base_status.dart'; |
|
||||
import 'package:hadi_hoda_flutter/core/utils/context_provider.dart'; |
|
||||
import 'package:hadi_hoda_flutter/core/utils/local_storage.dart'; |
|
||||
import 'package:hadi_hoda_flutter/features/download/domain/entities/download_entity.dart'; |
|
||||
import 'package:hadi_hoda_flutter/features/intro/domain/usecases/get_images_usecase.dart'; |
|
||||
import 'package:hadi_hoda_flutter/features/intro/domain/usecases/loading_stream_usecase.dart'; |
|
||||
import 'package:hadi_hoda_flutter/features/intro/presentation/bloc/intro_event.dart'; |
import 'package:hadi_hoda_flutter/features/intro/presentation/bloc/intro_event.dart'; |
||||
import 'package:hadi_hoda_flutter/features/intro/presentation/bloc/intro_state.dart'; |
import 'package:hadi_hoda_flutter/features/intro/presentation/bloc/intro_state.dart'; |
||||
|
|
||||
class IntroBloc extends Bloc<IntroEvent, IntroState> { |
class IntroBloc extends Bloc<IntroEvent, IntroState> { |
||||
/// ------------constructor------------ |
/// ------------constructor------------ |
||||
IntroBloc( |
|
||||
this._getImagesUseCase, |
|
||||
this._loadingStreamUseCase, |
|
||||
) |
|
||||
: super(const IntroState()) { |
|
||||
on<GetImagesEvent>(_getImagesEvent); |
|
||||
loadingStream = _loadingStreamUseCase(); |
|
||||
} |
|
||||
|
IntroBloc() : super(const IntroState()); |
||||
|
|
||||
/// ------------UseCases------------ |
/// ------------UseCases------------ |
||||
final GetImagesUseCase _getImagesUseCase; |
|
||||
final LoadingStreamUseCase _loadingStreamUseCase; |
|
||||
|
|
||||
/// ------------Variables------------ |
/// ------------Variables------------ |
||||
Stream<DownloadEntity> loadingStream = Stream.empty(); |
|
||||
|
|
||||
/// ------------Controllers------------ |
/// ------------Controllers------------ |
||||
|
|
||||
/// ------------Functions------------ |
/// ------------Functions------------ |
||||
|
Future<void> _precacheAllImages(BuildContext context) async { |
||||
|
await Future.wait( |
||||
|
MyAssets.images.map( |
||||
|
(assetPath) => precacheImage(AssetImage(assetPath), context), |
||||
|
), |
||||
|
); |
||||
|
} |
||||
|
|
||||
/// ------------Api Calls------------ |
|
||||
FutureOr<void> _getImagesEvent( |
|
||||
GetImagesEvent event, |
|
||||
Emitter<IntroState> emit, |
|
||||
) async { |
|
||||
emit(state.copyWith(getFilesStatus: BaseInit())); |
|
||||
await _getImagesUseCase(NoParams()).then((value) { |
|
||||
value.fold( |
|
||||
(data) async { |
|
||||
if(LocalStorage.readData(key: MyConstants.firstLanguagePage) != 'true'){ |
|
||||
ContextProvider.context.goNamed(Routes.languagePage); |
|
||||
} else { |
|
||||
await Future.delayed(Duration(milliseconds: 500), () { |
|
||||
if (ContextProvider.context.mounted) { |
|
||||
ContextProvider.context.goNamed(Routes.homePage); |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
}, |
|
||||
(error) async { |
|
||||
emit(state.copyWith(getFilesStatus: BaseError(error.errorMessage))); |
|
||||
}, |
|
||||
); |
|
||||
}); |
|
||||
|
Future<void> goToHomePage(BuildContext context) async { |
||||
|
if (context.mounted) { |
||||
|
await _precacheAllImages(context); |
||||
|
} |
||||
|
|
||||
|
await Future.delayed( |
||||
|
Duration(seconds: 2), |
||||
|
() { |
||||
|
if (context.mounted) { |
||||
|
context.goNamed(Routes.homePage); |
||||
|
} |
||||
|
}, |
||||
|
); |
||||
} |
} |
||||
|
|
||||
|
/// ------------Api Calls------------ |
||||
} |
} |
||||
@ -1,4 +1,3 @@ |
|||||
sealed class IntroEvent { |
sealed class IntroEvent { |
||||
const IntroEvent(); |
const IntroEvent(); |
||||
} |
} |
||||
class GetImagesEvent extends IntroEvent {} |
|
||||
@ -1,136 +0,0 @@ |
|||||
import 'package:flutter/material.dart'; |
|
||||
import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart'; |
|
||||
import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart'; |
|
||||
import 'package:hadi_hoda_flutter/features/download/domain/entities/download_entity.dart'; |
|
||||
|
|
||||
|
|
||||
class IntroLoadingWidget extends StatelessWidget { |
|
||||
const IntroLoadingWidget({ |
|
||||
super.key, |
|
||||
this.loadingStream, |
|
||||
}); |
|
||||
|
|
||||
final Stream<DownloadEntity>? loadingStream; |
|
||||
|
|
||||
@override |
|
||||
Widget build(BuildContext context) { |
|
||||
return ClipPath( |
|
||||
clipper: BubbleClip(), |
|
||||
child: Container( |
|
||||
width: 300, |
|
||||
height: 60, |
|
||||
padding: EdgeInsets.symmetric( |
|
||||
vertical: MySpaces.s4, |
|
||||
horizontal: MySpaces.s2, |
|
||||
), |
|
||||
decoration: const BoxDecoration( |
|
||||
gradient: LinearGradient( |
|
||||
begin: Alignment(0, 1), // bottom |
|
||||
end: Alignment(0, -1), // top |
|
||||
colors: [ |
|
||||
Color(0xFFCADCFF), // #CADCFF |
|
||||
Colors.white, // #FFFFFF |
|
||||
], |
|
||||
), |
|
||||
), |
|
||||
child: StreamBuilder<DownloadEntity>( |
|
||||
initialData: DownloadEntity(), |
|
||||
stream: loadingStream, |
|
||||
builder: (context, snapshot) { |
|
||||
return Row( |
|
||||
children: [ |
|
||||
Expanded( |
|
||||
flex: 85, |
|
||||
child: ClipPath( |
|
||||
clipper: BubbleClip(), |
|
||||
child: AnimatedContainer( |
|
||||
duration: const Duration(milliseconds: 300), |
|
||||
padding: EdgeInsetsDirectional.only( |
|
||||
end: 260 - ((snapshot.data?.percent ?? 0) * 260 / 100), |
|
||||
), |
|
||||
decoration: BoxDecoration( |
|
||||
color: Color(0xFF1F59BD).withValues(alpha: 0.25), |
|
||||
), |
|
||||
child: ClipPath( |
|
||||
clipper: BubbleClip(), |
|
||||
child: Container( |
|
||||
decoration: BoxDecoration( |
|
||||
gradient: RadialGradient( |
|
||||
radius: 2, |
|
||||
colors: [ |
|
||||
Color(0xFFFFBD00), // #CADCFF |
|
||||
Color(0xFFFF772C), // #CADCFF |
|
||||
], |
|
||||
), |
|
||||
), |
|
||||
), |
|
||||
), |
|
||||
), |
|
||||
), |
|
||||
), |
|
||||
Expanded( |
|
||||
flex: 15, |
|
||||
child: Center( |
|
||||
child: Text( |
|
||||
'${snapshot.data?.percent?.toInt() ?? 0}%', |
|
||||
style: DinoKids.regular17.copyWith( |
|
||||
color: Color(0XFF6E83A8), |
|
||||
), |
|
||||
), |
|
||||
), |
|
||||
), |
|
||||
], |
|
||||
); |
|
||||
} |
|
||||
), |
|
||||
), |
|
||||
); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
class BubbleClip extends CustomClipper<Path> { |
|
||||
@override |
|
||||
Path getClip(Size size) { |
|
||||
// Original SVG viewBox: 334 x 60 |
|
||||
const double w0 = 334.0; |
|
||||
const double h0 = 60.0; |
|
||||
final sx = size.width / w0; |
|
||||
final sy = size.height / h0; |
|
||||
|
|
||||
// SVG path: |
|
||||
// M9.82057 10.3597 |
|
||||
// C -1.70838 17.1589 -3.47995 44.4301 6.60447 53.1719 |
|
||||
// C 16.0075 61.291 305.076 61.9385 323.201 53.4956 |
|
||||
// C 341.326 45.0527 332.116 8.04571 324.829 5.7273 |
|
||||
// C 307.985 -2.06805 28.6539 -0.77294 9.82057 10.3597 |
|
||||
// Z |
|
||||
final p = Path() |
|
||||
..moveTo(9.82057 * sx, 10.3597 * sy) |
|
||||
..cubicTo( |
|
||||
-1.70838 * sx, 17.1589 * sy, |
|
||||
-3.47995 * sx, 44.4301 * sy, |
|
||||
6.60447 * sx, 53.1719 * sy, |
|
||||
) |
|
||||
..cubicTo( |
|
||||
16.0075 * sx, 61.291 * sy, |
|
||||
305.076 * sx, 61.9385 * sy, |
|
||||
323.201 * sx, 53.4956 * sy, |
|
||||
) |
|
||||
..cubicTo( |
|
||||
341.326 * sx, 45.0527 * sy, |
|
||||
332.116 * sx, 8.04571 * sy, |
|
||||
324.829 * sx, 5.7273 * sy, |
|
||||
) |
|
||||
..cubicTo( |
|
||||
307.985 * sx, -2.06805 * sy, |
|
||||
28.6539 * sx, -0.77294 * sy, |
|
||||
9.82057 * sx, 10.3597 * sy, |
|
||||
) |
|
||||
..close(); |
|
||||
|
|
||||
return p; |
|
||||
} |
|
||||
|
|
||||
@override |
|
||||
bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false; |
|
||||
} |
|
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue