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
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 @@
...
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
export
'animation_demo.dart'
;
export
'buttons_demo.dart'
;
export
'buttons_demo.dart'
;
export
'contacts_demo.dart'
;
export
'contacts_demo.dart'
;
export
'cards_demo.dart'
;
export
'cards_demo.dart'
;
...
...
examples/flutter_gallery/lib/demo/animation_demo.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:async'
;
import
'package:flutter/gestures.dart'
;
import
'package:flutter/material.dart'
;
enum
_DragTarget
{
start
,
end
}
// How close a drag's start position must be to the target point. This is
// a distance squared.
const
double
_kTargetSlop
=
2500.0
;
// Used by the Painter classes.
const
double
_kPointRadius
=
6.0
;
class
_DragHandler
extends
Drag
{
_DragHandler
(
this
.
onUpdate
,
this
.
onCancel
,
this
.
onEnd
);
final
GestureDragUpdateCallback
onUpdate
;
final
GestureDragCancelCallback
onCancel
;
final
GestureDragEndCallback
onEnd
;
@override
void
update
(
DragUpdateDetails
details
)
{
onUpdate
(
details
);
}
@override
void
cancel
()
{
onCancel
();
}
@override
void
end
(
DragEndDetails
details
)
{
onEnd
(
details
);
}
}
class
_IgnoreDrag
extends
Drag
{
}
class
_PointDemoPainter
extends
CustomPainter
{
_PointDemoPainter
({
Animation
<
double
>
repaint
,
this
.
arc
})
:
_repaint
=
repaint
,
super
(
repaint:
repaint
);
final
MaterialPointArcTween
arc
;
Animation
<
double
>
_repaint
;
void
drawPoint
(
Canvas
canvas
,
Point
point
,
Color
color
)
{
final
Paint
paint
=
new
Paint
()
..
color
=
color
.
withOpacity
(
0.25
)
..
style
=
PaintingStyle
.
fill
;
canvas
.
drawCircle
(
point
,
_kPointRadius
,
paint
);
paint
..
color
=
color
..
style
=
PaintingStyle
.
stroke
..
strokeWidth
=
2.0
;
canvas
.
drawCircle
(
point
,
_kPointRadius
+
1.0
,
paint
);
}
@override
void
paint
(
Canvas
canvas
,
Size
size
)
{
final
Paint
paint
=
new
Paint
();
if
(
arc
.
center
!=
null
)
drawPoint
(
canvas
,
arc
.
center
,
Colors
.
blue
[
400
]);
paint
..
color
=
Colors
.
green
[
500
].
withOpacity
(
0.25
)
..
strokeWidth
=
4.0
..
style
=
PaintingStyle
.
stroke
;
if
(
arc
.
center
!=
null
&&
arc
.
radius
!=
null
)
canvas
.
drawCircle
(
arc
.
center
,
arc
.
radius
,
paint
);
else
canvas
.
drawLine
(
arc
.
begin
,
arc
.
end
,
paint
);
drawPoint
(
canvas
,
arc
.
begin
,
Colors
.
green
[
500
]);
drawPoint
(
canvas
,
arc
.
end
,
Colors
.
red
[
500
]);
paint
..
color
=
Colors
.
green
[
500
]
..
style
=
PaintingStyle
.
fill
;
canvas
.
drawCircle
(
arc
.
lerp
(
_repaint
.
value
),
_kPointRadius
,
paint
);
}
@override
bool
hitTest
(
Point
position
)
{
return
(
arc
.
begin
-
position
).
distanceSquared
<
_kTargetSlop
||
(
arc
.
end
-
position
).
distanceSquared
<
_kTargetSlop
;
}
@override
bool
shouldRepaint
(
_PointDemoPainter
oldPainter
)
=>
arc
!=
oldPainter
.
arc
;
}
class
_PointDemo
extends
StatefulWidget
{
_PointDemo
({
Key
key
,
this
.
controller
})
:
super
(
key:
key
);
final
AnimationController
controller
;
@override
_PointDemoState
createState
()
=>
new
_PointDemoState
();
}
class
_PointDemoState
extends
State
<
_PointDemo
>
{
final
GlobalKey
_painterKey
=
new
GlobalKey
();
CurvedAnimation
_animation
;
_DragTarget
_dragTarget
;
Point
_begin
=
const
Point
(
180.0
,
110.0
);
Point
_end
=
const
Point
(
37.0
,
250.0
);
@override
void
initState
()
{
super
.
initState
();
_animation
=
new
CurvedAnimation
(
parent:
config
.
controller
,
curve:
Curves
.
ease
);
}
@override
void
dispose
()
{
config
.
controller
.
value
=
0.0
;
super
.
dispose
();
}
Drag
_handleOnStart
(
Point
position
)
{
// TODO(hansmuller): allow the user to drag both points at the same time.
if
(
_dragTarget
!=
null
)
return
new
_IgnoreDrag
();
final
RenderBox
box
=
_painterKey
.
currentContext
.
findRenderObject
();
final
double
startOffset
=
(
box
.
localToGlobal
(
_begin
)
-
position
).
distanceSquared
;
final
double
endOffset
=
(
box
.
localToGlobal
(
_end
)
-
position
).
distanceSquared
;
setState
(()
{
if
(
startOffset
<
endOffset
&&
startOffset
<
_kTargetSlop
)
_dragTarget
=
_DragTarget
.
start
;
else
if
(
endOffset
<
_kTargetSlop
)
_dragTarget
=
_DragTarget
.
end
;
else
_dragTarget
=
null
;
});
return
new
_DragHandler
(
_handleDragUpdate
,
_handleDragCancel
,
_handleDragEnd
);
}
void
_handleDragUpdate
(
DragUpdateDetails
details
)
{
switch
(
_dragTarget
)
{
case
_DragTarget
.
start
:
setState
(()
{
_begin
=
_begin
+
details
.
delta
;
});
break
;
case
_DragTarget
.
end
:
setState
(()
{
_end
=
_end
+
details
.
delta
;
});
break
;
}
}
void
_handleDragCancel
()
{
_dragTarget
=
null
;
config
.
controller
.
value
=
0.0
;
}
void
_handleDragEnd
(
DragEndDetails
details
)
{
_dragTarget
=
null
;
}
@override
Widget
build
(
BuildContext
context
)
{
final
MaterialPointArcTween
arc
=
new
MaterialPointArcTween
(
begin:
_begin
,
end:
_end
);
return
new
RawGestureDetector
(
behavior:
_dragTarget
==
null
?
HitTestBehavior
.
deferToChild
:
HitTestBehavior
.
opaque
,
gestures:
<
Type
,
GestureRecognizerFactory
>{
ImmediateMultiDragGestureRecognizer:
(
ImmediateMultiDragGestureRecognizer
recognizer
)
{
return
(
recognizer
??=
new
ImmediateMultiDragGestureRecognizer
())
..
onStart
=
_handleOnStart
;
}
},
child:
new
ClipRect
(
child:
new
CustomPaint
(
key:
_painterKey
,
foregroundPainter:
new
_PointDemoPainter
(
repaint:
_animation
,
arc:
arc
),
// Watch out: if this IgnorePointer is left out, then gestures that
// fail _PointDemoPainter.hitTest() will still be recognized because
// they do overlap this child, which is as big as the CustomPaint.
child:
new
IgnorePointer
(
child:
new
Padding
(
padding:
const
EdgeInsets
.
all
(
16.0
),
child:
new
Text
(
"Tap the refresh button to run the animation. Drag the green "
"and red points to change the animation's path."
,
style:
Theme
.
of
(
context
).
textTheme
.
caption
.
copyWith
(
fontSize:
16.0
)
)
)
)
)
)
);
}
}
class
_RectangleDemoPainter
extends
CustomPainter
{
_RectangleDemoPainter
({
Animation
<
double
>
repaint
,
this
.
arc
})
:
_repaint
=
repaint
,
super
(
repaint:
repaint
);
final
MaterialRectArcTween
arc
;
Animation
<
double
>
_repaint
;
void
drawPoint
(
Canvas
canvas
,
Point
p
,
Color
color
)
{
final
Paint
paint
=
new
Paint
()
..
color
=
color
.
withOpacity
(
0.25
)
..
style
=
PaintingStyle
.
fill
;
canvas
.
drawCircle
(
p
,
_kPointRadius
,
paint
);
paint
..
color
=
color
..
style
=
PaintingStyle
.
stroke
..
strokeWidth
=
2.0
;
canvas
.
drawCircle
(
p
,
_kPointRadius
+
1.0
,
paint
);
}
void
drawRect
(
Canvas
canvas
,
Rect
rect
,
Color
color
)
{
final
Paint
paint
=
new
Paint
()
..
color
=
color
.
withOpacity
(
0.25
)
..
strokeWidth
=
4.0
..
style
=
PaintingStyle
.
stroke
;
canvas
.
drawRect
(
rect
,
paint
);
drawPoint
(
canvas
,
rect
.
center
,
color
);
}
@override
void
paint
(
Canvas
canvas
,
Size
size
)
{
drawRect
(
canvas
,
arc
.
begin
,
Colors
.
green
[
500
]);
drawRect
(
canvas
,
arc
.
end
,
Colors
.
red
[
500
]);
drawRect
(
canvas
,
arc
.
lerp
(
_repaint
.
value
),
Colors
.
blue
[
500
]);
}
@override
bool
hitTest
(
Point
position
)
{
return
(
arc
.
begin
.
center
-
position
).
distanceSquared
<
_kTargetSlop
||
(
arc
.
end
.
center
-
position
).
distanceSquared
<
_kTargetSlop
;
}
@override
bool
shouldRepaint
(
_RectangleDemoPainter
oldPainter
)
=>
arc
!=
oldPainter
.
arc
;
}
class
_RectangleDemo
extends
StatefulWidget
{
_RectangleDemo
({
Key
key
,
this
.
controller
})
:
super
(
key:
key
);
final
AnimationController
controller
;
@override
_RectangleDemoState
createState
()
=>
new
_RectangleDemoState
();
}
class
_RectangleDemoState
extends
State
<
_RectangleDemo
>
{
final
GlobalKey
_painterKey
=
new
GlobalKey
();
CurvedAnimation
_animation
;
_DragTarget
_dragTarget
;
Rect
_begin
=
new
Rect
.
fromLTRB
(
180.0
,
100.0
,
330.0
,
200.0
);
Rect
_end
=
new
Rect
.
fromLTRB
(
32.0
,
275.0
,
132.0
,
425.0
);
@override
void
initState
()
{
super
.
initState
();
_animation
=
new
CurvedAnimation
(
parent:
config
.
controller
,
curve:
Curves
.
ease
);
}
@override
void
dispose
()
{
config
.
controller
.
value
=
0.0
;
super
.
dispose
();
}
Drag
_handleOnStart
(
Point
position
)
{
// TODO(hansmuller): allow the user to drag both points at the same time.
if
(
_dragTarget
!=
null
)
return
new
_IgnoreDrag
();
final
RenderBox
box
=
_painterKey
.
currentContext
.
findRenderObject
();
final
double
startOffset
=
(
box
.
localToGlobal
(
_begin
.
center
)
-
position
).
distanceSquared
;
final
double
endOffset
=
(
box
.
localToGlobal
(
_end
.
center
)
-
position
).
distanceSquared
;
setState
(()
{
if
(
startOffset
<
endOffset
&&
startOffset
<
_kTargetSlop
)
_dragTarget
=
_DragTarget
.
start
;
else
if
(
endOffset
<
_kTargetSlop
)
_dragTarget
=
_DragTarget
.
end
;
else
_dragTarget
=
null
;
});
return
new
_DragHandler
(
_handleDragUpdate
,
_handleDragCancel
,
_handleDragEnd
);
}
void
_handleDragUpdate
(
DragUpdateDetails
details
)
{
switch
(
_dragTarget
)
{
case
_DragTarget
.
start
:
setState
(()
{
_begin
=
_begin
.
shift
(
details
.
delta
);
});
break
;
case
_DragTarget
.
end
:
setState
(()
{
_end
=
_end
.
shift
(
details
.
delta
);
});
break
;
}
}
void
_handleDragCancel
()
{
_dragTarget
=
null
;
config
.
controller
.
value
=
0.0
;
}
void
_handleDragEnd
(
DragEndDetails
details
)
{
_dragTarget
=
null
;
}
@override
Widget
build
(
BuildContext
context
)
{
final
MaterialRectArcTween
arc
=
new
MaterialRectArcTween
(
begin:
_begin
,
end:
_end
);
return
new
RawGestureDetector
(
behavior:
_dragTarget
==
null
?
HitTestBehavior
.
deferToChild
:
HitTestBehavior
.
opaque
,
gestures:
<
Type
,
GestureRecognizerFactory
>{
ImmediateMultiDragGestureRecognizer:
(
ImmediateMultiDragGestureRecognizer
recognizer
)
{
return
(
recognizer
??=
new
ImmediateMultiDragGestureRecognizer
())
..
onStart
=
_handleOnStart
;
}
},
child:
new
ClipRect
(
child:
new
CustomPaint
(
key:
_painterKey
,
foregroundPainter:
new
_RectangleDemoPainter
(
repaint:
_animation
,
arc:
arc
),
// Watch out: if this IgnorePointer is left out, then gestures that
// fail _RectDemoPainter.hitTest() will still be recognized because
// they do overlap this child, which is as big as the CustomPaint.
child:
new
IgnorePointer
(
child:
new
Padding
(
padding:
const
EdgeInsets
.
all
(
16.0
),
child:
new
Text
(
"Tap the refresh button to run the animation. Drag the rectangles "
"to change the animation's path."
,
style:
Theme
.
of
(
context
).
textTheme
.
caption
.
copyWith
(
fontSize:
16.0
)
)
)
)
)
)
);
}
}
typedef
Widget
_DemoBuilder
(
_ArcDemo
demo
);
class
_ArcDemo
{
_ArcDemo
(
String
_title
,
this
.
builder
)
:
title
=
_title
,
key
=
new
GlobalKey
(
debugLabel:
_title
);
final
AnimationController
controller
=
new
AnimationController
(
duration:
const
Duration
(
milliseconds:
500
));
final
String
title
;
final
_DemoBuilder
builder
;
final
GlobalKey
key
;
}
class
AnimationDemo
extends
StatefulWidget
{
AnimationDemo
({
Key
key
})
:
super
(
key:
key
);
static
const
String
routeName
=
'/animation'
;
@override
_AnimationDemoState
createState
()
=>
new
_AnimationDemoState
();
}
class
_AnimationDemoState
extends
State
<
AnimationDemo
>
{
static
final
GlobalKey
<
TabBarSelectionState
<
_ArcDemo
>>
_tabsKey
=
new
GlobalKey
<
TabBarSelectionState
<
_ArcDemo
>>();
static
final
List
<
_ArcDemo
>
_allDemos
=
<
_ArcDemo
>[
new
_ArcDemo
(
'POINT'
,
(
_ArcDemo
demo
)
{
return
new
_PointDemo
(
key:
demo
.
key
,
controller:
demo
.
controller
);
}),
new
_ArcDemo
(
'RECTANGLE'
,
(
_ArcDemo
demo
)
{
return
new
_RectangleDemo
(
key:
demo
.
key
,
controller:
demo
.
controller
);
})
];
Future
<
Null
>
_play
()
async
{
_ArcDemo
demo
=
_tabsKey
.
currentState
.
value
;
await
demo
.
controller
.
forward
();
if
(
demo
.
key
.
currentState
!=
null
&&
demo
.
key
.
currentState
.
mounted
)
demo
.
controller
.
reverse
();
}
@override
Widget
build
(
BuildContext
context
)
{
return
new
TabBarSelection
<
_ArcDemo
>(
key:
_tabsKey
,
values:
_allDemos
,
child:
new
Scaffold
(
appBar:
new
AppBar
(
title:
new
Text
(
'Animation'
),
bottom:
new
TabBar
<
_ArcDemo
>(
labels:
new
Map
<
_ArcDemo
,
TabLabel
>.
fromIterable
(
_allDemos
,
value:
(
_ArcDemo
demo
)
{
return
new
TabLabel
(
text:
demo
.
title
);
})
)
),
floatingActionButton:
new
FloatingActionButton
(
onPressed:
_play
,
child:
new
Icon
(
Icons
.
refresh
)
),
body:
new
TabBarView
<
_ArcDemo
>(
children:
_allDemos
.
map
((
_ArcDemo
demo
)
=>
demo
.
builder
(
demo
)).
toList
()
)
)
);
}
}
examples/flutter_gallery/lib/gallery/item.dart
View file @
36eb4a06
...
@@ -66,6 +66,12 @@ final List<GalleryItem> kAllGalleryItems = <GalleryItem>[
...
@@ -66,6 +66,12 @@ final List<GalleryItem> kAllGalleryItems = <GalleryItem>[
buildRoute:
(
BuildContext
context
)
=>
new
ContactsDemo
()
buildRoute:
(
BuildContext
context
)
=>
new
ContactsDemo
()
),
),
// Components
// Components
new
GalleryItem
(
title:
'Animation'
,
subtitle:
'Material motion for points and rectangles'
,
routeName:
AnimationDemo
.
routeName
,
buildRoute:
(
BuildContext
context
)
=>
new
AnimationDemo
()
),
new
GalleryItem
(
new
GalleryItem
(
title:
'Buttons'
,
title:
'Buttons'
,
subtitle:
'All kinds: flat, raised, dropdown, icon, etc'
,
subtitle:
'All kinds: flat, raised, dropdown, icon, etc'
,
...
...
packages/flutter/lib/material.dart
View file @
36eb4a06
...
@@ -14,6 +14,7 @@ library material;
...
@@ -14,6 +14,7 @@ library material;
export
'src/material/about.dart'
;
export
'src/material/about.dart'
;
export
'src/material/app.dart'
;
export
'src/material/app.dart'
;
export
'src/material/app_bar.dart'
;
export
'src/material/app_bar.dart'
;
export
'src/material/arc.dart'
;
export
'src/material/bottom_sheet.dart'
;
export
'src/material/bottom_sheet.dart'
;
export
'src/material/button.dart'
;
export
'src/material/button.dart'
;
export
'src/material/button_bar.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;
...
@@ -7,6 +7,7 @@ import 'dart:io' show Platform;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:flutter/widgets.dart'
;
import
'arc.dart'
;
import
'colors.dart'
;
import
'colors.dart'
;
import
'overscroll_indicator.dart'
;
import
'overscroll_indicator.dart'
;
import
'page.dart'
;
import
'page.dart'
;
...
@@ -152,7 +153,17 @@ final ScrollConfigurationDelegate _indicatorScroll = new _IndicatorScrollConfigu
...
@@ -152,7 +153,17 @@ final ScrollConfigurationDelegate _indicatorScroll = new _IndicatorScrollConfigu
final
ScrollConfigurationDelegate
_bounceScroll
=
new
ScrollConfigurationDelegate
();
final
ScrollConfigurationDelegate
_bounceScroll
=
new
ScrollConfigurationDelegate
();
class
_MaterialAppState
extends
State
<
MaterialApp
>
{
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
)
{
Route
<
dynamic
>
_onGenerateRoute
(
RouteSettings
settings
)
{
WidgetBuilder
builder
=
config
.
routes
[
settings
.
name
];
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> {
...
@@ -61,7 +61,7 @@ class MaterialPageRoute<T> extends PageRoute<T> {
final
WidgetBuilder
builder
;
final
WidgetBuilder
builder
;
@override
@override
Duration
get
transitionDuration
=>
const
Duration
(
milliseconds:
15
0
);
Duration
get
transitionDuration
=>
const
Duration
(
milliseconds:
30
0
);
@override
@override
Color
get
barrierColor
=>
null
;
Color
get
barrierColor
=>
null
;
...
...
packages/flutter/lib/src/widgets/heroes.dart
View file @
36eb4a06
...
@@ -66,13 +66,13 @@ class _HeroManifest {
...
@@ -66,13 +66,13 @@ class _HeroManifest {
final
GlobalKey
key
;
final
GlobalKey
key
;
final
Widget
config
;
final
Widget
config
;
final
Set
<
HeroState
>
sourceStates
;
final
Set
<
HeroState
>
sourceStates
;
final
Re
lativeRe
ct
currentRect
;
final
Rect
currentRect
;
final
double
currentTurns
;
final
double
currentTurns
;
}
}
abstract
class
HeroHandle
{
abstract
class
HeroHandle
{
bool
get
alwaysAnimate
;
bool
get
alwaysAnimate
;
_HeroManifest
_takeChild
(
Rect
animationArea
,
Animation
<
double
>
currentAnimation
);
_HeroManifest
_takeChild
(
Animation
<
double
>
currentAnimation
);
}
}
class
Hero
extends
StatefulWidget
{
class
Hero
extends
StatefulWidget
{
...
@@ -161,7 +161,7 @@ class HeroState extends State<Hero> implements HeroHandle {
...
@@ -161,7 +161,7 @@ class HeroState extends State<Hero> implements HeroHandle {
bool
get
alwaysAnimate
=>
config
.
alwaysAnimate
;
bool
get
alwaysAnimate
=>
config
.
alwaysAnimate
;
@override
@override
_HeroManifest
_takeChild
(
Rect
animationArea
,
Animation
<
double
>
currentAnimation
)
{
_HeroManifest
_takeChild
(
Animation
<
double
>
currentAnimation
)
{
assert
(
mounted
);
assert
(
mounted
);
final
RenderBox
renderObject
=
context
.
findRenderObject
();
final
RenderBox
renderObject
=
context
.
findRenderObject
();
assert
(
renderObject
!=
null
);
assert
(
renderObject
!=
null
);
...
@@ -175,12 +175,11 @@ class HeroState extends State<Hero> implements HeroHandle {
...
@@ -175,12 +175,11 @@ class HeroState extends State<Hero> implements HeroHandle {
final
Point
heroTopLeft
=
renderObject
.
localToGlobal
(
Point
.
origin
);
final
Point
heroTopLeft
=
renderObject
.
localToGlobal
(
Point
.
origin
);
final
Point
heroBottomRight
=
renderObject
.
localToGlobal
(
renderObject
.
size
.
bottomRight
(
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
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
(
_HeroManifest
result
=
new
_HeroManifest
(
key:
_key
,
// might be null, e.g. if the hero is returning to us
key:
_key
,
// might be null, e.g. if the hero is returning to us
config:
config
,
config:
config
,
sourceStates:
new
HashSet
<
HeroState
>.
from
(<
HeroState
>[
this
]),
sourceStates:
new
HashSet
<
HeroState
>.
from
(<
HeroState
>[
this
]),
currentRect:
startRect
,
currentRect:
heroArea
,
currentTurns:
config
.
turns
.
toDouble
()
currentTurns:
config
.
turns
.
toDouble
()
);
);
if
(
_key
!=
null
)
if
(
_key
!=
null
)
...
@@ -224,6 +223,7 @@ class _HeroQuestState implements HeroHandle {
...
@@ -224,6 +223,7 @@ class _HeroQuestState implements HeroHandle {
this
.
key
,
this
.
key
,
this
.
child
,
this
.
child
,
this
.
sourceStates
,
this
.
sourceStates
,
this
.
animationArea
,
this
.
targetRect
,
this
.
targetRect
,
this
.
targetTurns
,
this
.
targetTurns
,
this
.
targetState
,
this
.
targetState
,
...
@@ -237,10 +237,11 @@ class _HeroQuestState implements HeroHandle {
...
@@ -237,10 +237,11 @@ class _HeroQuestState implements HeroHandle {
final
GlobalKey
key
;
final
GlobalKey
key
;
final
Widget
child
;
final
Widget
child
;
final
Set
<
HeroState
>
sourceStates
;
final
Set
<
HeroState
>
sourceStates
;
final
RelativeRect
targetRect
;
final
Rect
animationArea
;
final
Rect
targetRect
;
final
int
targetTurns
;
final
int
targetTurns
;
final
HeroState
targetState
;
final
HeroState
targetState
;
final
Re
lativeRe
ctTween
currentRect
;
final
RectTween
currentRect
;
final
Tween
<
double
>
currentTurns
;
final
Tween
<
double
>
currentTurns
;
@override
@override
...
@@ -250,7 +251,7 @@ class _HeroQuestState implements HeroHandle {
...
@@ -250,7 +251,7 @@ class _HeroQuestState implements HeroHandle {
bool
_taken
=
false
;
bool
_taken
=
false
;
@override
@override
_HeroManifest
_takeChild
(
Rect
animationArea
,
Animation
<
double
>
currentAnimation
)
{
_HeroManifest
_takeChild
(
Animation
<
double
>
currentAnimation
)
{
assert
(!
taken
);
assert
(!
taken
);
_taken
=
true
;
_taken
=
true
;
Set
<
HeroState
>
states
=
sourceStates
;
Set
<
HeroState
>
states
=
sourceStates
;
...
@@ -266,8 +267,9 @@ class _HeroQuestState implements HeroHandle {
...
@@ -266,8 +267,9 @@ class _HeroQuestState implements HeroHandle {
}
}
Widget
build
(
BuildContext
context
,
Animation
<
double
>
animation
)
{
Widget
build
(
BuildContext
context
,
Animation
<
double
>
animation
)
{
return
new
PositionedTransition
(
return
new
Relative
PositionedTransition
(
rect:
currentRect
.
animate
(
animation
),
rect:
currentRect
.
animate
(
animation
),
size:
animationArea
.
size
,
child:
new
RotationTransition
(
child:
new
RotationTransition
(
turns:
currentTurns
.
animate
(
animation
),
turns:
currentTurns
.
animate
(
animation
),
child:
new
KeyedSubtree
(
child:
new
KeyedSubtree
(
...
@@ -286,10 +288,13 @@ class _HeroMatch {
...
@@ -286,10 +288,13 @@ class _HeroMatch {
final
Object
tag
;
final
Object
tag
;
}
}
typedef
RectTween
CreateRectTween
(
Rect
begin
,
Rect
end
);
class
HeroParty
{
class
HeroParty
{
HeroParty
({
this
.
onQuestFinished
});
HeroParty
({
this
.
onQuestFinished
,
this
.
createRectTween
});
final
VoidCallback
onQuestFinished
;
final
VoidCallback
onQuestFinished
;
final
CreateRectTween
createRectTween
;
List
<
_HeroQuestState
>
_heroes
=
<
_HeroQuestState
>[];
List
<
_HeroQuestState
>
_heroes
=
<
_HeroQuestState
>[];
bool
get
isEmpty
=>
_heroes
.
isEmpty
;
bool
get
isEmpty
=>
_heroes
.
isEmpty
;
...
@@ -302,8 +307,10 @@ class HeroParty {
...
@@ -302,8 +307,10 @@ class HeroParty {
return
result
;
return
result
;
}
}
RelativeRectTween
createRectTween
(
RelativeRect
begin
,
RelativeRect
end
)
{
RectTween
_doCreateRectTween
(
Rect
begin
,
Rect
end
)
{
return
new
RelativeRectTween
(
begin:
begin
,
end:
end
);
if
(
createRectTween
!=
null
)
return
createRectTween
(
begin
,
end
);
return
new
RectTween
(
begin:
begin
,
end:
end
);
}
}
Tween
<
double
>
createTurnsTween
(
double
begin
,
double
end
)
{
Tween
<
double
>
createTurnsTween
(
double
begin
,
double
end
)
{
...
@@ -331,30 +338,29 @@ class HeroParty {
...
@@ -331,30 +338,29 @@ class HeroParty {
if
((
heroPair
.
from
==
null
&&
!
heroPair
.
to
.
alwaysAnimate
)
||
if
((
heroPair
.
from
==
null
&&
!
heroPair
.
to
.
alwaysAnimate
)
||
(
heroPair
.
to
==
null
&&
!
heroPair
.
from
.
alwaysAnimate
))
(
heroPair
.
to
==
null
&&
!
heroPair
.
from
.
alwaysAnimate
))
continue
;
continue
;
_HeroManifest
from
=
heroPair
.
from
?.
_takeChild
(
animationArea
,
_currentAnimation
);
_HeroManifest
from
=
heroPair
.
from
?.
_takeChild
(
_currentAnimation
);
assert
(
heroPair
.
to
==
null
||
heroPair
.
to
is
HeroState
);
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
(
from
!=
null
||
to
!=
null
);
assert
(
to
==
null
||
to
.
sourceStates
.
length
==
1
);
assert
(
to
==
null
||
to
.
sourceStates
.
length
==
1
);
assert
(
to
==
null
||
to
.
currentTurns
.
floor
()
==
to
.
currentTurns
);
assert
(
to
==
null
||
to
.
currentTurns
.
floor
()
==
to
.
currentTurns
);
HeroState
targetState
=
to
!=
null
?
to
.
sourceStates
.
elementAt
(
0
)
:
null
;
HeroState
targetState
=
to
!=
null
?
to
.
sourceStates
.
elementAt
(
0
)
:
null
;
Set
<
HeroState
>
sourceStates
=
from
!=
null
?
from
.
sourceStates
:
new
HashSet
<
HeroState
>();
Set
<
HeroState
>
sourceStates
=
from
!=
null
?
from
.
sourceStates
:
new
HashSet
<
HeroState
>();
sourceStates
.
remove
(
targetState
);
sourceStates
.
remove
(
targetState
);
RelativeRect
sourceRect
=
from
!=
null
?
from
.
currentRect
:
Rect
sourceRect
=
from
?.
currentRect
??
to
.
currentRect
.
center
&
Size
.
zero
;
new
RelativeRect
.
fromRect
(
to
.
currentRect
.
toRect
(
animationArea
).
center
&
Size
.
zero
,
animationArea
);
Rect
targetRect
=
to
?.
currentRect
??
from
.
currentRect
.
center
&
Size
.
zero
;
RelativeRect
targetRect
=
to
!=
null
?
to
.
currentRect
:
double
sourceTurns
=
from
?.
currentTurns
??
0.0
;
new
RelativeRect
.
fromRect
(
from
.
currentRect
.
toRect
(
animationArea
).
center
&
Size
.
zero
,
animationArea
);
double
targetTurns
=
to
?.
currentTurns
??
0.0
;
double
sourceTurns
=
from
!=
null
?
from
.
currentTurns
:
0.0
;
double
targetTurns
=
to
!=
null
?
to
.
currentTurns
:
0.0
;
_newHeroes
.
add
(
new
_HeroQuestState
(
_newHeroes
.
add
(
new
_HeroQuestState
(
tag:
heroPair
.
tag
,
tag:
heroPair
.
tag
,
key:
from
!=
null
?
from
.
key
:
to
.
key
,
key:
from
?.
key
??
to
.
key
,
child:
to
!=
null
?
to
.
config
:
from
.
config
,
child:
to
?.
config
??
from
.
config
,
sourceStates:
sourceStates
,
sourceStates:
sourceStates
,
animationArea:
animationArea
,
targetRect:
targetRect
,
targetRect:
targetRect
,
targetTurns:
targetTurns
.
floor
(),
targetTurns:
targetTurns
.
floor
(),
targetState:
targetState
,
targetState:
targetState
,
currentRect:
c
reateRectTween
(
sourceRect
,
targetRect
),
currentRect:
_doC
reateRectTween
(
sourceRect
,
targetRect
),
currentTurns:
createTurnsTween
(
sourceTurns
,
targetTurns
)
currentTurns:
createTurnsTween
(
sourceTurns
,
targetTurns
)
));
));
}
}
...
@@ -400,8 +406,11 @@ class HeroParty {
...
@@ -400,8 +406,11 @@ class HeroParty {
}
}
class
HeroController
extends
NavigatorObserver
{
class
HeroController
extends
NavigatorObserver
{
HeroController
()
{
HeroController
({
CreateRectTween
createRectTween
})
{
_party
=
new
HeroParty
(
onQuestFinished:
_handleQuestFinished
);
_party
=
new
HeroParty
(
onQuestFinished:
_handleQuestFinished
,
createRectTween:
createRectTween
);
}
}
HeroParty
_party
;
HeroParty
_party
;
...
...
packages/flutter/lib/src/widgets/transitions.dart
View file @
36eb4a06
...
@@ -292,6 +292,10 @@ class RelativeRectTween extends Tween<RelativeRect> {
...
@@ -292,6 +292,10 @@ class RelativeRectTween extends Tween<RelativeRect> {
/// position to and end position over the lifetime of the animation.
/// position to and end position over the lifetime of the animation.
///
///
/// Only works if it's the child of a [Stack].
/// Only works if it's the child of a [Stack].
///
/// See also:
///
/// * [RelativePositionedTransition]
class
PositionedTransition
extends
AnimatedWidget
{
class
PositionedTransition
extends
AnimatedWidget
{
/// Creates a transition for [Positioned].
/// Creates a transition for [Positioned].
///
///
...
@@ -320,6 +324,46 @@ class PositionedTransition extends AnimatedWidget {
...
@@ -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.
/// A builder that builds a widget given a child.
typedef
Widget
TransitionBuilder
(
BuildContext
context
,
Widget
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 {
...
@@ -79,12 +79,16 @@ class ServiceProtocolDevFSOperations implements DevFSOperations {
return
e
;
return
e
;
}
}
String
fileContents
=
BASE64
.
encode
(
bytes
);
String
fileContents
=
BASE64
.
encode
(
bytes
);
try
{
return
await
serviceProtocol
.
sendRequest
(
'_writeDevFSFile'
,
return
await
serviceProtocol
.
sendRequest
(
'_writeDevFSFile'
,
<
String
,
dynamic
>
{
<
String
,
dynamic
>
{
'fsName'
:
fsName
,
'fsName'
:
fsName
,
'path'
:
entry
.
devicePath
,
'path'
:
entry
.
devicePath
,
'fileContents'
:
fileContents
'fileContents'
:
fileContents
});
});
}
catch
(
e
)
{
print
(
'failed on
${entry.devicePath}
$e
'
);
}
}
}
@override
@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