Skip to content

Instantly share code, notes, and snippets.

@romanejaquez
Created March 30, 2022 13:57
Show Gist options
  • Save romanejaquez/8ffab81baf436c2bedc2ba4043827684 to your computer and use it in GitHub Desktop.
Save romanejaquez/8ffab81baf436c2bedc2ba4043827684 to your computer and use it in GitHub Desktop.
import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return UserDetails();
}
}
class UserDetails extends StatefulWidget {
const UserDetails({Key? key}) : super(key: key);
@override
State<UserDetails> createState() => _UserDetailsState();
}
class _UserDetailsState extends State<UserDetails>
with SingleTickerProviderStateMixin {
late AnimationController animationController;
late Animation cameraTranslationAnimation, galleryTranslationAnimation;
late Animation rotationAnimation;
String pickedItem = 'Select icon';
double getRadiansFromDegree(double degree) {
double unitRadian = 57.295779513;
return degree / unitRadian;
}
@override
void initState() {
animationController = AnimationController(
vsync: this, duration: const Duration(milliseconds: 250));
cameraTranslationAnimation = TweenSequence([
TweenSequenceItem<double>(
tween: Tween(begin: 0.0, end: 1.2), weight: 75.0),
TweenSequenceItem<double>(
tween: Tween(begin: 1.2, end: 1.0), weight: 25.0)
]).animate(animationController);
galleryTranslationAnimation = TweenSequence([
TweenSequenceItem<double>(
tween: Tween(begin: 0.0, end: 1.4), weight: 55.0),
TweenSequenceItem<double>(
tween: Tween(begin: 1.4, end: 1.0), weight: 45.0)
]).animate(animationController);
rotationAnimation = Tween<double>(begin: 180.0, end: 0.0).animate(
CurvedAnimation(parent: animationController, curve: Curves.easeOut));
super.initState();
}
@override
void dispose() {
animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
title: const Text('User Details'),
),
body: SingleChildScrollView(
child: Column(
children: [
SizedBox(
width: size.width,
height: 190,
child: Stack(
children: [
Positioned(
top: 30,
left: (size.width) / 2 - 70,
right: 0,
child: Stack(
children: [
AnimatedBuilder(
animation: animationController,
builder: (context, child) {
return Transform.translate(
offset: Offset.fromDirection(
getRadiansFromDegree(30),
cameraTranslationAnimation.value * 165),
child: Transform(
transform: Matrix4.rotationZ(
getRadiansFromDegree(
rotationAnimation.value))
..scale(cameraTranslationAnimation.value),
alignment: Alignment.center,
child: CircularButton(
width: 50,
height: 50,
color: Colors.white,
icon: const Icon(Icons.add_to_photos,
color: Colors.black87),
onClick: () {
setState(() {
pickedItem = 'add to photos pressed';
});
}),
),
);
},
),
AnimatedBuilder(
animation: animationController,
builder: (_, child) {
return Positioned(
left: 10,
child: Transform.translate(
offset: Offset.fromDirection(
getRadiansFromDegree(365),
galleryTranslationAnimation.value * 135),
child: Transform(
transform: Matrix4.rotationZ(
getRadiansFromDegree(
rotationAnimation.value))
..scale(galleryTranslationAnimation.value),
alignment: Alignment.center,
child: CircularButton(
width: 50,
height: 50,
color: Colors.white,
icon: const Icon(Icons.camera_alt,
color: Colors.black87),
onClick: () {
setState(() {
pickedItem = 'camera pressed';
});
}),
),
),
);
},
),
GestureDetector(
onTap: () {
if (animationController.isCompleted) {
animationController.reverse();
} else {
animationController.forward();
}
},
child: const CircleAvatar(
radius: 70,
child: Text('Add Photo'),
),
),
],
),
),
],
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
Text(pickedItem),
const SizedBox(height: 30),
],
),
),
],
),
),
);
}
}
class CircularButton extends StatelessWidget {
final double width;
final double height;
final Color color;
final Icon icon;
final VoidCallback onClick;
const CircularButton(
{Key? key,
required this.width,
required this.height,
required this.color,
required this.icon,
required this.onClick})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(color: color, shape: BoxShape.circle),
width: width,
height: height,
child: IconButton(
icon: icon,
onPressed: () => onClick(),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment