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
441d7f3f
Unverified
Commit
441d7f3f
authored
Aug 12, 2020
by
Justin McCandless
Committed by
GitHub
Aug 12, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
InteractiveViewer scale interpretation improvement (#63543)
parent
afc95099
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
88 additions
and
24 deletions
+88
-24
interactive_viewer.dart
packages/flutter/lib/src/widgets/interactive_viewer.dart
+31
-24
interactive_viewer_test.dart
packages/flutter/test/widgets/interactive_viewer_test.dart
+57
-0
No files found.
packages/flutter/lib/src/widgets/interactive_viewer.dart
View file @
441d7f3f
...
...
@@ -684,6 +684,22 @@ class _InteractiveViewerState extends State<InteractiveViewer> with TickerProvid
}
}
// Decide which type of gesture this is by comparing the amount of scale
// and rotation in the gesture, if any. Scale starts at 1 and rotation
// starts at 0. Pan will have no scale and no rotation because it uses only one
// finger.
_GestureType
_getGestureType
(
ScaleUpdateDetails
details
)
{
final
double
scale
=
!
widget
.
scaleEnabled
?
1.0
:
details
.
scale
;
final
double
rotation
=
!
_rotateEnabled
?
0.0
:
details
.
rotation
;
if
((
scale
-
1
).
abs
()
>
rotation
.
abs
())
{
return
_GestureType
.
scale
;
}
else
if
(
rotation
!=
0.0
)
{
return
_GestureType
.
rotate
;
}
else
{
return
_GestureType
.
pan
;
}
}
// Handle the start of a gesture. All of pan, scale, and rotate are handled
// with GestureDetector's scale gesture.
void
_onScaleStart
(
ScaleStartDetails
details
)
{
...
...
@@ -723,23 +739,23 @@ class _InteractiveViewerState extends State<InteractiveViewer> with TickerProvid
final
Offset
focalPointScene
=
_transformationController
.
toScene
(
details
.
localFocalPoint
,
);
_gestureType
??=
_getGestureType
(
!
widget
.
scaleEnabled
?
1.0
:
details
.
scale
,
!
_rotateEnabled
?
0.0
:
details
.
rotation
,
);
if
(
_gestureType
==
_GestureType
.
pan
)
{
_panAxis
??=
_getPanAxis
(
_referenceFocalPoint
,
focalPointScene
);
// When a gesture first starts, it sometimes has no change in scale and
// rotation despite being a two-finger gesture. Here the gesture is
// allowed to be reinterpreted as its correct type after originally
// being marked as a pan.
_gestureType
=
_getGestureType
(
details
);
}
else
{
_gestureType
??=
_getGestureType
(
details
);
}
if
(!
_gestureIsSupported
(
_gestureType
))
{
return
;
}
switch
(
_gestureType
)
{
case
_GestureType
.
scale
:
if
(
_scaleStart
==
null
)
{
return
;
}
assert
(
_scaleStart
!=
null
);
// details.scale gives us the amount to change the scale as of the
// start of this gesture, so calculate the amount to scale as of the
// previous call to _onScaleUpdate.
...
...
@@ -789,9 +805,14 @@ class _InteractiveViewerState extends State<InteractiveViewer> with TickerProvid
return
;
case
_GestureType
.
pan
:
if
(
_referenceFocalPoint
==
null
||
details
.
scale
!=
1.0
)
{
assert
(
_referenceFocalPoint
!=
null
);
// details may have a change in scale here when scaleEnabled is false.
// In an effort to keep the behavior similar whether or not scaleEnabled
// is true, these gestures are thrown away.
if
(
details
.
scale
!=
1.0
)
{
return
;
}
_panAxis
??=
_getPanAxis
(
_referenceFocalPoint
,
focalPointScene
);
// Translate so that the same point in the scene is underneath the
// focal point before and after the movement.
final
Offset
translationChange
=
focalPointScene
-
_referenceFocalPoint
;
...
...
@@ -1082,20 +1103,6 @@ double _getFinalTime(double velocity, double drag) {
return
math
.
log
(
effectivelyMotionless
/
velocity
)
/
math
.
log
(
drag
/
100
);
}
// Decide which type of gesture this is by comparing the amount of scale
// and rotation in the gesture, if any. Scale starts at 1 and rotation
// starts at 0. Pan will have 0 scale and 0 rotation because it uses only one
// finger.
_GestureType
_getGestureType
(
double
scale
,
double
rotation
)
{
if
((
scale
-
1
).
abs
()
>
rotation
.
abs
())
{
return
_GestureType
.
scale
;
}
else
if
(
rotation
!=
0
)
{
return
_GestureType
.
rotate
;
}
else
{
return
_GestureType
.
pan
;
}
}
// Return the translation from the given Matrix4 as an Offset.
Offset
_getMatrixTranslation
(
Matrix4
matrix
)
{
final
Vector3
nextTranslation
=
matrix
.
getTranslation
();
...
...
packages/flutter/test/widgets/interactive_viewer_test.dart
View file @
441d7f3f
...
...
@@ -672,6 +672,63 @@ void main() {
await
tester
.
pumpAndSettle
();
expect
(
transformationController
.
value
,
equals
(
Matrix4
.
identity
()));
});
testWidgets
(
'gesture can start as pan and become scale'
,
(
WidgetTester
tester
)
async
{
final
TransformationController
transformationController
=
TransformationController
();
const
double
boundaryMargin
=
50.0
;
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Scaffold
(
body:
Center
(
child:
InteractiveViewer
(
boundaryMargin:
const
EdgeInsets
.
all
(
boundaryMargin
),
transformationController:
transformationController
,
child:
Container
(
width:
200.0
,
height:
200.0
),
),
),
),
),
);
Vector3
translation
=
transformationController
.
value
.
getTranslation
();
expect
(
translation
.
x
,
0.0
);
expect
(
translation
.
y
,
0.0
);
// Start a pan gesture.
final
Offset
childCenter
=
tester
.
getCenter
(
find
.
byType
(
Container
));
final
TestGesture
gesture
=
await
tester
.
createGesture
();
await
gesture
.
down
(
childCenter
);
await
tester
.
pump
();
await
gesture
.
moveTo
(
Offset
(
childCenter
.
dx
+
5.0
,
childCenter
.
dy
+
5.0
,
));
await
tester
.
pump
();
translation
=
transformationController
.
value
.
getTranslation
();
expect
(
translation
.
x
,
greaterThan
(
0.0
));
expect
(
translation
.
y
,
greaterThan
(
0.0
));
// Put another finger down and turn it into a scale gesture.
final
TestGesture
gesture2
=
await
tester
.
createGesture
();
await
gesture2
.
down
(
Offset
(
childCenter
.
dx
-
5.0
,
childCenter
.
dy
-
5.0
,
));
await
tester
.
pump
();
await
gesture
.
moveTo
(
Offset
(
childCenter
.
dx
+
25.0
,
childCenter
.
dy
+
25.0
,
));
await
gesture2
.
moveTo
(
Offset
(
childCenter
.
dx
-
25.0
,
childCenter
.
dy
-
25.0
,
));
await
tester
.
pump
();
await
gesture
.
up
();
await
gesture2
.
up
();
await
tester
.
pumpAndSettle
();
expect
(
transformationController
.
value
.
getMaxScaleOnAxis
(),
greaterThan
(
1.0
));
});
});
group
(
'getNearestPointOnLine'
,
()
{
...
...
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