DrawingsCreate drawings using canvases and shapes. You can combine lines and curves with fill patterns using a variety of colors and styles. View on YouTube
ShapesA Shape formatter holds a group of open or closed paths. Here the path is a simple line segment. LineSize = LessonExample.FontHeight * 0.5;readonly Stroke Stroke1 = new(LineSize);LineSeg = Canvas(ExtentWidth * 50%, ExtentWidth * 10%) { Margin: LineSize; Shape(null, Stroke1) { OpenPath(0, 0) { LineTo(33%, 100%); }; };};
Open PathsMake an open line path using the OpenPath formatterThe arguments are the starting point of the shape. ZigZag(Stroke stroke) = Canvas(ExtentWidth * 50%, ExtentWidth * 10%) { Margin: LineSize; Shape(null, stroke) { OpenPath(0, 0) { LineTo(33%, 100%); LineTo(66%, 0); LineTo(100%, 100%); } };};BlackZigZag = ZigZag(Stroke1);
Color optionsChange the color of the line with the 2nd parameter of the Stroke constructor. Stroke LS1 = new(LineSize, Colors.Red);Line1 = ZigZag(LS1);
Line StylesChange the style of the line using LineStyles, the 3rd parameter of the Stroke constructor. Stroke LS2 = new(LineSize, Colors.Red, Dotted);Line2 = ZigZag(LS2);
Line Style GalleryUse a loop to enumerate the different LineStyles options. DrawLineStyle(LineStyles linestyle) = Canvas(40%, LessonExample.FontHeight) { Shape(null, new(LineSize, Colors.Black, linestyle, Flat)) { OpenPath(0, 50%) {LineTo(100%, 50%)}; };};LineStyleList = TwoColumTable { foreach (var style in LineStyles) Row {style.Name; DrawLineStyle(style)};};SolidDashedDottedDashDotDashDotDot
Line CapsChange the LineCap style using the 4th parameter of the Stroke constructor. Stroke LS3 = new(LineSize, Colors.Red, Dotted, Round);Line3 = ZigZag(LS3);
Line Cap GalleryIterate over the different LineCaps options. DrawLineCap(LineCaps cap) = Canvas(10%, LessonExample.FontHeight*2) { Shape(null, new(LineSize*2, Colors.Black, LineStyles.Solid, cap)) { OpenPath(0, 50%) { LineTo(100%, 50%);} }; Shape(null, new(LineSize*0.25, Colors.Red, LineStyles.Solid, cap)) { OpenPath(0, 50%) {LineTo(100%, 50%);} };};LineCapTable = TwoColumTable { foreach (var cap in LineCaps) Row {cap.Name; DrawLineCap(cap)};};FlatSquareRound
Line JoinsChange the LineJoin style using the 5th parameter of the Stroke constructor. Stroke LS4 = new(LineSize*2, Colors.Blue, Solid, Flat, Round);Line4 = ZigZag(LS4);
Line Join GalleryLoop over the different LineJoins options. DrawLineJoin(LineJoins linejoin) = Canvas(7%, LessonExample.FontHeight*2) { VAlign: Center; Shape(null, new(LineSize, Colors.Black, Solid, Flat, linejoin)) { OpenPath(0) {LineTo(50%, 70%); LineTo(100%, 0)}; };};LineJoinTable = TwoColumTable { foreach (var linejoin in LineJoins) Row {linejoin.Name; DrawLineJoin(linejoin)};};MiterRoundBevel
Miter limitUse the miterlimit parameter to limit the ratio of the extent of a miter join to the stroke size (default: 4.0).DrawMiterJoin(miter) = Canvas(6%, LessonExample.FontHeight*1.5) { VAlign: Center; Shape(null, new(LineSize*0.25, Colors.Black, Solid, Flat, Miter, miter)) { OpenPath(0, 30%) {LineTo(100%, 50%); LineTo(0, 70%)}; };};MiterTable = TwoColumTable { Row {Bold; "Miter Limit"; "Effect"}; foreach (var m in [50, 1]) Row {TextDigits: 0; m; DrawMiterJoin(m)};};Miter LimitEffect501
Closed pathsUse the ClosedPath formatter to create a closed, fillable path. A final line segment to the origin of the path is automatically added to the end of the path. ShowClosedPath = Canvas(LessonExample.FontHeight*10, LessonExample.FontHeight*10) { Shape(Colors.Green) { ClosedPath(10%, 10%) { LineTo(90%, 90%); LineTo(10%, 90%); // Line to origin is added automatically }; };};
CutoutsAdding a second closed path in the same shape will 'cut a hole' in the first shape. CutoutFigure = Canvas(LessonExample.FontHeight*10, LessonExample.FontHeight*10) { Shape(Colors.Green) { ClosedPath(10%, 10%) { LineTo(90%, 90%); LineTo(10%, 90%); }; EllipsePath(new(new(15%, 40%), new(20%))); // Cutout };};
Repeated segmentsUse a loop to make a shape with a repeated set of line segments. Saw = Canvas(90%, LessonExample.FontHeight*3) { Shape(Colors.Silver) { ClosedPath(0) { foreach (var x in 0%..100% step 10%) { LineTo(x, 100%); LineTo(x, 50%); } LineTo(100%, 0); }; };};
PolygonPathMake a regular n-sided polygon using the PolygonPath function. NGon(radius, n) = VBox(radius*2+6) { HAlign: Center; Span {TextColor: Colors.Red; n}; Shape(Colors.Yellow, 3) { PolygonPath(new(0, radius*2), n, -90 degrees); };};NGons = HBox { VAlign: Top; var sep = LessonExample.FontHeight * 0.5; Separation: sep; NGon(ExtentWidth / 16 - sep, each 3..10);};345678910
QuadTo formatterMake a quadratic curve with two endpoints and a control point using the QuadTo function. CheckMark = Canvas(LessonExample.FontHeight*7, LessonExample.FontHeight*5) { Shape(Colors.LightGreen, Colors.DarkGreen) { ClosedPath(1%, 50%) { QuadTo(new(9%, 44%), new(20%, 43%)); QuadTo(new(31%, 52%), new(36%, 69%)); QuadTo(new(60%, 28%), new(99%, 5%)); QuadTo(new(55%, 39%), new(36%, 96%)); QuadTo(new(34.5%, 100%), new(33%, 96%)); QuadTo(new(21%, 60%), new(1%, 50%)); }; };};
Quadratic ExamplesHere are some examples of how the position of the control point affects the shape of a quadratic curve. ShowQuads = Canvas { Margin: LineSize; ShowQExample(each QuadExamples);};
Cubic curvesMake a cubic curve with two endpoints and two control points, using the CurveTo function. BowTie = Canvas(LessonExample.FontHeight*5, LessonExample.FontHeight*5) { Shape(null, LS1) { OpenPath(33%, 10%) { CurveTo(new(100%, 100%), new(0, 100%), new(65%, 10%)); }; };};
Cubic ExamplesThe following examples show how the control points bend the curve.ShowCubics = Canvas { Margin: LineSize; ShowCurve(each CubicExamples);};
Glyph pathsPlacing a string inside a shape will cause the paths of the character glyphs to be added to the shape. This allows you to build fanciful titles and designs with text. GlyphBox(text, angle=0) = Canvas(null, null, new Edge(0, LineSize*2)) { Background: AgedWood; BorderRadius: LineSize; Transform: Transform.Rotate(angle); TransformFit: true; Shape(null, new(LineSize*0.25, Colors.Black, Dotted, Round)) { text; };};AGlyph = HBox { VAlign: Top; TextHeight: LessonExample.FontHeight*5; GlyphBox("Shooting"); GlyphBox("Range", 20 degrees);};