颤振:刮刮卡

时间:2018-08-21 09:13:22

标签: dart flutter

这里是react-native刮刮卡的示例,我想在Flutter中实现,但是我没有任何办法做到这一点。我尝试使用blendMode,但是它不起作用,甚至CustomPaint中也没有明确的功能。 https://github.com/aleksik/react-scratchcardenter image description here

 Future<Null> main() async {
  runApp(MaterialApp(home: Scaffold(body: new Roller())));
}

class Roller extends StatefulWidget {
  @override
  _ScratchCardState createState() => new _ScratchCardState();
}

class _ScratchCardState extends State<Roller> {
  ui.Image _image;
  String _urlImage = 'assets/BedRoom.png';

  List<Offset> _points = <Offset>[];
  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    super.initState();

    load(_urlImage).then((j) {
      _image = j;
      print('image:${_image}');
    });
  }

  Future<ui.Image> load(String asset) async {
    ByteData data = await rootBundle.load(asset);

    ui.Codec codec = await ui.instantiateImageCodec(
      data.buffer.asUint8List(),
    );
    ui.FrameInfo fi = await codec.getNextFrame();
    return fi.image;
  }

  void _onPanStart(DragStartDetails dt) {
    print('drag start ');
    setState(() {

    });
  }

  Offset _localPosition;
  void _onPanUpdate(DragUpdateDetails details) {
    setState(() {
      RenderBox object = context.findRenderObject();

      _localPosition = object.globalToLocal(details.globalPosition);
      _points = new List.from(_points)..add(_localPosition);
    });
  }

  _onPanEnd(DragEndDetails dt) {
    _points.add(null);
  }

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

  Widget _scale(BuildContext context) {
    return GestureDetector(
      onPanStart: _onPanStart,
      onPanUpdate: _onPanUpdate,
      onPanEnd: _onPanEnd,
      onDoubleTap: () {
        setState(() {
          _points.clear();
        });
      },
      child: Container(
        child: CustomPaint(
          painter: ScratchCard(
              imagePath: _image, points: _points,),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _scale(context),
    );
  }
}

class ScratchCard extends CustomPainter {
  final ui.Image imagePath;
  List<Offset> points;
  ScratchCard({Key key, this.imagePath, this.points}) : super();
  Paint _paint = Paint();

  Rect rect, inputSubrect, outputSubrect;
  Path path = new Path();
  Paint paint1 = new Paint();
  @override
  void paint(Canvas canvas, Size size) {
    _paint.blendMode = BlendMode.src;
    if (imagePath != null)
      canvas.drawImage(imagePath, Offset(10.0, 100.0), _paint);
    Paint paint = new Paint()
      ..color = Colors.white
      ..strokeCap = StrokeCap.round
      ..strokeWidth = 30.0;
    _paint.blendMode = BlendMode.clear;
    for (int i = 0; i < points.length - 1; i++) {
      if (points[i] != null && points[i + 1] != null) {
        canvas.drawLine(points[i], points[i + 1], paint);
        path.reset();
      }
    }
  }

  @override
  bool shouldRepaint(ScratchCard oldDelegate) {
    return true;
  }
}

1 个答案:

答案 0 :(得分:0)

我在Flutter中为刮刮卡创建了一个库,该库同时支持-颜色和图像可刮擦的覆盖层。您可以从https://pub.dev/packages/scratcher那里获得反馈。欢迎反馈!

示例:

Scratcher(
  brushSize: 30,
  threshold: 50,
  color: Colors.red,
  onChange: (value) { print("Scratch progress: $value%"); },
  onThreshold: () { print("Threshold reached, you won!"); },
  child: Container(
    height: 300,
    width: 300,
    child: Text("Hidden text"),
  ),
)

Preview