반응형
Flutter 터치로 사진 확대/축소 시키기
이번에는 화면 터치를 통해 사진/그림을 확대/축소 시키는 방법에 대해 알아보겠다.
Animation 위젯을 응용하여 사용할 것이고 관련 내용을 통해
progress bar 등으로의 활용도 가능하다.
사용법은 매우매우 간단하다.
동작 원리
1. Animation, AnimationController 생성
2. 특정 행동(터치)을 감지하여 행동 발생시 설정한 애니메이션이 동작하도록 수행
1. Animation, AnimationController 생성
Animation _animation;
AnimationController _animationController;
@override
void initState() {
// TODO: implement initState
super.initState();
_animationController = new AnimationController(vsync: this, duration: Duration(milliseconds: 100));
_animation = Tween(begin: 1.0, end: 2.0).animate(CurvedAnimation(parent: _animationController, curve: Curves.easeInOut))..addListener(() {
setState(() {
});
});
}
2. 특정 행동(터치)을 감지하여 행동 발생시 설정한 애니메이션이 동작하도록 수행
GestureDetector(
onTap: () {
if(_animationController.isCompleted) {
_animationController.reverse();
} else {
_animationController.forward();
}
},
child: Container(
child: Transform(
alignment: Alignment.center,
transform: Matrix4.diagonal3(Vector3(_animation.value, _animation.value, _animation.value)),
child: Image.network('https://images.unsplash.com/photo-1598294203238-ed1ac7484b8b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=676&q=80')
),
width: MediaQuery.of(context).size.width * 0.5,
height: MediaQuery.of(context).size.height * 0.5,
),
),
3. 결과 화면
4. 전체 소스
import 'package:flutter/material.dart';
import 'package:vector_math/vector_math_64.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: DoubleTapZoom(),
);
}
}
class DoubleTapZoom extends StatefulWidget {
const DoubleTapZoom({
Key key,
}) : super(key: key);
@override
_DoubleTapZoomState createState() => _DoubleTapZoomState();
}
class _DoubleTapZoomState extends State<DoubleTapZoom> with SingleTickerProviderStateMixin {
Animation _animation;
AnimationController _animationController;
@override
void initState() {
// TODO: implement initState
super.initState();
_animationController = new AnimationController(vsync: this, duration: Duration(milliseconds: 100));
_animation = Tween(begin: 1.0, end: 2.0).animate(CurvedAnimation(parent: _animationController, curve: Curves.easeInOut))..addListener(() {
setState(() {
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('1111', style: TextStyle(fontSize: 20)),
Text('2222', style: TextStyle(fontSize: 20)),
Text('3333', style: TextStyle(fontSize: 20)),
Text('4444', style: TextStyle(fontSize: 20)),
Text('5555', style: TextStyle(fontSize: 20)),
GestureDetector(
onTap: () {
if(_animationController.isCompleted) {
_animationController.reverse();
} else {
_animationController.forward();
}
},
child: Container(
child: Transform(
alignment: Alignment.center,
transform: Matrix4.diagonal3(Vector3(_animation.value, _animation.value, _animation.value)),
child: Image.network('https://images.unsplash.com/photo-1598294203238-ed1ac7484b8b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=676&q=80')
),
width: MediaQuery.of(context).size.width * 0.5,
height: MediaQuery.of(context).size.height * 0.5,
),
),
Text('6666', style: TextStyle(fontSize: 20)),
Text('7777', style: TextStyle(fontSize: 20)),
Text('8888', style: TextStyle(fontSize: 20)),
],
),
)
);
}
}
반응형
댓글