Flutter全景展示插件panorama的使用

发布于 1周前 作者 htzhanglong 来自 Flutter

Flutter全景展示插件panorama的使用

Panorama

pub package

这是一个360度全景查看器。

Getting Started

要在Flutter项目中使用panorama插件,首先需要在pubspec.yaml文件中添加依赖:

dependencies:
  panorama: ^0.4.1

然后,在Dart代码中导入panorama包,并将Panorama小部件添加到您的项目中。下面是一个简单的例子:

import 'package:flutter/material.dart';
import 'package:panorama/panorama.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Panorama Example')),
        body: Center(
          child: Panorama(
            animSpeed: 1.0,
            sensorControl: SensorControl.Orientation,
            child: Image.asset('assets/panorama.jpg'),
          ),
        ),
      ),
    );
  }
}

在这个例子中,我们创建了一个包含Panorama小部件的应用程序。该小部件加载一个名为panorama.jpg的资产图片作为全景图像。animSpeed参数定义了自动旋转的速度,而sensorControl参数允许用户通过移动设备来改变视角。

示例Demo

为了更详细地了解如何使用panorama插件,这里提供一个完整的示例demo。此示例展示了如何切换不同的全景场景、添加热点以及从相册选择新的全景图。

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:panorama/panorama.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Panorama',
      theme: ThemeData.dark(),
      home: MyHomePage(title: 'Flutter Panorama'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, this.title}) : super(key: key);
  final String? title;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  double _lon = 0;
  double _lat = 0;
  double _tilt = 0;
  int _panoId = 0;
  List<Image> panoImages = [
    Image.asset('assets/panorama.jpg'),
    Image.asset('assets/panorama2.webp'),
    Image.asset('assets/panorama_cropped.webp'),
  ];
  ImagePicker picker = ImagePicker();

  void onViewChanged(longitude, latitude, tilt) {
    setState(() {
      _lon = longitude;
      _lat = latitude;
      _tilt = tilt;
    });
  }

  Widget hotspotButton({String? text, IconData? icon, VoidCallback? onPressed}) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        TextButton(
          style: ButtonStyle(
            shape: MaterialStateProperty.all(CircleBorder()),
            backgroundColor: MaterialStateProperty.all(Colors.black38),
            foregroundColor: MaterialStateProperty.all(Colors.white),
          ),
          child: Icon(icon),
          onPressed: onPressed,
        ),
        text != null
            ? Container(
                padding: EdgeInsets.all(4.0),
                decoration: BoxDecoration(color: Colors.black38, borderRadius: BorderRadius.all(Radius.circular(4))),
                child: Center(child: Text(text)),
              )
            : Container(),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    Widget panorama;
    switch (_panoId % panoImages.length) {
      case 0:
        panorama = Panorama(
          animSpeed: 1.0,
          sensorControl: SensorControl.Orientation,
          onViewChanged: onViewChanged,
          onTap: (longitude, latitude, tilt) => print('onTap: $longitude, $latitude, $tilt'),
          onLongPressStart: (longitude, latitude, tilt) => print('onLongPressStart: $longitude, $latitude, $tilt'),
          onLongPressMoveUpdate: (longitude, latitude, tilt) => print('onLongPressMoveUpdate: $longitude, $latitude, $tilt'),
          onLongPressEnd: (longitude, latitude, tilt) => print('onLongPressEnd: $longitude, $latitude, $tilt'),
          child: Image.asset('assets/panorama.jpg'),
          hotspots: [
            Hotspot(
              latitude: -15.0,
              longitude: -129.0,
              width: 90,
              height: 75,
              widget: hotspotButton(text: "Next scene", icon: Icons.open_in_browser, onPressed: () => setState(() => _panoId++)),
            ),
            Hotspot(
              latitude: -42.0,
              longitude: -46.0,
              width: 60.0,
              height: 60.0,
              widget: hotspotButton(icon: Icons.search, onPressed: () => setState(() => _panoId = 2)),
            ),
            Hotspot(
              latitude: -33.0,
              longitude: 123.0,
              width: 60.0,
              height: 60.0,
              widget: hotspotButton(icon: Icons.arrow_upward, onPressed: () {}),
            ),
          ],
        );
        break;
      case 2:
        panorama = Panorama(
          animSpeed: 1.0,
          sensorControl: SensorControl.Orientation,
          onViewChanged: onViewChanged,
          croppedArea: Rect.fromLTWH(2533.0, 1265.0, 5065.0, 2533.0),
          croppedFullWidth: 10132.0,
          croppedFullHeight: 5066.0,
          child: Image.asset('assets/panorama_cropped.jpg'),
          hotspots: [
            Hotspot(
              latitude: 0.0,
              longitude: -46.0,
              width: 90.0,
              height: 75.0,
              widget: hotspotButton(text: "Next scene", icon: Icons.double_arrow, onPressed: () => setState(() => _panoId++)),
            ),
          ],
        );
        break;
      default:
        panorama = Panorama(
          animSpeed: 1.0,
          sensorControl: SensorControl.Orientation,
          onViewChanged: onViewChanged,
          child: panoImages[_panoId % panoImages.length],
          hotspots: [
            Hotspot(
              latitude: 0.0,
              longitude: 160.0,
              width: 90.0,
              height: 75.0,
              widget: hotspotButton(text: "Next scene", icon: Icons.double_arrow, onPressed: () => setState(() => _panoId++)),
            ),
          ],
        );
    }
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title!),
      ),
      body: Stack(
        children: [
          panorama,
          Text('${_lon.toStringAsFixed(3)}, ${_lat.toStringAsFixed(3)}, ${_tilt.toStringAsFixed(3)}'),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        mini: true,
        onPressed: () async {
          final pickedFile = await picker.getImage(source: ImageSource.gallery);
          setState(() {
            if (pickedFile != null) {
              panoImages.add(Image.file(File(pickedFile.path)));
              _panoId = panoImages.length - 1;
            }
          });
        },
        child: Icon(Icons.panorama),
      ),
    );
  }
}

这个例子包括了以下功能:

  • 切换场景:通过点击热点按钮可以在不同全景图之间切换。
  • 热点:在全景图上添加交互式热点,可以触发特定的操作(如导航到下一个场景)。
  • 从相册选择新全景图:通过浮动按钮可以从设备相册中选择新的全景图并添加到应用中。

使用教程

如果您想了解更多关于panorama插件的用法,可以参考以下资源:

希望这些信息对您有所帮助!如果有任何问题或需要进一步的帮助,请随时提问。


更多关于Flutter全景展示插件panorama的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter全景展示插件panorama的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter中使用panorama插件来实现全景展示的示例代码。为了这个示例,我们假设你已经在你的Flutter项目中添加了panorama依赖,并且已经运行了flutter pub get来安装它。

首先,你需要在你的pubspec.yaml文件中添加panorama依赖:

dependencies:
  flutter:
    sdk: flutter
  panorama: ^最新版本号  # 请替换为实际的最新版本号

然后,你可以在你的Flutter应用中按照以下步骤使用panorama插件:

  1. 导入必要的包
import 'package:flutter/material.dart';
import 'package:panorama/panorama.dart';
  1. 创建一个全景页面
class PanoramaPage extends StatefulWidget {
  @override
  _PanoramaPageState createState() => _PanoramaPageState();
}

class _PanoramaPageState extends State<PanoramaPage> {
  PanoramaController? _controller;

  @override
  void initState() {
    super.initState();
    // 初始化PanoramaController,并加载全景图片
    _controller = PanoramaController(
      imageProvider: AssetImage('assets/panorama.jpg'), // 请确保你已经在pubspec.yaml中声明了这个资产
    )..addListener(() {
        // 监听控制器状态变化,例如加载完成
        if (_controller!.state == PanoramaState.loaded) {
          print('Panorama loaded');
        }
      });
  }

  @override
  void dispose() {
    _controller?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Panorama Demo'),
      ),
      body: Center(
        child: PanoramaWidget(
          controller: _controller!,
        ),
      ),
    );
  }
}
  1. 确保你的资产文件(全景图片)已被正确声明

pubspec.yaml中的flutter部分添加你的资产:

flutter:
  assets:
    - assets/panorama.jpg  # 确保这个路径是正确的
  1. 运行你的应用

现在你可以运行你的Flutter应用,并应该能够在PanoramaPage页面上看到一个可交互的全景图片。

这是一个基本的示例,展示了如何使用panorama插件来加载和显示一个全景图片。PanoramaController提供了更多的功能,比如设置热点、添加交互等,你可以根据插件的文档进一步探索这些功能。

请注意,实际使用中可能需要根据插件的最新文档调整代码,因为插件的API可能会随着版本更新而变化。

回到顶部