I am trying to implement animation in Flutter.
I got the following result. But what I am trying to achieve is that the illustration starts sliding from the faded part, like it should display 10% of the image then linearly increase as it slides. But here it slides from the bottom of the screen and behind the other widgets. I just want the image to be visible in its restricted part of the column only.
Here is the code for the same:
This is the initialisation part
late AnimationController controller;
late Animation<Offset> offset;
@override
void initState() {
super.initState();
controller =
AnimationController(vsync: this, duration: const Duration(seconds: 3));
offset = Tween<Offset>(begin: const Offset(0.0, 1.0), end: Offset.zero)
.animate(controller);
controller.forward();
}
Here is the code in return widget
ShaderMask(
shaderCallback: (rect) {
return const LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.white,
Colors.white,
Colors.white,
Colors.transparent
],
).createShader(
Rect.fromLTRB(0, 0, rect.width, rect.height));
},
blendMode: BlendMode.dstIn,
//page illustration
//slides from bottom to up
child: SlideTransition(
position: offset,
child: Image.asset(
onboardingEntries[index]["imageUrl"],
height: 350,
),
),
),
Just use ClipRect
to clip the image. It clips the child on its original layout.
Check it out (also the live demo on DartPad):
Here's the code:
import 'dart:async';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
late AnimationController controller;
late Animation<Offset> offset;
late NetworkImage _image;
@override
void initState() {
super.initState();
controller =
AnimationController(vsync: this, duration: const Duration(seconds: 3));
offset = Tween<Offset>(begin: const Offset(0.0, 1.0), end: Offset.zero)
.animate(controller);
_image =
const NetworkImage('https://source.unsplash.com/random/225x400?cars');
Timer.run(
() => precacheImage(_image, context).then((_) => controller.forward()));
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ClipRect(
child: ShaderMask(
shaderCallback: (rect) {
return const LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.white,
Colors.white,
Colors.white,
Colors.transparent
],
).createShader(Rect.fromLTRB(0, 0, rect.width, rect.height));
},
blendMode: BlendMode.dstIn,
child: SlideTransition(
position: offset,
child: Image(
image: _image,
height: 350,
),
),
),
),
),
);
}
}