Dart 颤振:刮刮卡

Dart 颤振:刮刮卡,dart,flutter,Dart,Flutter,这里是react native中的一个scratch卡示例,我想在Flatter中实现,但我没有任何方法来实现这一点。我试过使用blendMode,但它不起作用,甚至在颤振中的CustomPaint中也没有给出明确的功能。 Future main()异步{ runApp(MaterialApp)(主页:脚手架(主体:新滚筒()); } 类Roller扩展StatefulWidget{ @凌驾 _ScratchCardState createState()=>新建_ScratchCardStat

这里是react native中的一个scratch卡示例,我想在Flatter中实现,但我没有任何方法来实现这一点。我试过使用
blendMode
,但它不起作用,甚至在颤振中的
CustomPaint
中也没有给出明确的功能。

Future main()异步{
runApp(MaterialApp)(主页:脚手架(主体:新滚筒());
}
类Roller扩展StatefulWidget{
@凌驾
_ScratchCardState createState()=>新建_ScratchCardState();
}
类_ScratchCardState扩展状态{
ui.Image\u图像;
字符串_urlImage='assets/dombery.png';
列出_点=[];
@凌驾
void initState(){
//TODO:实现initState
super.initState();
super.initState();
加载(_urimage)。然后((j){
_image=j;
打印('image:${u image}');
});
}
未来加载(字符串资产)异步{
ByteData data=等待rootBundle.load(资产);
ui.Codec Codec=wait ui.instantialeimagecodec(
data.buffer.asUint8List(),
);
ui.FrameInfo fi=await codec.getNextFrame();
返回fi.image;
}
void _onPanStart(dragstartdt){
打印(“拖动开始”);
设置状态(){
});
}
偏移量_localPosition;
void _onPanUpdate(DragUpdate详细信息){
设置状态(){
RenderBox object=context.findenderobject();
_localPosition=object.GlobalTopLocal(details.globalPosition);
_点=新列表。从(_点)…添加(_本地位置);
});
}
_onPanEnd(Dragendt){
_添加(空);
}
@凌驾
无效处置(){
super.dispose();
}
小部件规模(构建上下文){
返回手势检测器(
onPanStart:_onPanStart,
onPanUpdate:_onPanUpdate,
onPanEnd:_onPanEnd,
onDoubleTap:(){
设置状态(){
_点。清除();
});
},
子:容器(
孩子:定制油漆(
画家:草稿卡(
图像路径:_图像,点:_点,),
),
),
);
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:_刻度(上下文),
);
}
}
类ScratchCard扩展了CustomPainter{
最终ui.imagePath;
列出要点;
ScratchCard({Key Key,this.imagePath,this.points}):super();
油漆_油漆=油漆();
Rect Rect,inputSubrect,outputSubrect;
路径路径=新路径();
油漆油漆1=新油漆();
@凌驾
空心油漆(帆布,尺寸){
_paint.blendMode=blendMode.src;
if(imagePath!=null)
画布.drawImage(图像路径,偏移量(10.0,100.0),_-paint);
油漆=新油漆()
…颜色=颜色。白色
..strokeCap=strokeCap.round
..冲程宽度=30.0;
_paint.blendMode=blendMode.clear;
对于(int i=0;i
我已经为Flitter中的scratch卡创建了一个库,它支持彩色和图像可刮的覆盖层。你可以从反馈中得到它,这是非常受欢迎的

例如:

Scratcher(
字号:30,
阈值:50,
颜色:颜色,红色,
onChange:(value){print(“Scratch progress:$value%”;},
onThreshold:(){打印(“达到阈值,您赢了!”);},
子:容器(
身高:300,
宽度:300,
子项:文本(“隐藏文本”),
),
)

您包含的代码远未完成。请包含代码的其余部分,或者重写它,使它是自封闭的,而不暴露更多的代码。问题已经解决了。这很好!如果你有时间,如果你能写出一个最小的解决方案,或者至少解释一下什么是有效的,这样下一个遇到这个问题的人就可以使用它,那就太好了。你好,卡米尔,谢谢你的大力控制。我打开了一个与专栏小部件相关的bug..嘿@bashan,谢谢你的报道。该问题已在最新的主分支中修复(将在1.2.1版本中提供)。
 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;
  }
}