refactor: ExposureSliderPainter を別ファイルに切り出し
camera_screen.dart の末尾にあった _ExposureSliderPainter (60行) を lib/screens/camera_exposure_painter.dart に分離。 動作変更なし。718行 → 659行。 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
b7f5edf9a9
commit
cc5175ebae
|
|
@ -0,0 +1,70 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@ import 'package:image_picker/image_picker.dart'; // Gallery & Camera
|
|||
import '../services/image_compression_service.dart';
|
||||
import '../theme/app_colors.dart';
|
||||
import 'camera_analysis_mixin.dart';
|
||||
import 'camera_exposure_painter.dart';
|
||||
|
||||
|
||||
enum CameraMode {
|
||||
|
|
@ -475,8 +476,8 @@ class _CameraScreenState extends ConsumerState<CameraScreen> with SingleTickerPr
|
|||
height: 180,
|
||||
width: 48, // Wider for easier tapping
|
||||
child: CustomPaint(
|
||||
key: ValueKey(_currentExposureOffset), // Force repaint on value change
|
||||
painter: _ExposureSliderPainter(
|
||||
key: ValueKey(_currentExposureOffset),
|
||||
painter: ExposureSliderPainter(
|
||||
currentValue: _currentExposureOffset,
|
||||
minValue: _minExposure,
|
||||
maxValue: _maxExposure,
|
||||
|
|
@ -656,63 +657,3 @@ class _CameraScreenState extends ConsumerState<CameraScreen> with SingleTickerPr
|
|||
|
||||
}
|
||||
|
||||
// Custom Painter for Exposure Slider
|
||||
class _ExposureSliderPainter extends CustomPainter {
|
||||
final double currentValue;
|
||||
final double minValue;
|
||||
final double maxValue;
|
||||
|
||||
_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); // Draw vertical track (centered)
|
||||
final trackX = size.width / 2;
|
||||
canvas.drawLine(
|
||||
Offset(trackX, 10),
|
||||
Offset(trackX, size.height - 10),
|
||||
trackPaint,
|
||||
); // Draw center marker
|
||||
canvas.drawLine(
|
||||
Offset(trackX - 6, size.height / 2),
|
||||
Offset(trackX + 6, size.height / 2),
|
||||
centerLinePaint,
|
||||
); // Calculate knob position
|
||||
final range = maxValue - minValue;
|
||||
if (range > 0) {
|
||||
// Normalize currentValue to 0.0-1.0 range
|
||||
// minValue (e.g., -4.0) -> 0.0 (bottom)
|
||||
// 0.0 (center) -> 0.5 (middle)
|
||||
// maxValue (e.g., +4.0) -> 1.0 (top)
|
||||
final normalized = (currentValue - minValue) / range;
|
||||
// Map to Y coordinate: 0.0 (normalized) -> bottom, 1.0 (normalized) -> top
|
||||
final knobY = (size.height - 20) * (1.0 - normalized) + 10;
|
||||
// Draw knob shadow
|
||||
canvas.drawCircle(Offset(trackX, knobY), 7, knobShadowPaint);
|
||||
// Draw knob
|
||||
canvas.drawCircle(Offset(trackX, knobY), 6, knobPaint);
|
||||
}
|
||||
} @override
|
||||
bool shouldRepaint(_ExposureSliderPainter oldDelegate) {
|
||||
return oldDelegate.currentValue != currentValue ||
|
||||
oldDelegate.minValue != minValue ||
|
||||
oldDelegate.maxValue != maxValue;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
# In Windows, build-name is used as the major, minor, and patch parts
|
||||
# of the product and file versions while build-number is used as the build suffix.
|
||||
version: 1.0.41+48
|
||||
version: 1.0.42+49
|
||||
|
||||
environment:
|
||||
sdk: ^3.10.1
|
||||
|
|
|
|||
Loading…
Reference in New Issue