1
0
mirror of https://github.com/flutter/samples.git synced 2025-11-13 19:08:41 +00:00

Add flutter_web samples (#75)

This commit is contained in:
Kevin Moore
2019-05-07 13:32:08 -07:00
committed by Andrew Brogdon
parent 42f2dce01b
commit 3fe927cb29
697 changed files with 241026 additions and 0 deletions

View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2019 John Mark Grancapal
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,28 @@
A sample that shows a visual recipe catalog for Filipino food.
Contributed as part of the Flutter Create 5K challenge by John Mark Grancapal.
**Asset License**: All images used on this app are under the "CC0 - Creative Commons" license
## Developed By
John Mark Grancapal <mark.grancapal@gmail.com>
Homepage: https://github.com/markgrancapal
## License
Copyright 2019 John Mark Grancapal
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,56 @@
import 'package:flutter_web/material.dart';
class Cook extends StatefulWidget {
final List dr;
final img;
final nme;
Cook(this.dr, this.img, this.nme);
CState createState() => CState();
}
class CState extends State<Cook> {
List cb;
initState() {
super.initState();
cb = List();
}
Widget build(ct) {
List dr = widget.dr;
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.red,
title: Text("INSTRUCTIONS"),
centerTitle: true),
body: Column(children: <Widget>[
Container(
child: ListTile(
leading: ClipRRect(
borderRadius: BorderRadius.circular(50),
child: Hero(
tag: widget.nme,
child: Image.asset(widget.img,
fit: BoxFit.cover, width: 100, height: 100))),
title: Text(widget.nme,
style: Theme.of(ct)
.textTheme
.display2
.copyWith(fontFamily: 'ark', color: Colors.black))),
margin: EdgeInsets.only(top: 40, bottom: 30, left: 20)),
Expanded(
child: ListView.builder(
itemCount: dr.length,
padding: EdgeInsets.all(10),
itemBuilder: (ct, i) {
cb.add(false);
return ListTile(
title: Text(dr[i]),
trailing: Checkbox(
value: cb[i],
onChanged: (v) => setState(() => cb[i] = v)));
})),
]));
}
}

View File

@@ -0,0 +1,353 @@
// Package flutter_page_indicator:
// https://pub.dartlang.org/packages/flutter_page_indicator
import 'package:flutter_web/material.dart';
import 'package:flutter_web/widgets.dart';
class WarmPainter extends BasePainter {
WarmPainter(PageIndicator widget, double page, int index, Paint paint)
: super(widget, page, index, paint);
void draw(Canvas canvas, double space, double size, double radius) {
double progress = page - index;
double distance = size + space;
double start = index * (size + space);
if (progress > 0.5) {
double right = start + size + distance;
//progress=>0.5-1.0
//left:0.0=>distance
double left = index * distance + distance * (progress - 0.5) * 2;
canvas.drawRRect(
new RRect.fromLTRBR(
left, 0.0, right, size, new Radius.circular(radius)),
_paint);
} else {
double right = start + size + distance * progress * 2;
canvas.drawRRect(
new RRect.fromLTRBR(
start, 0.0, right, size, new Radius.circular(radius)),
_paint);
}
}
}
class DropPainter extends BasePainter {
DropPainter(PageIndicator widget, double page, int index, Paint paint)
: super(widget, page, index, paint);
@override
void draw(Canvas canvas, double space, double size, double radius) {
double progress = page - index;
double dropHeight = widget.dropHeight;
double rate = (0.5 - progress).abs() * 2;
double scale = widget.scale;
//lerp(begin, end, progress)
canvas.drawCircle(
new Offset(radius + ((page) * (size + space)),
radius - dropHeight * (1 - rate)),
radius * (scale + rate * (1.0 - scale)),
_paint);
}
}
class NonePainter extends BasePainter {
NonePainter(PageIndicator widget, double page, int index, Paint paint)
: super(widget, page, index, paint);
@override
void draw(Canvas canvas, double space, double size, double radius) {
double progress = page - index;
double secondOffset = index == widget.count - 1
? radius
: radius + ((index + 1) * (size + space));
if (progress > 0.5) {
canvas.drawCircle(new Offset(secondOffset, radius), radius, _paint);
} else {
canvas.drawCircle(new Offset(radius + (index * (size + space)), radius),
radius, _paint);
}
}
}
class SlidePainter extends BasePainter {
SlidePainter(PageIndicator widget, double page, int index, Paint paint)
: super(widget, page, index, paint);
@override
void draw(Canvas canvas, double space, double size, double radius) {
canvas.drawCircle(
new Offset(radius + (page * (size + space)), radius), radius, _paint);
}
}
class ScalePainter extends BasePainter {
ScalePainter(PageIndicator widget, double page, int index, Paint paint)
: super(widget, page, index, paint);
// 连续的两个点,含有最后一个和第一个
@override
bool _shouldSkip(int i) {
if (index == widget.count - 1) {
return i == 0 || i == index;
}
return (i == index || i == index + 1);
}
@override
void paint(Canvas canvas, Size size) {
_paint.color = widget.color;
double space = widget.space;
double size = widget.size;
double radius = size / 2;
for (int i = 0, c = widget.count; i < c; ++i) {
if (_shouldSkip(i)) {
continue;
}
canvas.drawCircle(new Offset(i * (size + space) + radius, radius),
radius * widget.scale, _paint);
}
_paint.color = widget.activeColor;
draw(canvas, space, size, radius);
}
@override
void draw(Canvas canvas, double space, double size, double radius) {
double secondOffset = index == widget.count - 1
? radius
: radius + ((index + 1) * (size + space));
double progress = page - index;
_paint.color = Color.lerp(widget.activeColor, widget.color, progress);
//last
canvas.drawCircle(new Offset(radius + (index * (size + space)), radius),
lerp(radius, radius * widget.scale, progress), _paint);
//first
_paint.color = Color.lerp(widget.color, widget.activeColor, progress);
canvas.drawCircle(new Offset(secondOffset, radius),
lerp(radius * widget.scale, radius, progress), _paint);
}
}
class ColorPainter extends BasePainter {
ColorPainter(PageIndicator widget, double page, int index, Paint paint)
: super(widget, page, index, paint);
// 连续的两个点,含有最后一个和第一个
@override
bool _shouldSkip(int i) {
if (index == widget.count - 1) {
return i == 0 || i == index;
}
return (i == index || i == index + 1);
}
@override
void draw(Canvas canvas, double space, double size, double radius) {
double progress = page - index;
double secondOffset = index == widget.count - 1
? radius
: radius + ((index + 1) * (size + space));
_paint.color = Color.lerp(widget.activeColor, widget.color, progress);
//left
canvas.drawCircle(
new Offset(radius + (index * (size + space)), radius), radius, _paint);
//right
_paint.color = Color.lerp(widget.color, widget.activeColor, progress);
canvas.drawCircle(new Offset(secondOffset, radius), radius, _paint);
}
}
abstract class BasePainter extends CustomPainter {
final PageIndicator widget;
final double page;
final int index;
final Paint _paint;
double lerp(double begin, double end, double progress) {
return begin + (end - begin) * progress;
}
BasePainter(this.widget, this.page, this.index, this._paint);
void draw(Canvas canvas, double space, double size, double radius);
bool _shouldSkip(int index) {
return false;
}
//double secondOffset = index == widget.count-1 ? radius : radius + ((index + 1) * (size + space));
@override
void paint(Canvas canvas, Size size) {
_paint.color = widget.color;
double space = widget.space;
double size = widget.size;
double radius = size / 2;
for (int i = 0, c = widget.count; i < c; ++i) {
if (_shouldSkip(i)) {
continue;
}
canvas.drawCircle(
new Offset(i * (size + space) + radius, radius), radius, _paint);
}
double page = this.page;
if (page < index) {
page = 0.0;
}
_paint.color = widget.activeColor;
draw(canvas, space, size, radius);
}
@override
bool shouldRepaint(BasePainter oldDelegate) {
return oldDelegate.page != page;
}
}
class _PageIndicatorState extends State<PageIndicator> {
int index = 0;
Paint _paint = new Paint();
BasePainter _createPainer() {
switch (widget.layout) {
case PageIndicatorLayout.NONE:
return new NonePainter(
widget, widget.controller.page ?? 0.0, index, _paint);
case PageIndicatorLayout.SLIDE:
return new SlidePainter(
widget, widget.controller.page ?? 0.0, index, _paint);
case PageIndicatorLayout.WARM:
return new WarmPainter(
widget, widget.controller.page ?? 0.0, index, _paint);
case PageIndicatorLayout.COLOR:
return new ColorPainter(
widget, widget.controller.page ?? 0.0, index, _paint);
case PageIndicatorLayout.SCALE:
return new ScalePainter(
widget, widget.controller.page ?? 0.0, index, _paint);
case PageIndicatorLayout.DROP:
return new DropPainter(
widget, widget.controller.page ?? 0.0, index, _paint);
default:
throw new Exception("Not a valid layout");
}
}
@override
Widget build(BuildContext context) {
Widget child = new SizedBox(
width: widget.count * widget.size + (widget.count - 1) * widget.space,
height: widget.size,
child: new CustomPaint(
painter: _createPainer(),
),
);
if (widget.layout == PageIndicatorLayout.SCALE ||
widget.layout == PageIndicatorLayout.COLOR) {
child = new ClipRect(
child: child,
);
}
return new IgnorePointer(
child: child,
);
}
void _onController() {
double page = widget.controller.page ?? 0.0;
index = page.floor();
setState(() {});
}
@override
void initState() {
widget.controller.addListener(_onController);
super.initState();
}
@override
void didUpdateWidget(PageIndicator oldWidget) {
if (widget.controller != oldWidget.controller) {
oldWidget.controller.removeListener(_onController);
widget.controller.addListener(_onController);
}
super.didUpdateWidget(oldWidget);
}
@override
void dispose() {
widget.controller.removeListener(_onController);
super.dispose();
}
}
enum PageIndicatorLayout {
NONE,
SLIDE,
WARM,
COLOR,
SCALE,
DROP,
}
class PageIndicator extends StatefulWidget {
/// size of the dots
final double size;
/// space between dots.
final double space;
/// count of dots
final int count;
/// active color
final Color activeColor;
/// normal color
final Color color;
/// layout of the dots,default is [PageIndicatorLayout.SLIDE]
final PageIndicatorLayout layout;
// Only valid when layout==PageIndicatorLayout.scale
final double scale;
// Only valid when layout==PageIndicatorLayout.drop
final double dropHeight;
final PageController controller;
final double activeSize;
PageIndicator(
{Key key,
this.size: 20.0,
this.space: 5.0,
this.count,
this.activeSize: 20.0,
this.controller,
this.color: Colors.white30,
this.layout: PageIndicatorLayout.SLIDE,
this.activeColor: Colors.white,
this.scale: 0.6,
this.dropHeight: 20.0})
: assert(count != null),
assert(controller != null),
super(key: key);
@override
State<StatefulWidget> createState() {
return new _PageIndicatorState();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,135 @@
import 'package:flutter_web/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'cook.dart';
import 'flutter_swiper.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
Widget build(ct) {
return MaterialApp(
theme: ThemeData(
brightness: Brightness.light,
accentColor: Colors.red,
iconTheme: IconThemeData(color: Colors.red)),
title: "Filipino Cuisine",
home: Home());
}
}
class Home extends StatefulWidget {
HState createState() => HState();
}
class HState extends State<Home> {
List fd;
Map fi;
void initState() {
super.initState();
getData();
}
getData() async {
http.Response r =
await http.get('https://filipino-cuisine-app.firebaseio.com/data.json');
fd = json.decode(r.body);
setState(() => fi = fd[0]);
}
Widget build(ct) {
if (fd == null)
return Container(
color: Colors.white,
child: Center(
child: CircularProgressIndicator(),
));
var t = Theme.of(ct).textTheme;
return Scaffold(
body: Column(
children: <Widget>[
Expanded(
flex: 5,
child: Swiper(
onIndexChanged: (n) => setState(() => fi = fd[n]),
itemCount: fd.length,
itemBuilder: (cx, i) {
return Container(
margin: EdgeInsets.only(top: 40, bottom: 24),
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Hero(
tag: fd[i]['fn'],
child:
Image.asset(fd[i]['pf'], fit: BoxFit.cover)),
));
},
viewportFraction: .85,
scale: .9)),
Text(fi['fn'],
style:
t.display3.copyWith(fontFamily: 'ark', color: Colors.black)),
Container(
child: Text(fi['cn'],
style: t.subhead.apply(color: Colors.red, fontFamily: 'opb')),
margin: EdgeInsets.only(top: 10, bottom: 30),
),
Container(
child: Text(fi['dc'],
textAlign: TextAlign.center,
style: t.subhead.copyWith(fontFamily: 'opr')),
margin: EdgeInsets.only(left: 10, right: 10)),
Expanded(
flex: 2,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: fi['ig'].length,
itemBuilder: (cx, i) {
return Row(children: <Widget>[
Container(
margin: EdgeInsets.only(left: 10),
height: 60,
child: Image.asset(fi['ig'][i]['p'],
fit: BoxFit.contain)),
Container(
margin: EdgeInsets.only(left: 5, right: 10),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(fi['ig'][i]['n'],
style:
t.subtitle.copyWith(fontFamily: 'opb')),
Text(fi['ig'][i]['c'],
style:
t.caption.copyWith(fontFamily: 'opr'))
]))
]);
}))
],
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.restaurant_menu),
onPressed: () => Navigator.push(
ct,
MaterialPageRoute(
builder: (cx) => Cook(fi['in'], fi['pf'], fi['fn']))),
),
bottomNavigationBar: BottomAppBar(
shape: CircularNotchedRectangle(),
notchMargin: 4.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
IconButton(
icon:
Icon(fi['fv'] ? Icons.favorite : Icons.favorite_border),
onPressed: () => setState(() => fi['fv'] = !fi['fv'])),
IconButton(icon: Icon(Icons.share), onPressed: () {})
])),
);
}
}

View File

@@ -0,0 +1,809 @@
// Package transformer_page_view:
// https://pub.dartlang.org/packages/transformer_page_view
import 'dart:async';
import 'package:flutter_web/foundation.dart';
import 'package:flutter_web/widgets.dart';
class IndexController extends ChangeNotifier {
static const int NEXT = 1;
static const int PREVIOUS = -1;
static const int MOVE = 0;
Completer _completer;
int index;
bool animation;
int event;
Future move(int index, {bool animation: true}) {
this.animation = animation ?? true;
this.index = index;
this.event = MOVE;
_completer = new Completer();
notifyListeners();
return _completer.future;
}
Future next({bool animation: true}) {
this.event = NEXT;
this.animation = animation ?? true;
_completer = new Completer();
notifyListeners();
return _completer.future;
}
Future previous({bool animation: true}) {
this.event = PREVIOUS;
this.animation = animation ?? true;
_completer = new Completer();
notifyListeners();
return _completer.future;
}
void complete() {
if (!_completer.isCompleted) {
_completer.complete();
}
}
}
typedef void PaintCallback(Canvas canvas, Size siz);
class ColorPainter extends CustomPainter {
final Paint _paint;
final TransformInfo info;
final List<Color> colors;
ColorPainter(this._paint, this.info, this.colors);
@override
void paint(Canvas canvas, Size size) {
int index = info.fromIndex;
_paint.color = colors[index];
canvas.drawRect(
new Rect.fromLTWH(0.0, 0.0, size.width, size.height), _paint);
if (info.done) {
return;
}
int alpha;
int color;
double opacity;
double position = info.position;
if (info.forward) {
if (index < colors.length - 1) {
color = colors[index + 1].value & 0x00ffffff;
opacity = (position <= 0
? (-position / info.viewportFraction)
: 1 - position / info.viewportFraction);
if (opacity > 1) {
opacity -= 1.0;
}
if (opacity < 0) {
opacity += 1.0;
}
alpha = (0xff * opacity).toInt();
_paint.color = new Color((alpha << 24) | color);
canvas.drawRect(
new Rect.fromLTWH(0.0, 0.0, size.width, size.height), _paint);
}
} else {
if (index > 0) {
color = colors[index - 1].value & 0x00ffffff;
opacity = (position > 0
? position / info.viewportFraction
: (1 + position / info.viewportFraction));
if (opacity > 1) {
opacity -= 1.0;
}
if (opacity < 0) {
opacity += 1.0;
}
alpha = (0xff * opacity).toInt();
_paint.color = new Color((alpha << 24) | color);
canvas.drawRect(
new Rect.fromLTWH(0.0, 0.0, size.width, size.height), _paint);
}
}
}
@override
bool shouldRepaint(ColorPainter oldDelegate) {
return oldDelegate.info != info;
}
}
class _ParallaxColorState extends State<ParallaxColor> {
Paint paint = new Paint();
@override
Widget build(BuildContext context) {
return new CustomPaint(
painter: new ColorPainter(paint, widget.info, widget.colors),
child: widget.child,
);
}
}
class ParallaxColor extends StatefulWidget {
final Widget child;
final List<Color> colors;
final TransformInfo info;
ParallaxColor({
@required this.colors,
@required this.info,
@required this.child,
});
@override
State<StatefulWidget> createState() {
return new _ParallaxColorState();
}
}
class ParallaxContainer extends StatelessWidget {
final Widget child;
final double position;
final double translationFactor;
final double opacityFactor;
ParallaxContainer(
{@required this.child,
@required this.position,
this.translationFactor: 100.0,
this.opacityFactor: 1.0})
: assert(position != null),
assert(translationFactor != null);
@override
Widget build(BuildContext context) {
return Opacity(
opacity: (1 - position.abs()).clamp(0.0, 1.0) * opacityFactor,
child: new Transform.translate(
offset: new Offset(position * translationFactor, 0.0),
child: child,
),
);
}
}
class ParallaxImage extends StatelessWidget {
final Image image;
final double imageFactor;
ParallaxImage.asset(String name, {double position, this.imageFactor: 0.3})
: assert(imageFactor != null),
image = Image.asset(name,
fit: BoxFit.cover,
alignment: FractionalOffset(
0.5 + position * imageFactor,
0.5,
));
@override
Widget build(BuildContext context) {
return image;
}
}
///
/// NOTICE::
///
/// In order to make package smaller,currently we're not supporting any build-in page transformers
/// You can find build in transforms here:
///
///
///
const int kMaxValue = 2000000000;
const int kMiddleValue = 1000000000;
/// Default auto play transition duration (in millisecond)
const int kDefaultTransactionDuration = 300;
class TransformInfo {
/// The `width` of the `TransformerPageView`
final double width;
/// The `height` of the `TransformerPageView`
final double height;
/// The `position` of the widget pass to [PageTransformer.transform]
/// A `position` describes how visible the widget is.
/// The widget in the center of the screen' which is full visible, position is 0.0.
/// The widge in the left ,may be hidden, of the screen's position is less than 0.0, -1.0 when out of the screen.
/// The widge in the right ,may be hidden, of the screen's position is greater than 0.0, 1.0 when out of the screen
///
///
final double position;
/// The `index` of the widget pass to [PageTransformer.transform]
final int index;
/// The `activeIndex` of the PageView
final int activeIndex;
/// The `activeIndex` of the PageView, from user start to swipe
/// It will change when user end drag
final int fromIndex;
/// Next `index` is greater than this `index`
final bool forward;
/// User drag is done.
final bool done;
/// Same as [TransformerPageView.viewportFraction]
final double viewportFraction;
/// Copy from [TransformerPageView.scrollDirection]
final Axis scrollDirection;
TransformInfo(
{this.index,
this.position,
this.width,
this.height,
this.activeIndex,
this.fromIndex,
this.forward,
this.done,
this.viewportFraction,
this.scrollDirection});
}
abstract class PageTransformer {
///
final bool reverse;
PageTransformer({this.reverse: false});
/// Return a transformed widget, based on child and TransformInfo
Widget transform(Widget child, TransformInfo info);
}
typedef Widget PageTransformerBuilderCallback(Widget child, TransformInfo info);
class PageTransformerBuilder extends PageTransformer {
final PageTransformerBuilderCallback builder;
PageTransformerBuilder({bool reverse: false, @required this.builder})
: assert(builder != null),
super(reverse: reverse);
@override
Widget transform(Widget child, TransformInfo info) {
return builder(child, info);
}
}
class TransformerPageController extends PageController {
final bool loop;
final int itemCount;
final bool reverse;
TransformerPageController({
int initialPage = 0,
bool keepPage = true,
double viewportFraction = 1.0,
this.loop: false,
this.itemCount,
this.reverse: false,
}) : super(
initialPage: TransformerPageController._getRealIndexFromRenderIndex(
initialPage ?? 0, loop, itemCount, reverse),
keepPage: keepPage,
viewportFraction: viewportFraction);
int getRenderIndexFromRealIndex(num index) {
return _getRenderIndexFromRealIndex(index, loop, itemCount, reverse);
}
int getRealItemCount() {
if (itemCount == 0) return 0;
return loop ? itemCount + kMaxValue : itemCount;
}
static _getRenderIndexFromRealIndex(
num index, bool loop, int itemCount, bool reverse) {
if (itemCount == 0) return 0;
int renderIndex;
if (loop) {
renderIndex = index - kMiddleValue;
renderIndex = renderIndex % itemCount;
if (renderIndex < 0) {
renderIndex += itemCount;
}
} else {
renderIndex = index;
}
if (reverse) {
renderIndex = itemCount - renderIndex - 1;
}
return renderIndex;
}
double get realPage {
double page;
if (position.maxScrollExtent == null || position.minScrollExtent == null) {
page = 0.0;
} else {
page = super.page;
}
return page;
}
static _getRenderPageFromRealPage(
double page, bool loop, int itemCount, bool reverse) {
double renderPage;
if (loop) {
renderPage = page - kMiddleValue;
renderPage = renderPage % itemCount;
if (renderPage < 0) {
renderPage += itemCount;
}
} else {
renderPage = page;
}
if (reverse) {
renderPage = itemCount - renderPage - 1;
}
return renderPage;
}
double get page {
return loop
? _getRenderPageFromRealPage(realPage, loop, itemCount, reverse)
: realPage;
}
int getRealIndexFromRenderIndex(num index) {
return _getRealIndexFromRenderIndex(index, loop, itemCount, reverse);
}
static int _getRealIndexFromRenderIndex(
num index, bool loop, int itemCount, bool reverse) {
int result = reverse ? (itemCount - index - 1) : index;
if (loop) {
result += kMiddleValue;
}
return result;
}
}
class TransformerPageView extends StatefulWidget {
/// Create a `transformed` widget base on the widget that has been passed to the [PageTransformer.transform].
/// See [TransformInfo]
///
final PageTransformer transformer;
/// Same as [PageView.scrollDirection]
///
/// Defaults to [Axis.horizontal].
final Axis scrollDirection;
/// Same as [PageView.physics]
final ScrollPhysics physics;
/// Set to false to disable page snapping, useful for custom scroll behavior.
/// Same as [PageView.pageSnapping]
final bool pageSnapping;
/// Called whenever the page in the center of the viewport changes.
/// Same as [PageView.onPageChanged]
final ValueChanged<int> onPageChanged;
final IndexedWidgetBuilder itemBuilder;
// See [IndexController.mode],[IndexController.next],[IndexController.previous]
final IndexController controller;
/// Animation duration
final Duration duration;
/// Animation curve
final Curve curve;
final TransformerPageController pageController;
/// Set true to open infinity loop mode.
final bool loop;
/// This value is only valid when `pageController` is not set,
final int itemCount;
/// This value is only valid when `pageController` is not set,
final double viewportFraction;
/// If not set, it is controlled by this widget.
final int index;
/// Creates a scrollable list that works page by page using widgets that are
/// created on demand.
///
/// This constructor is appropriate for page views with a large (or infinite)
/// number of children because the builder is called only for those children
/// that are actually visible.
///
/// Providing a non-null [itemCount] lets the [PageView] compute the maximum
/// scroll extent.
///
/// [itemBuilder] will be called only with indices greater than or equal to
/// zero and less than [itemCount].
TransformerPageView({
Key key,
this.index,
Duration duration,
this.curve: Curves.ease,
this.viewportFraction: 1.0,
this.loop: false,
this.scrollDirection = Axis.horizontal,
this.physics,
this.pageSnapping = true,
this.onPageChanged,
this.controller,
this.transformer,
this.itemBuilder,
this.pageController,
@required this.itemCount,
}) : assert(itemCount != null),
assert(itemCount == 0 || itemBuilder != null || transformer != null),
this.duration =
duration ?? new Duration(milliseconds: kDefaultTransactionDuration),
super(key: key);
factory TransformerPageView.children(
{Key key,
int index,
Duration duration,
Curve curve: Curves.ease,
double viewportFraction: 1.0,
bool loop: false,
Axis scrollDirection = Axis.horizontal,
ScrollPhysics physics,
bool pageSnapping = true,
ValueChanged<int> onPageChanged,
IndexController controller,
PageTransformer transformer,
@required List<Widget> children,
TransformerPageController pageController}) {
assert(children != null);
return new TransformerPageView(
itemCount: children.length,
itemBuilder: (BuildContext context, int index) {
return children[index];
},
pageController: pageController,
transformer: transformer,
pageSnapping: pageSnapping,
key: key,
index: index,
duration: duration,
curve: curve,
viewportFraction: viewportFraction,
scrollDirection: scrollDirection,
physics: physics,
onPageChanged: onPageChanged,
controller: controller,
);
}
@override
State<StatefulWidget> createState() {
return new _TransformerPageViewState();
}
static int getRealIndexFromRenderIndex(
{bool reverse, int index, int itemCount, bool loop}) {
int initPage = reverse ? (itemCount - index - 1) : index;
if (loop) {
initPage += kMiddleValue;
}
return initPage;
}
static PageController createPageController(
{bool reverse,
int index,
int itemCount,
bool loop,
double viewportFraction}) {
return new PageController(
initialPage: getRealIndexFromRenderIndex(
reverse: reverse, index: index, itemCount: itemCount, loop: loop),
viewportFraction: viewportFraction);
}
}
class _TransformerPageViewState extends State<TransformerPageView> {
Size _size;
int _activeIndex;
double _currentPixels;
bool _done = false;
///This value will not change until user end drag.
int _fromIndex;
PageTransformer _transformer;
TransformerPageController _pageController;
Widget _buildItemNormal(BuildContext context, int index) {
int renderIndex = _pageController.getRenderIndexFromRealIndex(index);
Widget child = widget.itemBuilder(context, renderIndex);
return child;
}
Widget _buildItem(BuildContext context, int index) {
return new AnimatedBuilder(
animation: _pageController,
builder: (BuildContext c, Widget w) {
int renderIndex = _pageController.getRenderIndexFromRealIndex(index);
Widget child;
if (widget.itemBuilder != null) {
child = widget.itemBuilder(context, renderIndex);
}
if (child == null) {
child = new Container();
}
if (_size == null) {
return child ?? new Container();
}
double position;
double page = _pageController.realPage;
if (_transformer.reverse) {
position = page - index;
} else {
position = index - page;
}
position *= widget.viewportFraction;
TransformInfo info = new TransformInfo(
index: renderIndex,
width: _size.width,
height: _size.height,
position: position.clamp(-1.0, 1.0),
activeIndex:
_pageController.getRenderIndexFromRealIndex(_activeIndex),
fromIndex: _fromIndex,
forward: _pageController.position.pixels - _currentPixels >= 0,
done: _done,
scrollDirection: widget.scrollDirection,
viewportFraction: widget.viewportFraction);
return _transformer.transform(child, info);
});
}
double _calcCurrentPixels() {
_currentPixels = _pageController.getRenderIndexFromRealIndex(_activeIndex) *
_pageController.position.viewportDimension *
widget.viewportFraction;
// print("activeIndex:$_activeIndex , pix:$_currentPixels");
return _currentPixels;
}
@override
Widget build(BuildContext context) {
IndexedWidgetBuilder builder =
_transformer == null ? _buildItemNormal : _buildItem;
Widget child = new PageView.builder(
itemBuilder: builder,
itemCount: _pageController.getRealItemCount(),
onPageChanged: _onIndexChanged,
controller: _pageController,
scrollDirection: widget.scrollDirection,
physics: widget.physics,
pageSnapping: widget.pageSnapping,
reverse: _pageController.reverse,
);
if (_transformer == null) {
return child;
}
return new NotificationListener(
onNotification: (ScrollNotification notification) {
if (notification is ScrollStartNotification) {
_calcCurrentPixels();
_done = false;
_fromIndex = _activeIndex;
} else if (notification is ScrollEndNotification) {
_calcCurrentPixels();
_fromIndex = _activeIndex;
_done = true;
}
return false;
},
child: child);
}
void _onIndexChanged(int index) {
_activeIndex = index;
if (widget.onPageChanged != null) {
widget.onPageChanged(_pageController.getRenderIndexFromRealIndex(index));
}
}
void _onGetSize(_) {
Size size;
if (context == null) {
onGetSize(size);
return;
}
RenderObject renderObject = context.findRenderObject();
if (renderObject != null) {
Rect bounds = renderObject.paintBounds;
if (bounds != null) {
size = bounds.size;
}
}
_calcCurrentPixels();
onGetSize(size);
}
void onGetSize(Size size) {
if (mounted) {
setState(() {
_size = size;
});
}
}
@override
void initState() {
_transformer = widget.transformer;
// int index = widget.index ?? 0;
_pageController = widget.pageController;
if (_pageController == null) {
_pageController = new TransformerPageController(
initialPage: widget.index,
itemCount: widget.itemCount,
loop: widget.loop,
reverse:
widget.transformer == null ? false : widget.transformer.reverse);
}
// int initPage = _getRealIndexFromRenderIndex(index);
// _pageController = new PageController(initialPage: initPage,viewportFraction: widget.viewportFraction);
_fromIndex = _activeIndex = _pageController.initialPage;
_controller = getNotifier();
if (_controller != null) {
_controller.addListener(onChangeNotifier);
}
super.initState();
}
@override
void didUpdateWidget(TransformerPageView oldWidget) {
_transformer = widget.transformer;
int index = widget.index ?? 0;
bool created = false;
if (_pageController != widget.pageController) {
if (widget.pageController != null) {
_pageController = widget.pageController;
} else {
created = true;
_pageController = new TransformerPageController(
initialPage: widget.index,
itemCount: widget.itemCount,
loop: widget.loop,
reverse: widget.transformer == null
? false
: widget.transformer.reverse);
}
}
if (_pageController.getRenderIndexFromRealIndex(_activeIndex) != index) {
_fromIndex = _activeIndex = _pageController.initialPage;
if (!created) {
int initPage = _pageController.getRealIndexFromRenderIndex(index);
_pageController.animateToPage(initPage,
duration: widget.duration, curve: widget.curve);
}
}
if (_transformer != null)
WidgetsBinding.instance.addPostFrameCallback(_onGetSize);
if (_controller != getNotifier()) {
if (_controller != null) {
_controller.removeListener(onChangeNotifier);
}
_controller = getNotifier();
if (_controller != null) {
_controller.addListener(onChangeNotifier);
}
}
super.didUpdateWidget(oldWidget);
}
@override
void didChangeDependencies() {
if (_transformer != null)
WidgetsBinding.instance.addPostFrameCallback(_onGetSize);
super.didChangeDependencies();
}
ChangeNotifier getNotifier() {
return widget.controller;
}
int _calcNextIndex(bool next) {
int currentIndex = _activeIndex;
if (_pageController.reverse) {
if (next) {
currentIndex--;
} else {
currentIndex++;
}
} else {
if (next) {
currentIndex++;
} else {
currentIndex--;
}
}
if (!_pageController.loop) {
if (currentIndex >= _pageController.itemCount) {
currentIndex = 0;
} else if (currentIndex < 0) {
currentIndex = _pageController.itemCount - 1;
}
}
return currentIndex;
}
void onChangeNotifier() {
int event = widget.controller.event;
int index;
switch (event) {
case IndexController.MOVE:
{
index = _pageController
.getRealIndexFromRenderIndex(widget.controller.index);
}
break;
case IndexController.PREVIOUS:
case IndexController.NEXT:
{
index = _calcNextIndex(event == IndexController.NEXT);
}
break;
default:
//ignore this event
return;
}
if (widget.controller.animation) {
_pageController
.animateToPage(index,
duration: widget.duration, curve: widget.curve ?? Curves.ease)
.whenComplete(widget.controller.complete);
} else {
_pageController.jumpToPage(index);
widget.controller.complete();
}
}
ChangeNotifier _controller;
void dispose() {
super.dispose();
if (_controller != null) {
_controller.removeListener(onChangeNotifier);
}
}
}

View File

@@ -0,0 +1,471 @@
# Generated by pub
# See https://www.dartlang.org/tools/pub/glossary#lockfile
packages:
analyzer:
dependency: transitive
description:
name: analyzer
url: "https://pub.dartlang.org"
source: hosted
version: "0.36.3"
archive:
dependency: transitive
description:
name: archive
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.1"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.0"
bazel_worker:
dependency: transitive
description:
name: bazel_worker
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.20"
build:
dependency: transitive
description:
name: build
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.4"
build_config:
dependency: transitive
description:
name: build_config
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.0"
build_daemon:
dependency: transitive
description:
name: build_daemon
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.0"
build_modules:
dependency: transitive
description:
name: build_modules
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
build_resolvers:
dependency: transitive
description:
name: build_resolvers
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
build_runner:
dependency: "direct dev"
description:
name: build_runner
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.0"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.5"
build_web_compilers:
dependency: "direct dev"
description:
name: build_web_compilers
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
built_collection:
dependency: transitive
description:
name: built_collection
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.1"
built_value:
dependency: transitive
description:
name: built_value
url: "https://pub.dartlang.org"
source: hosted
version: "6.5.0"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.2"
code_builder:
dependency: transitive
description:
name: code_builder
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.0"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.14.11"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.6"
csslib:
dependency: transitive
description:
name: csslib
url: "https://pub.dartlang.org"
source: hosted
version: "0.16.0"
dart_style:
dependency: transitive
description:
name: dart_style
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.7"
fixnum:
dependency: transitive
description:
name: fixnum
url: "https://pub.dartlang.org"
source: hosted
version: "0.10.9"
flutter_web:
dependency: "direct main"
description:
path: "packages/flutter_web"
ref: HEAD
resolved-ref: "7a92f7391ee8a72c398f879e357380084e2076b4"
url: "https://github.com/flutter/flutter_web"
source: git
version: "0.0.0"
flutter_web_ui:
dependency: "direct main"
description:
path: "packages/flutter_web_ui"
ref: HEAD
resolved-ref: "7a92f7391ee8a72c398f879e357380084e2076b4"
url: "https://github.com/flutter/flutter_web"
source: git
version: "0.0.0"
front_end:
dependency: transitive
description:
name: front_end
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.18"
glob:
dependency: transitive
description:
name: glob
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.7"
graphs:
dependency: transitive
description:
name: graphs
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0"
html:
dependency: transitive
description:
name: html
url: "https://pub.dartlang.org"
source: hosted
version: "0.14.0+2"
http:
dependency: transitive
description:
name: http
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.0+2"
http_multi_server:
dependency: transitive
description:
name: http_multi_server
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.6"
http_parser:
dependency: transitive
description:
name: http_parser
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.3"
intl:
dependency: transitive
description:
name: intl
url: "https://pub.dartlang.org"
source: hosted
version: "0.15.8"
io:
dependency: transitive
description:
name: io
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.3"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.1+1"
json_annotation:
dependency: transitive
description:
name: json_annotation
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.0"
kernel:
dependency: transitive
description:
name: kernel
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.18"
logging:
dependency: transitive
description:
name: logging
url: "https://pub.dartlang.org"
source: hosted
version: "0.11.3+2"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.5"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.7"
mime:
dependency: transitive
description:
name: mime
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.6+2"
package_config:
dependency: transitive
description:
name: package_config
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.5"
package_resolver:
dependency: transitive
description:
name: package_resolver
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.10"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.2"
pedantic:
dependency: "direct dev"
description:
name: pedantic
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.0"
pool:
dependency: transitive
description:
name: pool
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.0"
protobuf:
dependency: transitive
description:
name: protobuf
url: "https://pub.dartlang.org"
source: hosted
version: "0.13.11"
pub_semver:
dependency: transitive
description:
name: pub_semver
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.2"
pubspec_parse:
dependency: transitive
description:
name: pubspec_parse
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.4"
quiver:
dependency: transitive
description:
name: quiver
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.3"
scratch_space:
dependency: transitive
description:
name: scratch_space
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.3+2"
shelf:
dependency: transitive
description:
name: shelf
url: "https://pub.dartlang.org"
source: hosted
version: "0.7.5"
shelf_web_socket:
dependency: transitive
description:
name: shelf_web_socket
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.3"
source_maps:
dependency: transitive
description:
name: source_maps
url: "https://pub.dartlang.org"
source: hosted
version: "0.10.8"
source_span:
dependency: transitive
description:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.5"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.3"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
stream_transform:
dependency: transitive
description:
name: stream_transform
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.19"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
timing:
dependency: transitive
description:
name: timing
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.1+1"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.6"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
watcher:
dependency: transitive
description:
name: watcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.7+10"
web_socket_channel:
dependency: transitive
description:
name: web_socket_channel
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.12"
yaml:
dependency: transitive
description:
name: yaml
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.15"
sdks:
dart: ">=2.3.0-dev.0.1 <3.0.0"

View File

@@ -0,0 +1,26 @@
name: filipino_cuisine
environment:
sdk: ">=2.2.0 <3.0.0"
dependencies:
flutter_web: any
flutter_web_ui: any
dev_dependencies:
pedantic: ^1.3.0
build_runner: any
build_web_compilers: any
# flutter_web packages are not published to pub.dartlang.org
# These overrides tell the package tools to get them from GitHub
dependency_overrides:
flutter_web:
git:
url: https://github.com/flutter/flutter_web
path: packages/flutter_web
flutter_web_ui:
git:
url: https://github.com/flutter/flutter_web
path: packages/flutter_web_ui

View File

@@ -0,0 +1,34 @@
[
{
"family": "MaterialIcons",
"fonts": [
{
"asset": "https://fonts.gstatic.com/s/materialicons/v42/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.woff2"
}
]
},
{
"family": "opr",
"fonts": [
{
"asset": "fonts/OpenSans-Regular.ttf"
}
]
},
{
"family": "opb",
"fonts": [
{
"asset": "fonts/OpenSans-Bold.ttf"
}
]
},
{
"family": "ark",
"fonts": [
{
"asset": "fonts/Arkipelago.otf"
}
]
}
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 541 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

View File

@@ -0,0 +1,366 @@
[
{
"cn": "120 Gr 85 Kcal 13 Min",
"ct": "3 minutes",
"dc": "Calamares is the Filipino version of the Mediterranean breaded fried squid dish, Calamari. ",
"fn": "Calamares",
"fv": false,
"ig": [
{
"c": "1/2 lb",
"n": "Squid",
"p": "squid.png"
},
{
"c": "3/4 cup",
"n": "Flour",
"p": "flour.png"
},
{
"c": "1 pc",
"n": "Egg",
"p": "egg.png"
},
{
"c": "1 tsp",
"n": "Salt",
"p": "salt.png"
},
{
"c": "1/2 tsp",
"n": "Black Pepper",
"p": "black_pepper.png"
},
{
"c": "2 cups",
"n": "Cooking Oil",
"p": "oil.png"
}
],
"in": [
"Combine squid, salt, and ground black pepper then mix well. Let stand for 10 minutes",
"Heat a cooking pot the pour-in cooking oil",
"Dredge the squid in flour then dip in beaten egg and roll over",
"When the oil is hot enough, deep-fry the squid until the color of the coating turns brown",
"Remove the fried squid from the cooking pot and transfer in a plate lined with paper towels",
"Serve with sinamak or Asian dipping sauce"
],
"pf": "calamares.jpg",
"pt": "10 minutes",
"sv": "3",
"tt": "13 MIN"
},
{
"cn": "260 Gr 293 Kcal 1 Hour 42 Min",
"ct": "1 hour 30 minutes",
"dc": "Sisig is a popular Filipino dish. It is composed of minced pork, chopped onion, and mayonnaise.",
"fn": "Pork Sisig",
"fv": false,
"ig": [
{
"c": "1 1/2 lb",
"n": "Pork Meat",
"p": "pork.png"
},
{
"c": "1 pc",
"n": "Onion",
"p": "onion.png"
},
{
"c": "3 tsp",
"n": "Chili",
"p": "chili.png"
},
{
"c": "1/2 tsp",
"n": "Garlic",
"p": "garlic.png"
},
{
"c": "1/4 tsp",
"n": "Black Pepper",
"p": "black_pepper.png"
},
{
"c": "1 pc",
"n": "Lemon",
"p": "lemon.png"
},
{
"c": "1/2 cup",
"n": "Butter",
"p": "butter.png"
},
{
"c": "1/2 tsp",
"n": "Salt",
"p": "salt.png"
},
{
"c": "1 pc",
"n": "Egg",
"p": "egg.png"
}
],
"in": [
"Pour the water in a pan and bring to a boil Add salt and pepper",
"Put-in the pork meat then simmer for 40 minutes to 1 hour (or until tender)",
"Grill the boiled pork meat until done",
"Chop the pork meat into fine pieces",
"In a wide pan, melt the butter. Add the onions. Cook until onions are soft.",
"Put-in the ginger and cook for 2 minutes",
"Add the pork meat. Cook for 10 to 12 minutes",
"Put-in the soy sauce, garlic powder, and chili. Mix well",
"Add salt and pepper to taste",
"Put-in the mayonnaise and mix with the other ingredients",
"Transfer to a serving plate. Top with chopped green onions and raw egg",
"Add the lemon before eating"
],
"pf": "pork_sisig.jpg",
"pt": "12 minutes",
"sv": "6",
"tt": "1 hour 42 minutes"
},
{
"cn": "120 Gr 168 Kcal 1 Hour 10 Min",
"ct": "3 minutes",
"dc": "Pochero or Puchero is a well-loved Filipino stew. Made with meat, tomatoes, and saba bananas. ",
"fn": "Pochero",
"fv": false,
"ig": [
{
"c": "1 large",
"n": "Banana",
"p": "banana.png"
},
{
"c": "2 pcs",
"n": "Tomato",
"p": "tomato.png"
},
{
"c": "1 lb",
"n": "Pork Meat",
"p": "pork.png"
},
{
"c": "1 pc",
"n": "Onion",
"p": "onion.png"
},
{
"c": "1 tsp",
"n": "Garlic",
"p": "garlic.png"
},
{
"c": "1 tbsp",
"n": "Peppercorn",
"p": "black_pepper.png"
},
{
"c": "1 medium",
"n": "Potato",
"p": "potato.png"
},
{
"c": "1 small",
"n": "Cabbage",
"p": "cabbage.png"
},
{
"c": "1 bunch",
"n": "Bok Choy",
"p": "bokchoy.png"
},
{
"c": "1/4 lb",
"n": "Green Beans",
"p": "green_beans.png"
},
{
"c": "2 tbsp",
"n": "Cooking Oil",
"p": "oil.png"
}
],
"in": [
"Heat cooking oil in a cooking pot",
"Sauté garlic, onions, and tomatoes",
"Add pork and cook until the color turns light brown",
"Put-in fish sauce, whole pepper corn, and tomato sauce. Stir.",
"Add water and let boil. Simmer until pork is tender (about 30 to 40 minutes)",
"Put-in potato, plantain, and chick peas. Cook for 5 to 7 minutes.",
"Add cabbage and long green beans. Cook for 5 minutes",
"Stir-in the bok choy. Cover the pot and turn off the heat",
"Let the residual heat cook the bok choy (about 5 minutes)",
"Transfer to a serving plate and serve"
],
"pf": "pochero.jpg",
"pt": "10 minutes",
"sv": "3",
"tt": "13 MIN"
},
{
"cn": "140 Gr 250 Kcal 1 Hour 30 Min",
"ct": "3 minutes",
"dc": "A type of Filipino Beef Stew. This dish is cooked in a tomato-based sauce with vegetables such as potato, carrot, and bell pepper.",
"fn": "Beef Caldereta",
"fv": false,
"ig": [
{
"c": "1/2 lb",
"n": "Beef",
"p": "beef.png"
},
{
"c": "2 medium",
"n": "Carrot",
"p": "carrot.png"
},
{
"c": "1 large",
"n": "Potato",
"p": "potato.png"
},
{
"c": "1 small",
"n": "Green Bell Pepper",
"p": "green_bell.png"
},
{
"c": "1 small",
"n": "Red Bell Pepper",
"p": "red_bell.png"
},
{
"c": "2 Cloves",
"n": "Garlic",
"p": "garlic.png"
},
{
"c": "1 medium",
"n": "Yellow Onion",
"p": "yellow_onion.png"
},
{
"c": "1 tsp",
"n": "Salt",
"p": "salt.png"
},
{
"c": "6 tbsp",
"n": "Cooking oil",
"p": "oil.png"
},
{
"c": "1 tsp",
"n": "Peppercorn",
"p": "black_pepper.png"
},
{
"c": "1 tsp",
"n": "Red Pepper",
"p": "chili.png"
}
],
"in": [
"Heat a pan or wok and then pour 3 tablespoons cooking oil. Stir-fry the bell peppers for 3 minutes. Remove the bell peppers and put in a plate. Set aside",
"Using the oil in the pan (add more if necessary), pan fry the carrots and potato for 3 to 5 minutes. Put these in a plate and then set aside",
"Heat the remaining 3 tablespoons of oil in a clean pot",
"Sauté the garlic and onion",
"Add the beef. Cook until it turns light brown",
"Pour in tomato sauce and water. Let boil",
"Continue to cook in low heat for 60 minutes or until the beef gets tender. Add more water if needed",
"Stir-in the liver spread and then add some salt and pepper",
"Put the pan-fried potato and carrots in the pot. Stir. Add the bell peppers",
"Cover the pot. Continue to cook for 5 minutes",
"Add the red pepper flakes. Stir and cook for 3 minutes more",
"Transfer to a serving plate. Serve"
],
"pf": "beef_caldereta.jpg",
"pt": "10 minutes",
"sv": "3",
"tt": "13 MIN"
},
{
"cn": "90 Gr 130 Kcal 1 Hour 15 Min",
"ct": "3 minutes",
"dc": "Pork Embutido is a Filipino-style meatloaf made with a festive mixture of ground pork, carrots, and raisins wrapped around slices of eggs and sausage.",
"fn": "Embutido",
"fv": false,
"ig": [
{
"c": "2 lbs",
"n": "Ground pork",
"p": "ground_pork.png"
},
{
"c": "12 pcs",
"n": "Sausage",
"p": "sausage.png"
},
{
"c": "3 pcs",
"n": "Egg",
"p": "egg.png"
},
{
"c": "2 cups",
"n": "Cheese",
"p": "cheese.png"
},
{
"c": "1 cup",
"n": "Red Bell Pepper",
"p": "red_bell.png"
},
{
"c": "1 cup",
"n": "Green Bell Pepper",
"p": "green_bell.png"
},
{
"c": "1/2 cup",
"n": "Raisins",
"p": "raisins.png"
},
{
"c": "1/2 cup",
"n": "Carrot",
"p": "carrot.png"
},
{
"c": "1/2 cup",
"n": "Onion",
"p": "onion.png"
},
{
"c": "2 tbsp",
"n": "Salt",
"p": "salt.png"
},
{
"c": "1 tbsp",
"n": "Peppercorn",
"p": "black_pepper.png"
}
],
"in": [
"Place the ground pork in a large container",
"Add the bread crumbs then break the raw eggs and add it in. Mix well",
"Put-in the carrots, bell pepper (red and green), onion, pickle relish, and cheddar cheese. Mix thoroughly",
"Add the raisins, tomato sauce, salt, and pepper then mix well.",
"Put in the sliced vienna sausage and sliced boiled eggs alternately on the middle of the flat meat mixture.",
"Roll the foil to form a cylinder — locking the sausage and egg in the middle if the meat mixture. Once done, lock the edges of the foil.",
"Place in a steamer and let cook for 1 hour.",
"Place inside the refrigerator until temperature turns cold",
"Slice and serve"
],
"pf": "embutido.jpg",
"pt": "10 minutes",
"sv": "3",
"tt": "13 MIN"
}
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 514 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

View File

@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script defer src="main.dart.js" type="application/javascript"></script>
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,10 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter_web_ui/ui.dart' as ui;
import 'package:filipino_cuisine/main.dart' as app;
main() async {
await ui.webOnlyInitializePlatform();
app.main();
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB