canvas_danmaku 0.2.4 copy "canvas_danmaku: ^0.2.4" to clipboard
canvas_danmaku: ^0.2.4 copied to clipboard

A high performance danmaku lib for flutter.

example/lib/main.dart

import 'dart:io';
import 'dart:async';
import 'dart:convert';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:canvas_danmaku/canvas_danmaku.dart';

import 'package:flutter/services.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'CanvasDanmaku Demo',
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  HomePage({Key? key}) : super(key: key);

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  late DanmakuController _controller;
  var _key = new GlobalKey<ScaffoldState>();

  final _danmuKey = GlobalKey();

  bool _running = true;

  /// 弹幕描边
  bool _showStroke = true;

  /// 弹幕海量模式(弹幕轨道填满时继续绘制)
  bool _massiveMode = false;

  /// 弹幕透明度
  double _opacity = 1.0;

  /// 弹幕持续时间
  int _duration = 8;

  /// 弹幕字号
  double _fontSize = (Platform.isIOS || Platform.isAndroid) ? 16 : 25;

  /// 弹幕粗细
  int _fontWeight = 4;

  /// 隐藏滚动弹幕
  bool _hideScroll = false;

  /// 隐藏顶部弹幕
  bool _hideTop = false;

  /// 隐藏底部弹幕
  bool _hideBottom = false;

  /// 为字幕预留空间
  bool _safeArea = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _key,
      appBar: AppBar(
        title: Text('CanvasDanmaku Demo'),
      ),
      body: Column(
        children: [
          Wrap(
            children: [
              IconButton(
                icon: Icon(Icons.add),
                tooltip: 'Add Scroll',
                onPressed: () {
                  _controller.addDanmaku(
                    DanmakuContentItem(
                        "这是一条超长弹幕ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789这是一条超长的弹幕,这条弹幕会超出屏幕宽度",
                        color: getRandomColor()),
                  );
                },
              ),
              IconButton(
                icon: Icon(Icons.add),
                tooltip: 'Add Top',
                onPressed: () {
                  _controller.addDanmaku(
                    DanmakuContentItem("这是一条顶部弹幕",
                        color: getRandomColor(), type: DanmakuItemType.top),
                  );
                },
              ),
              IconButton(
                icon: Icon(Icons.add),
                tooltip: 'Add Bottom',
                onPressed: () {
                  _controller.addDanmaku(
                    DanmakuContentItem("这是一条底部弹幕",
                        color: getRandomColor(), type: DanmakuItemType.bottom),
                  );
                },
              ),
              IconButton(
                icon: Icon(Icons.add),
                tooltip: 'Add Bottom',
                onPressed: () {
                  _controller.addDanmaku(
                    DanmakuContentItem("这是一条自己发的弹幕",
                        color: getRandomColor(),
                        type: DanmakuItemType.scroll,
                        selfSend: true),
                  );
                },
              ),
              IconButton(
                icon: Icon(Icons.play_circle_outline_outlined),
                onPressed: startPlay,
                tooltip: 'Start Player',
              ),
              IconButton(
                icon: Icon(_running ? Icons.pause : Icons.play_arrow),
                onPressed: () {
                  if (_running) {
                    _controller.pause();
                  } else {
                    _controller.resume();
                  }
                  setState(() {
                    _running = !_running;
                  });
                },
                tooltip: 'Play Resume',
              ),
              IconButton(
                icon: Icon(_showStroke
                    ? Icons.font_download
                    : Icons.font_download_rounded),
                onPressed: () {
                  _controller.updateOption(
                      _controller.option.copyWith(showStroke: !_showStroke));
                  setState(() {
                    _showStroke = !_showStroke;
                  });
                },
                tooltip: 'Stroke',
              ),
              IconButton(
                icon: Icon(Icons.clear),
                onPressed: () {
                  _controller.clear();
                },
                tooltip: 'Clear',
              ),
            ],
          ),
          Expanded(
              child: Container(
            color: Colors.grey,
            child: DanmakuScreen(
              key: _danmuKey,
              createdController: (DanmakuController e) {
                _controller = e;
              },
              option: DanmakuOption(
                opacity: _opacity,
                fontSize: _fontSize,
                fontWeight: _fontWeight,
                duration: _duration,
                showStroke: _showStroke,
                massiveMode: _massiveMode,
                hideScroll: _hideScroll,
                hideTop: _hideTop,
                hideBottom: _hideBottom,
                safeArea: _safeArea,
              ),
            ),
          )),
        ],
      ),
      endDrawer: Drawer(
        child: SafeArea(
          child: ListView(
            padding: EdgeInsets.all(8),
            children: [
              Text("Opacity : $_opacity"),
              Slider(
                value: _opacity,
                max: 1.0,
                min: 0.1,
                divisions: 9,
                onChanged: (e) {
                  setState(() {
                    _opacity = e;
                  });
                  _controller
                      .updateOption(_controller.option.copyWith(opacity: e));
                },
              ),
              Text("FontSize : $_fontSize"),
              Slider(
                value: _fontSize,
                min: 8,
                max: 36,
                divisions: 14,
                onChanged: (e) {
                  setState(() {
                    _fontSize = e;
                  });
                  _controller
                      .updateOption(_controller.option.copyWith(fontSize: e));
                },
              ),
              Text("Duration : $_duration"),
              Slider(
                value: _duration.toDouble(),
                min: 4,
                max: 20,
                divisions: 16,
                onChanged: (e) {
                  setState(() {
                    _duration = e.toInt();
                  });
                  _controller.updateOption(
                      _controller.option.copyWith(duration: e.toInt()));
                },
              ),
              SwitchListTile(
                  title: const Text('MassiveMode'),
                  value: _massiveMode,
                  onChanged: (e) {
                    setState(() {
                      _massiveMode = e;
                    });
                    _controller.updateOption(
                        _controller.option.copyWith(massiveMode: e));
                  }),
              SwitchListTile(
                  title: const Text('SafeArea'),
                  value: _safeArea,
                  onChanged: (e) {
                    setState(() {
                      _safeArea = e;
                    });
                    _controller
                        .updateOption(_controller.option.copyWith(safeArea: e));
                  })
            ],
          ),
        ),
      ),
    );
  }

  Timer? timer;
  int sec = 0;
  void startPlay() async {
    String data = await rootBundle.loadString('assets/132590001.json');
    List<DanmakuContentItem> _items = [];
    var jsonMap = json.decode(data);
    for (var item in jsonMap['comments']) {
      _items.add(DanmakuContentItem(
        item['m'],
        color: Colors.white,
      ));
    }
    if (timer == null) {
      timer = Timer.periodic(Duration(seconds: 1), (timer) {
        if (!_controller.running) return;
        _controller.addDanmaku(_items[sec]);
        sec++;
      });
    }
  }

  // 生成随机颜色
  Color getRandomColor() {
    final Random random = Random();
    return Color.fromARGB(
      255, // 固定 alpha 为 255(完全不透明)
      random.nextInt(256),
      random.nextInt(256),
      random.nextInt(256),
    );
  }

  @override
  void dispose() {
    timer?.cancel();
    super.dispose();
  }
}
4
likes
145
pub points
79%
popularity

Publisher

unverified uploader

A high performance danmaku lib for flutter.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on canvas_danmaku