71 lines
2.0 KiB
Dart
71 lines
2.0 KiB
Dart
|
|
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;
|
|||
|
|
}
|
|||
|
|
}
|