ponshu-room-lite/lib/screens/camera_exposure_painter.dart

71 lines
2.0 KiB
Dart
Raw Normal View History

import 'package:flutter/material.dart';
/// カメラ画面右端の露出スライダーを描画する CustomPainter。
///
/// - 縦トラック(白半透明)
/// - 中央基準線0 EV を示すマーカー)
/// - 現在値を示すノブ(影付き白丸)
class ExposureSliderPainter extends CustomPainter {
final double currentValue;
final double minValue;
final double maxValue;
const ExposureSliderPainter({
required this.currentValue,
required this.minValue,
required this.maxValue,
});
@override
void paint(Canvas canvas, Size size) {
final trackPaint = Paint()
..color = Colors.white.withValues(alpha: 0.3)
..strokeWidth = 4
..strokeCap = StrokeCap.round;
final centerLinePaint = Paint()
..color = Colors.white54
..strokeWidth = 2;
final knobPaint = Paint()
..color = Colors.white
..style = PaintingStyle.fill;
final knobShadowPaint = Paint()
..color = Colors.black26
..maskFilter = const MaskFilter.blur(BlurStyle.normal, 4);
// 縦トラック(中央線)
final trackX = size.width / 2;
canvas.drawLine(
Offset(trackX, 10),
Offset(trackX, size.height - 10),
trackPaint,
);
// 0 EV マーカー
canvas.drawLine(
Offset(trackX - 6, size.height / 2),
Offset(trackX + 6, size.height / 2),
centerLinePaint,
);
// ノブ位置を算出
final range = maxValue - minValue;
if (range > 0) {
// minValue(下端) → 0.0、maxValue(上端) → 1.0 に正規化してY座標に変換
final normalized = (currentValue - minValue) / range;
final knobY = (size.height - 20) * (1.0 - normalized) + 10;
canvas.drawCircle(Offset(trackX, knobY), 7, knobShadowPaint);
canvas.drawCircle(Offset(trackX, knobY), 6, knobPaint);
}
}
@override
bool shouldRepaint(ExposureSliderPainter oldDelegate) {
return oldDelegate.currentValue != currentValue ||
oldDelegate.minValue != minValue ||
oldDelegate.maxValue != maxValue;
}
}