Я разработчик JavaScript и новичок во Flutter. Я просто хочу анимировать набор изображений при наведении курсора мыши, например this, с помощью Flutter for Web. Он включает в себя преобразования масштабирования, непрозрачности и оттенков серого. Как это сделать во Flutter? Заранее спасибо.
Как анимировать изображения при наведении курсора мыши с помощью Flutter for Web?
Ответы (4)
Кроме анимационной части вашего вопроса. Аргумент onHover
InkWell
работает только в том случае, если вы сначала укажете аргумент onTap
.
InkWell(
child: SomeWidget(),
onTap: () {
//You can leave it empty, like that.
}
onHover: (isHovering) {
if (isHovering) {
//The mouse is hovering.
} else {
//The mouse is no longer hovering.
}
}
)
Из документации можно узнать о преимуществах boolean
, которые передаются в обратный вызов onHover
:
Значение, переданное обратному вызову, истинно, если указатель вошел в эту часть материала, и ложно, если указатель вышел из этой части материала.
Это просто демонстрация, демонстрирующая, что вы можете использовать виджет onHover
из Inkwell
для выполнения задачи. Вам нужно будет придумать логику, чтобы решить, сколько смещения и масштаба следует использовать и как позиционировать виджет. В моем примере я использовал вид сетки. Возможно, вы можете использовать стек для установки текущего активного виджета на основе наведения.
Вот пример с сеткой. Его действующая версия доступна на этом блокноте.
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GridView.count(
crossAxisCount: 3,
children: <Widget>[ImageHover(),ImageHover(),ImageHover(),ImageHover(),ImageHover(),ImageHover(),ImageHover(),],
);
}
}
class ImageHover extends StatefulWidget {
@override
_ImageHoverState createState() => _ImageHoverState();
}
class _ImageHoverState extends State<ImageHover> {
double elevation = 4.0;
double scale = 1.0;
Offset translate = Offset(0,0);
@override
Widget build(context) {
return InkWell(
onTap: (){},
onHover: (value){
print(value);
if(value){
setState((){
elevation = 20.0;
scale = 2.0;
translate = Offset(20,20);
});
}else{
setState((){
elevation = 4.0;
scale = 1.0;
translate = Offset(0,0);
});
}
},
child: Transform.translate(
offset: translate ,
child: Transform.scale(
scale: scale,
child: Material(
elevation: elevation,
child: Image.network(
'https://i.ytimg.com/vi/acm9dCI5_dc/maxresdefault.jpg',
),
),
),
),
);
}
}
Просто создайте расширение
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
extension HoverExtension on Widget {
Widget get translateOnHover {
return kIsWeb ? TranslateOnHover(child: this) : ThisContainer(child: this);
}
}
class ThisContainer extends StatelessWidget {
ThisContainer({this.child});
final child;
@override
Widget build(BuildContext context) {
return Container(child: child);
}
}
class TranslateOnHover extends StatefulWidget {
final Widget child;
TranslateOnHover({required this.child});
@override
_TranslateOnHoverState createState() => _TranslateOnHoverState();
}
class _TranslateOnHoverState extends State<TranslateOnHover> {
double scale = 1.0;
@override
Widget build(BuildContext context) {
return MouseRegion(
onEnter: (e) => _mouseEnter(true),
onExit: (e) => _mouseEnter(false),
child: TweenAnimationBuilder(
duration: const Duration(milliseconds: 200),
tween: Tween<double>(begin: 1.0, end: scale),
builder: (BuildContext context, double value, _) {
return Transform.scale(scale: value, child: widget.child);
},
),
);
}
void _mouseEnter(bool hover) {
setState(() {
if (hover)
scale = 1.03;
else
scale = 1.0;
});
}
}
И используйте его где угодно, позвонив
yourWidget.translateOnHover