/
canvas_shadow_wrapper.dart
135 lines (115 loc) · 3.58 KB
/
canvas_shadow_wrapper.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
part of '../display_ex.dart';
/// This class is a replacement for the deprecated shadow property of the
/// DisplayObject class. Please consider to use the DropShadowFilter class
/// which is the recommended technique to render shadows in WebGL.
///
/// The CanvasShadowWrapper takes an arbitrary DisplayObject and renders
/// it with a drop shadow if the render engine is Canvas2D (not WebGL).
///
/// Example with deprecated shadow property:
///
/// var spaceship = new Spaceship();
/// spaceship.x = 160;
/// spaceship.y = 200;
/// spaceship.shadow = new Shadow(Color.Black, 10, 10, 5);
/// stage.addChild(spaceship);
///
/// Example with the CanvasShadowWrapper class:
///
/// var spaceship = new Spaceship();
/// spaceship.x = 160;
/// spaceship.y = 200;
/// var shadow = new CanvasShadowWrapper(spaceship, Color.Black, 10, 10, 5);
/// stage.addChild(shadow);
///
class CanvasShadowWrapper extends DisplayObject {
final DisplayObject displayObject;
int shadowColor;
num shadowOffsetX;
num shadowOffsetY;
num shadowBlur;
CanvasShadowWrapper(this.displayObject,
[this.shadowColor = Color.Black,
this.shadowOffsetX = 10.0,
this.shadowOffsetY = 10.0,
this.shadowBlur = 0.0]);
//-----------------------------------------------------------------------------------------------
void _throwUnsupportedError() {
throw UnsupportedError(
'CanvasShadowWrapper does not implement this property or method.');
}
@override
set x(num value) {
_throwUnsupportedError();
}
@override
set y(num value) {
_throwUnsupportedError();
}
@override
set pivotX(num value) {
_throwUnsupportedError();
}
@override
set pivotY(num value) {
_throwUnsupportedError();
}
@override
set scaleX(num value) {
_throwUnsupportedError();
}
@override
set scaleY(num value) {
_throwUnsupportedError();
}
@override
set skewX(num value) {
_throwUnsupportedError();
}
@override
set skewY(num value) {
_throwUnsupportedError();
}
@override
set rotation(num value) {
_throwUnsupportedError();
}
@override
set alpha(num value) {
_throwUnsupportedError();
}
@override
set mask(Mask? mask) {
_throwUnsupportedError();
}
//-----------------------------------------------------------------------------------------------
@override
DisplayObject? hitTestInput(num localX, num localY) {
final matrix = displayObject.transformationMatrix;
final deltaX = localX - matrix.tx;
final deltaY = localY - matrix.ty;
final childX = (matrix.d * deltaX - matrix.c * deltaY) / matrix.det;
final childY = (matrix.a * deltaY - matrix.b * deltaX) / matrix.det;
return displayObject.hitTestInput(childX, childY);
}
//-----------------------------------------------------------------------------------------------
@override
void render(RenderState renderState) {
final renderContext = renderState.renderContext;
if (renderContext is RenderContextCanvas) {
final rawContext = renderContext.rawContext;
final shadowMatrix = renderState.globalMatrix;
rawContext.save();
rawContext.shadowColor = color2rgba(shadowColor);
rawContext.shadowBlur = sqrt(shadowMatrix.det) * shadowBlur;
rawContext.shadowOffsetX =
shadowOffsetX * shadowMatrix.a + shadowOffsetY * shadowMatrix.c;
rawContext.shadowOffsetY =
shadowOffsetX * shadowMatrix.b + shadowOffsetY * shadowMatrix.d;
renderState.renderObject(displayObject);
rawContext.restore();
} else {
renderState.renderObject(displayObject);
}
}
}