This is easy to do with a ListView nested inside a SizedBox
SizedBox(
height: MediaQuery.of(context).size.height, //Constraints of viewport to fit screen
width: MediaQuery.of(context).size.width, //Constraints of viewport to fit screen
child: ListView( //Scrollable widget
shrinkWrap: true, //Reduce ListView's height to the childrens's
controller: listViewController, //Allows to programatically animate between offsets of the ListView (1365, 1712, 2032)
physics: NeverScrollableScrollPhysics(), //The user can't swipe the picture up or down
scrollDirection: Axis.vertical,
children: [
Image.asset("assets/svg/ZFh5j.jpg", fit: BoxFit.fitHeight) //BigImage
],
),
),
To animate between offsets in the ListView add a ScrollController:
class Screen extends StatefulWidget {
Screen({Key key}) : super(key: key);
@override
_ScreenState createState() => _ScreenState();
}
class _ScreenState extends State<Screen> {
ScrollController listViewController = ScrollController(initialScrollOffset: 0);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
SizedBox(
height: MediaQuery.of(context).size.height, //Constraints of viewport to fit screen
width: MediaQuery.of(context).size.width, //Constraints of viewport to fit screen
child: ListView( //Scrollable widget
shrinkWrap: true, //Reduce ListView's height to the childrens's
controller: listViewController, //Allows to programatically animate between offsets of the ListView (1365, 1712, 2032)
physics: NeverScrollableScrollPhysics(), //The user can't swipe the picture up or down
scrollDirection: Axis.vertical,
children: [
Image.asset("assets/svg/ZFh5j.jpg") //BigImage
],
),
),
//contents on top of the background here
],
),
);
}
}
Then you can animate the ListView's position like this:
(You can put this function in a GestureDetector. The ListView must already be built before animating it)
listViewController.animateTo(/*offset*/, duration: Duration(milliseconds: 500), curve: Curves.easeInOutQuad);
This will scroll the ListView to "offset" pixels from the top, so animating to the offset 2032 won't align the lower line of the image with the bottom constraint of the viewport. To make it easy, add a SizedBox in the ListView before the image
SizedBox(
height: MediaQuery.of(context).size.height, //Constraints of viewport to fit screen
width: MediaQuery.of(context).size.width, //Constraints of viewport to fit screen
child: ListView( //Scrollable widget
shrinkWrap: true, //Reduce ListView's height to the childrens's
controller: listViewController, //Allows to programatically animate between offsets of the ListView (1365, 1712, 2032)
physics: NeverScrollableScrollPhysics(), //The user can't swipe the picture up or down
scrollDirection: Axis.vertical,
children: [
SizedBox(height: MediaQuery.of(context).size.height), //Must be height of viewport in order to work
SizedBox(
height: 2048,
width: 553,
child: Image.asset("assets/svg/ZFh5j.jpg", fit: BoxFit.fitHeight,) //BigImage
)
],
),
),
Now calling listViewController.animateTo(2032, duration: Duration(milliseconds: 500), curve: Curves.easeInOutQuad) should align the lower line with the bottom of the viewport