Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
36eb4a06
Commit
36eb4a06
authored
Jul 21, 2016
by
Hans Muller
Committed by
GitHub
Jul 21, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support for Material arc point and rect transitions (#4938)
parent
4abaf64c
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
875 additions
and
27 deletions
+875
-27
all.dart
examples/flutter_gallery/lib/demo/all.dart
+1
-0
animation_demo.dart
examples/flutter_gallery/lib/demo/animation_demo.dart
+439
-0
item.dart
examples/flutter_gallery/lib/gallery/item.dart
+6
-0
material.dart
packages/flutter/lib/material.dart
+1
-0
app.dart
packages/flutter/lib/src/material/app.dart
+12
-1
arc.dart
packages/flutter/lib/src/material/arc.dart
+253
-0
page.dart
packages/flutter/lib/src/material/page.dart
+1
-1
heroes.dart
packages/flutter/lib/src/widgets/heroes.dart
+34
-25
transitions.dart
packages/flutter/lib/src/widgets/transitions.dart
+44
-0
arc_test.dart
packages/flutter/test/material/arc_test.dart
+80
-0
devfs.dart
packages/flutter_tools/lib/src/devfs.dart
+4
-0
No files found.
examples/flutter_gallery/lib/demo/all.dart
View file @
36eb4a06
...
...
@@ -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
'buttons_demo.dart'
;
export
'contacts_demo.dart'
;
export
'cards_demo.dart'
;
...
...
examples/flutter_gallery/lib/demo/animation_demo.dart
0 → 100644
View file @
36eb4a06
This diff is collapsed.
Click to expand it.
examples/flutter_gallery/lib/gallery/item.dart
View file @
36eb4a06
...
...
@@ -66,6 +66,12 @@ final List<GalleryItem> kAllGalleryItems = <GalleryItem>[
buildRoute:
(
BuildContext
context
)
=>
new
ContactsDemo
()
),
// Components
new
GalleryItem
(
title:
'Animation'
,
subtitle:
'Material motion for points and rectangles'
,
routeName:
AnimationDemo
.
routeName
,
buildRoute:
(
BuildContext
context
)
=>
new
AnimationDemo
()
),
new
GalleryItem
(
title:
'Buttons'
,
subtitle:
'All kinds: flat, raised, dropdown, icon, etc'
,
...
...
packages/flutter/lib/material.dart
View file @
36eb4a06
...
...
@@ -14,6 +14,7 @@ library material;
export
'src/material/about.dart'
;
export
'src/material/app.dart'
;
export
'src/material/app_bar.dart'
;
export
'src/material/arc.dart'
;
export
'src/material/bottom_sheet.dart'
;
export
'src/material/button.dart'
;
export
'src/material/button_bar.dart'
;
...
...
packages/flutter/lib/src/material/app.dart
View file @
36eb4a06
...
...
@@ -7,6 +7,7 @@ import 'dart:io' show Platform;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/widgets.dart'
;
import
'arc.dart'
;
import
'colors.dart'
;
import
'overscroll_indicator.dart'
;
import
'page.dart'
;
...
...
@@ -152,7 +153,17 @@ final ScrollConfigurationDelegate _indicatorScroll = new _IndicatorScrollConfigu
final
ScrollConfigurationDelegate
_bounceScroll
=
new
ScrollConfigurationDelegate
();
class
_MaterialAppState
extends
State
<
MaterialApp
>
{
final
HeroController
_heroController
=
new
HeroController
();
HeroController
_heroController
;
@override
void
initState
()
{
super
.
initState
();
_heroController
=
new
HeroController
(
createRectTween:
_createRectTween
);
}
RectTween
_createRectTween
(
Rect
begin
,
Rect
end
)
{
return
new
MaterialRectArcTween
(
begin:
begin
,
end:
end
);
}
Route
<
dynamic
>
_onGenerateRoute
(
RouteSettings
settings
)
{
WidgetBuilder
builder
=
config
.
routes
[
settings
.
name
];
...
...
packages/flutter/lib/src/material/arc.dart
0 → 100644
View file @
36eb4a06
// Copyright 2016 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
'dart:math'
as
math
;
import
'dart:ui'
show
hashValues
,
lerpDouble
;
import
'package:flutter/material.dart'
;
import
'package:meta/meta.dart'
;
// How close the begin and end points must be to an axis to be considered
// vertical or horizontal.
const
double
_kOnAxisDelta
=
2.0
;
/// A Tween that animates a point along a circular arc.
///
/// The arc's radius is related to the bounding box that contains the [begin]
/// and [end] points. If the bounding box is taller than it is wide, then the
/// center of the circle will be horizontally aligned with the end point.
/// Otherwise the center of the circle will be aligned with the begin point.
/// The arc's sweep is always less than or equal to 90 degrees.
///
/// See also:
///
/// * [MaterialRectArcTween]
class
MaterialPointArcTween
extends
Tween
<
Point
>
{
MaterialPointArcTween
({
@required
Point
begin
,
@required
Point
end
})
:
super
(
begin:
begin
,
end:
end
)
{
// An explanation with a diagram can be found at https://goo.gl/vMSdRg
final
Offset
delta
=
end
-
begin
;
final
double
deltaX
=
delta
.
dx
.
abs
();
final
double
deltaY
=
delta
.
dy
.
abs
();
final
double
distanceFromAtoB
=
delta
.
distance
;
final
Point
c
=
new
Point
(
end
.
x
,
begin
.
y
);
double
sweepAngle
()
=>
2.0
*
math
.
asin
(
distanceFromAtoB
/
(
2.0
*
_radius
));
if
(
deltaX
>
_kOnAxisDelta
&&
deltaY
>
_kOnAxisDelta
)
{
if
(
deltaX
<
deltaY
)
{
_radius
=
distanceFromAtoB
*
distanceFromAtoB
/
(
c
-
begin
).
distance
/
2.0
;
_center
=
new
Point
(
end
.
x
+
_radius
*
(
begin
.
x
-
end
.
x
).
sign
,
end
.
y
);
if
(
begin
.
x
<
end
.
x
)
{
_beginAngle
=
sweepAngle
()
*
(
begin
.
y
-
end
.
y
).
sign
;
_endAngle
=
0.0
;
}
else
{
_beginAngle
=
math
.
PI
+
sweepAngle
()
*
(
end
.
y
-
begin
.
y
).
sign
;
_endAngle
=
math
.
PI
;
}
}
else
{
_radius
=
distanceFromAtoB
*
distanceFromAtoB
/
(
c
-
end
).
distance
/
2.0
;
_center
=
new
Point
(
begin
.
x
,
begin
.
y
+
(
end
.
y
-
begin
.
y
).
sign
*
_radius
);
if
(
begin
.
y
<
end
.
y
)
{
_beginAngle
=
-
math
.
PI
/
2.0
;
_endAngle
=
_beginAngle
+
sweepAngle
()
*
(
end
.
x
-
begin
.
x
).
sign
;
}
else
{
_beginAngle
=
math
.
PI
/
2.0
;
_endAngle
=
_beginAngle
+
sweepAngle
()
*
(
begin
.
x
-
end
.
x
).
sign
;
}
}
}
}
Point
_center
;
double
_radius
;
double
_beginAngle
;
double
_endAngle
;
/// The center of the circular arc, null if [begin] and [end] are horiztonally or
/// vertically aligned.
Point
get
center
=>
_center
;
/// The radius of the circular arc, null if begin and end are horiztonally or
/// vertically aligned.
double
get
radius
=>
_radius
;
/// The beginning of the arc's sweep in radians, measured from the positive X axis.
/// Positive angles turn clockwise. Null if begin and end are horiztonally or
/// vertically aligned.
double
get
beginAngle
=>
_beginAngle
;
/// The end of the arc's sweep in radians, measured from the positive X axis.
/// Positive angles turn clockwise.
double
get
endAngle
=>
_beginAngle
;
/// Setting the arc's [begin] parameter is not supported. Construct a new arc instead.
@override
set
begin
(
Point
value
)
{
assert
(
false
);
// not supported
}
/// Setting the arc's [end] parameter is not supported. Construct a new arc instead.
@override
set
end
(
Point
value
)
{
assert
(
false
);
// not supported
}
@override
Point
lerp
(
double
t
)
{
if
(
t
==
0.0
)
return
begin
;
if
(
t
==
1.0
)
return
end
;
if
(
_beginAngle
==
null
||
_endAngle
==
null
)
return
Point
.
lerp
(
begin
,
end
,
t
);
final
double
angle
=
lerpDouble
(
_beginAngle
,
_endAngle
,
t
);
final
double
x
=
math
.
cos
(
angle
)
*
_radius
;
final
double
y
=
math
.
sin
(
angle
)
*
_radius
;
return
_center
+
new
Offset
(
x
,
y
);
}
@override
bool
operator
==(
dynamic
other
)
{
if
(
identical
(
this
,
other
))
return
true
;
if
(
other
is
!
MaterialPointArcTween
)
return
false
;
final
MaterialPointArcTween
typedOther
=
other
;
return
begin
==
typedOther
.
begin
&&
end
==
typedOther
.
end
;
}
@override
int
get
hashCode
=>
hashValues
(
begin
,
end
);
@override
String
toString
()
{
return
'
$runtimeType
(
$begin
\
u2192
$end
center=
$center
, radius=
$radius
, beginAngle=
$beginAngle
, endAngle=
$endAngle
)'
;
}
}
enum
_CornerId
{
topLeft
,
topRight
,
bottomLeft
,
bottomRight
}
class
_Diagonal
{
const
_Diagonal
(
this
.
beginId
,
this
.
endId
);
final
_CornerId
beginId
;
final
_CornerId
endId
;
}
const
List
<
_Diagonal
>
_allDiagonals
=
const
<
_Diagonal
>[
const
_Diagonal
(
_CornerId
.
topLeft
,
_CornerId
.
bottomRight
),
const
_Diagonal
(
_CornerId
.
bottomRight
,
_CornerId
.
topLeft
),
const
_Diagonal
(
_CornerId
.
topRight
,
_CornerId
.
bottomLeft
),
const
_Diagonal
(
_CornerId
.
bottomLeft
,
_CornerId
.
topRight
),
];
/// A Tween that animates a rectangle from [begin] to [end].
///
/// The rectangle corners whose diagonal is closest to the overall direction of
/// the animation follow arcs defined with [MaterialPointArcTween].
///
/// See also:
///
/// * [RectTween] (linear rectangle interpolation)
/// * [MaterialPointArcTween]
class
MaterialRectArcTween
extends
RectTween
{
MaterialRectArcTween
({
@required
Rect
begin
,
@required
Rect
end
})
:
super
(
begin:
begin
,
end:
end
)
{
final
Offset
centersVector
=
end
.
center
-
begin
.
center
;
double
maxSupport
=
0.0
;
for
(
_Diagonal
diagonal
in
_allDiagonals
)
{
final
double
support
=
_diagonalSupport
(
centersVector
,
diagonal
);
if
(
support
>
maxSupport
)
{
_diagonal
=
diagonal
;
maxSupport
=
support
;
}
}
_beginArc
=
new
MaterialPointArcTween
(
begin:
_cornerFor
(
begin
,
_diagonal
.
beginId
),
end:
_cornerFor
(
end
,
_diagonal
.
beginId
)
);
_endArc
=
new
MaterialPointArcTween
(
begin:
_cornerFor
(
begin
,
_diagonal
.
endId
),
end:
_cornerFor
(
end
,
_diagonal
.
endId
)
);
}
_Diagonal
_diagonal
;
MaterialPointArcTween
_beginArc
;
MaterialPointArcTween
_endArc
;
Point
_cornerFor
(
Rect
rect
,
_CornerId
id
)
{
switch
(
id
)
{
case
_CornerId
.
topLeft
:
return
rect
.
topLeft
;
case
_CornerId
.
topRight
:
return
rect
.
topRight
;
case
_CornerId
.
bottomLeft
:
return
rect
.
bottomLeft
;
case
_CornerId
.
bottomRight
:
return
rect
.
bottomRight
;
}
return
Point
.
origin
;
}
double
_diagonalSupport
(
Offset
centersVector
,
_Diagonal
diagonal
)
{
final
Offset
delta
=
_cornerFor
(
begin
,
diagonal
.
endId
)
-
_cornerFor
(
begin
,
diagonal
.
beginId
);
final
double
length
=
delta
.
distance
;
return
centersVector
.
dx
*
delta
.
dx
/
length
+
centersVector
.
dy
*
delta
.
dy
/
length
;
}
/// The path of the corresponding [begin], [end] rectangle corners that lead
/// the animation.
MaterialPointArcTween
get
beginArc
=>
_beginArc
;
/// The path of the corresponding [begin], [end] rectangle corners that trail
/// the animation.
MaterialPointArcTween
get
endArc
=>
_endArc
;
/// Setting the arc's [begin] parameter is not supported. Construct a new arc instead.
@override
set
begin
(
Rect
value
)
{
assert
(
false
);
// not supported
}
/// Setting the arc's [end] parameter is not supported. Construct a new arc instead.
@override
set
end
(
Rect
value
)
{
assert
(
false
);
// not supported
}
@override
Rect
lerp
(
double
t
)
{
if
(
t
==
0.0
)
return
begin
;
if
(
t
==
1.0
)
return
end
;
return
new
Rect
.
fromPoints
(
_beginArc
.
lerp
(
t
),
_endArc
.
lerp
(
t
));
}
@override
bool
operator
==(
dynamic
other
)
{
if
(
identical
(
this
,
other
))
return
true
;
if
(
other
is
!
MaterialRectArcTween
)
return
false
;
final
MaterialRectArcTween
typedOther
=
other
;
return
begin
==
typedOther
.
begin
&&
end
==
typedOther
.
end
;
}
@override
int
get
hashCode
=>
hashValues
(
begin
,
end
);
@override
String
toString
()
{
return
'
$runtimeType
(
$begin
\
u2192
$end
beginArc=
$beginArc
, endArc=
$endArc
)'
;
}
}
packages/flutter/lib/src/material/page.dart
View file @
36eb4a06
...
...
@@ -61,7 +61,7 @@ class MaterialPageRoute<T> extends PageRoute<T> {
final
WidgetBuilder
builder
;
@override
Duration
get
transitionDuration
=>
const
Duration
(
milliseconds:
15
0
);
Duration
get
transitionDuration
=>
const
Duration
(
milliseconds:
30
0
);
@override
Color
get
barrierColor
=>
null
;
...
...
packages/flutter/lib/src/widgets/heroes.dart
View file @
36eb4a06
...
...
@@ -66,13 +66,13 @@ class _HeroManifest {
final
GlobalKey
key
;
final
Widget
config
;
final
Set
<
HeroState
>
sourceStates
;
final
Re
lativeRe
ct
currentRect
;
final
Rect
currentRect
;
final
double
currentTurns
;
}
abstract
class
HeroHandle
{
bool
get
alwaysAnimate
;
_HeroManifest
_takeChild
(
Rect
animationArea
,
Animation
<
double
>
currentAnimation
);
_HeroManifest
_takeChild
(
Animation
<
double
>
currentAnimation
);
}
class
Hero
extends
StatefulWidget
{
...
...
@@ -161,7 +161,7 @@ class HeroState extends State<Hero> implements HeroHandle {
bool
get
alwaysAnimate
=>
config
.
alwaysAnimate
;
@override
_HeroManifest
_takeChild
(
Rect
animationArea
,
Animation
<
double
>
currentAnimation
)
{
_HeroManifest
_takeChild
(
Animation
<
double
>
currentAnimation
)
{
assert
(
mounted
);
final
RenderBox
renderObject
=
context
.
findRenderObject
();
assert
(
renderObject
!=
null
);
...
...
@@ -175,12 +175,11 @@ class HeroState extends State<Hero> implements HeroHandle {
final
Point
heroTopLeft
=
renderObject
.
localToGlobal
(
Point
.
origin
);
final
Point
heroBottomRight
=
renderObject
.
localToGlobal
(
renderObject
.
size
.
bottomRight
(
Point
.
origin
));
final
Rect
heroArea
=
new
Rect
.
fromLTRB
(
heroTopLeft
.
x
,
heroTopLeft
.
y
,
heroBottomRight
.
x
,
heroBottomRight
.
y
);
final
RelativeRect
startRect
=
new
RelativeRect
.
fromRect
(
heroArea
,
animationArea
);
_HeroManifest
result
=
new
_HeroManifest
(
key:
_key
,
// might be null, e.g. if the hero is returning to us
config:
config
,
sourceStates:
new
HashSet
<
HeroState
>.
from
(<
HeroState
>[
this
]),
currentRect:
startRect
,
currentRect:
heroArea
,
currentTurns:
config
.
turns
.
toDouble
()
);
if
(
_key
!=
null
)
...
...
@@ -224,6 +223,7 @@ class _HeroQuestState implements HeroHandle {
this
.
key
,
this
.
child
,
this
.
sourceStates
,
this
.
animationArea
,
this
.
targetRect
,
this
.
targetTurns
,
this
.
targetState
,
...
...
@@ -237,10 +237,11 @@ class _HeroQuestState implements HeroHandle {
final
GlobalKey
key
;
final
Widget
child
;
final
Set
<
HeroState
>
sourceStates
;
final
RelativeRect
targetRect
;
final
Rect
animationArea
;
final
Rect
targetRect
;
final
int
targetTurns
;
final
HeroState
targetState
;
final
Re
lativeRe
ctTween
currentRect
;
final
RectTween
currentRect
;
final
Tween
<
double
>
currentTurns
;
@override
...
...
@@ -250,7 +251,7 @@ class _HeroQuestState implements HeroHandle {
bool
_taken
=
false
;
@override
_HeroManifest
_takeChild
(
Rect
animationArea
,
Animation
<
double
>
currentAnimation
)
{
_HeroManifest
_takeChild
(
Animation
<
double
>
currentAnimation
)
{
assert
(!
taken
);
_taken
=
true
;
Set
<
HeroState
>
states
=
sourceStates
;
...
...
@@ -266,8 +267,9 @@ class _HeroQuestState implements HeroHandle {
}
Widget
build
(
BuildContext
context
,
Animation
<
double
>
animation
)
{
return
new
PositionedTransition
(
return
new
Relative
PositionedTransition
(
rect:
currentRect
.
animate
(
animation
),
size:
animationArea
.
size
,
child:
new
RotationTransition
(
turns:
currentTurns
.
animate
(
animation
),
child:
new
KeyedSubtree
(
...
...
@@ -286,10 +288,13 @@ class _HeroMatch {
final
Object
tag
;
}
typedef
RectTween
CreateRectTween
(
Rect
begin
,
Rect
end
);
class
HeroParty
{
HeroParty
({
this
.
onQuestFinished
});
HeroParty
({
this
.
onQuestFinished
,
this
.
createRectTween
});
final
VoidCallback
onQuestFinished
;
final
CreateRectTween
createRectTween
;
List
<
_HeroQuestState
>
_heroes
=
<
_HeroQuestState
>[];
bool
get
isEmpty
=>
_heroes
.
isEmpty
;
...
...
@@ -302,8 +307,10 @@ class HeroParty {
return
result
;
}
RelativeRectTween
createRectTween
(
RelativeRect
begin
,
RelativeRect
end
)
{
return
new
RelativeRectTween
(
begin:
begin
,
end:
end
);
RectTween
_doCreateRectTween
(
Rect
begin
,
Rect
end
)
{
if
(
createRectTween
!=
null
)
return
createRectTween
(
begin
,
end
);
return
new
RectTween
(
begin:
begin
,
end:
end
);
}
Tween
<
double
>
createTurnsTween
(
double
begin
,
double
end
)
{
...
...
@@ -331,30 +338,29 @@ class HeroParty {
if
((
heroPair
.
from
==
null
&&
!
heroPair
.
to
.
alwaysAnimate
)
||
(
heroPair
.
to
==
null
&&
!
heroPair
.
from
.
alwaysAnimate
))
continue
;
_HeroManifest
from
=
heroPair
.
from
?.
_takeChild
(
animationArea
,
_currentAnimation
);
_HeroManifest
from
=
heroPair
.
from
?.
_takeChild
(
_currentAnimation
);
assert
(
heroPair
.
to
==
null
||
heroPair
.
to
is
HeroState
);
_HeroManifest
to
=
heroPair
.
to
?.
_takeChild
(
animationArea
,
_currentAnimation
);
_HeroManifest
to
=
heroPair
.
to
?.
_takeChild
(
_currentAnimation
);
assert
(
from
!=
null
||
to
!=
null
);
assert
(
to
==
null
||
to
.
sourceStates
.
length
==
1
);
assert
(
to
==
null
||
to
.
currentTurns
.
floor
()
==
to
.
currentTurns
);
HeroState
targetState
=
to
!=
null
?
to
.
sourceStates
.
elementAt
(
0
)
:
null
;
Set
<
HeroState
>
sourceStates
=
from
!=
null
?
from
.
sourceStates
:
new
HashSet
<
HeroState
>();
sourceStates
.
remove
(
targetState
);
RelativeRect
sourceRect
=
from
!=
null
?
from
.
currentRect
:
new
RelativeRect
.
fromRect
(
to
.
currentRect
.
toRect
(
animationArea
).
center
&
Size
.
zero
,
animationArea
);
RelativeRect
targetRect
=
to
!=
null
?
to
.
currentRect
:
new
RelativeRect
.
fromRect
(
from
.
currentRect
.
toRect
(
animationArea
).
center
&
Size
.
zero
,
animationArea
);
double
sourceTurns
=
from
!=
null
?
from
.
currentTurns
:
0.0
;
double
targetTurns
=
to
!=
null
?
to
.
currentTurns
:
0.0
;
Rect
sourceRect
=
from
?.
currentRect
??
to
.
currentRect
.
center
&
Size
.
zero
;
Rect
targetRect
=
to
?.
currentRect
??
from
.
currentRect
.
center
&
Size
.
zero
;
double
sourceTurns
=
from
?.
currentTurns
??
0.0
;
double
targetTurns
=
to
?.
currentTurns
??
0.0
;
_newHeroes
.
add
(
new
_HeroQuestState
(
tag:
heroPair
.
tag
,
key:
from
!=
null
?
from
.
key
:
to
.
key
,
child:
to
!=
null
?
to
.
config
:
from
.
config
,
key:
from
?.
key
??
to
.
key
,
child:
to
?.
config
??
from
.
config
,
sourceStates:
sourceStates
,
animationArea:
animationArea
,
targetRect:
targetRect
,
targetTurns:
targetTurns
.
floor
(),
targetState:
targetState
,
currentRect:
c
reateRectTween
(
sourceRect
,
targetRect
),
currentRect:
_doC
reateRectTween
(
sourceRect
,
targetRect
),
currentTurns:
createTurnsTween
(
sourceTurns
,
targetTurns
)
));
}
...
...
@@ -400,8 +406,11 @@ class HeroParty {
}
class
HeroController
extends
NavigatorObserver
{
HeroController
()
{
_party
=
new
HeroParty
(
onQuestFinished:
_handleQuestFinished
);
HeroController
({
CreateRectTween
createRectTween
})
{
_party
=
new
HeroParty
(
onQuestFinished:
_handleQuestFinished
,
createRectTween:
createRectTween
);
}
HeroParty
_party
;
...
...
packages/flutter/lib/src/widgets/transitions.dart
View file @
36eb4a06
...
...
@@ -292,6 +292,10 @@ class RelativeRectTween extends Tween<RelativeRect> {
/// position to and end position over the lifetime of the animation.
///
/// Only works if it's the child of a [Stack].
///
/// See also:
///
/// * [RelativePositionedTransition]
class
PositionedTransition
extends
AnimatedWidget
{
/// Creates a transition for [Positioned].
///
...
...
@@ -320,6 +324,46 @@ class PositionedTransition extends AnimatedWidget {
}
}
/// Animated version of [Positioned] which transitions the child's position
/// based on the value of [rect] relative to a bounding box with the
/// specified [size].
///
/// Only works if it's the child of a [Stack].
///
/// See also:
///
/// * [PositionedTransition]
class
RelativePositionedTransition
extends
AnimatedWidget
{
RelativePositionedTransition
({
Key
key
,
@required
Animation
<
Rect
>
rect
,
@required
this
.
size
,
this
.
child
})
:
super
(
key:
key
,
animation:
rect
);
/// The animation that controls the child's size and position.
Animation
<
Rect
>
get
rect
=>
animation
;
/// The [Positioned] widget's offsets are relative to a box of this
/// size whose origin is 0,0.
final
Size
size
;
/// The widget below this widget in the tree.
final
Widget
child
;
@override
Widget
build
(
BuildContext
context
)
{
final
RelativeRect
offsets
=
new
RelativeRect
.
fromSize
(
rect
.
value
,
size
);
return
new
Positioned
(
top:
offsets
.
top
,
right:
offsets
.
right
,
bottom:
offsets
.
bottom
,
left:
offsets
.
left
,
child:
child
);
}
}
/// A builder that builds a widget given a child.
typedef
Widget
TransitionBuilder
(
BuildContext
context
,
Widget
child
);
...
...
packages/flutter/test/material/arc_test.dart
0 → 100644
View file @
36eb4a06
// Copyright 2016 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_test/flutter_test.dart'
;
import
'package:flutter/material.dart'
;
void
main
(
)
{
test
(
'on-axis MaterialPointArcTween'
,
()
{
MaterialPointArcTween
tween
=
new
MaterialPointArcTween
(
begin:
Point
.
origin
,
end:
new
Point
(
0.0
,
10.0
)
);
expect
(
tween
.
lerp
(
0.5
),
equals
(
new
Point
(
0.0
,
5.0
)));
expect
(
tween
,
hasOneLineDescription
);
tween
=
new
MaterialPointArcTween
(
begin:
Point
.
origin
,
end:
new
Point
(
10.0
,
0.0
)
);
expect
(
tween
.
lerp
(
0.5
),
equals
(
new
Point
(
5.0
,
0.0
)));
});
test
(
'on-axis MaterialRectArcTween'
,
()
{
MaterialRectArcTween
tween
=
new
MaterialRectArcTween
(
begin:
new
Rect
.
fromLTWH
(
0.0
,
0.0
,
10.0
,
10.0
),
end:
new
Rect
.
fromLTWH
(
0.0
,
10.0
,
10.0
,
10.0
)
);
expect
(
tween
.
lerp
(
0.5
),
equals
(
new
Rect
.
fromLTWH
(
0.0
,
5.0
,
10.0
,
10.0
)));
expect
(
tween
,
hasOneLineDescription
);
tween
=
new
MaterialRectArcTween
(
begin:
new
Rect
.
fromLTWH
(
0.0
,
0.0
,
10.0
,
10.0
),
end:
new
Rect
.
fromLTWH
(
10.0
,
0.0
,
10.0
,
10.0
)
);
expect
(
tween
.
lerp
(
0.5
),
equals
(
new
Rect
.
fromLTWH
(
5.0
,
0.0
,
10.0
,
10.0
)));
});
test
(
'MaterialPointArcTween'
,
()
{
final
Point
begin
=
const
Point
(
180.0
,
110.0
);
final
Point
end
=
const
Point
(
37.0
,
250.0
);
MaterialPointArcTween
tween
=
new
MaterialPointArcTween
(
begin:
begin
,
end:
end
);
expect
(
tween
.
lerp
(
0.0
),
begin
);
expect
((
tween
.
lerp
(
0.25
)
-
const
Point
(
126.0
,
120.0
)).
distance
,
closeTo
(
0.0
,
2.0
));
expect
((
tween
.
lerp
(
0.75
)
-
const
Point
(
48.0
,
196.0
)).
distance
,
closeTo
(
0.0
,
2.0
));
expect
(
tween
.
lerp
(
1.0
),
end
);
tween
=
new
MaterialPointArcTween
(
begin:
end
,
end:
begin
);
expect
(
tween
.
lerp
(
0.0
),
end
);
expect
((
tween
.
lerp
(
0.25
)
-
const
Point
(
91.0
,
239.0
)).
distance
,
closeTo
(
0.0
,
2.0
));
expect
((
tween
.
lerp
(
0.75
)
-
const
Point
(
168.3
,
163.8
)).
distance
,
closeTo
(
0.0
,
2.0
));
expect
(
tween
.
lerp
(
1.0
),
begin
);
});
test
(
'MaterialRectArcTween'
,
()
{
final
Rect
begin
=
new
Rect
.
fromLTRB
(
180.0
,
100.0
,
330.0
,
200.0
);
final
Rect
end
=
new
Rect
.
fromLTRB
(
32.0
,
275.0
,
132.0
,
425.0
);
bool
sameRect
(
Rect
a
,
Rect
b
)
{
return
(
a
.
left
-
b
.
left
).
abs
()
<
2.0
&&
(
a
.
top
-
b
.
top
).
abs
()
<
2.0
&&
(
a
.
right
-
b
.
right
).
abs
()
<
2.0
&&
(
a
.
bottom
-
b
.
bottom
).
abs
()
<
2.0
;
}
MaterialRectArcTween
tween
=
new
MaterialRectArcTween
(
begin:
begin
,
end:
end
);
expect
(
tween
.
lerp
(
0.0
),
begin
);
expect
(
sameRect
(
tween
.
lerp
(
0.25
),
new
Rect
.
fromLTRB
(
120.0
,
113.0
,
259.0
,
237.0
)),
isTrue
);
expect
(
sameRect
(
tween
.
lerp
(
0.75
),
new
Rect
.
fromLTRB
(
42.3
,
206.5
,
153.5
,
354.7
)),
isTrue
);
expect
(
tween
.
lerp
(
1.0
),
end
);
tween
=
new
MaterialRectArcTween
(
begin:
end
,
end:
begin
);
expect
(
tween
.
lerp
(
0.0
),
end
);
expect
(
sameRect
(
tween
.
lerp
(
0.25
),
new
Rect
.
fromLTRB
(
92.0
,
262.0
,
203.0
,
388.0
)),
isTrue
);
expect
(
sameRect
(
tween
.
lerp
(
0.75
),
new
Rect
.
fromLTRB
(
169.7
,
168.5
,
308.5
,
270.3
)),
isTrue
);
expect
(
tween
.
lerp
(
1.0
),
begin
);
});
}
packages/flutter_tools/lib/src/devfs.dart
View file @
36eb4a06
...
...
@@ -79,12 +79,16 @@ class ServiceProtocolDevFSOperations implements DevFSOperations {
return
e
;
}
String
fileContents
=
BASE64
.
encode
(
bytes
);
try
{
return
await
serviceProtocol
.
sendRequest
(
'_writeDevFSFile'
,
<
String
,
dynamic
>
{
'fsName'
:
fsName
,
'path'
:
entry
.
devicePath
,
'fileContents'
:
fileContents
});
}
catch
(
e
)
{
print
(
'failed on
${entry.devicePath}
$e
'
);
}
}
@override
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment