You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter中显示太阳方向箭头及逐小时太阳路径

太阳走向示意图

在Flutter中实现指定地点太阳走向可视化

一、核心:计算太阳轨迹数据

要实现图中效果,首先得根据目标地点的经纬度、指定日期,计算太阳在不同时间点的位置参数。可以直接用Dart的suncalc库(对应前端同名库的dart实现),它能快速生成任意经纬度、时间下太阳的方位角、高度角。我们只需要按固定时间间隔(比如每30分钟)生成一系列时间点,算出每个点的太阳位置,就能得到轨迹的原始数据。

二、用CustomPainter绘制轨迹UI

Flutter的自定义绘制是实现这个效果的关键,通过CustomPainter可以精准控制轨迹线和关键节点:

  • 把计算得到的太阳方位、高度数据转换成画布坐标:以画布中心为原点,将方位角映射为角度,高度角映射到径向距离,得到屏幕上的Offset点集合。
  • 用Path连接所有点绘制轨迹曲线,再给日出、正午、日落这些关键节点添加标记和文字标注。

基础绘制代码示例

class SunTrackPainter extends CustomPainter {
  final List<Offset> trackPoints;
  final Offset sunrise;
  final Offset noon;
  final Offset sunset;

  SunTrackPainter({
    required this.trackPoints,
    required this.sunrise,
    required this.noon,
    required this.sunset,
  });

  @override
  void paint(Canvas canvas, Size size) {
    // 绘制轨迹线
    final trackPaint = Paint()
      ..color = const Color(0xFFFF9800)
      ..strokeWidth = 2.5
      ..style = PaintingStyle.stroke;
    
    final path = Path();
    if (trackPoints.isNotEmpty) {
      path.moveTo(trackPoints.first.dx, trackPoints.first.dy);
      for (var point in trackPoints.skip(1)) {
        path.lineTo(point.dx, point.dy);
      }
    }
    canvas.drawPath(path, trackPaint);

    // 绘制关键节点
    final nodePaint = Paint()..color = const Color(0xFFF44336);
    canvas.drawCircle(sunrise, 4, nodePaint);
    canvas.drawCircle(noon, 4, nodePaint);
    canvas.drawCircle(sunset, 4, nodePaint);

    // 添加节点文字标注
    _drawText(canvas, '日出', Offset(sunrise.dx + 8, sunrise.dy));
    _drawText(canvas, '正午', Offset(noon.dx + 8, noon.dy));
    _drawText(canvas, '日落', Offset(sunset.dx + 8, sunset.dy));
  }

  void _drawText(Canvas canvas, String text, Offset offset) {
    final textPainter = TextPainter(
      text: TextSpan(
        text: text,
        style: const TextStyle(color: Colors.black, fontSize: 12),
      ),
      textDirection: TextDirection.ltr,
    );
    textPainter.layout();
    textPainter.paint(canvas, offset);
  }

  @override
  bool shouldRepaint(SunTrackPainter oldDelegate) {
    return trackPoints != oldDelegate.trackPoints;
  }
}

三、地点搜索转经纬度

用户输入地点名称后,调用地理编码API(比如主流地图SDK提供的接口)把地名转换成经纬度坐标,拿到坐标后传入太阳位置计算逻辑,更新轨迹数据,最后触发CustomPainter重绘,就能显示对应地点的太阳走向了。


内容的提问来源于stack exchange,提问作者Jay Tarpara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 23:15:19