Skip to content

Instantly share code, notes, and snippets.

@timburks
Last active May 10, 2020 04:43
Show Gist options
  • Save timburks/bd6e11466b6932e07ed936c5cef3b0da to your computer and use it in GitHub Desktop.
Save timburks/bd6e11466b6932e07ed936c5cef3b0da to your computer and use it in GitHub Desktop.
100-line web-based drum machine in flutter
import 'package:flutter/material.dart';
import 'package:universal_html/html.dart' as web;
import 'dart:async';
const instruments = ["hat", "stick", "cymbal", "snare", "bass"];
List<_ButtonRowState> states = [];
main() {
const delta = const Duration(milliseconds: 160);
new Timer.periodic(delta, (Timer t) {
for (var state in states) {
state.tick();
}
});
runApp(BeatMachine());
}
class ButtonRow extends StatefulWidget {
final String instrument;
ButtonRow(this.instrument);
@override
_ButtonRowState createState() {
states.add(_ButtonRowState(instrument));
return states.last;
}
}
class _ButtonRowState extends State<ButtonRow> {
var beat = 0;
var isSelected = new List<bool>(16);
var players = new List<web.AudioElement>(16);
_ButtonRowState(String name) {
for (int i = 0; i < 16; i++) {
isSelected[i] = false;
players[i] = web.AudioElement();
players[i].id = name + i.toString();
players[i].src =
"https://storage.googleapis.com/radtastical/sounds/" + name + ".mp3";
web.document.body.append(players[i]);
}
}
void tick() {
setState(() {
beat = (beat + 1) % 16;
});
if (isSelected[beat]) {
players[beat].play();
}
}
@override
Widget build(BuildContext context) {
var children = new List<Widget>(16);
for (int i = 0; i < 16; i++) {
children[i] = Icon((beat == i) ? Icons.star : Icons.star_border);
}
return Center(
child: ToggleButtons(
children: children,
onPressed: (index) {
setState(() {
isSelected[index] = !isSelected[index];
});
},
isSelected: isSelected,
),
);
}
}
class BeatMachine extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Beat Machine',
home: Scaffold(
appBar: AppBar(
title: Text('Give me a beat!'),
),
body: Center(
child: Column(children: [
for (var instrument in instruments)
Row(
children: [
Container(
width: 100,
child: Text(instrument,
style: TextStyle(fontSize: 18),
textAlign: TextAlign.center),
),
ButtonRow(instrument)
],
),
]),
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment