Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
sxychenjing
engine
提交
7a386db1
E
engine
项目概览
sxychenjing
/
engine
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
engine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
7a386db1
编写于
7月 30, 2015
作者:
M
mpcomplete
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #352 from mpcomplete/generic.slidein
Use SnackBar's SlideInIntention for Drawer animation.
上级
5f687552
f7d97d4c
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
194 addition
and
131 deletion
+194
-131
sky/packages/sky/lib/animation/animated_value.dart
sky/packages/sky/lib/animation/animated_value.dart
+2
-2
sky/packages/sky/lib/animation/animation_performance.dart
sky/packages/sky/lib/animation/animation_performance.dart
+30
-19
sky/packages/sky/lib/animation/forces.dart
sky/packages/sky/lib/animation/forces.dart
+10
-5
sky/packages/sky/lib/animation/scroll_behavior.dart
sky/packages/sky/lib/animation/scroll_behavior.dart
+1
-2
sky/packages/sky/lib/widgets/animation_intentions.dart
sky/packages/sky/lib/widgets/animation_intentions.dart
+87
-0
sky/packages/sky/lib/widgets/drawer.dart
sky/packages/sky/lib/widgets/drawer.dart
+59
-66
sky/packages/sky/lib/widgets/snack_bar.dart
sky/packages/sky/lib/widgets/snack_bar.dart
+5
-37
未找到文件。
sky/packages/sky/lib/animation/animated_value.dart
浏览文件 @
7a386db1
...
...
@@ -69,8 +69,8 @@ class AnimatedList extends AnimatedVariable {
String
toString
()
=>
'AnimatedList([
$variables
])'
;
}
class
AnimatedColor
extends
AnimatedValue
<
Color
>
{
AnimatedColor
(
Color
begin
,
{
Color
end
,
Curve
curve:
linear
})
class
AnimatedColor
Value
extends
AnimatedValue
<
Color
>
{
AnimatedColor
Value
(
Color
begin
,
{
Color
end
,
Curve
curve:
linear
})
:
super
(
begin
,
end:
end
,
curve:
curve
);
void
setProgress
(
double
t
)
{
...
...
sky/packages/sky/lib/animation/animation_performance.dart
浏览文件 @
7a386db1
...
...
@@ -8,10 +8,7 @@ import 'package:sky/animation/animated_value.dart';
import
'package:sky/animation/forces.dart'
;
import
'package:sky/animation/timeline.dart'
;
enum
AnimationDirection
{
forward
,
reverse
}
export
'package:sky/animation/forces.dart'
show
Direction
;
enum
AnimationStatus
{
dismissed
,
// stoped at 0
...
...
@@ -39,8 +36,21 @@ class AnimationPerformance {
Timeline
_timeline
;
Timeline
get
timeline
=>
_timeline
;
AnimationDirection
_direction
;
AnimationDirection
get
direction
=>
_direction
;
Direction
_direction
;
Direction
get
direction
=>
_direction
;
// If non-null, animate with this force instead of a tween animation.
Force
attachedForce
;
void
addVariable
(
AnimatedVariable
newVariable
)
{
if
(
variable
==
null
)
{
variable
=
newVariable
;
}
else
if
(
variable
is
AnimatedList
)
{
(
variable
as
AnimatedList
).
variables
.
add
(
newVariable
);
}
else
{
variable
=
new
AnimatedList
([
variable
,
newVariable
]);
}
}
double
get
progress
=>
timeline
.
value
;
void
set
progress
(
double
t
)
{
...
...
@@ -59,33 +69,34 @@ class AnimationPerformance {
return
AnimationStatus
.
completed
;
if
(!
isAnimating
&&
progress
==
0.0
)
return
AnimationStatus
.
dismissed
;
return
direction
==
Animation
Direction
.
forward
?
return
direction
==
Direction
.
forward
?
AnimationStatus
.
forward
:
AnimationStatus
.
reverse
;
}
Future
play
([
AnimationDirection
direction
=
Animation
Direction
.
forward
])
{
Future
play
([
Direction
direction
=
Direction
.
forward
])
{
_direction
=
direction
;
return
resume
();
}
Future
forward
()
=>
play
(
AnimationDirection
.
forward
);
Future
reverse
()
=>
play
(
AnimationDirection
.
reverse
);
Future
resume
()
=>
_animateTo
(
direction
==
AnimationDirection
.
forward
?
1.0
:
0.0
);
Future
forward
()
=>
play
(
Direction
.
forward
);
Future
reverse
()
=>
play
(
Direction
.
reverse
);
Future
resume
()
{
if
(
attachedForce
!=
null
)
return
fling
(
_direction
,
force:
attachedForce
);
return
_animateTo
(
direction
==
Direction
.
forward
?
1.0
:
0.0
);
}
void
stop
()
{
timeline
.
stop
();
}
// Flings the timeline with an optional force (defaults to a critically damped
// spring) and initial velocity. Negative velocity causes the timeline to go
// in reverse.
Future
fling
({
double
velocity:
1.0
,
Force
force
})
{
// Flings the timeline in the given direction with an optional force
// (defaults to a critically damped spring) and initial velocity.
Future
fling
(
Direction
direction
,
{
double
velocity:
0.0
,
Force
force
})
{
if
(
force
==
null
)
force
=
kDefaultSpringForce
;
// This is an approximation - the force may not necessarily result in
// animating the same direction as the initial velocity.
_direction
=
velocity
>=
0.0
?
AnimationDirection
.
forward
:
AnimationDirection
.
reverse
;
return
timeline
.
fling
(
force
.
release
(
progress
,
velocity
));
_direction
=
direction
;
return
timeline
.
fling
(
force
.
release
(
progress
,
velocity
,
_direction
));
}
final
List
<
Function
>
_listeners
=
new
List
<
Function
>();
...
...
sky/packages/sky/lib/animation/forces.dart
浏览文件 @
7a386db1
...
...
@@ -4,9 +4,15 @@
import
'package:newton/newton.dart'
;
// TODO(mpcomplete): This doesn't belong here.
enum
Direction
{
forward
,
reverse
}
// Base class for creating Simulations for the animation Timeline.
abstract
class
Force
{
Simulation
release
(
double
position
,
double
velocity
);
Simulation
release
(
double
position
,
double
velocity
,
Direction
direction
);
}
class
SpringForce
extends
Force
{
...
...
@@ -17,18 +23,17 @@ class SpringForce extends Force {
// respectively.
final
double
left
,
right
;
Simulation
release
(
double
position
,
double
velocity
)
{
Simulation
release
(
double
position
,
double
velocity
,
Direction
direction
)
{
// Target just past the endpoint, because the animation will stop once the
// Spring gets within the epsilon, and we want to stop at the endpoint.
double
target
=
velocity
<
0.0
?
double
target
=
direction
==
Direction
.
reverse
?
this
.
left
-
_kEpsilon
:
this
.
right
+
_kEpsilon
;
return
new
SpringSimulation
(
spring
,
position
,
target
,
velocity
);
}
}
final
SpringDescription
_kDefaultSpringDesc
=
new
SpringDescription
.
withDampingRatio
(
mass:
1.0
,
springConstant:
500.0
,
ratio:
1.0
);
new
SpringDescription
.
withDampingRatio
(
mass:
1.0
,
springConstant:
500.0
,
ratio:
1.0
);
final
SpringForce
kDefaultSpringForce
=
new
SpringForce
(
_kDefaultSpringDesc
);
const
double
_kEpsilon
=
0.001
;
sky/packages/sky/lib/animation/scroll_behavior.dart
浏览文件 @
7a386db1
...
...
@@ -5,11 +5,10 @@
import
'dart:math'
as
math
;
import
'package:newton/newton.dart'
;
import
'package:sky/animation/forces.dart'
;
const
double
_kSecondsPerMillisecond
=
1000.0
;
abstract
class
ScrollBehavior
extends
Force
{
abstract
class
ScrollBehavior
{
Simulation
release
(
double
position
,
double
velocity
)
=>
null
;
// Returns the new scroll offset.
...
...
sky/packages/sky/lib/widgets/animation_intentions.dart
0 → 100644
浏览文件 @
7a386db1
// Copyright 2015 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.
// This file contains a set of common intentions to use with AnimationContainer
// for describing how to animate certain properties.
import
'dart:sky'
;
import
'package:sky/animation/animated_value.dart'
;
import
'package:sky/animation/animation_performance.dart'
;
import
'package:sky/widgets/animated_container.dart'
;
import
'package:sky/widgets/basic.dart'
;
import
'package:vector_math/vector_math.dart'
;
// Slides a container in from |start| to |end| when the container's |tag| is
// true (reverses if false).
class
SlideInIntention
extends
AnimationIntention
{
SlideInIntention
({
Duration
duration
,
this
.
performance
,
Point
start
,
Point
end
})
{
if
(
performance
==
null
)
{
assert
(
duration
!=
null
);
performance
=
new
AnimationPerformance
(
duration:
duration
);
}
_position
=
new
AnimatedValue
<
Point
>(
start
,
end:
end
);
performance
.
addVariable
(
_position
);
}
AnimatedValue
<
Point
>
_position
;
AnimationPerformance
performance
;
void
initFields
(
AnimatedContainer
container
)
{
performance
.
addListener
(()
{
_updateProgress
(
container
);
});
performance
.
progress
=
0.0
;
if
(
container
.
tag
)
performance
.
play
();
}
void
syncFields
(
AnimatedContainer
original
,
AnimatedContainer
updated
)
{
if
(
original
.
tag
!=
updated
.
tag
)
{
original
.
tag
=
updated
.
tag
;
performance
.
play
(
original
.
tag
?
Direction
.
forward
:
Direction
.
reverse
);
}
}
void
_updateProgress
(
AnimatedContainer
container
)
{
container
.
setState
(()
{
container
.
transform
=
new
Matrix4
.
identity
()
..
translate
(
_position
.
value
.
x
,
_position
.
value
.
y
);
});
}
}
// Changes color from |start| to |end| when the container's |tag| is true
// (reverses if false).
class
ColorTransitionIntention
extends
AnimationIntention
{
ColorTransitionIntention
({
Duration
duration
,
this
.
performance
,
Color
start
,
Color
end
})
{
if
(
performance
==
null
)
{
assert
(
duration
!=
null
);
performance
=
new
AnimationPerformance
(
duration:
duration
);
}
_color
=
new
AnimatedColorValue
(
start
,
end:
end
);
performance
.
addVariable
(
_color
);
}
AnimatedColorValue
_color
;
AnimationPerformance
performance
;
void
initFields
(
AnimatedContainer
container
)
{
performance
.
addListener
(()
{
_updateProgress
(
container
);
});
performance
.
progress
=
0.0
;
if
(
container
.
tag
)
performance
.
play
();
}
void
syncFields
(
AnimatedContainer
original
,
AnimatedContainer
updated
)
{
if
(
original
.
tag
!=
updated
.
tag
)
{
original
.
tag
=
updated
.
tag
;
performance
.
play
(
original
.
tag
?
Direction
.
forward
:
Direction
.
reverse
);
}
}
void
_updateProgress
(
AnimatedContainer
container
)
{
container
.
setState
(()
{
container
.
decoration
=
new
BoxDecoration
(
backgroundColor:
_color
.
value
);
});
}
}
sky/packages/sky/lib/widgets/drawer.dart
浏览文件 @
7a386db1
...
...
@@ -2,18 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:sky'
as
sky
;
import
'package:sky/animation/animated_value.dart'
;
import
'package:sky/animation/animation_performance.dart'
;
import
'package:sky/animation/forces.dart'
;
import
'package:sky/theme/shadows.dart'
;
import
'package:sky/theme/colors.dart'
as
colors
;
import
'package:sky/widgets/animated_component.dart'
;
import
'package:sky/widgets/animated_container.dart'
;
import
'package:sky/widgets/animation_intentions.dart'
;
import
'package:sky/widgets/basic.dart'
;
import
'package:sky/widgets/navigator.dart'
;
import
'package:sky/widgets/scrollable_viewport.dart'
;
import
'package:sky/widgets/theme.dart'
;
import
'package:vector_math/vector_math.dart'
;
export
'package:sky/animation/animation_performance.dart'
show
AnimationStatus
;
...
...
@@ -34,12 +35,13 @@ const double _kWidth = 304.0;
const
double
_kMinFlingVelocity
=
365.0
;
const
double
_kFlingVelocityScale
=
1.0
/
300.0
;
const
Duration
_kBaseSettleDuration
=
const
Duration
(
milliseconds:
246
);
const
Duration
_kThemeChangeDuration
=
const
Duration
(
milliseconds:
200
);
const
Point
_kOpenPosition
=
Point
.
origin
;
const
Point
_kClosedPosition
=
const
Point
(-
_kWidth
,
0.0
);
typedef
void
DrawerStatusChangedCallback
(
AnimationStatus
status
);
class
Drawer
extends
Animated
Component
{
class
Drawer
extends
Stateful
Component
{
Drawer
({
Key
key
,
this
.
children
,
...
...
@@ -55,70 +57,58 @@ class Drawer extends AnimatedComponent {
DrawerStatusChangedCallback
onStatusChanged
;
Navigator
navigator
;
AnimatedValue
<
Point
>
_posi
tion
;
AnimatedColor
_maskColor
;
AnimationPerformance
_
performance
;
SlideInIntention
_inten
tion
;
ColorTransitionIntention
_maskColorIntention
;
AnimationPerformance
get
_performance
=>
_intention
.
performance
;
void
initState
()
{
_position
=
new
AnimatedValue
<
Point
>(
_kClosedPosition
,
end:
_kOpenPosition
);
_maskColor
=
new
AnimatedColor
(
colors
.
transparent
,
end:
const
Color
(
0x7F000000
));
_performance
=
new
AnimationPerformance
()
..
duration
=
_kBaseSettleDuration
..
variable
=
new
AnimatedList
([
_position
,
_maskColor
])
..
addStatusListener
(
_onStatusChanged
);
watch
(
_performance
);
if
(
showing
)
_show
();
_intention
=
new
SlideInIntention
(
duration:
_kBaseSettleDuration
,
start:
_kClosedPosition
,
end:
_kOpenPosition
);
_maskColorIntention
=
new
ColorTransitionIntention
(
performance:
_intention
.
performance
,
start:
colors
.
transparent
,
end:
const
Color
(
0x7F000000
));
_performance
.
addStatusListener
(
_onStatusChanged
);
// Use a spring force for animating the drawer. We can't use curves for
// this because we need a linear curve in order to track the user's finger
// while dragging.
_performance
.
attachedForce
=
kDefaultSpringForce
;
if
(
navigator
!=
null
)
navigator
.
pushState
(
this
,
(
_
)
=>
_performance
.
reverse
());
}
void
syncFields
(
Drawer
source
)
{
children
=
source
.
children
;
level
=
source
.
level
;
navigator
=
source
.
navigator
;
if
(
showing
!=
source
.
showing
)
{
showing
=
source
.
showing
;
showing
?
_show
()
:
_hide
();
}
showing
=
source
.
showing
;
onStatusChanged
=
source
.
onStatusChanged
;
super
.
syncFields
(
source
);
}
void
_show
()
{
if
(
navigator
!=
null
)
navigator
.
pushState
(
this
,
(
_
)
=>
_performance
.
reverse
());
_fling
(
1.0
);
}
void
_hide
()
{
_fling
(-
1.0
);
}
// We fling the performance timeline instead of animating it to give it a
// nice spring effect. We can't use curves for this because we need a linear
// curve in order to track the user's finger while dragging.
void
_fling
(
double
direction
)
{
_performance
.
fling
(
velocity:
direction
.
sign
);
}
Widget
build
()
{
var
mask
=
new
Listener
(
child:
new
Container
(
decoration:
new
BoxDecoration
(
backgroundColor:
_maskColor
.
value
)
child:
new
AnimatedContainer
(
intentions:
[
_maskColorIntention
],
tag:
showing
),
onGestureTap:
handleMaskTap
);
Matrix4
transform
=
new
Matrix4
.
identity
();
transform
.
translate
(
_position
.
value
.
x
,
_position
.
value
.
y
);
Widget
content
=
new
Transform
(
transform:
transform
,
child:
new
Container
(
decoration:
new
BoxDecoration
(
backgroundColor:
Theme
.
of
(
this
).
canvasColor
,
boxShadow:
shadows
[
level
]),
width:
_kWidth
,
child:
new
ScrollableBlock
(
children
)
));
Widget
content
=
new
AnimatedContainer
(
intentions:
[
_intention
,
// TODO(mpcomplete): it should be easier to override some intentions,
// and have those you don't care about revert to a sensible default.
new
ImplicitlySyncDecorationIntention
(
_kThemeChangeDuration
),
new
ImplicitlySyncWidthIntention
(
_kThemeChangeDuration
),
],
tag:
showing
,
decoration:
new
BoxDecoration
(
backgroundColor:
Theme
.
of
(
this
).
canvasColor
,
boxShadow:
shadows
[
level
]),
width:
_kWidth
,
child:
new
ScrollableBlock
(
children
)
);
return
new
Listener
(
child:
new
Stack
([
mask
,
content
]),
...
...
@@ -130,27 +120,27 @@ class Drawer extends AnimatedComponent {
);
}
double
get
xPosition
=>
_position
.
value
.
x
;
void
_onStatusChanged
(
AnimationStatus
status
)
{
if
(
status
==
AnimationStatus
.
dismissed
&&
navigator
!=
null
&&
navigator
.
currentRoute
is
RouteState
&&
(
navigator
.
currentRoute
as
RouteState
).
owner
==
this
)
// TODO(ianh): remove cast once analyzer is cleverer
navigator
.
pop
();
if
(
onStatusChanged
!=
null
)
onStatusChanged
(
status
);
scheduleMicrotask
(()
{
if
(
status
==
AnimationStatus
.
dismissed
&&
navigator
!=
null
&&
navigator
.
currentRoute
is
RouteState
&&
(
navigator
.
currentRoute
as
RouteState
).
owner
==
this
)
// TODO(ianh): remove cast once analyzer is cleverer
navigator
.
pop
();
if
(
onStatusChanged
!=
null
)
onStatusChanged
(
status
);
});
}
bool
get
_isMostlyClosed
=>
xPosition
<=
-
_kWidth
/
2
;
bool
get
_isMostlyClosed
=>
_performance
.
progress
<
0.5
;
void
_settle
()
=>
_fling
(
_isMostlyClosed
?
-
1.0
:
1.0
);
void
_settle
()
{
_isMostlyClosed
?
_performance
.
reverse
()
:
_performance
.
play
();
}
void
handleMaskTap
(
_
)
=>
_fling
(-
1.0
);
void
handleMaskTap
(
_
)
{
_performance
.
reverse
();
}
// TODO(mpcomplete): Figure out how to generalize these handlers on a
// "PannableThingy" interface.
void
handlePointerDown
(
_
)
=>
_performance
.
stop
();
void
handlePointerDown
(
_
)
{
_performance
.
stop
();
}
void
handlePointerMove
(
sky
.
PointerEvent
event
)
{
if
(
_performance
.
isAnimating
)
...
...
@@ -169,7 +159,10 @@ class Drawer extends AnimatedComponent {
}
void
handleFlingStart
(
event
)
{
if
(
event
.
velocityX
.
abs
()
>=
_kMinFlingVelocity
)
_performance
.
fling
(
velocity:
event
.
velocityX
*
_kFlingVelocityScale
);
if
(
event
.
velocityX
.
abs
()
>=
_kMinFlingVelocity
)
{
_performance
.
fling
(
event
.
velocityX
<
0.0
?
Direction
.
reverse
:
Direction
.
forward
,
velocity:
event
.
velocityX
.
abs
()
*
_kFlingVelocityScale
);
}
}
}
sky/packages/sky/lib/widgets/snack_bar.dart
浏览文件 @
7a386db1
...
...
@@ -4,16 +4,15 @@
import
'dart:async'
;
import
'package:sky/animation/animated_value.dart'
;
import
'package:sky/animation/animation_performance.dart'
;
import
'package:sky/painting/text_style.dart'
;
import
'package:sky/theme/typography.dart'
as
typography
;
import
'package:sky/widgets/animated_container.dart'
;
import
'package:sky/widgets/animation_intentions.dart'
;
import
'package:sky/widgets/basic.dart'
;
import
'package:sky/widgets/default_text_style.dart'
;
import
'package:sky/widgets/material.dart'
;
import
'package:sky/widgets/theme.dart'
;
import
'package:vector_math/vector_math.dart'
;
export
'package:sky/animation/animation_performance.dart'
show
AnimationStatus
;
...
...
@@ -41,39 +40,6 @@ class SnackBarAction extends Component {
}
}
// TODO(mpcomplete): generalize this to a SlideIn class.
class
SnackBarSlideInIntention
extends
AnimationIntention
{
SnackBarSlideInIntention
(
Duration
duration
)
{
_position
=
new
AnimatedValue
<
Point
>(
const
Point
(
0.0
,
50.0
),
end:
Point
.
origin
);
performance
=
new
AnimationPerformance
(
duration:
duration
,
variable:
_position
);
}
SnackBarStatusChangedCallback
onStatusChanged
;
AnimatedValue
<
Point
>
_position
;
AnimationPerformance
performance
;
void
initFields
(
AnimatedContainer
container
)
{
performance
.
addListener
(()
{
_updateProgress
(
container
);
});
performance
.
progress
=
0.0
;
if
(
container
.
tag
)
performance
.
play
();
}
void
syncFields
(
AnimatedContainer
original
,
AnimatedContainer
updated
)
{
if
(
original
.
tag
!=
updated
.
tag
)
{
original
.
tag
=
updated
.
tag
;
performance
.
play
(
original
.
tag
?
AnimationDirection
.
forward
:
AnimationDirection
.
reverse
);
}
}
void
_updateProgress
(
AnimatedContainer
container
)
{
container
.
setState
(()
{
container
.
transform
=
new
Matrix4
.
identity
()
..
translate
(
_position
.
value
.
x
,
_position
.
value
.
y
);
});
}
}
class
SnackBar
extends
StatefulComponent
{
SnackBar
({
...
...
@@ -91,10 +57,12 @@ class SnackBar extends StatefulComponent {
bool
showing
;
SnackBarStatusChangedCallback
onStatusChanged
;
S
nackBarS
lideInIntention
_intention
;
SlideInIntention
_intention
;
void
initState
()
{
_intention
=
new
SnackBarSlideInIntention
(
_kSlideInDuration
);
_intention
=
new
SlideInIntention
(
duration:
_kSlideInDuration
,
start:
const
Point
(
0.0
,
50.0
),
end:
Point
.
origin
);
_intention
.
performance
.
addStatusListener
(
_onStatusChanged
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录