• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2013 The Flutter 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
5part of engine;
6
7/// A canvas that renders to DOM elements and CSS properties.
8class DomCanvas extends EngineCanvas with SaveElementStackTracking {
9  @override
10  final html.Element rootElement = html.Element.tag('flt-dom-canvas');
11
12  DomCanvas() {
13    rootElement.style
14      ..position = 'absolute'
15      ..top = '0'
16      ..right = '0'
17      ..bottom = '0'
18      ..left = '0';
19  }
20
21  /// Prepare to reuse this canvas by clearing it's current contents.
22  @override
23  void clear() {
24    super.clear();
25    // TODO(yjbanov): we should measure if reusing old elements is beneficial.
26    domRenderer.clearDom(rootElement);
27  }
28
29  @override
30  void clipRect(ui.Rect rect) {
31    throw UnimplementedError();
32  }
33
34  @override
35  void clipRRect(ui.RRect rrect) {
36    throw UnimplementedError();
37  }
38
39  @override
40  void clipPath(ui.Path path) {
41    throw UnimplementedError();
42  }
43
44  @override
45  void drawColor(ui.Color color, ui.BlendMode blendMode) {
46    // TODO(yjbanov): implement blendMode
47    final html.Element box = html.Element.tag('draw-color');
48    box.style
49      ..position = 'absolute'
50      ..top = '0'
51      ..right = '0'
52      ..bottom = '0'
53      ..left = '0'
54      ..backgroundColor = color.toCssString();
55    currentElement.append(box);
56  }
57
58  @override
59  void drawLine(ui.Offset p1, ui.Offset p2, ui.PaintData paint) {
60    throw UnimplementedError();
61  }
62
63  @override
64  void drawPaint(ui.PaintData paint) {
65    throw UnimplementedError();
66  }
67
68  @override
69  void drawRect(ui.Rect rect, ui.PaintData paint) {
70    assert(paint.shader == null);
71    final html.Element rectangle = html.Element.tag('draw-rect');
72    assert(() {
73      rectangle.setAttribute('flt-rect', '$rect');
74      rectangle.setAttribute('flt-paint', '$paint');
75      return true;
76    }());
77    String effectiveTransform;
78    final bool isStroke = paint.style == ui.PaintingStyle.stroke;
79    final double left = math.min(rect.left, rect.right);
80    final double right = math.max(rect.left, rect.right);
81    final double top = math.min(rect.top, rect.bottom);
82    final double bottom = math.max(rect.top, rect.bottom);
83    if (currentTransform.isIdentity()) {
84      if (isStroke) {
85        effectiveTransform =
86            'translate(${left - (paint.strokeWidth / 2.0)}px, ${top - (paint.strokeWidth / 2.0)}px)';
87      } else {
88        effectiveTransform = 'translate(${left}px, ${top}px)';
89      }
90    } else {
91      // Clone to avoid mutating _transform.
92      final Matrix4 translated = currentTransform.clone();
93      if (isStroke) {
94        translated.translate(
95            left - (paint.strokeWidth / 2.0), top - (paint.strokeWidth / 2.0));
96      } else {
97        translated.translate(left, top);
98      }
99      effectiveTransform = matrix4ToCssTransform(translated);
100    }
101    final html.CssStyleDeclaration style = rectangle.style;
102    style
103      ..position = 'absolute'
104      ..transformOrigin = '0 0 0'
105      ..transform = effectiveTransform;
106
107    final String cssColor = paint.color?.toCssString() ?? '#000000';
108
109    if (paint.maskFilter != null) {
110      style.filter = 'blur(${paint.maskFilter.webOnlySigma}px)';
111    }
112
113    if (isStroke) {
114      style
115        ..width = '${right - left - paint.strokeWidth}px'
116        ..height = '${bottom - top - paint.strokeWidth}px'
117        ..border = '${paint.strokeWidth}px solid $cssColor';
118    } else {
119      style
120        ..width = '${right - left}px'
121        ..height = '${bottom - top}px'
122        ..backgroundColor = cssColor;
123    }
124
125    currentElement.append(rectangle);
126  }
127
128  @override
129  void drawRRect(ui.RRect rrect, ui.PaintData paint) {
130    throw UnimplementedError();
131  }
132
133  @override
134  void drawDRRect(ui.RRect outer, ui.RRect inner, ui.PaintData paint) {
135    throw UnimplementedError();
136  }
137
138  @override
139  void drawOval(ui.Rect rect, ui.PaintData paint) {
140    throw UnimplementedError();
141  }
142
143  @override
144  void drawCircle(ui.Offset c, double radius, ui.PaintData paint) {
145    throw UnimplementedError();
146  }
147
148  @override
149  void drawPath(ui.Path path, ui.PaintData paint) {
150    throw UnimplementedError();
151  }
152
153  @override
154  void drawShadow(ui.Path path, ui.Color color, double elevation,
155      bool transparentOccluder) {
156    throw UnimplementedError();
157  }
158
159  @override
160  void drawImage(ui.Image image, ui.Offset p, ui.PaintData paint) {
161    throw UnimplementedError();
162  }
163
164  @override
165  void drawImageRect(
166      ui.Image image, ui.Rect src, ui.Rect dst, ui.PaintData paint) {
167    throw UnimplementedError();
168  }
169
170  @override
171  void drawParagraph(ui.Paragraph paragraph, ui.Offset offset) {
172    final html.Element paragraphElement =
173        _drawParagraphElement(paragraph, offset, transform: currentTransform);
174    currentElement.append(paragraphElement);
175  }
176}
177