Skip to content

Instantly share code, notes, and snippets.

@johnpryan
Forked from redbrogdon/main.dart
Last active November 22, 2019 22:52

Revisions

  1. johnpryan revised this gist Nov 22, 2019. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions main.dart
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,7 @@
    // 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:ui' as ui;
    import 'package:flutter/material.dart';

  2. @redbrogdon redbrogdon revised this gist Nov 19, 2019. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions main.dart
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,4 @@
    import 'dart:ui' as ui;
    import 'package:flutter/material.dart';

    void main() {
  3. @redbrogdon redbrogdon revised this gist Nov 19, 2019. 1 changed file with 2 additions and 5 deletions.
    7 changes: 2 additions & 5 deletions main.dart
    Original file line number Diff line number Diff line change
    @@ -1,9 +1,6 @@
    import 'package:flutter_web/material.dart';
    import 'package:flutter_web_test/flutter_web_test.dart';
    import 'package:flutter_web_ui/ui.dart' as ui;
    import 'package:flutter/material.dart';

    Future main() async {
    await ui.webOnlyInitializePlatform();
    void main() {
    runApp(MaterialApp(
    debugShowCheckedModeBanner: false,
    home: AnimatedAlignDemo(),
  4. johnpryan revised this gist Oct 21, 2019. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions main.dart
    Original file line number Diff line number Diff line change
    @@ -98,6 +98,9 @@ class Tile extends StatelessWidget {
    borderRadius: BorderRadius.circular(4.0),
    color: Colors.deepOrange,
    ),
    child: Center(
    child: Text('Slide me!', style: TextStyle(color: Colors.white)),
    ),
    ),
    );
    }
  5. johnpryan revised this gist Oct 17, 2019. No changes.
  6. johnpryan created this gist Oct 17, 2019.
    241 changes: 241 additions & 0 deletions main.dart
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,241 @@
    import 'package:flutter_web/material.dart';
    import 'package:flutter_web_test/flutter_web_test.dart';
    import 'package:flutter_web_ui/ui.dart' as ui;

    Future main() async {
    await ui.webOnlyInitializePlatform();
    runApp(MaterialApp(
    debugShowCheckedModeBanner: false,
    home: AnimatedAlignDemo(),
    theme: ThemeData.dark(),
    ));
    }

    class AnimatedAlignDemo extends StatelessWidget {
    Widget build(BuildContext context) {
    return Scaffold(
    body: Center(
    child: AspectRatio(
    aspectRatio: 1,
    child: Padding(
    padding: const EdgeInsets.all(16.0),
    child: SlidePuzzle(
    boardSize: 5,
    ),
    ),
    ),
    ),
    );
    }
    }

    class SlidePuzzle extends StatefulWidget {
    final Duration duration = Duration(milliseconds: 200);
    final int boardSize;

    SlidePuzzle({this.boardSize = 5});

    _SlidePuzzleState createState() => _SlidePuzzleState();
    }

    class _SlidePuzzleState extends State<SlidePuzzle> {
    int row;
    int col;

    void initState() {
    row = widget.boardSize ~/ 2;
    col = widget.boardSize ~/ 2;
    super.initState();
    }

    List<AnimatedTile> get tiles => [
    AnimatedTile(
    boardSize: widget.boardSize,
    row: row,
    col: col,
    child: Tile(),
    duration: widget.duration,
    ),
    ];

    void _moveTileLeft() => row = (row - 1) % widget.boardSize;

    void _moveTileUp() => col = (col - 1) % widget.boardSize;

    void _moveTileRight() => row = (row + 1) % widget.boardSize;

    void _moveTileDown() => col = (col + 1) % widget.boardSize;

    Widget build(BuildContext context) {
    return SwipeDetector(
    onSwipeUp: () => setState(() => _moveTileUp()),
    onSwipeDown: () => setState(() => _moveTileDown()),
    onSwipeLeft: () => setState(() => _moveTileLeft()),
    onSwipeRight: () => setState(() => _moveTileRight()),
    child: Container(
    child: Stack(
    children: tiles,
    ),
    decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(4.0),
    color: Colors.grey.shade700,
    ),
    ),
    );
    }
    }

    class Tile extends StatelessWidget {
    const Tile({
    Key key,
    }) : super(key: key);

    Widget build(BuildContext context) {
    return Padding(
    padding: const EdgeInsets.all(4.0),
    child: DecoratedBox(
    decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(4.0),
    color: Colors.deepOrange,
    ),
    ),
    );
    }
    }

    class AnimatedTile extends StatelessWidget {
    final int boardSize;
    final int row;
    final int col;
    final Widget child;
    final Duration duration;

    AnimatedTile({
    this.boardSize,
    this.row,
    this.col,
    this.child,
    this.duration,
    });

    AlignmentGeometry get alignment {
    var maxTileIndex = (boardSize - 1).toDouble();
    var rowPosition = ui.lerpDouble(-1.0, 1.0, row.toDouble() / maxTileIndex);
    var colPosition = ui.lerpDouble(-1.0, 1.0, col.toDouble() / maxTileIndex);
    return Alignment(rowPosition, colPosition);
    }

    Widget build(BuildContext context) {
    return AnimatedAlign(
    alignment: alignment,
    duration: duration,
    curve: Curves.ease,
    child: FractionallySizedBox(
    widthFactor: 1.0 / boardSize,
    heightFactor: 1.0 / boardSize,
    child: child,
    ),
    );
    }
    }

    class SwipeDetector extends StatefulWidget {
    final Widget child;
    final VoidCallback onSwipeLeft;
    final VoidCallback onSwipeUp;
    final VoidCallback onSwipeRight;
    final VoidCallback onSwipeDown;

    SwipeDetector({
    this.child,
    this.onSwipeLeft,
    this.onSwipeUp,
    this.onSwipeRight,
    this.onSwipeDown,
    });

    _SwipeDetectorState createState() => _SwipeDetectorState();
    }

    class _SwipeDetectorState extends State<SwipeDetector> {
    double _verticalStartY = 0.0;
    double _verticalEndY = 0.0;
    double _verticalDrag = 0.0;
    double _horizontalStartX = 0.0;
    double _horizontalEndX = 0.0;
    double _horizontalDrag = 0.0;

    _horizontalStart(DragStartDetails details) {
    if (details == null || details.globalPosition == null) return;
    _horizontalStartX = details.globalPosition.dx;
    }

    _horizontalUpdate(DragUpdateDetails details) {
    if (details == null || details.globalPosition == null) {
    return;
    }

    _horizontalEndX = details.globalPosition.dx;

    var distance = _horizontalEndX - _horizontalStartX;
    if (distance != null && distance < 0 && _horizontalDrag < 0 ||
    distance > 0 && _horizontalDrag > 0) {
    return;
    }

    if (distance < 0) {
    widget.onSwipeLeft();
    } else if (distance > 0) {
    widget.onSwipeRight();
    }

    _horizontalDrag = distance;
    }

    _horizontalEnd(DragEndDetails details) {
    _horizontalDrag = 0.0;
    }

    _verticalStart(DragStartDetails details) {
    if (details == null || details.globalPosition == null) return;
    _verticalStartY = details.globalPosition.dy;
    }

    _verticalUpdate(DragUpdateDetails details) {
    if (details == null || details.globalPosition == null) {
    return;
    }

    _verticalEndY = details.globalPosition.dy;

    var distance = _verticalEndY - _verticalStartY;
    if (distance != null && distance < 0 && _verticalDrag < 0 ||
    distance > 0 && _verticalDrag > 0) {
    return;
    }

    if (distance < 0) {
    widget.onSwipeUp();
    } else if (distance > 0) {
    widget.onSwipeDown();
    }

    _verticalDrag = distance;
    }

    _verticalEnd(DragEndDetails details) {
    _verticalDrag = 0.0;
    }

    Widget build(BuildContext context) {
    return GestureDetector(
    onHorizontalDragStart: _horizontalStart,
    onHorizontalDragUpdate: _horizontalUpdate,
    onHorizontalDragEnd: _horizontalEnd,
    onVerticalDragStart: _verticalStart,
    onVerticalDragUpdate: _verticalUpdate,
    onVerticalDragEnd: _verticalEnd,
    child: widget.child,
    );
    }
    }