Last active
August 25, 2023 23:56
-
-
Save hukusuke1007/3ba8f2b29a0c8195d0e51f9b6754b166 to your computer and use it in GitHub Desktop.
タコメーター
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import 'package:flutter/material.dart'; | |
| import 'dart:math'; | |
| void main() { | |
| runApp(MyApp()); | |
| } | |
| class MyApp extends StatelessWidget { | |
| @override | |
| Widget build(BuildContext context) { | |
| return MaterialApp( | |
| debugShowCheckedModeBanner: false, | |
| title: 'Flutter Demo', | |
| theme: ThemeData( | |
| primarySwatch: Colors.blue, | |
| ), | |
| home: MyHomePage(), | |
| ); | |
| } | |
| } | |
| class MyHomePage extends StatelessWidget { | |
| @override | |
| Widget build(BuildContext context) { | |
| return Scaffold( | |
| body: Padding( | |
| padding: EdgeInsets.all(16), | |
| child: AnimatedEngineMeter(targetValue: 0.3), | |
| ), | |
| ); | |
| } | |
| } | |
| class AnimatedEngineMeter extends StatelessWidget { | |
| const AnimatedEngineMeter({required this.targetValue}); | |
| final double targetValue; | |
| @override | |
| Widget build(BuildContext context) { | |
| return TweenAnimationBuilder<double>( | |
| tween: Tween(begin: 0.0, end: targetValue), | |
| duration: const Duration(seconds: 2), | |
| builder: (context, value, child) { | |
| return Tachometer(rpmValue: value); | |
| }, | |
| ); | |
| } | |
| } | |
| class Tachometer extends StatelessWidget { | |
| const Tachometer({required this.rpmValue}); | |
| final double rpmValue; // 0.0から1.0までの値。例:0.5は50%のRPMを示す | |
| @override | |
| Widget build(BuildContext context) { | |
| return CustomPaint( | |
| painter: TachometerPainter(rpmValue), | |
| size: const Size(300, 200), // こちらのサイズは適宜調整してください | |
| ); | |
| } | |
| } | |
| class TachometerPainter extends CustomPainter { | |
| const TachometerPainter(this.rpmValue); | |
| final double rpmValue; | |
| @override | |
| void paint(Canvas canvas, Size size) { | |
| final center = Offset(size.width / 2, size.height); | |
| final radius = size.width / 2 - 20; | |
| // 半円背景の描画 | |
| final bgPaint = Paint()..color = Colors.black; | |
| canvas.drawArc( | |
| Rect.fromCircle(center: center, radius: radius), | |
| pi, | |
| pi, | |
| false, | |
| bgPaint, | |
| ); | |
| // 数値メモリとラベルの描画 | |
| final memPaint = Paint() | |
| ..color = Colors.white | |
| ..strokeWidth = 2.0; | |
| final textPainter = TextPainter( | |
| textDirection: TextDirection.ltr, | |
| ); | |
| const totalMarks = 9; | |
| const startAngle = 1.1 * pi; // 開始角度を調整 | |
| const endAngle = 1.9 * pi; // 終了角度を調整 | |
| for (int i = 0; i <= totalMarks; i++) { | |
| // メモリの線を描画 | |
| var angle = startAngle + (endAngle - startAngle) * (i / totalMarks); | |
| final start = Offset( | |
| center.dx + (radius - 10) * cos(angle), | |
| center.dy + (radius - 10) * sin(angle), | |
| ); | |
| final end = Offset( | |
| center.dx + radius * cos(angle), | |
| center.dy + radius * sin(angle), | |
| ); | |
| canvas.drawLine(start, end, memPaint); | |
| // メモリの数値ラベルの描画 | |
| textPainter.text = TextSpan( | |
| text: '${i * 20}', | |
| style: const TextStyle(color: Colors.white, fontSize: 12.0), | |
| ); | |
| textPainter.layout(); | |
| textPainter.paint( | |
| canvas, | |
| Offset( | |
| center.dx + (radius - 30) * cos(angle) - textPainter.width / 2, | |
| center.dy + (radius - 30) * sin(angle) - textPainter.height / 2, | |
| ), | |
| ); | |
| } | |
| // 針の描画 | |
| final angle = startAngle + (endAngle - startAngle) * rpmValue; | |
| final needleEnd = Offset( | |
| center.dx + (radius - 20) * cos(angle), | |
| center.dy + (radius - 20) * sin(angle), | |
| ); | |
| final needlePaint = Paint() | |
| ..color = Colors.red | |
| ..style = PaintingStyle.stroke | |
| ..strokeWidth = 5.0; | |
| canvas.drawLine(center, needleEnd, needlePaint); | |
| } | |
| @override | |
| bool shouldRepaint(TachometerPainter oldDelegate) { | |
| print("oldDelegate.rpmValue ${oldDelegate.rpmValue}"); | |
| return oldDelegate.rpmValue != rpmValue; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment