Commit 54d95416 authored by Hans Muller's avatar Hans Muller Committed by GitHub

Added a gallery animation demo (#8547)

parent baaa2e67
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
export 'animation_demo.dart';
export 'calculator_demo.dart';
export 'colors_demo.dart';
export 'contacts_demo.dart';
......
This diff is collapsed.
// Copyright 2017 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.
// Raw data for the animation demo.
import 'package:flutter/material.dart';
const Color _mariner = const Color(0xFF3B5F8F);
const Color _mediumPurple = const Color(0xFF8266D4);
const Color _tomato = const Color(0xFFF95B57);
const Color _mySin = const Color(0xFFF3A646);
const Color _deepCerise = const Color(0xFFD93F9B);
class SectionDetail {
const SectionDetail({ this.title, this.subtitle, this.imageAsset });
final String title;
final String subtitle;
final String imageAsset;
}
class Section {
const Section({ this.title, this.backgroundAsset, this.leftColor, this.rightColor, this.details });
final String title;
final String backgroundAsset;
final Color leftColor;
final Color rightColor;
final List<SectionDetail> details;
@override
bool operator==(Object other) {
if (other is! Section)
return false;
final Section otherSection = other;
return title == otherSection.title;
}
@override
int get hashCode => title.hashCode;
}
// TODO(hansmuller): replace the SectionDetail images and text. Get rid of
// the const vars like _eyeglassesDetail and insert a variety of titles and
// image SectionDetails in the allSections list.
const SectionDetail _eyeglassesDetail = const SectionDetail(
imageAsset: 'packages/flutter_gallery_assets/shrine/products/sunnies.png',
title: 'Flutter enables interactive animation',
subtitle: '3K views - 5 days',
);
const SectionDetail _eyeglassesImageDetail = const SectionDetail(
imageAsset: 'packages/flutter_gallery_assets/shrine/products/sunnies.png',
);
const SectionDetail _seatingDetail = const SectionDetail(
imageAsset: 'packages/flutter_gallery_assets/shrine/products/lawn_chair.png',
title: 'Flutter enables interactive animation',
subtitle: '3K views - 5 days',
);
const SectionDetail _seatingImageDetail = const SectionDetail(
imageAsset: 'packages/flutter_gallery_assets/shrine/products/lawn_chair.png',
);
const SectionDetail _decorationDetail = const SectionDetail(
imageAsset: 'packages/flutter_gallery_assets/shrine/products/lipstick.png',
title: 'Flutter enables interactive animation',
subtitle: '3K views - 5 days',
);
const SectionDetail _decorationImageDetail = const SectionDetail(
imageAsset: 'packages/flutter_gallery_assets/shrine/products/lipstick.png',
);
const SectionDetail _protectionDetail = const SectionDetail(
imageAsset: 'packages/flutter_gallery_assets/shrine/products/helmet.png',
title: 'Flutter enables interactive animation',
subtitle: '3K views - 5 days',
);
const SectionDetail _protectionImageDetail = const SectionDetail(
imageAsset: 'packages/flutter_gallery_assets/shrine/products/helmet.png',
);
final List<Section> allSections = <Section>[
const Section(
title: 'EYEGLASSES',
leftColor: _mediumPurple,
rightColor: _mariner,
backgroundAsset: 'packages/flutter_gallery_assets/shrine/products/sunnies.png',
details: const <SectionDetail>[
_eyeglassesDetail,
_eyeglassesImageDetail,
_eyeglassesDetail,
_eyeglassesDetail,
_eyeglassesDetail,
_eyeglassesDetail,
],
),
const Section(
title: 'SEATING',
leftColor: _tomato,
rightColor: _mediumPurple,
backgroundAsset: 'packages/flutter_gallery_assets/shrine/products/lawn_chair.png',
details: const <SectionDetail>[
_seatingDetail,
_seatingImageDetail,
_seatingDetail,
_seatingDetail,
_seatingDetail,
_seatingDetail,
],
),
const Section(
title: 'DECORATION',
leftColor: _mySin,
rightColor: _tomato,
backgroundAsset: 'packages/flutter_gallery_assets/shrine/products/lipstick.png',
details: const <SectionDetail>[
_decorationDetail,
_decorationImageDetail,
_decorationDetail,
_decorationDetail,
_decorationDetail,
_decorationDetail,
],
),
const Section(
title: 'PROTECTION',
leftColor: Colors.white,
rightColor: _tomato,
backgroundAsset: 'packages/flutter_gallery_assets/shrine/products/helmet.png',
details: const <SectionDetail>[
_protectionDetail,
_protectionImageDetail,
_protectionDetail,
_protectionDetail,
_protectionDetail,
_protectionDetail,
],
),
];
// Copyright 2017 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/material.dart';
import 'sections.dart';
const double kSectionIndicatorWidth = 32.0;
// The card for a single section. Displays the section's gradient and background image.
class SectionCard extends StatelessWidget {
SectionCard({ Key key, this.section }) : super(key: key) {
assert(section != null);
}
final Section section;
@override
Widget build(BuildContext context) {
return new Padding(
padding: const EdgeInsets.only(bottom: 1.0),
child: new DecoratedBox(
decoration: new BoxDecoration(
borderRadius: new BorderRadius.circular(4.0),
gradient: new LinearGradient(
begin: FractionalOffset.topLeft,
end: FractionalOffset.topRight,
colors: <Color>[
section.leftColor,
section.rightColor,
],
),
),
child: new Opacity(
opacity: 0.075,
child: new Image.asset(
section.backgroundAsset,
fit: ImageFit.cover,
),
),
),
);
}
}
// The title is rendered with two overlapping text widgets that are vertically
// offset a little. It's supposed to look sort-of 3D.
class SectionTitle extends StatelessWidget {
static const TextStyle sectionTitleStyle = const TextStyle(
fontFamily: 'Raleway',
inherit: false,
fontSize: 24.0,
fontWeight: FontWeight.w500,
color: Colors.white,
textBaseline: TextBaseline.alphabetic,
);
static final TextStyle sectionTitleShadowStyle = sectionTitleStyle.copyWith(
color: const Color(0x19000000),
);
SectionTitle({ Key key, this.section, this.scale, this.opacity }) : super(key: key) {
assert(section != null);
assert(scale != null);
assert(opacity != null && opacity >= 0.0 && opacity <= 1.0);
}
final Section section;
final double scale;
final double opacity;
@override
Widget build(BuildContext context) {
return new IgnorePointer(
child: new Opacity(
opacity: opacity,
child: new Transform(
transform: new Matrix4.identity()..scale(scale),
alignment: FractionalOffset.center,
child: new Stack(
children: <Widget>[
new Positioned(
top: 4.0,
child: new Text(section.title, style: sectionTitleShadowStyle),
),
new Text(section.title, style: sectionTitleStyle),
],
),
),
),
);
}
}
// Small horizontal bar that indicates the selected section.
class SectionIndicator extends StatelessWidget {
SectionIndicator({ Key key, this.opacity: 1.0 }) : super(key: key);
final double opacity;
@override
Widget build(BuildContext context) {
return new IgnorePointer(
child: new Container(
width: kSectionIndicatorWidth,
height: 3.0,
decoration: new BoxDecoration(
backgroundColor: Colors.white.withOpacity(opacity),
),
),
);
}
}
// Display a single SectionDetail.
class SectionDetailView extends StatelessWidget {
SectionDetailView({ Key key, this.detail }) : super(key: key) {
assert(detail != null && detail.imageAsset != null);
assert((detail.imageAsset ?? detail.title) != null);
}
final SectionDetail detail;
@override
Widget build(BuildContext context) {
final Widget image = new DecoratedBox(
decoration: new BoxDecoration(
borderRadius: new BorderRadius.circular(6.0),
backgroundImage: new BackgroundImage(
image: new AssetImage(detail.imageAsset),
fit: ImageFit.cover,
alignment: FractionalOffset.center,
),
),
);
Widget item;
if (detail.title == null && detail.subtitle == null) {
item = new Container(
height: 240.0,
padding: const EdgeInsets.all(16.0),
child: image,
);
} else {
item = new ListItem(
title: new Text(detail.title),
subtitle: new Text(detail.subtitle),
leading: new SizedBox(width: 32.0, height: 32.0, child: image),
);
}
return new DecoratedBox(
decoration: new BoxDecoration(backgroundColor: Colors.grey[200]),
child: item,
);
}
}
// Copyright 2017 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/material.dart';
import 'animation/home.dart';
class AnimationDemo extends StatelessWidget {
AnimationDemo({Key key}) : super(key: key);
static const String routeName = '/animation';
@override
Widget build(BuildContext context) => new AnimationDemoHome();
}
......@@ -67,6 +67,13 @@ final List<GalleryItem> kAllGalleryItems = <GalleryItem>[
routeName: ContactsDemo.routeName,
buildRoute: (BuildContext context) => new ContactsDemo(),
),
new GalleryItem(
title: 'Animation',
subtitle: 'Section organizer',
category: 'Demos',
routeName: AnimationDemo.routeName,
buildRoute: (BuildContext context) => new AnimationDemo(),
),
// Material Components
new GalleryItem(
title: 'Bottom navigation',
......
......@@ -18,6 +18,7 @@ final List<String> demoTitles = <String>[
'Pesto',
'Shrine',
'Contact profile',
'Animation',
// Material Components
'Bottom navigation',
'Buttons',
......
......@@ -215,9 +215,9 @@ class ScrollPosition extends ViewportOffset {
/// scroll notifications will be dispatched. No overscroll notifications can
/// be generated by this method.
///
/// Immediately after the jump, a ballistic activity is started, in case the
/// value was out of range.
void jumpTo(double value) {
/// If settle is true then, immediately after the jump, a ballistic activity
/// is started, in case the value was out of range.
void jumpTo(double value, { bool settle: true }) {
beginIdleActivity();
if (_pixels != value) {
final double oldPixels = _pixels;
......@@ -227,6 +227,7 @@ class ScrollPosition extends ViewportOffset {
state.dispatchNotification(activity.createScrollUpdateNotification(state, _pixels - oldPixels));
state.dispatchNotification(activity.createScrollEndNotification(state));
}
if (settle)
beginBallisticActivity(0.0);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment