| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- import 'package:flutter/material.dart';
- import 'package:get/get.dart';
- import '../../styles/theme.dart';
- class Ruler extends StatelessWidget{
- const Ruler({
- super.key,
- required this.hideHeight,
- required this.mapScale});
- final double hideHeight;
- final double mapScale;
- @override
- Widget build(BuildContext context) {
- return CustomPaint(
- size: Size(context.width, context.height),
- painter: _RulerPainter(
- hideHeight: hideHeight,
- mapScale: mapScale
- ),
- );
- }
- }
- class _Scale{
- var text = '';
- var px = 0.0;
- var meter = 0;
- _Scale(this.text, this.px, this.meter);
- }
- class _RulerPainter extends CustomPainter {
- _RulerPainter({
- required this.hideHeight,
- required this.mapScale,
- });
- final double hideHeight;
- final double mapScale;
- static const Color _color = Colors.black;
- final painter = Paint()
- ..color = _color
- ..strokeWidth = 1.5;
- final textPainter = TextPainter(
- textDirection: TextDirection.ltr,
- textAlign: TextAlign.center,
- );
- final path = Path();
- @override
- void paint(Canvas canvas, Size size) {
- final centerX = size.width/2;
- const arrowHeight = 24.0;
- canvas.drawLine(Offset(centerX, arrowHeight), Offset(centerX, size.height - hideHeight), painter);
- final oneScale = _getScale();
- const steps = 10.0;
- double heightLeft = size.height;
- final scaleXLeft = centerX-5;
- final scaleXRight = centerX + 5;
- final littleScale = oneScale.px / steps;
- final littleScaleXLeft = scaleXLeft + 2;
- final littleScaleXRight = scaleXRight - 2;
- path.moveTo(centerX, 0);
- path.lineTo(centerX + 5, arrowHeight);
- path.lineTo(centerX - 5, arrowHeight);
- path.close();
- canvas.drawPath(path, painter);
- for(var i = 0; heightLeft > arrowHeight + 1;i++){
- if(size.height - heightLeft < hideHeight){
- heightLeft -= littleScale;
- continue;
- }
- if(i % steps == 0){
- canvas.drawLine(Offset(scaleXLeft, heightLeft), Offset(scaleXRight, heightLeft), painter);
- textPainter.text = TextSpan(
- text: _meterToStr(i ~/ steps * oneScale.meter),
- style: const TextStyle(
- color: _color,
- fontSize: 14,
- fontWeight: FontWeight.w500,
- ),
- );
- textPainter.layout();
- Offset labelOffset =
- Offset(
- centerX + 10,
- heightLeft - textPainter.height / 2);
- textPainter.paint(canvas, labelOffset);
- }else{
- canvas.drawLine(Offset(littleScaleXLeft, heightLeft), Offset(littleScaleXRight, heightLeft), painter);
- }
- heightLeft -= littleScale;
- }
- }
- @override
- bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
- _Scale? _getOneScaleLen(int meter) {
- var valuePx = meter * mapScale;
- if (valuePx > 100) {
- return _Scale(_meterToStr(meter), valuePx, meter);
- }
- return null;
- }
- String _meterToStr(int meter){
- if(meter < 1000){
- return '$meter m';
- }else{
- return "${(meter.toDouble()/1000).toStringAsFixed(1)} km";
- }
- }
- _Scale _getScale() {
- var s = 1;
- _Scale? out;
- while(out == null){
- out = _getOneScaleLen(5 * s);
- if (out != null) {
- return out;
- }
- out = _getOneScaleLen(10 * s);
- if (out != null) {
- return out;
- }
- out = _getOneScaleLen(20 * s);
- if (out != null) {
- return out;
- }
- s *= 10;
- }
- return out;
- }
- }
- void main() async {
- runApp(GetMaterialApp(
- theme: appThemeData(),
- home: const Scaffold(
- body: Ruler(hideHeight: 20, mapScale: 1),
- )));
- }
|