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

SVG na ratunek nudnym UI (FlutteredWrocław)

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers. →

SVG na ratunek nudnym UI (FlutteredWrocław)

Avatar for Wojciech Warwas

Wojciech Warwas

November 09, 2022

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