header.dart 4.92 KB
Newer Older
1 2 3 4
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_sprites/flutter_sprites.dart';

class GalleryHeader extends StatefulWidget {
  @override
  _GalleryHeaderState createState() => new _GalleryHeaderState();
}

class _GalleryHeaderState extends State<GalleryHeader> {
  _FlutterHeaderNode _headerNode;
  ImageMap _images;

  Future<Null> _loadAssets() async {
    final AssetBundle bundle = DefaultAssetBundle.of(context);
    _images = new ImageMap(bundle);
    await _images.load(<String>[
      'packages/flutter_gallery_assets/grain.png',
    ]);
  }

  @override
  void initState() {
    super.initState();
    _loadAssets().then((_) {
      setState(() {
        _headerNode = new _FlutterHeaderNode(_images);
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return _headerNode == null ? new Container() : new SpriteWidget(_headerNode);
  }
}

const Size _kCanvasSize = const Size(1024.0, 1024.0);
const Point _kCenterPoint = const Point(512.0, 512.0);

class _FlutterHeaderNode extends NodeWithSize {
  _FlutterHeaderNode(this._images) : super(_kCanvasSize) {
    clippingLayer.opacity = 0.0;
    clippingLayer.actions.run(new ActionTween((double a) => clippingLayer.opacity = a, 0.0, 1.0, 0.5));
    addChild(clippingLayer);

    clippingLayer.addChild(new _BackgroundBox());

    paperAnimation.position = _kCenterPoint;
    clippingLayer.addChild(paperAnimation);

    final Sprite grain = new Sprite.fromImage(_images['packages/flutter_gallery_assets/grain.png'])
      ..position = _kCenterPoint;
    clippingLayer.addChild(grain);

    userInteractionEnabled = true;
  }

  final ImageMap _images;
  final Layer clippingLayer = new Layer();
  final _PaperAnimation paperAnimation = new _PaperAnimation();

  @override
  void spriteBoxPerformedLayout() {
    clippingLayer.layerRect = spriteBox.visibleArea;
  }
}

final List<_PaperConfig> _kPaperConfigs = <_PaperConfig>[
  new _PaperConfig(
    color: Colors.deepPurple[500],
    startPosition: const Point(-300.0, -300.0),
    startRotation: -10.0,
    rotationSpeed: -1.0,
    parallaxDepth: 0.0,
    rect: new Rect.fromLTRB(-1024.0, -280.0, 1024.0, 280.0)
  ),
  new _PaperConfig(
    color: Colors.purple[400],
    startPosition: const Point(550.0, 0.0),
    startRotation: 45.0,
    rotationSpeed: 0.7,
    parallaxDepth: 1.0,
    rect: new Rect.fromLTRB(-512.0, -512.0, 512.0, 512.0)
  ),
  new _PaperConfig(
    color: Colors.purple[600],
    startPosition: const Point(550.0, 0.0),
    startRotation: 55.0,
    rotationSpeed: 0.9,
    parallaxDepth: 2.0,
    rect: new Rect.fromLTRB(-512.0, -512.0, 512.0, 512.0)
  ),
  new _PaperConfig(
    color: Colors.purple[700],
    startPosition: const Point(550.0, 0.0),
    startRotation: 65.0,
    rotationSpeed: 1.1,
    parallaxDepth: 3.0,
    rect: new Rect.fromLTRB(-512.0, -512.0, 512.0, 512.0)
  )
];

class _PaperAnimation extends Node {
  _PaperAnimation() {
    for (_PaperConfig config in _kPaperConfigs) {

      final _PaperSheet sheet = new _PaperSheet(config);
      final _PaperSheetShadow shadow = new _PaperSheetShadow(config);

      addChild(shadow);
      addChild(sheet);
      _sheets.add(sheet);

      shadow.constraints = <Constraint>[
        new ConstraintRotationToNodeRotation(sheet),
        new ConstraintPositionToNode(sheet, offset: const Offset(0.0, 10.0))
      ];
    }
  }

  final List<_PaperSheet> _sheets = <_PaperSheet>[];
}

class _PaperConfig {
  _PaperConfig({
    this.color,
    this.startPosition,
    this.startRotation,
    this.rotationSpeed,
    this.parallaxDepth,
    this.rect
  });

  final Color color;
  final Point startPosition;
  final double startRotation;
  final double rotationSpeed;
  final double parallaxDepth;
  final Rect rect;
}

class _PaperSheet extends Node {
  _PaperSheet(this._config) {
    _paperPaint.color = _config.color;

    position = _config.startPosition;
    rotation = _config.startRotation;
  }

  final _PaperConfig _config;
  final Paint _paperPaint = new Paint();

  @override
  void paint(Canvas canvas) {
    canvas.drawRect(_config.rect, _paperPaint);
  }

  @override
  void update(double dt) {
    rotation += _config.rotationSpeed * dt;
  }
}

class _PaperSheetShadow extends Node {
  _PaperSheetShadow(this._config) {
    _paperPaint.color = Colors.black45;
    _paperPaint.maskFilter = new MaskFilter.blur(BlurStyle.normal, 10.0);
  }

  final _PaperConfig _config;
  final Paint _paperPaint = new Paint();

  @override
  void paint(Canvas canvas) {
    canvas.drawRect(_config.rect, _paperPaint);
  }
}

class _BackgroundBox extends Node {
  final Paint _boxPaint = new Paint()..color = Colors.purple[500];

  @override
  void paint(Canvas canvas) {
    canvas.drawRect(new Rect.fromLTWH(0.0, 0.0, _kCanvasSize.width, _kCanvasSize.height), _boxPaint);
  }
}