Skip to content

Instantly share code, notes, and snippets.

@mkiisoft
Last active April 11, 2020 20:53
Show Gist options
  • Select an option

  • Save mkiisoft/8d467275a46ee247a7b959177519a5aa to your computer and use it in GitHub Desktop.

Select an option

Save mkiisoft/8d467275a46ee247a7b959177519a5aa to your computer and use it in GitHub Desktop.

Revisions

  1. mkiisoft revised this gist Apr 11, 2020. 1 changed file with 16 additions and 3 deletions.
    19 changes: 16 additions & 3 deletions wave_clipper.dart
    Original file line number Diff line number Diff line change
    @@ -1,11 +1,24 @@
    import 'package:flutter/material.dart';

    class HomeScreen extends StatefulWidget {
    void main() {
    runApp(MyApp());
    }

    class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return MaterialApp(
    home: WaveScreen()
    );
    }
    }

    class WaveScreen extends StatefulWidget {
    @override
    _HomeScreenState createState() => _HomeScreenState();
    _WaveScreenState createState() => _WaveScreenState();
    }

    class _HomeScreenState extends State<HomeScreen> {
    class _WaveScreenState extends State<WaveScreen> {
    var _slider = 0.0;
    var _depth = 10.0;
    var _red = 0.0;
  2. mkiisoft revised this gist Apr 11, 2020. 1 changed file with 99 additions and 23 deletions.
    122 changes: 99 additions & 23 deletions wave_clipper.dart
    Original file line number Diff line number Diff line change
    @@ -1,30 +1,20 @@
    import 'package:flutter/material.dart';

    void main() {
    runApp(MyApp());
    }

    class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return MaterialApp(
    home: WaveScreen()
    );
    }
    }

    class WaveScreen extends StatefulWidget {
    class HomeScreen extends StatefulWidget {
    @override
    _WaveScreenState createState() => _WaveScreenState();
    _HomeScreenState createState() => _HomeScreenState();
    }

    class _WaveScreenState extends State<WaveScreen> {
    class _HomeScreenState extends State<HomeScreen> {
    var _slider = 0.0;
    var _depth = 10.0;
    var _red = 0.0;
    var _green = 0.0;
    var _blue = 0.0;

    var _orientation = 0;
    var _waveOrientation = Orientation.UP;

    @override
    Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    @@ -39,6 +29,41 @@ class _WaveScreenState extends State<WaveScreen> {
    fit: BoxFit.none,
    child: Column(
    children: [
    Text('Orientation'),
    Container(
    width: size.width,
    child: Row(
    mainAxisSize: MainAxisSize.max,
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
    Radio(
    value: 0,
    groupValue: _orientation,
    onChanged: _orientationChanged,
    ),
    Text('UP'),
    Radio(
    value: 1,
    groupValue: _orientation,
    onChanged: _orientationChanged,
    ),
    Text('UP REVERSE'),
    Radio(
    value: 2,
    groupValue: _orientation,
    onChanged: _orientationChanged,
    ),
    Text('DOWN'),
    Radio(
    value: 3,
    groupValue: _orientation,
    onChanged: _orientationChanged,
    ),
    Text('DOWN REVERSE'),
    ],
    ),
    ),
    SizedBox(height: 20),
    Text('Color Selector'),
    Container(
    width: size.width,
    @@ -76,7 +101,7 @@ class _WaveScreenState extends State<WaveScreen> {
    ],
    ),
    ),
    SizedBox(height: 10),
    SizedBox(height: 20),
    Text('Waves: ${_slider.toInt()}'),
    Container(
    width: size.width - 60,
    @@ -90,7 +115,6 @@ class _WaveScreenState extends State<WaveScreen> {
    inactiveColor: Color.fromARGB(255, _red.toInt(), _green.toInt(), _blue.toInt()),
    ),
    ),
    SizedBox(height: 10),
    Text('Depth: ${_depth.toInt()}'),
    Container(
    width: size.width - 60,
    @@ -105,7 +129,10 @@ class _WaveScreenState extends State<WaveScreen> {
    ),
    SizedBox(height: 10),
    ClipPath(
    clipper: _slider.toInt() == 0 ? null : WaveGeneratorPath(amount: _slider, depth: _depth.toInt()),
    clipper: _slider.toInt() == 0
    ? null
    : WaveGeneratorPath(
    amount: _slider.toInt(), depth: _depth.toInt(), orientation: _waveOrientation),
    child: Container(
    padding: const EdgeInsets.only(bottom: 50),
    width: size.width,
    @@ -121,31 +148,80 @@ class _WaveScreenState extends State<WaveScreen> {
    ),
    );
    }

    _orientationChanged(int index) {
    setState(() => _orientation = index);
    switch (index) {
    case 0:
    setState(() => _waveOrientation = Orientation.UP);
    break;
    case 1:
    setState(() => _waveOrientation = Orientation.UP_REVERSE);
    break;
    case 2:
    setState(() => _waveOrientation = Orientation.DOWN);
    break;
    case 3:
    setState(() => _waveOrientation = Orientation.DOWN_REVERSE);
    break;
    }
    }
    }

    enum Orientation { UP, UP_REVERSE, DOWN, DOWN_REVERSE }

    class WaveGeneratorPath extends CustomClipper<Path> {
    final amount;
    final depth;
    final orientation;

    WaveGeneratorPath({this.amount, this.depth});
    WaveGeneratorPath({this.amount, this.depth, this.orientation});

    @override
    Path getClip(Size size) {
    var path = new Path();
    var sections = size.width / amount;
    for (int index = 0; index < amount; index++) {
    path.lineTo(sections * index, size.height - depth);
    path.lineTo(
    sections * index,
    when(orientation, {
    Orientation.UP: 0.0 + depth,
    Orientation.UP_REVERSE: 0.0 + depth,
    Orientation.DOWN: size.height - depth,
    Orientation.DOWN_REVERSE: size.height - depth,
    }));
    path.quadraticBezierTo(
    (sections * index) + (sections / 2),
    index % 2 == 0 ? size.height + depth : size.height - (depth * 3),
    when(orientation, {
    Orientation.UP: index % 2 == 0 ? 0.0 + depth * 3 : 0.0 - depth,
    Orientation.UP_REVERSE: index % 2 != 0 ? 0.0 + depth * 3 : 0.0 - depth,
    Orientation.DOWN: index % 2 == 0 ? size.height + depth : size.height - (depth * 3),
    Orientation.DOWN_REVERSE: index % 2 != 0 ? size.height + depth : size.height - (depth * 3),
    }),
    sections * (index + 1),
    size.height - depth);
    when(orientation, {
    Orientation.UP: 0.0 + depth,
    Orientation.UP_REVERSE: 0.0 + depth,
    Orientation.DOWN: size.height - depth,
    Orientation.DOWN_REVERSE: size.height - depth,
    }));
    }
    path.lineTo(size.width, 0.0);
    if (orientation == Orientation.UP || orientation == Orientation.UP_REVERSE) {
    path.lineTo(size.width, size.height);
    path.lineTo(0.0, size.height);
    }
    path.close();
    return path;
    }

    @override
    bool shouldReclip(CustomClipper<Path> oldClipper) => true;
    }

    Type when<Input, Type>(Input selectedOption, Map<Input, Type> branches, [Type defaultValue]) {
    if (!branches.containsKey(selectedOption)) {
    return defaultValue;
    }
    return branches[selectedOption];
    }
  3. mkiisoft revised this gist Apr 11, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion wave_clipper.dart
    Original file line number Diff line number Diff line change
    @@ -15,7 +15,7 @@ class MyApp extends StatelessWidget {

    class WaveScreen extends StatefulWidget {
    @override
    _WaveScreenState createState() => _WavecreenState();
    _WaveScreenState createState() => _WaveScreenState();
    }

    class _WaveScreenState extends State<WaveScreen> {
  4. mkiisoft created this gist Apr 11, 2020.
    151 changes: 151 additions & 0 deletions wave_clipper.dart
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,151 @@
    import 'package:flutter/material.dart';

    void main() {
    runApp(MyApp());
    }

    class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return MaterialApp(
    home: WaveScreen()
    );
    }
    }

    class WaveScreen extends StatefulWidget {
    @override
    _WaveScreenState createState() => _WavecreenState();
    }

    class _WaveScreenState extends State<WaveScreen> {
    var _slider = 0.0;
    var _depth = 10.0;
    var _red = 0.0;
    var _green = 0.0;
    var _blue = 0.0;

    @override
    Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;

    return Material(
    color: Colors.white,
    child: Stack(
    children: [
    Align(
    alignment: Alignment(0, 0),
    child: FittedBox(
    fit: BoxFit.none,
    child: Column(
    children: [
    Text('Color Selector'),
    Container(
    width: size.width,
    child: Row(
    mainAxisSize: MainAxisSize.max,
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
    Slider(
    value: _red,
    onChanged: (value) => setState(() => _red = value),
    min: 0,
    max: 255,
    divisions: 255,
    activeColor: Colors.red,
    inactiveColor: Colors.red,
    ),
    Slider(
    value: _green,
    onChanged: (value) => setState(() => _green = value),
    min: 0,
    max: 255,
    divisions: 255,
    activeColor: Colors.green,
    inactiveColor: Colors.green,
    ),
    Slider(
    value: _blue,
    onChanged: (value) => setState(() => _blue = value),
    min: 0,
    max: 255,
    divisions: 255,
    activeColor: Colors.blue,
    inactiveColor: Colors.blue,
    )
    ],
    ),
    ),
    SizedBox(height: 10),
    Text('Waves: ${_slider.toInt()}'),
    Container(
    width: size.width - 60,
    child: Slider(
    value: _slider,
    onChanged: (value) => setState(() => _slider = value),
    min: 0,
    max: 80,
    divisions: 80,
    activeColor: Color.fromARGB(255, _red.toInt(), _green.toInt(), _blue.toInt()),
    inactiveColor: Color.fromARGB(255, _red.toInt(), _green.toInt(), _blue.toInt()),
    ),
    ),
    SizedBox(height: 10),
    Text('Depth: ${_depth.toInt()}'),
    Container(
    width: size.width - 60,
    child: Slider(
    value: _depth,
    onChanged: (value) => setState(() => _depth = value),
    min: 0,
    max: 80,
    activeColor: Color.fromARGB(255, _red.toInt(), _green.toInt(), _blue.toInt()),
    inactiveColor: Color.fromARGB(255, _red.toInt(), _green.toInt(), _blue.toInt()),
    ),
    ),
    SizedBox(height: 10),
    ClipPath(
    clipper: _slider.toInt() == 0 ? null : WaveGeneratorPath(amount: _slider, depth: _depth.toInt()),
    child: Container(
    padding: const EdgeInsets.only(bottom: 50),
    width: size.width,
    height: 200,
    color: Color.fromARGB(255, _red.toInt(), _green.toInt(), _blue.toInt()),
    ),
    ),
    ],
    ),
    ),
    )
    ],
    ),
    );
    }
    }

    class WaveGeneratorPath extends CustomClipper<Path> {
    final amount;
    final depth;

    WaveGeneratorPath({this.amount, this.depth});

    @override
    Path getClip(Size size) {
    var path = new Path();
    var sections = size.width / amount;
    for (int index = 0; index < amount; index++) {
    path.lineTo(sections * index, size.height - depth);
    path.quadraticBezierTo(
    (sections * index) + (sections / 2),
    index % 2 == 0 ? size.height + depth : size.height - (depth * 3),
    sections * (index + 1),
    size.height - depth);
    }
    path.lineTo(size.width, 0.0);
    path.close();
    return path;
    }

    @override
    bool shouldReclip(CustomClipper<Path> oldClipper) => true;
    }