Cursor pointing hover animation in Flutter web - flutter

I have SVG as an image file where I want to do this cursor hover effect.
I tried onhoverbutton but that does not work here.
I am using flutter_svg package for showing SVG image
Container(
width: double.infinity,
height: 400,
child: SvgPicture.asset('assets/below.svg',
cacheColorFilter: true,
color: const Color(0xff2C66B8)),
)
This is what I want in my web-app

if you run below code in dartpad, you will get idea about how hover works in flutter.
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MouseRegion with custom cursor',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const HomePage(),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Center(
child: MouseRegionWithCustomCursor(
cursor: const Icon(Icons.refresh, color: Colors.white),
// here you have to replace this with your svg image
child: Container(width: 300, height: 200, color: Colors.blueGrey),
),
);
}
}
// and in this class you can implement your blue line expansion and compression lines
class MouseRegionWithCustomCursor extends HookWidget {
final Widget cursor;
final Widget child;
const MouseRegionWithCustomCursor({
Key? key,
required this.cursor,
required this.child,
}) : super(key: key);
#override
Widget build(BuildContext context) {
final cursorPosition = useState<Offset?>(null);
return MouseRegion(
cursor: SystemMouseCursors.none,
onHover: (event) => cursorPosition.value = event.localPosition,
onExit: (event) => cursorPosition.value = null,
child: Stack(
children: [
child,
if (cursorPosition.value != null)
AnimatedPositioned(
duration: const Duration(),
left: cursorPosition.value?.dx,
top: cursorPosition.value?.dy,
child: cursor,
),
],
),
);
}
}
i know this is not best explanation but you can start with this.

Related

How can I place a container laid out above a Scaffold?

I would like to have a persistent container occupy the space about my material Scaffolds AppBar. I would like the Scaffold to resize to take up the available space.
When I try to do this, my Scaffold continues to be the height of the entire screen, and it is simply pushed lower, with a portion overflowing off the screen.
Is there a way I can have the Scaffold to resize to the available space?
Here is what I have coded so far...
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return PersistenTopBar(
child: Scaffold(
appBar: AppBar(
title: const Text("Test App"),
),
body: Container(),
),
);
}
}
class PersistenTopBar extends StatelessWidget {
final Widget child;
const PersistenTopBar({Key? key , required this.child }) : super(key: key);
#override
Widget build(BuildContext context) {
var mediaQuery = MediaQuery.of(context);
return Column(
children: [
Container(
width: double.infinity,
height: 200,
color: Colors.red,
),
SizedBox(
width: mediaQuery.size.width,
height: mediaQuery.size.height,
child: child,
),
],
);
}
}
You could also create a CustomAppBar that would take as children a topChild and an appBar.
class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
final double height;
final Widget topChild;
final AppBar appBar;
const CustomAppBar(
{Key? key,
this.height = 200.0,
required this.topChild,
required this.appBar})
: super(key: key);
#override
Widget build(BuildContext context) {
return Column(
children: [
Expanded(child: topChild),
appBar,
],
);
}
#override
Size get preferredSize => Size.fromHeight(height);
}
Full code sample
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 MaterialApp(
theme: ThemeData.light(),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
topChild: Container(color: Colors.red),
appBar: AppBar(title: const Text('My awesome Test App')),
),
body: const Center(
child: Text(
"Test App",
style: TextStyle(fontSize: 32.0),
),
),
);
}
}
class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
final double height;
final Widget topChild;
final AppBar appBar;
const CustomAppBar(
{Key? key,
this.height = 200.0,
required this.topChild,
required this.appBar})
: super(key: key);
#override
Widget build(BuildContext context) {
return Column(
children: [
Expanded(child: topChild),
appBar,
],
);
}
#override
Size get preferredSize => Size.fromHeight(height);
}
the available space = mediaQuery.size.height - the Height of the Container above the appBar so the SizedBox under the appBar wil be :
SizedBox(
width: mediaQuery.size.width,
height: mediaQuery.size.height - 200,
child: child,
),
the result:
or you can wrap your SizedBox with Expanded Widget :
Expanded(
child: SizedBox(
width: mediaQuery.size.width,
child: child,
),
),
the same result :

Can't make a big size container after increasing height

This is my code where I have increased my height of this container to make big circle in mobile emulator but couldn't make it. I don't know the reason behind these.
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(
home: NewScreen(),
debugShowCheckedModeBanner: false,
);
}
}
class NewScreen extends StatelessWidget {
const NewScreen({ Key? key }) : super(key: key);
#override
Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
return Scaffold(
body: Stack(
children: [
Positioned(
top: -150.0,
left: 0.0,
bottom: 450.0,
right: 0.0,
child: Container(
height: 800.0,
decoration: BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
),
),
],
),
);
}
}
I cannot make much bigger than initial size. What can I do to finish this?
I think you try to achieve this result
It's simple, give the left and right properties negative values as you want to achieve the result that you want
Positioned(
left: -100.0,
right: -100.0,
Position wrapping Container is constraining the Container's size.
Current Position widget is forcing child widget's size to have Stack's height-600 and same width with Stack.
Since you didn't include the final result of your expected output, i have add few version of circle that might suit your needs. Few this to take note here:
a) when giving height: size.height the container widget will take the space of the whole screen. The reason you see that the circle did not fit to the height because it is bounded by the width. This can be overcome with the code from example 2
b) height: size,height/2 means that the container will take half the size of the screen.
Big red circle in the centre of the screen
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(
home: NewScreen(),
debugShowCheckedModeBanner: false,
);
}
}
class NewScreen extends StatelessWidget {
const NewScreen({ Key? key }) : super(key: key);
#override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
return Scaffold(
body: Container(
height: size.height,
width: size.width,
decoration: BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
),
);
}
}
Circle with hidden side
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(
home: NewScreen(),
debugShowCheckedModeBanner: false,
);
}
}
class NewScreen extends StatelessWidget {
const NewScreen({ Key? key }) : super(key: key);
#override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
return Scaffold(
body: Stack(
children: [
Positioned(
left: -100,
right: -100,
child: Container(
height: size.height,
width: size.width,
decoration: BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
),
),
],
),
);
}
}
Circle at the top of the screen
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(
home: NewScreen(),
debugShowCheckedModeBanner: false,
);
}
}
class NewScreen extends StatelessWidget {
const NewScreen({ Key? key }) : super(key: key);
#override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
return Scaffold(
body: Column(
children: [
Container(
height: size.height/2,
width: size.width,
decoration: BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
),
],
),
);
}
}

SetState does not update immediately

I'm new to flutter and I'm having a problem here.
I'm developing an application to schedule meals and I wanted that when he got to the widget to confirm the appointments the calendar would appear gray and disabled
Booking Area widget
import 'package:app/widgets/booking/datepicker.dart';
import 'package:app/widgets/booking/pageone.dart';
import 'package:flutter/material.dart';
bool confirmationPage = false;
class BookingArea extends StatefulWidget {
const BookingArea({Key? key}) : super(key: key);
#override
_BookingAreaState createState() => _BookingAreaState();
}
class _BookingAreaState extends State<BookingArea> {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
child: Row(
children: [
Container(
width: 600,
height: 350,
color: Colors.amber,
child: const PageOne(),
),
Container(
foregroundDecoration: confirmationPage
? const BoxDecoration(
color: Colors.grey,
backgroundBlendMode: BlendMode.saturation,
)
: null,
width: 300,
height: 300,
child: const DatePicker(),
),
],
),
);
}
}
Confirmation Page widget
import 'package:app/widgets/booking/booking_area.dart';
import 'package:flutter/material.dart';
class PageOne extends StatefulWidget {
const PageOne({Key? key}) : super(key: key);
#override
_PageOneState createState() => _PageOneState();
}
class _PageOneState extends State<PageOne> {
#override
Widget build(BuildContext context) {
setState(() {
confirmationPage = true;
});
return const Center(
child: Text("Pagina 1"),
);
}
}
what happens is that when I give the setState on PageOne it only applies the state (changes the widget color) when I "restart" the page through routes.
What I wanted was that when he got to page one he would immediately change the color of the calendar
sorry for bad english
Thanks :)
That is because you are only updating your PageOne with this setState((){}) call.
It doesn't rebuild the parent widget.
This would be the quick solution, but I would highly recommend looking for a sophisticated statemanagement solution
import 'package:app/widgets/booking/datepicker.dart';
import 'package:app/widgets/booking/pageone.dart';
import 'package:flutter/material.dart';
class BookingArea extends StatefulWidget {
const BookingArea({Key? key}) : super(key: key);
#override
_BookingAreaState createState() => _BookingAreaState();
}
class _BookingAreaState extends State<BookingArea> {
bool confirmationPage = false;
#override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
child: Row(
children: [
Container(
width: 600,
height: 350,
color: Colors.amber,
child: PageOne(onInit:() {
setState((){
confirmation = true;
});
}),
),
Container(
foregroundDecoration: confirmationPage
? const BoxDecoration(
color: Colors.grey,
backgroundBlendMode: BlendMode.saturation,
)
: null,
width: 300,
height: 300,
child: const DatePicker(),
),
],
),
);
}
}
import 'package:app/widgets/booking/booking_area.dart';
import 'package:flutter/material.dart';
class PageOne extends StatefulWidget {
const PageOne({Key? key, required this.onInit}) : super(key: key);
final VoidCallback onInit;
#override
_PageOneState createState() => _PageOneState();
}
class _PageOneState extends State<PageOne> {
#override
void initState() {
super.initState();
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
widget.onInit();
});
}
#override
Widget build(BuildContext context) {
return const Center(
child: Text("Pagina 1"),
);
}
}

How to get rid of load times for asset images in flutter

I am building an app that uses lots of images and I was wondering if there is a way to get rid of the time it takes for the image to load and show up on screen when the image is being called? Here is a simple example of an image that I want to be loaded that is contained inside of a visibility widget.
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 MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool isVis = false;
Widget _showAssetImage() {
return Visibility(
visible: isVis,
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(
color: Colors.amber,
image: DecorationImage(image: AssetImage('deer.jpg'))),
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text('test app'),
),
body: _showAssetImage(),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.image),
onPressed: () {
setState(() {
isVis = true;
});
},
),
);
}
}
you can try precacheImage():
final theImage = Image.asset("deer.jpg");
#override
void didChangeDependencies() {
precacheImage(theImage.image, context);
super.didChangeDependencies();
}
use it with:
Container(
width: 100,
height: 100,
child: theImage,
),

How to pass data to stateless widget calling from another stateless widget?

I am trying to pass some color info from one widget to another but I am not able to get that color in destination widget. I wanted to build a single class with some UI code in it and just call this class in my main widget so that I don't have to repeat the code all over again, but I am not able to pass the data,
Here is the code that I am working on: What I am doing wrong?
void main(List<String> args) => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark(),
home: Scaffold(
appBar: AppBar(
title: const Text('Stateless/Clean Code'),
),
body: const StatelessOne(),
),
);
}
}
class StatelessOne extends StatelessWidget {
const StatelessOne({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
const Text(
'Widget color can be customised without \nhaving to retype the entire code'),
StatelessTwo(key: key, param: Colors.green),
StatelessTwo(key: key, param: Colors.pink),
StatelessTwo(key: key, param: Colors.blue),
StatelessTwo(key: key, param: Colors.orange),
],
),
);
}
}
class StatelessTwo extends StatelessWidget {
StatelessTwo({Key? key, #required param}) : super(key: key);
final Map param = {};
#override
Widget build(BuildContext context) {
return Container(
height: 120,
width: 250,
color: param['color'],
child: Center(child: Text('Your Repetitive Widget $key')),
);
}
}
Simple way will be
class StatelessTwo extends StatelessWidget {
final Color color;
const StatelessTwo({
Key? key,
required this.color,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
height: 120,
width: 250,
color: color,
child: Center(
child: Text('Your Repetitive Widget ${key ?? "no key found"}')),
);
}
}
-----
color: color, //use
Pass color
StatelessTwo(key: key, color: Colors.green), and seems you are passing same key, avoid it is not necessary for Ui-logic. Most likely, you don't need to pass key, if you still want to pass use UinqueKey()