• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2015 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// This example shows how to use the ui.Canvas interface to draw various shapes
6// with gradients and transforms.
7
8import 'dart:math' as math;
9import 'dart:typed_data';
10import 'dart:ui' as ui;
11
12ui.Picture paint(ui.Rect paintBounds) {
13  // First we create a PictureRecorder to record the commands we're going to
14  // feed in the canvas. The PictureRecorder will eventually produce a Picture,
15  // which is an immutable record of those commands.
16  final ui.PictureRecorder recorder = ui.PictureRecorder();
17
18  // Next, we create a canvas from the recorder. The canvas is an interface
19  // which can receive drawing commands. The canvas interface is modeled after
20  // the SkCanvas interface from Skia. The paintBounds establishes a "cull rect"
21  // for the canvas, which lets the implementation discard any commands that
22  // are entirely outside this rectangle.
23  final ui.Canvas canvas = ui.Canvas(recorder, paintBounds);
24
25  final ui.Paint paint = ui.Paint();
26  canvas.drawPaint(ui.Paint()..color = const ui.Color(0xFFFFFFFF));
27
28  final ui.Size size = paintBounds.size;
29  final ui.Offset mid = size.center(ui.Offset.zero);
30  final double radius = size.shortestSide / 2.0;
31
32  final double devicePixelRatio = ui.window.devicePixelRatio;
33  final ui.Size logicalSize = ui.window.physicalSize / devicePixelRatio;
34
35  // Saves a copy of current transform onto the save stack
36  canvas.save();
37
38  // Note that transforms that occur after this point apply only to the
39  // yellow-bluish rectangle
40
41  // This line will cause the transform to shift entirely outside the paint
42  // boundaries, which will cause the canvas interface to discard its
43  // commands. Comment it out to see it on screen.
44  canvas.translate(-mid.dx / 2.0, logicalSize.height * 2.0);
45
46  // Clips the current transform
47  canvas.clipRect(
48    ui.Rect.fromLTRB(0, radius + 50, logicalSize.width, logicalSize.height),
49    clipOp: ui.ClipOp.difference
50  );
51
52  // Shifts the coordinate space of and rotates the current transform
53  canvas.translate(mid.dx, mid.dy);
54  canvas.rotate(math.pi/4);
55
56  final ui.Gradient yellowBlue = ui.Gradient.linear(
57    ui.Offset(-radius, -radius),
58    const ui.Offset(0.0, 0.0),
59    <ui.Color>[const ui.Color(0xFFFFFF00), const ui.Color(0xFF0000FF)],
60  );
61
62  // Draws a yellow-bluish rectangle
63  canvas.drawRect(
64    ui.Rect.fromLTRB(-radius, -radius, radius, radius),
65    ui.Paint()..shader = yellowBlue,
66  );
67
68  // Note that transforms that occur after this point apply only to the
69  // yellow circle
70
71  // Scale x and y by 0.5.
72  final Float64List scaleMatrix = Float64List.fromList(<double>[
73      0.5, 0.0, 0.0, 0.0,
74      0.0, 0.5, 0.0, 0.0,
75      0.0, 0.0, 1.0, 0.0,
76      0.0, 0.0, 0.0, 1.0,
77  ]);
78  canvas.transform(scaleMatrix);
79
80  // Sets paint to transparent yellow
81  paint.color = const ui.Color.fromARGB(128, 0, 255, 0);
82
83  // Draws a transparent yellow circle
84  canvas.drawCircle(ui.Offset.zero, radius, paint);
85
86  // Restores the transform from before `save` was called
87  canvas.restore();
88
89  // Sets paint to transparent red
90  paint.color = const ui.Color.fromARGB(128, 255, 0, 0);
91
92  // Note that this circle is drawn on top of the previous layer that contains
93  // the rectangle and smaller circle
94  canvas.drawCircle(const ui.Offset(150.0, 300.0), radius, paint);
95
96  // When we're done issuing painting commands, we end the recording an receive
97  // a Picture, which is an immutable record of the commands we've issued. You
98  // can draw a Picture into another canvas or include it as part of a
99  // composited scene.
100  return recorder.endRecording();
101}
102
103ui.Scene composite(ui.Picture picture, ui.Rect paintBounds) {
104  final double devicePixelRatio = ui.window.devicePixelRatio;
105  final Float64List deviceTransform = Float64List(16)
106    ..[0] = devicePixelRatio
107    ..[5] = devicePixelRatio
108    ..[10] = 1.0
109    ..[15] = 1.0;
110  final ui.SceneBuilder sceneBuilder = ui.SceneBuilder()
111    ..pushTransform(deviceTransform)
112    ..addPicture(ui.Offset.zero, picture)
113    ..pop();
114  return sceneBuilder.build();
115}
116
117void beginFrame(Duration timeStamp) {
118  final ui.Rect paintBounds = ui.Offset.zero & (ui.window.physicalSize / ui.window.devicePixelRatio);
119  final ui.Picture picture = paint(paintBounds);
120  final ui.Scene scene = composite(picture, paintBounds);
121  ui.window.render(scene);
122}
123
124void main() {
125  ui.window.onBeginFrame = beginFrame;
126  ui.window.scheduleFrame();
127}
128