blob: 7ce75cdfc92bd469631ea1b195add075488ae072 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. 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:math';
import 'package:flutter/widgets.dart';
import 'package:meta/meta.dart';
/// 60-30 isometric projection matrix
final Matrix4 _iso = Matrix4.identity()
..rotateX(60 * pi / 180.0)
..rotateZ(30 * pi / 180.0);
/// Widget that performs an isometric transformation on a Widget,
/// scaling it so that it fits within the bounds of its original rectangle
class IsoMetric extends StatelessWidget {
/// The child to transform
final Widget child;
/// This size to draw the widget in orthographic projection
final double scaleFactor;
/// Constructor
const IsoMetric({@required this.child, this.scaleFactor = 4.0});
@override
Widget build(BuildContext context) => LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
BoxConstraints _scaledConstraints = constraints * scaleFactor;
return FittedBox(
fit: BoxFit.scaleDown,
child: Container(
constraints: _scaledConstraints,
child: Transform(
child: child,
transform: _getTransformation(constraints: _scaledConstraints),
origin: _scaledConstraints.biggest.center(Offset.zero),
),
),
);
},
);
/// Get the isometric transformation to apply to the views
Matrix4 _getTransformation({BoxConstraints constraints}) {
// Scale the transformation so the views fit in the original rectangles
Rect constraintsRect = Offset.zero & constraints.biggest;
Rect transRect = MatrixUtils.transformRect(
_iso,
constraintsRect,
);
double isoScale = min(constraintsRect.height / transRect.height,
constraintsRect.width / transRect.width);
return Matrix4.copy(_iso)..scale(isoScale);
}
}