Criar um aplicativo inclui diversos desafios e um que já faz parte da base de todos os frameworks e linguagens é a criação de estruturas visuais, e essa tarefa pode ser realizada facilmente em qualquer das linguagens modernas. porém controlar essa renderização e principalmente criar uma ferramenta de desenhos pode ser uma tarefa extremamente difícil mas que o flutter consegue resolver facilmente:
Quero apresentar umas ideias de como podemos desenvolver um aplicativo de desenho no flutter e com quais ferramentas, minha ideia aqui não é disponibilizar código, na programação precisamos trilhar nossos próprios caminhos e trilhar um caminho que já foi passado por outro ok, pegar um uber pelo caminho só vai tornar seu trabalho mais fácil, mas nem vai dar de apreciar a vista não é mesmo? dito isso:
O canvas
Tudo no Flutter é renderizado e gerenciado através do canvas, é ele que mostra na tela todos as tabelas, listas, menus de navegação e conteúdos que você codifica, o canvas é uma abstração tão potente para a gerência do frontend de um sistema IOS e Android que além de bibliotecas extremamente complexas de animação como o Rive, há planos de tornar o canvas 3D — abrindo espaço para programas mais complicados e jogos por exemplo.
O uso do canvas no flutter é simples, e existem diversos métodos no flutter como o drawLine ou drawnCircle que facilitam o desenho de formas geométricas ou do que for necessário:
Estrutura
Algo que o canvas também permite é que você modifique ele em tempo de execução facilmente, então através de um widget de controle de gestos GestureDetector é possível saber os gestos do usuário como movimento de pinça, começar a arrastar o dedo pela tela, clicar. Tudo isso pode ser gerenciado e fazer com que você realmente controle o desenho no sistema e faça com que você tenha uma ferramenta de desenho.
Pra facilitar nossa vida essa atualização pode ser feita de uma maneira extremamente mais rápida através de um StreamController esse controlador basicamente vai usar os processos em background do flutter para atualizar a sua tela em cada atualização do usuário, são bastante atualizações realizadas por segundo, mas se seu código for atualizar apenas uma pequena parte tudo bem.
Então para que realmente fosse uma pequena parte da tela que atualizasse quando estivéssemos escrevendo, precisávamos que todos os outros desenhos que já foram criados, estivessem em outra camada que não atualiza com tanta frequência, na estrutura do flutter nosso projeto ficou com algo mais ou menos assim:
GestureDetector
A ferramenta de GestureDetector do flutter auxilia em muitos pontos como recarregar listas ao puxar de cima para baixo, arrastar para excluir e outros gestos que já são comuns no mundo mobile. Além disso, o mais importante para nós no momento, o GestureDetector conta com alguns métodos que observam seu movimento do dedo:
onPanStart
Ao começar a arrastar o dedo pela tela.
onPanUpdate
Ao ir arrastando o dedo pela tela.
onPanEnd
Ao finalizar.
Obviamente nosso shape vai começar a ser contabilizado no onPanStart que nós dá a posição exata em tela que esse evento aconteceu, enquanto estiver sendo feito o desenho (onPanUpdate) apenas será atualizado, sua posição inicial persiste a mesma e a final igual a posição da atualização. Ao final, quando terminarmos, salvaremos o desenho na lista de já desenhados, como iniciando no onPanStart e finalizando na posição onPanEnd.
Todos os botões em tela
Nossa estrutura como já é possível ver anteriormente no artigo possui alguns tipos diferentes de formatos na área superior, algumas ferramentas são mais complexas e outras seguem apenas o conceito do GestureDetector apresentado antes, óbvio que para controlar todas elas precisamos que nosso sistema controle de forma específica, por exemplo ao escolher a grossura ou a cor, esses valores ficam guardados na gerência de estado para mudar todos os tipos de figuras.
No caso do texto (ao clicar), ele cria o texto acima daquela parte do sistema (graças ao nosso stack), e o movimento de pinça aumenta ou diminui o tamanho do texto, que é um widget à parte. Então, para que o controle seja feito, todas as nossas figuras herdam uma classe chamada DrawnShape, que irá possuir as funções de atualizar e criar a figura.
Dando uma analisada na nossa estrutura temos um código mais ou menos assim na base do nosso projeto.
E no nosso DrawingCanvas apenas teremos a chamada para o sketcher (rascunho) que basicamente possui uma lista de DrawnShapes, claro que pra lista que estamos desenhando esse sketcher só possui um desenho mas no caso da lista de já desenhados é uma lista de vários itens:
Enfim, esperamos que as ideias que utilizamos possam ajudar outras pessoas e que incentivem vocês a escreverem sobre seus trabalhos. Boa sorte!