API Canvas: ścieżki, pędzle i shadery
Rysuj kształty, gradienty i obrysy za pomocą prymitywów Canvas oraz konfiguracji Paint
API Canvas: ścieżki, pędzle i shadery to bezpłatna lekcja Flutter Mobile Development na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Flutter Mobile Development, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Flutter Mobile Development zawiera 4 lekcji w sumie.
Poznajemy Canvas
Podczas tworzenia CustomPainter Flutter przekazuje Państwu w paint() dwie rzeczy: Canvas i Size.
- Canvas to obszar rysowania. Udostępnia takie prymitywy jak
drawRect,drawCircle,drawPathidrawLine. - Size określa rozmiar obszaru, dzięki czemu można skalować rysunek tak, aby pasował do dowolnego urządzenia.
Każde wywołanie rysowania wymaga obiektu Paint, który opisuje sposób rysowania: kolor, obrys lub wypełnienie, szerokość i inne właściwości.
void paint(Canvas canvas, Size size) {
final paint = Paint()..color = const Color(0xFF2196F3);
canvas.drawRect(
Rect.fromLTWH(0, 0, size.width, size.height),
paint,
);
}Obiekt Paint
Paint to zestaw opcji stylu. Najważniejsze pola to:
color— kolor używany do rysowania.style—PaintingStyle.fill(wypełnienie) lubPaintingStyle.stroke(tylko obrys).strokeWidth— grubość linii podczas rysowania obrysu.isAntiAlias— wygładzanie krawędzi, domyślnie włączone.
W kodzie Fluttera często używa się operatora kaskadowego .., aby skonfigurować nowo utworzony Paint w jednym wyrażeniu.
final fill = Paint()
..color = const Color(0xFFE91E63)
..style = PaintingStyle.fill;
final outline = Paint()
..color = const Color(0xFF000000)
..style = PaintingStyle.stroke
..strokeWidth = 4.0;Rysowanie podstawowych kształtów
Canvas udostępnia gotowe prymitywy, więc nie zawsze trzeba używać ścieżki:
drawRect(Rect, Paint)— prostokąt o bokach równoległych do osi.drawRRect(RRect, Paint)— prostokąt z zaokrąglonymi rogami.drawCircle(Offset center, double radius, Paint)drawOval(Rect, Paint)— wypełnia prostokąt ograniczający elipsą.
Współrzędne zaczynają się od (0,0) w lewym górnym rogu; x rośnie w prawo, a y w dół.
void paint(Canvas canvas, Size size) {
final p = Paint()..color = const Color(0xFF4CAF50);
final center = Offset(size.width / 2, size.height / 2);
canvas.drawCircle(center, 40, p);
canvas.drawRRect(
RRect.fromRectAndRadius(
Rect.fromLTWH(10, 10, 80, 50),
const Radius.circular(12),
),
p,
);
}Obrysy: zakończenia, połączenia i szerokość
Gdy style ma wartość PaintingStyle.stroke, kilka właściwości wpływa na wygląd linii:
strokeWidth— grubość w pikselach logicznych.strokeCap— wygląd zakończeń linii:butt,roundlubsquare.strokeJoin— sposób łączenia narożników:miter,roundlubbevel.
Zaokrąglone zakończenia i połączenia są często używane do tworzenia przyjaznych, gładkich wykresów i podpisów.
final stroke = Paint()
..color = const Color(0xFF9C27B0)
..style = PaintingStyle.stroke
..strokeWidth = 6.0
..strokeCap = StrokeCap.round
..strokeJoin = StrokeJoin.round;
// canvas.drawLine(Offset(10, 10), Offset(120, 60), stroke);Tworzenie ścieżki
Path opisuje dowolny obrys złożony z odcinków prostych i krzywych. Najważniejsze metody to:
moveTo(x, y)— podnosi pióro i rozpoczyna nową podścieżkę.lineTo(x, y)— rysuje odcinek prosty.quadraticBezierTo / cubicTo— odcinki krzywe.close()— łączy z powrotem z początkiem podścieżki.
Gotową ścieżkę należy narysować za pomocą canvas.drawPath(path, paint).
void paint(Canvas canvas, Size size) {
final path = Path()
..moveTo(size.width / 2, 0)
..lineTo(size.width, size.height)
..lineTo(0, size.height)
..close();
final paint = Paint()..color = const Color(0xFFFF5722);
canvas.drawPath(path, paint);
}Krzywe z odcinkami Beziera
Gładkie kształty tworzy się za pomocą krzywych Beziera. Najczęściej używana jest kwadratowa krzywa Beziera, która korzysta z jednego punktu kontrolnego.
quadraticBezierTo(cpx, cpy, x, y)zakrzywia linię w stronę punktu kontrolnego(cpx, cpy)na drodze do punktu końcowego(x, y).cubicTo(c1x, c1y, c2x, c2y, x, y)korzysta z dwóch punktów kontrolnych do tworzenia krzywych w kształcie litery S.
Służą one do tworzenia falistych separatorów, linii wykresów i ogonków dymków dialogowych.
void paint(Canvas canvas, Size size) {
final wave = Path()
..moveTo(0, size.height * 0.5)
..quadraticBezierTo(
size.width * 0.25, size.height * 0.2,
size.width * 0.5, size.height * 0.5,
)
..quadraticBezierTo(
size.width * 0.75, size.height * 0.8,
size.width, size.height * 0.5,
);
final paint = Paint()
..color = const Color(0xFF00BCD4)
..style = PaintingStyle.stroke
..strokeWidth = 3;
canvas.drawPath(wave, paint);
}Czysty Dart: obliczanie punktów
Obliczenia dla Canvas to po prostu geometria. Przed rysowaniem często oblicza się współrzędne za pomocą czystego języka Dart. W tym przykładzie generujemy równomiernie rozmieszczone punkty na fali sinusoidalnej — te same wartości, które można przekazać do path.lineTo.
Ta logika nie zależy od frameworka, dlatego można ją testować jednostkowo bez renderowania czegokolwiek.
import 'dart:math';
List<Point<double>> wavePoints(double width, double height, int n) {
final pts = <Point<double>>[];
for (var i = 0; i <= n; i++) {
final x = width * i / n;
final y = height / 2 + sin(i / n * 2 * pi) * height / 4;
pts.add(Point(x, y));
}
return pts;
}
void main() {
final pts = wavePoints(200, 100, 4);
for (final p in pts) {
print('(${p.x.toStringAsFixed(1)}, ${p.y.toStringAsFixed(1)})');
}
}Shadery: gradienty liniowe
Shader wypełnia kształt czymś więcej niż jednolitym kolorem. Najczęściej używa się gradientu liniowego. Tworzy się go za pomocą ui.Gradient.linear i przypisuje do paint.shader.
from/toto początkowy i końcowyOffsetlinii gradientu.colorszawiera punkty gradientu, które są mieszane wzdłuż tej linii.
Po ustawieniu shader kolor color obiektu paint jest ignorowany przy wypełnianiu.
import 'dart:ui' as ui;
Paint gradientPaint(Size size) {
return Paint()
..shader = ui.Gradient.linear(
Offset.zero,
Offset(size.width, size.height),
const [Color(0xFF2196F3), Color(0xFF9C27B0)],
);
}Gradienty radialne i Sweep
Oprócz gradientu liniowego Flutter oferuje jeszcze dwa shadery gradientowe:
- Radial —
ui.Gradient.radial(center, radius, colors)rozprowadza kolory od punktu centralnego na zewnątrz; świetnie nadaje się do poświat i reflektorów. - Sweep —
ui.Gradient.sweep(center, colors)obraca kolory wokół środka; idealnie nadaje się do okrągłych wskaźników postępu i kół kolorów.
Można dodać opcjonalną listę stops (od 0.0 do 1.0), aby dokładnie określić położenie każdego koloru.
import 'dart:ui' as ui;
Paint glow(Offset center) {
return Paint()
..shader = ui.Gradient.radial(
center,
60,
const [Color(0xFFFFEB3B), Color(0x00FFEB3B)],
const [0.0, 1.0],
);
}Łączenie elementów w painterze
Rzeczywisty CustomPainter łączy ścieżki, obiekty paint i shadery. Należy pamiętać o dwóch metodach przesłoniętych:
paint(canvas, size)— wykonuje rysowanie.shouldRepaint(old)— zwracatruetylko wtedy, gdy zmieniły się dane wejściowe, dzięki czemu Flutter unika niepotrzebnego ponownego rysowania.
Ten fragment rysuje kartę z zaokrąglonymi rogami, wypełnioną gradientem i obramowaną obrysem.
class CardPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final rect = Rect.fromLTWH(0, 0, size.width, size.height);
final rrect = RRect.fromRectAndRadius(rect, const Radius.circular(16));
final fill = Paint()
..shader = ui.Gradient.linear(
rect.topLeft, rect.bottomRight,
const [Color(0xFF42A5F5), Color(0xFF7E57C2)],
);
canvas.drawRRect(rrect, fill);
final border = Paint()
..style = PaintingStyle.stroke
..strokeWidth = 2
..color = const Color(0x33000000);
canvas.drawRRect(rrect, border);
}
@override
bool shouldRepaint(CardPainter oldDelegate) => false;
}Zapisywanie, przywracanie i transformacje
Canvas przechowuje stos transformacji i przycięć. Można go używać do rysowania obróconej lub przeskalowanej zawartości bez trwałej zmiany stanu:
canvas.save()odkłada bieżącą macierz na stos.canvas.translate / rotate / scalemodyfikują tę macierz.canvas.restore()przywraca poprzedni stan.
Zawsze należy parować każde save() z restore(), w przeciwnym razie kolejne rysunki odziedziczą transformację.
void paint(Canvas canvas, Size size) {
final p = Paint()..color = const Color(0xFF3F51B5);
canvas.save();
canvas.translate(size.width / 2, size.height / 2);
canvas.rotate(0.785398); // 45 degrees in radians
canvas.drawRect(
const Rect.fromLTWH(-30, -30, 60, 60),
p,
);
canvas.restore();
}Szybkie sprawdzenie
Proszę sprawdzić zrozumienie konfiguracji obiektu Paint.
Podsumowanie
Znają już Państwo API Canvas:
- Paint steruje sposobem rysowania:
color,style(wypełnienie lub obrys),strokeWidth, zakończenia i połączenia. - Prymitywy, takie jak
drawRect,drawRRectidrawCircle, obsługują typowe kształty; Path z metodamimoveTo,lineToi krzywymi Beziera pozwala tworzyć dowolne kształty niestandardowe. - Shadery (
Gradient.linear,radial,sweep) wypełniają lub obrysowują kształty gradientami i zastępują jednolity kolor. - save/restore izoluje transformacje, a
shouldRepaintzapewnia wydajne renderowanie.
Dzięki tym elementom można tworzyć wykresy, niestandardowe kontrolki i bogate dekoracje wyłącznie w języku Dart.
Ucz się Dart dzięki korepetycjom AI — za darmo
Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.
- Kursy
- 22
- Lekcje
- 88
Często zadawane pytania
Czy lekcja „API Canvas: ścieżki, pędzle i shadery” jest bezpłatna?
Tak — pełny tekst „API Canvas: ścieżki, pędzle i shadery” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Flutter Mobile Development, przejdź na CoddyKit PRO. Kurs Flutter Mobile Development zawiera 4 lekcji w sumie.
Co nauczysz się w „API Canvas: ścieżki, pędzle i shadery”?
Rysuj kształty, gradienty i obrysy za pomocą prymitywów Canvas oraz konfiguracji Paint Ćwiczysz Flutter Mobile Development z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Flutter Mobile Development?
Nie wymagamy żadnego doświadczenia. Flutter Mobile Development w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.
Ile czasu zajmuje lekcja „API Canvas: ścieżki, pędzle i shadery”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Flutter Mobile Development?
Tak. Każda lekcja Flutter Mobile Development zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- API Canvas: ścieżki, pędzle i shadery
- Tworzenie interaktywnego niestandardowego widgetu wykresu
- Przycinanie, tryby mieszania i komponowanie warstw
- Testowanie trafień i optymalizacja przemalowywania