Upgrade to Pro — share decks privately, control downloads, hide ads and more …

SVG na ratunek nudnym UI (FlutteredWrocław)

SVG na ratunek nudnym UI (FlutteredWrocław)

Avatar for Wojciech Warwas

Wojciech Warwas

November 09, 2022
Tweet

More Decks by Wojciech Warwas

Other Decks in Technology

Transcript

  1. SVG? <svg height="80" width="300"> <g fill="none"> <path stroke="red" d="M5 20

    l215 0" /> <path stroke="black" d="M5 40 l215 0" /> <path stroke="blue" d="M5 60 l215 0" /> </g> </svg>
  2. SVG? <svg viewBox="0 0 100 100" xmlns=“…”> <path fill="none" stroke="red"

    d="M 10,30 A 20,20 0,0,1 50,30 A 20,20 0,0,1 90,30 Q 90,60 50,90 Q 10,60 10,30 z" /> </svg>
  3. <svg height="80" width="300"> <g fill="none"> <path stroke="red" d="M5 20 l215

    0" /> <path stroke="black" d="M5 40 l215 0" /> <path stroke="blue" d="M5 60 l215 0" /> </g> </svg>
  4. Zalety tego podejścia • Brak I/O • Lepsza kontrola nad

    rysowaniem • Możliwość dalszej optymalizacji / zmian / animacji
  5. SVG to fl utter - node.js CLI • - generuje

    kod Flutter na podstawie SVG • - krzywe beziera • - FILL oraz STROKE • - path tracing • - custom clipper svg-to- fl utter convert ~/path.svg
  6. Show me the code! <svg height="80" width="300"> <g fill="none"> <path

    stroke="red" d="M5 20 l215 0" /> <path stroke="black" d="M5 40 l215 0" /> <path stroke="blue" d="M5 60 l215 0" /> </g> </svg>
  7. Show me the code! <svg height="80" width="300"> <g fill="none"> <path

    stroke="red" d="M5 20 l215 0" /> <path stroke="black" d="M5 40 l215 0" /> <path stroke="blue" d="M5 60 l215 0" /> </g> </svg> class StrokesPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { Path path = Path(); final Paint paint = Paint(); // Path 3 Stroke path = Path(); paint.color = const Color(0xff0000ff); paint.style = PaintingStyle.stroke; paint.strokeWidth = 1; path.moveTo(size.width * 0.02, size.height * 0.75); path.lineTo(size.width * 0.73, size.height * 0.75); canvas.drawPath(path, paint); } @override bool shouldRepaint(CustomPainter oldDelegate) { return true; } } // Path 1 Stroke paint.color = const Color(0xffff0000); paint.style = PaintingStyle.stroke; paint.strokeWidth = 1; path.moveTo(size.width * 0.02, size.height * 0.25); path.lineTo(size.width * 0.73, size.height * 0.25); canvas.drawPath(path, paint);
  8. Show me the code! <svg height="80" width="300"> <g fill="none"> <path

    stroke="red" d="M5 20 l215 0" /> <path stroke="black" d="M5 40 l215 0" /> <path stroke="blue" d="M5 60 l215 0" /> </g> </svg> // Path 1 Stroke paint.color = const Color(0xffff0000); paint.style = PaintingStyle.stroke; paint.strokeWidth = 1; path.moveTo(size.width * 0.02, size.height * 0.25); path.lineTo(size.width * 0.73, size.height * 0.25); canvas.drawPath(path, paint);
  9. Clip Photo by Chevanon Photography: https://www.pexels.com/photo/two-yellow-labrador-retriever-puppies-1108099/
 Photo by Pixabay: https://www.pexels.com/photo/short-coated-black-and-brown-puppy-in-white-and-red-polka-dot-ceramic-mug-on-green-

    fi eld-39317/ Photo by Denniz Futalan: https://www.pexels.com/photo/close-up-photo-of-a-small-short-coated-white-puppy-2523934/ svg-to- fl utter convert —clip {path}
  10. Clip Photo by Chevanon Photography: https://www.pexels.com/photo/two-yellow-labrador-retriever-puppies-1108099/
 Photo by Pixabay: https://www.pexels.com/photo/short-coated-black-and-brown-puppy-in-white-and-red-polka-dot-ceramic-mug-on-green-

    fi eld-39317/ Photo by Denniz Futalan: https://www.pexels.com/photo/close-up-photo-of-a-small-short-coated-white-puppy-2523934/ class MyClipper extends CustomClipper<Path> { @override Path getClip(Size size) { Path path = Path(); // Path 1 Fill path.moveTo(size.width * 0.7558, size.height * 1.0861); path.lineTo(size.width * 0.4946, size.height * 0.9256); path.lineTo(size.width * 0.2408, size.height * 1.1038); path.lineTo(size.width * 0.2821, size.height * 0.7435); path.lineTo(size.width * 0.0683, size.height * 0.4966); path.lineTo(size.width * 0.355, size.height * 0.4345); path.lineTo(size.width * 0.4766, size.height * 0.1038); path.lineTo(size.width * 0.6125, size.height * 0.4256); path.lineTo(size.width * 0.9015, size.height * 0.4681); path.lineTo(size.width * 0.6988, size.height * 0.7292); path.lineTo(size.width * 0.7558, size.height * 1.0861); return path; } @override bool shouldReclip(covariant CustomClipper<Path> oldClipper) { return true; } }
  11. Clip route transitions Photo by Denniz Futalan: https://www.pexels.com/photo/close- up- photo-of-a-small-short-coated-white-puppy-2523934/

    return PageRouteBuilder( transitionDuration: const Duration(seconds: 1), pageBuilder: (context, animation, _) => Page2(), transitionsBuilder: (context, animation, _, child) { if (animation.value == 1) { return child; } return ClipPath( clipper: PawClipper(progress: animation.value), child: child, ); }, );
  12. Path tracing PathMetrics pathMetrics = path.computeMetrics(); for (PathMetric pathMetric in

    pathMetrics) { Path extractPath = pathMetric.extractPath( 0.0, pathMetric.length * progress, ); canvas.drawPath(extractPath, paint); } svg-to- fl utter convert ~/path.svg --path-tracing svg-to- fl utter convert ~/path.svg --path-tracing-all
  13. Wnioski - Mierz wydajność - Nie bój się eksperymentować -

    Znaj narzędzia i formaty, z których korzystasz - Każdy problem da się rozwiązać na kilka sposobów