Skip to content

Instantly share code, notes, and snippets.

@maheshj01
Last active December 21, 2022 02:55
Show Gist options
  • Select an option

  • Save maheshj01/e96ed09af35868c256e37f2ea3c98de7 to your computer and use it in GitHub Desktop.

Select an option

Save maheshj01/e96ed09af35868c256e37f2ea3c98de7 to your computer and use it in GitHub Desktop.
Flutter Raining Balls (Flutter Counter app Challenge 2020)
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:math' as math;
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Counter(),
);
}
}
class Counter extends StatefulWidget {
const Counter({super.key});
@override
_CounterState createState() => _CounterState();
}
class _CounterState extends State<Counter> with SingleTickerProviderStateMixin {
@override
void dispose() {
// TODO: implement dispose
super.dispose();
}
void _incrementCounter() {
setState(() {
counter++;
});
}
int counter = 0;
late Size size;
@override
Widget build(BuildContext context) {
// TODO: implement build
size = MediaQuery.of(context).size;
return Scaffold(
// appBar: AppBar(),
body: Stack(
children: [
Align(
alignment: Alignment.center,
child: Container(
child: Text('$counter',
key: const Key('counter'),
style: const TextStyle(color: Colors.black, fontSize: 30)),
)),
for (int i = 0; i < counter; i++)
Ball(
size: size,
)
],
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(
width: 30,
),
FloatingActionButton(
key: const Key('increment'),
onPressed: _incrementCounter,
tooltip: 'ball Animation',
child: const Icon(Icons.radio_button_checked)),
],
),
);
}
}
class Ball extends StatefulWidget {
const Ball({
Key? key,
required this.size,
}) : super(key: key);
final Size size;
@override
_BallState createState() => _BallState();
}
class _BallState extends State<Ball> with SingleTickerProviderStateMixin {
late Animation<double> _ballAnimation;
late AnimationController ballController;
@override
void initState() {
super.initState();
generateList();
ballController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 4000),
)..addListener(() {
if (ballController.status == AnimationStatus.completed) {
ballController.reset();
}
});
_ballAnimation = Tween<double>(begin: widget.size.height + 100, end: 10).animate(
CurvedAnimation(parent: ballController, curve: GravityCurve()));
final index = math.Random().nextInt(positions.length);
dx = positions[index];
ballController.forward();
}
@override
void dispose() {
ballController.dispose();
super.dispose();
}
void generateList() {
for (double i = -widget.size.width / 2;
i < widget.size.width / 2;
i += 50.0) {
positions.add(i);
}
}
Widget ball({double? size}) {
return Container(
height: size ?? 20,
decoration: const BoxDecoration(color: Colors.red, shape: BoxShape.circle),
);
}
double? dx;
List<double> positions = [];
@override
Widget build(BuildContext context) {
// TODO: implement build
return AnimatedBuilder(
animation: _ballAnimation,
builder: (context, child) {
return Transform.translate(
offset: Offset(dx!, _ballAnimation.value), child: ball());
});
}
}
class GravityCurve extends Curve {
// 0-1
@override
double transformInternal(double t) {
return math.sin(math.pi * t);
// return t < 0.5 ? sin(pi * t) : sin(3 * t * pi / 2);
}
}
@maheshj01

Copy link
Copy Markdown
Author

ezgif com-gif-maker (1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment