JSON Canvas Viewer

Decisões Técnicas

1. Arquitetura de Estado

Decisão

Usar StatefulWidget com setState ao invés de gerenciamento de estado global (Provider, Bloc, Riverpod, etc.)

Justificativa

Trade-offs

Vantagens:

Desvantagens:

Alternativas Consideradas


2. Debouncing no Editor

Decisão

Implementar debounce de 300ms nas atualizações do editor.

_debounceTimer = Timer(const Duration(milliseconds: 300), () {
  final text = _codeController.text;
  widget.onJsonChanged(text);
  _validateJson(text);
});

Justificativa

Medições

Delay Chamadas/seg (digitação rápida) Percepção do usuário
0ms ~30-50 Lag visível
100ms ~10 Leve lag
300ms ~3-4 Imperceptível
500ms ~2 Lag perceptível

Alternativas Consideradas


3. Sincronização Bidirecional

Decisão

Implementar sincronização em tempo real usando flags de controle.

// HomePage
bool _isUpdatingFromCanvas = false;

// JsonEditorWidget
bool _isUpdatingFromExternal = false;
String _lastExternalData = '';

Justificativa

Mecanismo de Proteção

  1. HomePage Flag: Previne notificação circular quando canvas atualiza
  2. Editor Flag: Previne notificação quando recebe dados externos
  3. Cache: Evita atualizações com mesmo conteúdo

Complexidade

Risco: Condições de corrida se flags não forem gerenciadas corretamente

Mitigação: Future.microtask para operações assíncronas controladas


4. Sistema de Escala

Decisão

Implementar coordenadas de design fixo com escala proporcional.

double _getElementScaleFactor() {
  return math.min(canvasWidth / designWidth, canvasHeight / designHeight);
}

Justificativa

Exemplo

Design em 1080x1920, renderizado em 360x640:

Alternativa Considerada

Coordenadas relativas (0.0 a 1.0): Menos intuitivo para designers


5. Parsing de Cores

Decisão

Suportar apenas formato hexadecimal.

Color _parseColor(String hexColor) {
  hexColor = hexColor.replaceAll('#', '');
  if (hexColor.length == 6) hexColor = 'FF$hexColor';
  return Color(int.parse('0x$hexColor'));
}

Justificativa

Não Suportado

Alternativa Considerada

Múltiplos formatos: Aumenta complexidade sem benefício significativo


6. Google Fonts Dinâmico

Decisão

Carregar fontes do Google Fonts em tempo de execução.

TextStyle textStyle = GoogleFonts.getFont(
  fontFamily,
  fontSize: fontSize,
  fontWeight: fontWeight,
);

Justificativa

Trade-offs

Vantagens:

Desvantagens:


7. Estrutura de Elementos como Map

Decisão

Usar List<Map<String, dynamic>> ao invés de classes tipadas.

List<Map<String, dynamic>> elements = [];

Justificativa

Trade-offs

Vantagens:

Desvantagens:

Alternativa Considerada

Classes tipadas com json_serializable: Muito boilerplate para a flexibilidade desejada


8. Renderização com Stack e Positioned

Decisão

Usar Stack com Positioned para layout.

Stack(
  fit: StackFit.expand,
  children: elements.map((el) => Positioned(
    left: x,
    top: y,
    child: elementWidget,
  )).toList(),
)

Justificativa

Limitações

Performance

Número de Elementos FPS Memória Experiência
0-20 60 ~50MB Excelente
20-50 60 ~80MB Ótima
50-100 45-60 ~120MB Boa
100+ 30-45 ~200MB+ Degradada

9. Gesture Handling por Widget

Decisão

Envolver cada elemento com GestureDetector individual.

Widget _wrapWithDragGesture(Widget child, int elementIndex) {
  return GestureDetector(
    onPanStart: (details) => _onPanStart(details, elementIndex),
    onPanUpdate: (details) => _onPanUpdate(details, elementIndex),
    onPanEnd: _onPanEnd,
    child: child,
  );
}

Justificativa

Trade-offs

Vantagens:

Desvantagens:


10. Validação JSON Inline

Decisão

Validar através de try-catch no parse.

try {
  const JsonDecoder().convert(jsonString);
  // Válido
} catch (e) {
  // Inválido
}

Justificativa

Limitações

Alternativa Considerada

JSON Schema Validation: Overhead significativo para pouco benefício


11. Sem Undo/Redo

Decisão

Não implementar sistema de undo/redo na versão inicial.

Justificativa

Trade-off

Usuário experiente: Pode usar Ctrl+Z no editor Usuário iniciante: Precisa copiar JSON antes de mudanças

Roadmap

Planejado para fase futura com:


12. Plataforma Web First

Decisão

Focar em web (Chrome) como plataforma primária.

Justificativa

Limitações


Próximos Passos