scale.dart 2.14 KB
Newer Older
1 2 3 4
// Copyright 2015 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
import 'package:sky/material.dart';
6
import 'package:sky/rendering.dart';
7
import 'package:sky/widgets.dart';
8

9
class ScaleApp extends StatefulComponent {
10
  ScaleAppState createState() => new ScaleAppState();
11 12
}

13
class ScaleAppState extends State<ScaleApp> {
14 15
  void initState() {
    super.initState();
16 17 18
    _offset = Offset.zero;
    _zoom = 1.0;
  }
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37

  Point _startingFocalPoint;

  Offset _previousOffset;
  Offset _offset;

  double _previousZoom;
  double _zoom;

  void _handleScaleStart(Point focalPoint) {
    setState(() {
      _startingFocalPoint = focalPoint;
      _previousOffset = _offset;
      _previousZoom = _zoom;
    });
  }

  void _handleScaleUpdate(double scale, Point focalPoint) {
    setState(() {
38 39 40 41 42
      _zoom = (_previousZoom * scale);

      // Ensure that item under the focal point stays in the same place despite zooming
      Offset normalizedOffset = (_startingFocalPoint.toOffset() - _previousOffset) / _previousZoom;
      _offset = focalPoint.toOffset() - normalizedOffset * _zoom;
43 44 45 46
    });
  }

  void paint(PaintingCanvas canvas, Size size) {
47
    Point center = (size.center(Point.origin).toOffset() * _zoom + _offset).toPoint();
48 49 50
    double radius = size.width / 2.0 * _zoom;
    Gradient gradient = new RadialGradient(
      center: center, radius: radius,
51
      colors: [Colors.blue[200], Colors.blue[800]]
52 53 54 55 56 57
    );
    Paint paint = new Paint()
      ..shader = gradient.createShader();
    canvas.drawCircle(center, radius, paint);
  }

58
  Widget build(BuildContext context) {
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
    return new Theme(
      data: new ThemeData.dark(),
      child: new Scaffold(
        toolbar: new ToolBar(
            center: new Text('Scale Demo')),
        body: new Material(
          type: MaterialType.canvas,
          child: new GestureDetector(
            onScaleStart: _handleScaleStart,
            onScaleUpdate: _handleScaleUpdate,
            child: new CustomPaint(callback: paint, token: "$_zoom $_offset")
          )
        )
      )
    );
  }
}

void main() => runApp(new ScaleApp());