Масштабирование флаттера векторных фигур

Чтобы нарисовать кривую Лиссажу, мы создаем в LissajousAppa и инициализировать в виджете объект для некоторых постоянных значений (3, 4).

Мы хотели бы подать заявку FittedBox с участием BoxFit.contain в LissajousWidget при следующих ограничениях:

  • Мы не можем воссоздать объект. Учтите, что стоимость его создания слишком высока для повторного запуска.
  • В LissajousCurveимеет особое соотношение сторон. Он должен отображаться с таким соотношением сторон.
  • Растеризация должна выполняться после масштабирования, чтобы заполнить холст, а не до этого.

Первое ограничение означает, что если мы flutter run -d chrome и измените размер браузера, мы должны увидеть LissajousCurve.LissajousCurve... а также _LissajousWidgetState.build() только один раз.

      Performing hot restart...                                          105ms
Restarted application in 105ms.
LissajousCurve.LissajousCurve...
_LissajousWidgetState.build()
LissajousPainter.paint()...
LissajousPainter.paint()...
LissajousPainter.paint()...

Второе ограничение означает, что независимо от соотношения сторон окна просмотра соотношение сторон кривой должно сохраняться. Третий гарантирует, что мы не увидим артефактов сглаживания.

Как в настоящее время лучше всего удовлетворить эти три ограничения?

      import 'package:flutter/material.dart';
import 'dart:math' as math;
import 'dart:ui';

void main() => runApp(LissajousApp());

class LissajousApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return LissajousWidget(LissajousCurve(3, 4));
  }
}

class LissajousWidget extends StatefulWidget {
  LissajousCurve lissajousCurve;

  LissajousWidget(this.lissajousCurve) {}
  @override
  _LissajousWidgetState createState() => _LissajousWidgetState();
}

class _LissajousWidgetState extends State<LissajousWidget> {
  @override
  Widget build(BuildContext context) {
    print('_LissajousWidgetState.build()');
    return CustomPaint(painter: LissajousPainter(widget.lissajousCurve));
  }
}

class LissajousCurve {
  Path path;
  LissajousCurve(int a, int b) {
    print('LissajousCurve.LissajousCurve...');
    path = Path();
    final int N = 10000;
    final tValues = List.generate(N, (i) => -2 * math.pi + 6 * math.pi * i / N);

    final xValues = tValues.map((t) => 30 * math.sin(3 * t)).toList();
    final yValues = tValues.map((t) => 20 * math.sin(4 * t)).toList();

    final points = List.generate(N, (i) {
      return Offset(xValues[i], yValues[i]);
    });
    path = Path();
    path.moveTo(points[0].dx, points[1].dy);
    for (var i = 0; i < N; i++) {
      path.lineTo(points[i].dx, points[i].dy);
    }
    path.close();
  }
}

class LissajousPainter extends CustomPainter {
  final LissajousCurve lissajousCurve;
  LissajousPainter(this.lissajousCurve);
  @override
  void paint(Canvas canvas, Size size) {
    print('LissajousPainter.paint()...');
    final paint = Paint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = 4
      ..color = Colors.indigo;
    canvas.drawPath(lissajousCurve.path, paint);
  }

  @override
  bool shouldRepaint(LissajousPainter oldDelegate) => false;
}

0 ответов

Другие вопросы по тегам