import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:smtias_capture/models/preview_region.dart';
/// 表示向き適用済みの全体コンテンツ [child] を [region](表示後の画面座標 0.0–1.0)で
/// 切り出して画面いっぱいに拡大表示する(WYSIWYG).
///
/// ライブプレビュー([child] = CameraPreview)と保存中スナップショット
/// ([child] = 画像)で共通利用し,同じ領域・同じ拡大で表示を一致させる.
class RegionCrop extends StatelessWidget {
const RegionCrop({super.key, required this.region, required this.child});
/// クロップ領域(表示後の画面座標 0.0–1.0).
final PreviewRegion region;
/// クロップ対象(表示向き適用済みで領域全体を埋めるコンテンツ).
final Widget child;
@override
Widget build(BuildContext context) {
if (region.isFull) {
return child;
}
return LayoutBuilder(
builder: (context, constraints) {
final double w = constraints.maxWidth;
final double h = constraints.maxHeight;
final double roiCx = (region.left + region.right) / 2.0;
final double roiCy = (region.top + region.bottom) / 2.0;
// ROI 中心を画面中心へ寄せる平行移動量(画面ピクセル)
final double dx = (0.5 - roiCx) * w;
final double dy = (0.5 - roiCy) * h;
// ROI 全体を画面に収める contain ズーム(縦横同一スケールで歪み防止)
final double zoom = math.min(1.0 / region.width, 1.0 / region.height);
return ClipRect(
child: Transform.scale(
scale: zoom,
alignment: Alignment.center,
child: Transform.translate(
offset: Offset(dx, dy),
child: SizedBox(width: w, height: h, child: child),
),
),
);
},
);
}
}