Explore a animação da raspadinha no Flutter

Tempo de leitura: 4 minutes

Neste artigo, exploraremos a animação de cartões Scratch no Flutter. Veremos como executar um programa de demonstração. Vamos explicar a melhor maneira de criar uma animação de raspadinha interativa e imersiva usando o pacote scratcher em seus aplicativos Flutter.

Para o Scratcher

scratcher | pacote Flutter
Widget de raspadinha que oculta temporariamente o conteúdo do usuário.

Para o Confetti

confetti | pacote Flutter
Exploda confetti coloridos por toda a tela. Comemore as conquistas no aplicativo com estilo. Controle a velocidade, o ângulo.

 

Introdução

Uma animação de scratch card no seu aplicativo Flutter pode ser apenas o toque marcante que você deseja para encantar os usuários e aumentar o envolvimento. Visualize a expectativa quando os clientes deslizarem o dedo para descobrir o que está sendo guardado, o que sugere as raspadinhas de loteria. As raspadinhas são inseparáveis do fervor e do segredo.

As scratch card revelam descontos, ofertas extraordinárias ou conteúdo seletivo. As animações de raspadinhas oferecem um método divertido e conectado para interagir com o seu aplicativo.

 

Implementação:

Etapa 1: adicionar as dependências

Adicione dependências ao arquivo pubspec - yaml.

scratcher: ^2.5.0
confetti: ^0.7.0

Etapa 2: Import

import 'package:confetti/confetti.dart';
import 'package:scratcher/scratcher.dart';

Etapa 3: Adicionar os assets

Adicione os assets ao arquivo pubspec - yaml.

assets:
- assets/

Etapa 4: Execute os pacotes do flutter no diretório raiz do seu aplicativo.

Como implementar o código no arquivo dart:

Você precisa implementá-lo em seu código, respe1tivamente:

Crie um novo arquivo dart chamado main.dart dentro da pasta lib.

No arquivo main.dart, adicionamos o arquivo SlashScreen() que ira apresentar o logo do site, chamando logo após o arquivo  ScratchCardDemo() para ser executado. Nessa código na classe do State, criaremos uma variável ConfettiController tardia, chamada _controller.

late ConfettiController _controller;

Agora, adicionaremos o método initState(). Nesse método, adicionaremos que _controller é igual a ConfettiController(). Dentro do colchete, adicionaremos uma duração de 2 segundos.

@override
  void initState() {
    super.initState();
    _controller = ConfettiController(
      duration: const Duration(seconds: 2),
    );
  }

No corpo, adicionaremos um método Scratcher(). Nesse método, adicionaremos brushSize was 50, que significa o tamanho do pincel. Quanto maior ele for, mais rápido o usuário conseguirá raspar o cartão. Um threshold de 75 significa o nível percentual da área raspada que deve ser revelado para ser concluído. Quando a raspagem for concluída e atingir o valor threshold, o ConfettiController criará uma animação de confete.

Center(
  child: Scratcher(
    brushSize: 50,
    threshold: 75,
    color: Colors.blue,
    image: Image.asset(
      "assets/scratch.png",
      fit: BoxFit.fill,
    ),
    // ignore: avoid_print
    onChange: (value) => print("Scratch progress: $value%"),
    onThreshold: () => _controller.play(),
    child: SizedBox(
      height: MediaQuery.of(context).size.height * 0.3,
      width: MediaQuery.of(context).size.width * 0.6,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Image.asset(
            "assets/flutter.png",
            fit: BoxFit.cover,
            width: MediaQuery.of(context).size.height * 0.25,
            height: MediaQuery.of(context).size.height * 0.25,
          ),
          Column(
            children: [
              ConfettiWidget(
                blastDirectionality: BlastDirectionality.explosive,
                confettiController: _controller,
                particleDrag: 0.05,
                emissionFrequency: 0.05,
                numberOfParticles: 100,
                gravity: 0.05,
                shouldLoop: false,
                colors: const [
                  Colors.green,
                  Colors.red,
                  Colors.yellow,
                  Colors.blue,
                  Colors.purple
                ],
              ),
            ],
          ),
        ],
      ),
    ),
  ),
),

O widget Scratcher tem a propriedade “onThreshold” para reproduzir a animação de confete dentro do aplicativo. O ConfettiWidget e a imagem de recompensa são adicionados como filhos do widget Scratcher para mostrar os prêmios. Modifique a animação de confete envolvendo propriedades no ConfettiWidget, pois adicionamos algumas propriedades em nosso modelo.

Quando executamos o aplicativo, devemos obter a saída da tela como a captura de tela abaixo.

Código Completo

main.dart

import 'package:flutter/material.dart';
import 'app/splash_screen.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.teal,
      ),
      debugShowCheckedModeBanner: false,
      home: const SplashScreen(),
    );
  }
}

lib->app

splash_screen.dart

import 'dart:async';
import 'package:flutter/material.dart';
import 'scratch_card_demo.dart';

class SplashScreen extends StatefulWidget {
  const SplashScreen({super.key});

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

class VideoState extends State<SplashScreen> with SingleTickerProviderStateMixin{
  var _visible = true;

  late AnimationController animationController;
  late Animation<double> animation;

  startTime() async {
    // ignore: no_leading_underscores_for_local_identifiers
    var _duration = const Duration(seconds: 2);
    return Timer(_duration, navigationPage);
  }

  void navigationPage() {
    Navigator.of(context).push(
        MaterialPageRoute(builder: (context) => const ScratchCardDemo()),
    );
  }

  @override
  void initState() {
    super.initState();

    animationController = AnimationController(
        vsync: this, duration: const Duration(seconds: 1));
    animation =
    CurvedAnimation(parent: animationController, curve: Curves.easeOut);

    animation.addListener(() => setState(() {}));
    animationController.forward();

    setState(() {
      _visible = !_visible;
    });
    startTime();
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      backgroundColor: Colors.white,
      body: Stack(
        fit: StackFit.expand,
        children: <Widget>[
          Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Image.asset(
                'assets/devs.jpg',
                width: animation.value * 250,
                height: animation.value * 250,
              ),
            ],
          ),
        ],
      ),
    );
  }
}

scratch_card_demo.dart

import 'package:confetti/confetti.dart';
import 'package:flutter/material.dart';
import 'package:scratcher/scratcher.dart';

class ScratchCardDemo extends StatefulWidget {
  const ScratchCardDemo({super.key});

  @override
  State<ScratchCardDemo> createState() => _ScratchCardDemoState();
}

class _ScratchCardDemoState extends State<ScratchCardDemo> {
  late ConfettiController _controller;

  @override
  void initState() {
    super.initState();
    _controller = ConfettiController(
      duration: const Duration(seconds: 2),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: const Text("Flutter Scratch Card Demo"),
        automaticallyImplyLeading: false,
        centerTitle: true,
        backgroundColor: Colors.tealAccent,
      ),
      body: Center(
        child: Scratcher(
          brushSize: 50,
          threshold: 75,
          color: Colors.blue,
          image: Image.asset(
            "assets/scratch.png",
            fit: BoxFit.fill,
          ),
          // ignore: avoid_print
          onChange: (value) => print("Scratch progress: $value%"),
          onThreshold: () => _controller.play(),
          child: SizedBox(
            height: MediaQuery.of(context).size.height * 0.3,
            width: MediaQuery.of(context).size.width * 0.6,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Image.asset(
                  "assets/flutter.png",
                  fit: BoxFit.cover,
                  width: MediaQuery.of(context).size.height * 0.25,
                  height: MediaQuery.of(context).size.height * 0.25,
                ),
                Column(
                  children: [
                    ConfettiWidget(
                      blastDirectionality: BlastDirectionality.explosive,
                      confettiController: _controller,
                      particleDrag: 0.05,
                      emissionFrequency: 0.05,
                      numberOfParticles: 100,
                      gravity: 0.05,
                      shouldLoop: false,
                      colors: const [
                        Colors.green,
                        Colors.red,
                        Colors.yellow,
                        Colors.blue,
                        Colors.purple
                      ],
                    ),
                  ],
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

 

Conclusão

Neste artigo, expliquei a animação Scratch Card no Flutter; você pode modificar esse código de acordo com sua escolha. Essa foi uma pequena introdução à animação de raspadinha na interação do usuário do Flutter do meu lado, e está funcionando usando o Flutter.

Espero que este blog lhe forneça informações suficientes sobre como experimentar a animação Scratch Card em seus projetos do Flutter. Mostraremos a você o que é a Introdução. Criaremos um programa de demonstração para trabalhar com a animação de raspadinha usando o pacote scratcher em seus aplicativos Flutter. Então, por favor, experimente.