颤振:刮刮卡 [英] Flutter: Scratch card

查看:64
本文介绍了颤振:刮刮卡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里是react-native刮刮卡的示例,我想在Flutter中实现,但是我没有任何办法做到这一点。我尝试了 blendMode ,但是它不起作用,甚至在 CustomPaint 中也没有明确的功能。

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

类Roller扩展StatefulWidget {
@override
_ScratchCardState createState()=>新的_ScratchCardState();
}

类_ScratchCardState扩展了State< Roller> {
ui.Image _image;
字符串_urlImage =‘assets / BedRoom.png’;

List< Offset> _points =< Offset> [];
@override
void initState(){
// TODO:实现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编解码器=等待ui.instantiateImageCodec(
data.buffer.asUint8List(),
);
ui.FrameInfo fi =等待codec.getNextFrame();
返回图片。
}

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

});
}

偏移量_localPosition;
void _onPanUpdate(DragUpdateDetails详细信息){
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();
}

小部件_scale(BuildContext context){
return GestureDetector(
onPanStart:_onPanStart,
onPanUpdate:_onPanUpdate,
onPanEnd:_onPanEnd ,
onDoubleTap:(){
setState((){
_points.clear();
});
},
子级:Container(
子级:CustomPaint(
画家:ScratchCard(
imagePath:_image,points:_points,),
),
),
);
}

@override
小部件构建(BuildContext上下文){
return Scaffold(
body:_scale(context),
);
}
}

类ScratchCard扩展了CustomPainter {
final ui.Image imagePath;
List< Offset>点
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);
油漆= 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){
返回true;
}
}


解决方案

I在Flutter中为刮刮卡创建了一个库,该库同时支持-颜色和图像可刮擦的覆盖层。您可以从


Here is the example of a scratch card in react-native, I want to implement in Flutter, But I am not getting any way to do this. I tried with blendMode but it is not working, and even there is no clear functionality are given in CustomPaint in the flutter. https://github.com/aleksik/react-scratchcard.

 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;
  }
}

解决方案

I've created a library for scratch cards in Flutter which supports both - color and image scratchable overlays. You can get it from https://pub.dev/packages/scratcher Feedback is more than welcome!

Example:

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"),
  ),
)

这篇关于颤振:刮刮卡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆