De Canvas-API: paden, paints en shaders
Teken vormen, verlopen en lijnen met Canvas-primitieven en de configuratie van Paint.
De Canvas-API: paden, paints en shaders is een gratis Mobiele ontwikkeling met Flutter-les op CoddyKit. Dit is les 1 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Mobiele ontwikkeling met Flutter. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Mobiele ontwikkeling met Flutter bevat in totaal 4 lessen.
Maak kennis met het Canvas
Wanneer je een CustomPainter bouwt, geeft Flutter je in paint() twee dingen: een Canvas en een Size.
- Canvas is je tekenoppervlak. Het biedt basisbewerkingen zoals
drawRect,drawCircle,drawPathendrawLine. - Size vertelt je hoe groot het gebied is, zodat je je tekening kunt schalen voor elk apparaat.
Voor elke tekenaanroep heb je een Paint-object nodig dat beschrijft hoe je tekent: kleur, lijn of vulling, breedte en meer.
void paint(Canvas canvas, Size size) {
final paint = Paint()..color = const Color(0xFF2196F3);
canvas.drawRect(
Rect.fromLTWH(0, 0, size.width, size.height),
paint,
);
}Het Paint-object
Een Paint is een verzameling opmaakopties. De belangrijkste velden zijn:
color— de kleur die voor het tekenen wordt gebruikt.style—PaintingStyle.fill(effen binnenkant) ofPaintingStyle.stroke(alleen omtrek).strokeWidth— de lijndikte bij het tekenen van lijnen.isAntiAlias— maakt randen vloeiend; dit staat standaard aan.
In Flutter gebruik je de cascadeoperator .. om een pas gemaakt Paint-object in één expressie te configureren.
final fill = Paint()
..color = const Color(0xFFE91E63)
..style = PaintingStyle.fill;
final outline = Paint()
..color = const Color(0xFF000000)
..style = PaintingStyle.stroke
..strokeWidth = 4.0;Basisvormen tekenen
Het Canvas biedt kant-en-klare basisbewerkingen, zodat je niet altijd een pad nodig hebt:
drawRect(Rect, Paint)— rechthoek met zijden langs de assen.drawRRect(RRect, Paint)— afgeronde rechthoek.drawCircle(Offset center, double radius, Paint)drawOval(Rect, Paint)— vult de omvattende rechthoek met een ellips.
Coördinaten beginnen bij (0,0) in de linkerbovenhoek; x groeit naar rechts en y groeit naar beneden.
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,
);
}Lijnen: uiteinden, hoeken en breedte
Wanneer style gelijk is aan PaintingStyle.stroke, bepalen verschillende eigenschappen de lijn:
strokeWidth— dikte in logische pixels.strokeCap— hoe lijneinden eruitzien:butt,roundofsquare.strokeJoin— hoe hoeken met elkaar worden verbonden:miter,roundofbevel.
Ronde uiteinden en hoeken zijn gebruikelijk voor vriendelijke, vloeiende grafieken en handgeschreven tekeningen.
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);Een pad opbouwen
Een Path beschrijft een willekeurige omtrek die uit lijn- en krommingssegmenten bestaat. De belangrijkste methoden zijn:
moveTo(x, y)— til de pen op en begin een nieuw deelpad.lineTo(x, y)— teken een recht segment.quadraticBezierTo / cubicTo— gebogen segmenten.close()— verbind terug met het begin van het deelpad.
Teken het voltooide pad met 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);
}Krommingen met Béziersegmenten
Vloeiende vormen ontstaan met Bézierkrommingen. De meest voorkomende is de kwadratische Bézierkromming, die één controlepunt gebruikt.
quadraticBezierTo(cpx, cpy, x, y)buigt de lijn onderweg naar het eindpunt(x, y)in de richting van het controlepunt(cpx, cpy).cubicTo(c1x, c1y, c2x, c2y, x, y)gebruikt twee controlepunten voor S-vormige krommingen.
Hiermee maak je golfvormige scheidingen, grafieklijnen en staarten van tekstballonnen.
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);
}Dart zonder framework: punten berekenen
Wiskunde op een Canvas is gewoon geometrie. Voordat je tekent, bereken je vaak coördinaten met Dart zonder framework. Hier genereren we gelijkmatig verdeelde punten op een sinusgolf — dezelfde waarden die je aan path.lineTo zou doorgeven.
Deze logica is frameworkonafhankelijk, dus je kunt haar testen met een unitt est zonder iets te renderen.
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)})');
}
}Shaders: lineaire kleurverlopen
Een shader vult een vorm met meer dan één vlakke kleur. De meest voorkomende is een lineair kleurverloop. Je maakt dit met ui.Gradient.linear en wijst het toe aan paint.shader.
from/tozijn de begin- en eind-Offsets van de lijn van het kleurverloop.colorsbevat de kleurstops van het kleurverloop, die langs die lijn in elkaar overvloeien.
Zodra shader is ingesteld, wordt de color van de paint genegeerd bij vullingen.
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)],
);
}Radiale en ronddraaiende kleurverlopen
Naast lineaire kleurverlopen biedt Flutter nog twee shaders voor kleurverlopen:
- Radiaal —
ui.Gradient.radial(center, radius, colors)laat kleuren vanuit een middelpunt naar buiten overvloeien, ideaal voor gloed- en spotlichteffecten. - Ronddraaiend —
ui.Gradient.sweep(center, colors)laat kleuren rond een middelpunt draaien, ideaal voor cirkelvormige voortgangsindicatoren en kleurwielen.
Je kunt een optionele lijst stops toevoegen (van 0.0 tot 1.0) om precies te bepalen waar elke kleur staat.
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],
);
}Alles samenbrengen in een painter
Een echte CustomPainter combineert paden, paints en shaders. Onthoud twee overschrijvingen:
paint(canvas, size)— voer hier het tekenwerk uit.shouldRepaint(old)— geef alleentrueterug wanneer invoer is veranderd, zodat Flutter onnodig opnieuw tekenen voorkomt.
Dit fragment tekent een kaart met afgeronde hoeken, een vulling met kleurverloop en een omlijnde rand.
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;
}Opslaan, herstellen en transformaties
Het Canvas bewaart een stapel transformaties en uitsnijdingen. Gebruik die om gedraaide of geschaalde inhoud te tekenen zonder de status blijvend te wijzigen:
canvas.save()plaatst de huidige matrix op de stapel.canvas.translate / rotate / scalewijzigt de matrix.canvas.restore()haalt de vorige toestand weer van de stapel.
Koppel altijd elke save() aan een restore(), anders nemen latere tekenbewerkingen de transformatie over.
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();
}Korte controle
Test je begrip van de configuratie van Paint.
Samenvatting
Je beheerst nu de Canvas-API:
- Paint bepaalt hoe je tekent:
color,style(vulling of lijn),strokeWidth, uiteinden en hoeken. - Basisbewerkingen zoals
drawRect,drawRRectendrawCircleverwerken veelvoorkomende vormen; met Path enmoveTo,lineToen Bézierkrommingen maak je aangepaste vormen. - Shaders (
Gradient.linear,radial,sweep) vullen of omlijnen met kleurverlopen en vervangen de vlakke kleur. - save/restore houdt transformaties gescheiden en
shouldRepaintzorgt ervoor dat renderen efficiënt blijft.
Met deze bouwstenen kun je volledig in Dart grafieken, aangepaste bedieningselementen en rijke versieringen tekenen.
Leer Dart met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 22
- Lessen
- 88
Veelgestelde vragen
Is de les “De Canvas-API: paden, paints en shaders” gratis?
Ja — je kunt hier op het web alle 3 lessen van het leerpad Mobiele ontwikkeling met Flutter, waaronder “De Canvas-API: paden, paints en shaders”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus Mobiele ontwikkeling met Flutter bevat in totaal 4 lessen.
Wat leer ik in “De Canvas-API: paden, paints en shaders”?
Teken vormen, verlopen en lijnen met Canvas-primitieven en de configuratie van Paint. Je oefent met Mobiele ontwikkeling met Flutter door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met Mobiele ontwikkeling met Flutter te beginnen?
Ervaring vooraf is niet nodig. Mobiele ontwikkeling met Flutter op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 1 van 4.
Hoe lang duurt de les “De Canvas-API: paden, paints en shaders”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over Mobiele ontwikkeling met Flutter?
Ja. Elke les over Mobiele ontwikkeling met Flutter bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- De Canvas-API: paden, paints en shaders
- Een interactieve aangepaste chart-widget bouwen
- Clipping, blendmodi en compositing van lagen
- Hit-testing en optimalisatie van repaints