1 module uim.html.elements.canvas;
2 
3 import std.stdio;
4 import std.conv;
5 import std..string;
6 import uim.html;
7 
8 alias STRINGAA = string[string];
9 
10 class DH5Canvas : DH5Obj {
11 	string pre = "context.";
12 	mixin(H5This!"canvas");
13 
14 	this(string id, int width, int height, string style = "") { 
15 		super("canvas"); 
16 		this.attributes(["id":id, "width":to!string(width), "height":to!string(height), "style": style]); /* clean; */ }
17 
18 	// AddColorStop() 	Specifies the colors and stop positions in a gradient object
19 	auto addColorStop(this O)(string varName, string stop, string color) { 
20 		this.js(varName~".addColorStop("~stop~","~color~");"); return cast(O)this; }
21 	unittest {
22 /*		assert(Assert(H5Canvas("test", [""]).addColorStop("name", "0", "black"), `<canvas id="test"></canvas><script>function drawtest(){var canvas=document.getElementById('test');`~
23 		`var context=canvas.getContext('2d');name.addColorStop(0,black);}window.addEventListener("load",drawtest,true);</script>`));
24 */	}
25 
26 	// Arc() 	Creates an arc/curve (used to create circles, or parts of circles)
27 	auto arc(this O)(int x, int y, int r, int sAngle, int eAngle, bool b = false) { this.js(pre~"arc(%s,%s,%s,%s,%s,%s);".format(x, y, r, sAngle, eAngle, b ? "true" : "false")); return cast(O)this; }
28 	auto arc(this O)(string x, string y, string r, string sAngle, string eAngle, bool b = false) { this.js(pre~"arc(%s,%s,%s,%s,%s,%s);".format(x, y, r, sAngle, eAngle, b ? "true" : "false")); return cast(O)this; }
29 
30 	// ArcTo() 	Creates an arc/curve between two tangents
31 	auto arcTo(this O)(int x1, int y1, int x2, int y2, int r) { this.js(pre~"arcTo(%s,%s,%s,%s,%s);".format(x1, y1, x2, y2, r)); return cast(O)this; }
32 	auto arcTo(this O)(string x1, string y1, string x2, string y2, string r) { this.js(pre~"arcTo(%s,%s,%s,%s,%s);".format(x1, y1, x2, y2, r)); return cast(O)this; }
33 
34 	// beginPath() 	Begins a path, or resets the current path
35 	auto beginPath(this O)() { this.js(pre~"beginPath();"); return cast(O)this; }
36 
37 	// BezierCurveTo() 	Creates a cubic Bézier curve
38 	auto bezierCurveTo(this O)(int cpx0, int cpy0, int cpx1, int cpy1, int x, int  y) { this.js(pre~"bezierCurveTo(%s,%s,%s,%s,%s,%s);".format(cpx0, cpy0, cpx1, cpy1, x, y)); return cast(O)this; }
39 	auto bezierCurveTo(this O)(string cpx0, string cpy0, string cpx1, string cpy1, string x, string  y) { this.js(pre~"bezierCurveTo(%s,%s,%s,%s,%s,%s);".format(cpx0, cpy0, cpx1, cpy1, x, y)); return cast(O)this; }
40 
41 	//	clearRect 	Sets or returns the color, gradient, or pattern used to stroke the drawing
42 	auto clearRect(this O)(int x, int y, int width, int height) { this.js(pre~"clearRect(%s,%s,%s,%s);".format(x, y, width, height)); return cast(O)this; }
43 	auto clearRect(this O)(string x, string y, string width, string height) { this.js(pre~"clearRect(%s,%s,%s,%s);".format(x, y, width, height)); return cast(O)this; }
44 	unittest {
45 /*		assert(Assert(H5Canvas("test", [""]).clearRect("0","0","10","10"), `<canvas id="test"></canvas><script>function drawtest(){var canvas=document.getElementById('test');`~
46 		`var context=canvas.getContext('2d');context.clearRect(0,0,10,10);}window.addEventListener("load",drawtest,true);</script>`));
47 */	}
48 
49 	// Clip() 	Clips a region of any shape and size from the original canvas
50 	auto clip(this O)() { this.js(pre~"clip();"); return cast(O)this; }
51 
52 	// ClosePath() 	Creates a path from the current point back to the starting point
53  	auto closePath(this O)() { this.js(pre~"closePath();"); return cast(O)this; }
54 
55 	// CreateImageData() 	Creates a new, blank ImageData object
56 	auto createImageData(this O)(double width, double height) { this.js(pre~"createImageData(%s,%s)".format(width, height));  return cast(O)this; }
57 	auto createImageData(this O)(string width, string height) { this.js(pre~"createImageData(%s,%s)".format(width, height)); return cast(O)this; }
58 	auto createImageData(this O)(string image) { this.js(pre~"createImageData(%s)".format(image)); return cast(O)this; }
59 
60 	// CreateLinearGradient() 	Creates a linear gradient (to use on canvas content)
61 	auto createLinearGradient(this O)(string varName, int x0, int y0, int x1, int y1) { 
62 		this.js("var %s=context.createLinearGradient(%s,%s,%s,%s);".format(varName, x0, y0, x1, y1)); return cast(O)this; }
63 	auto createLinearGradient(this O)(string varName, string x0, string y0, string x1, string y1) { 
64 		this.js("var %s=context.createLinearGradient(%s,%s,%s,%s);".format(varName, x0, y0, x1, y1)); return cast(O)this; }
65 	unittest {
66 /*		assert(Assert(H5Canvas("test", [""]).createLinearGradient("name", "0", "0", "10", "10"), `<canvas id="test"></canvas><script>function drawtest(){var canvas=document.getElementById('test');`~
67 		`var context=canvas.getContext('2d');var name=context.createLinearGradient(0,0,10,10);}window.addEventListener("load",drawtest,true);</script>`));
68 */	}
69 
70 	// CreatePattern() 	Repeats a specified element in the specified direction
71 	auto createPattern(this O)(string varName,string image,string mode) { 
72 		this.js("var %s=context.createPattern(%s,%s);".format(varName, image, mode)); return cast(O)this; }
73 	unittest {
74 /*		assert(Assert(H5Canvas("test", [""]).createPattern("name", "image", "mode"), `<canvas id="test"></canvas><script>function drawtest(){var canvas=document.getElementById('test');`~
75 		`var context=canvas.getContext('2d');var name=context.createPattern(image,mode);}window.addEventListener("load",drawtest,true);</script>`));
76 */	}
77 
78 	// CreateRadialGradient() 	Creates a radial/circular gradient (to use on canvas content)
79 	auto createRadialGradient(this O)(string varName, int x0, int y0, int r0, int x1, int y1, int r1) { 
80 		this.js("var %s=context.createRadialGradient(%s,%s,%s,%s,%s,%s);".format(varName, x0, y0, r0, x1, y1, r1)); return cast(O)this; }
81 	auto createRadialGradient(this O)(string varName, string x0, string y0, string r0, string x1, string y1, string r1) { 
82 		this.js("var %s=context.createRadialGradient(%s,%s,%s,%s,%s,%s);".format(varName, x0, y0, r0, x1, y1, r1)); return cast(O)this; }
83 	unittest {
84 /*		assert(Assert(H5Canvas("test", [""]).createRadialGradient("name", "0", "0", "5", "10", "10", "100"), `<canvas id="test"></canvas><script>function drawtest(){var canvas=document.getElementById('test');`~
85 		`var context=canvas.getContext('2d');var name=context.createRadialGradient(0,0,5,10,10,100);}window.addEventListener("load",drawtest,true);</script>`));
86 */	}
87 
88 	// ----- Image Drawing
89 	// DrawImage() 	Draws an image, canvas, or video onto the canvas
90 	auto drawImage(this O)(string image, double x, double y) { this.js(pre~"drawImage(%s,%s,%s);".format(image, x, y)); return cast(O)this; }
91 	auto drawImage(this O)(string image, string x, string y) { this.js(pre~"drawImage(%s,%s,%s);".format(image, x, y)); return cast(O)this; }
92 	auto drawImage(this O)(string image, double x, double y, double width, double height) { this.js(pre~"drawImage(%s,%s,%s,%s,%s);".format(image, x, y, width, height)); return cast(O)this; }
93 	auto drawImage(this O)(string image, string x, string y, string width, string height) { this.js(pre~"drawImage(%s,%s,%s,%s,%s);".format(image, x, y, width, height)); return cast(O)this; }
94 	auto drawImage(this O)(string image, double sx, double sy, double sWidth, double sHeight, double x, double y, double width, double height) { this.js(pre~"drawImage(%s,%s,%s,%s,%s,%s,%s,%s,%s);".format(image, sx, sy, sWidth, sHeight, x, y, width, height)); return cast(O)this; }
95 
96 	// Fill() 	Fills the current drawing (path)
97  	auto fill(this O)() { this.js(pre~"fill();"); return cast(O)this; }
98 
99 	//	FillRect 	Sets or returns the color, gradient, or pattern used to fill the drawing
100 	auto fillRect(this O)(int x, int y, int width, int height) { this.js(pre~"fillRect(%s,%s,%s,%s);".format(x, y, width, height)); return cast(O)this; }
101 	auto fillRect(this O)(string x, string y, string width, string height) { this.js(pre~"fillRect(%s,%s,%s,%s);".format(x, y, width, height)); return cast(O)this; }
102 	unittest {
103 /*		assert(Assert(H5Canvas("test", [""]).fillRect("0","0","10","10"), `<canvas id="test"></canvas><script>function drawtest(){var canvas=document.getElementById('test');`~
104 		`var context=canvas.getContext('2d');context.fillRect(0,0,10,10);}window.addEventListener("load",drawtest,true);</script>`));
105 */	}
106 
107 	// FillStyle 	Sets or returns the color, gradient, or pattern used to fill the drawing
108 	auto fillStyle(this O)(string style) { this.js(pre~"fillStyle="~style~";"); return cast(O)this; }
109 	unittest {
110 /*		assert(Assert(H5Canvas("test", [""]).fillStyle("value"), `<canvas id="test"></canvas><script>function drawtest(){var canvas=document.getElementById('test');`~
111 		`var context=canvas.getContext('2d');context.fillStyle=value;}window.addEventListener("load",drawtest,true);</script>`));
112 */	}
113 	// FillText() 	Draws "filled" text on the canvas
114 	auto fillText(this O)(string text, double x, double y) { this.js(pre~"fillText(%s,%s,%s);".format(text, x, y)); return cast(O)this; }
115 	auto fillText(this O)(string text, double x, double y, double maxWidth) { this.js(pre~"fillText(%s,%s,%s,%s);".format(text, x, y, maxWidth)); return cast(O)this; }
116 	auto fillText(this O)(string text, string x, string y) { this.js(pre~"fillText(%s,%s,%s);".format(text, x, y)); return cast(O)this; }
117 	auto fillText(this O)(string text, string x, string y, string maxWidth) { this.js(pre~"fillText(%s,%s,%s,%s);".format(text, x, y, maxWidth)); return cast(O)this; }
118 
119 	// Font 	Sets or returns the current font properties for text content
120 	auto font(this O)(string value) { this.js(pre~"font("~value~");"); return cast(O)this; }
121 
122 	// GetImageData() 	Returns an ImageData object that copies the pixel data for the specified rectangle on a canvas
123 	auto getImageData(this O)(double x, double y, double width, double height) { this.js(pre~"getImageData(%s,%s,%s,%s)".format(x, y, width, height)); return this; }
124 	auto getImageData(this O)(string x, string y, string width, string height) { this.js(pre~"getImageData(%s,%s,%s,%s)".format(x, y, width, height)); return this; }
125 
126 	// GlobalAlpha 	Sets or returns the current alpha or transparency value of the drawing
127 	auto globalAlpha(this O)(double number) { this.js(pre~"globalAlpha(%s);".format(number)); return cast(O)this; }
128 	auto globalAlpha(this O)(string number) { this.js(pre~"globalAlpha(%s);".format(number)); return cast(O)this; }
129 
130 	// globalCompositeOperation 	Sets or returns how a new image are drawn onto an existing image
131 	enum CompositeOperations : string {
132 		SourceOver = "source-over", // 	Default. Displays the source image over the destination image 	
133 		SourceATop = "source-atop", // 	Displays the source image on top of the destination image. The part of the source image that is outside the destination image is not shown 	
134 		SourceIn = "source-in", // 	Displays the source image in to the destination image. Only the part of the source image that is INSIDE the destination image is shown, and the destination image is transparent 	
135 		SourceOut = "source-out", // 	Displays the source image out of the destination image. Only the part of the source image that is OUTSIDE the destination image is shown, and the destination image is transparent 	
136 		DestinationOver = "destination-over", // 	Displays the destination image over the source image 	
137 		DestinationATop = "destination-atop", // 	Displays the destination image on top of the source image. The part of the destination image that is outside the source image is not shown 	
138 		DestinationIn = "destination-in", // 	Displays the destination image in to the source image. Only the part of the destination image that is INSIDE the source image is shown, and the source image is transparent 	
139 		DestinationOut = "destination-out", // 	Displays the destination image out of the source image. Only the part of the destination image that is OUTSIDE the source image is shown, and the source image is transparent 	
140 		Lighter = "lighter", // 	Displays the source image + the destination image 	
141 		Copy = "copy", // 	Displays the source image. The destination image is ignored 	
142 		Xor = "xor" // 	The source image is combined by using an exclusive OR with the destination image
143 	}
144 	auto globalCompositeOperation(this O)(CompositeOperations operation) { this.js(pre~"globalCompositeOperation='%s';".format(operation)); return cast(O)this; }
145 	auto globalCompositeOperation(this O)(string operation) { this.js(pre~"globalCompositeOperation=%s;".format(operation)); return cast(O)this; }
146 
147 	// IsPointInPath() 	Returns true if the specified point is in the current path, otherwise false
148 	auto isPointInPath(this O)(double x, double y) { this.js(pre~"isPointInPath(%s,%s);".format(x, y)); return cast(O)this; }
149 	auto isPointInPath(this O)(string x, string y) { this.js(pre~"isPointInPath(%s,%s);".format(x, y)); return cast(O)this; }
150 
151 	// LineCap - Sets the style of the end caps for a line
152 	// valid values are butt, round, square
153 	auto lineCap(this O)(string value) { this.js(pre~"lineCap=%s;".format(value)); return cast(O)this; }
154 
155 	// LineJoin 	Sets the type of corner created, when two lines meet
156 	auto lineJoin(this O)(string value) { this.js(pre~"lineJoin=%s;".format(value)); return cast(O)this; }
157 
158 	// LineTo() 	Adds a new point and creates a line from that point to the last specified point in the canvas (x, y)
159 	auto lineTo(this O)(int x, int y) { this.js(pre~"lineTo(%s,%s);".format(x, y)); return cast(O)this; }
160 	auto lineTo(this O)(string x, string y) { this.js(pre~"lineTo(%s,%s);".format(x, y)); return cast(O)this; }
161 
162 	//	lineWidth 	Sets the current line width
163 	auto lineWidth(this O)(uint value) { this.js(pre~"lineWidth=%s;".format(value)); return cast(O)this; }
164 	auto lineWidth(this O)(string value) { this.js(pre~"lineWidth=%s;".format(value)); return cast(O)this; }
165 
166 	//	// MiterLimit 	Sets or returns the maximum miter length
167 	auto miterLimit(this O)(uint length) { this.js(pre~"miterLimit=%s;".format(length)); return cast(O)this; }
168 	auto miterLimit(this O)(string length) { this.js(pre~"miterLimit=%s;".format(length)); return cast(O)this; }
169 
170 	// measureText() 	Moves the path to the specified point in the canvas, without creating a line
171 	auto measureText(this O)(string varName, string text) { this.js(("%s="~pre~"measureText(%s).width;").format(varName, text)); return cast(O)this; }
172 
173 	// MoveTo() 	Moves the path to the specified point in the canvas, without creating a line
174 	auto moveTo(this O)(int x, int y) { this.js(pre~"moveTo(%s,%s);".format(x, y)); return cast(O)this; }
175 	auto moveTo(this O)(string x, string y) { this.js(pre~"moveTo(%s,%s);".format(x, y)); return cast(O)this; }
176 
177 	// PutImageData() 	Puts the image data (from a specified ImageData object) back onto the canvas
178 	auto putImageData(this O)(string image, double x, double y) { this.js(pre~"putImageData(%s,%s,%s);".format(image, x, y)); return cast(O)this; }
179 	auto putImageData(this O)(string image, string x, string y) { this.js(pre~"putImageData(%s,%s,%s);".format(image, x, y)); return cast(O)this; }
180 	auto putImageData(this O)(string image, double x, double y, double dirtyX, double dirtyY, double dirtyWidth, double dirtyHeight) { this.js(pre~"putImageData(%s,%s,%s,%s,%s,%s,%s);".format(image, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight)); return cast(O)this; }
181 	auto putImageData(this O)(string image, string x, string y, string dirtyX, string dirtyY, string dirtyWidth, string dirtyHeight) { this.js(pre~"putImageData(%s,%s,%s,%s,%s,%s,%s);".format(image, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight)); return cast(O)this; }
182 
183 	// QuadraticCurveTo() 	Creates a quadratic Bézier curve
184 	auto quadraticCurveTo(this O)(int cpx, int cpy, int x, int y) { this.js(pre~"quadraticCurveTo(%s,%s,%s,%s);".format(cpx, cpy, x, y)); return cast(O)this; }
185 	auto quadraticCurveTo(this O)(string cpx, string cpy, string x, string y) { this.js(pre~"quadraticCurveTo(%s,%s,%s,%s);".format(cpx, cpy, x, y)); return cast(O)this; }
186 
187 	//	Rect() 	Creates a rectangle
188 	auto rect(this O)(int x, int y, int width, int height) { this.js(pre~"rect(%s,%s,%s,%s);".format(x, y, width, height)); return cast(O)this; }
189 	auto rect(this O)(string x, int y, int width, int height) { this.js(pre~"rect(%s,%s,%s,%s);".format(x, y, width, height)); return cast(O)this; }
190 
191 	// Restore() 	Returns previously saved path state and attributes
192 	auto restore(this O)() { this.js(pre~"restore();"); return cast(O)this; }
193 
194 	// Rotate() 	Rotate	s the current drawing
195 	auto rotate(this O)(double angle) { this.js(pre~"rotate(%s);".format(angle)); return cast(O)this; }
196 	auto rotate(this O)(string angle) { this.js(pre~"rotate(%s);".format(angle)); return cast(O)this; }
197 
198 	// Save() 	Saves the state of the current context
199 	auto save(this O)() { this.js(pre~"save();"); return cast(O)this; }
200 
201 	// Scale() 	Scales the current drawing bigger or smaller
202 	auto scale(this O)(double scaleWidth, double scaleHeight) { this.js(pre~"scale(%s,%s);".format(scaleWidth, scaleHeight)); return cast(O)this; }
203 	auto scale(this O)(string scaleWidth, string scaleHeight) { this.js(pre~"scale(%s,%s);".format(scaleWidth, scaleHeight)); return cast(O)this; }
204 
205 	// ShadowBlur 	Sets or returns the blur level for shadows
206 	auto shadowBlur(this O)(uint blur) { this.js(pre~"shadowBlur=%s;".format(blur)); return cast(O)this; }
207 	auto shadowBlur(this O)(string blur) { this.js(pre~"shadowBlur=%s;".format(blur)); return cast(O)this; }
208 	unittest {
209 /*		assert(Assert(H5Canvas("test", [""]).shadowBlur("value"), `<canvas id="test"></canvas><script>function drawtest(){var canvas=document.getElementById('test');`~
210 		`var context=canvas.getContext('2d');context.shadowBlur=value;}window.addEventListener("load",drawtest,true);</script>`));
211 */	}
212 
213 	// ShadowColor 	Sets or returns the color to use for shadows
214 	// auto shadowColor(this O)() { add(pre~"shadowColor"); return this; }
215 	auto shadowColor(this O)(string color) { this.js(pre~"shadowColor=%s;".format(color)); return cast(O)this; }
216 	unittest {
217 /*		assert(Assert(H5Canvas("test", [""]).shadowColor("value"),  `<canvas id="test"></canvas><script>function drawtest(){var canvas=document.getElementById('test');`~
218 		`var context=canvas.getContext('2d');context.shadowColor=value;}window.addEventListener("load",drawtest,true);</script>`));
219 */	}
220 
221 	// ShadowOffsetX 	Sets the horizontal distance of the shadow from the shape
222 	auto shadowOffsetX(this O)(int value) { this.js(pre~"shadowOffsetX=%s;".format(value)); return cast(O)this; }
223 	auto shadowOffsetX(this O)(string value) { this.js(pre~"shadowOffsetX=%s;".format(value)); return cast(O)this; }
224 	unittest {
225 /*		assert(Assert(H5Canvas("test", [""]).shadowOffsetX("value"), `<canvas id="test"></canvas><script>function drawtest(){var canvas=document.getElementById('test');`~
226 		`var context=canvas.getContext('2d');context.shadowOffsetX=value;}window.addEventListener("load",drawtest,true);</script>`));
227 */	}
228 
229 	// ShadowOffsetY 	Sets the vertical distance of the shadow from the shape
230 	auto shadowOffsetY(this O)(int value) { this.js(pre~"shadowOffsetY=%s;".format(value)); return cast(O)this; }
231 	auto shadowOffsetY(this O)(string value) { this.js(pre~"shadowOffsetY=%s;".format(value)); return cast(O)this; }
232 	unittest {
233 /*		assert(Assert(H5Canvas("test", [""]).shadowOffsetY("value"), `<canvas id="test"></canvas><script>function drawtest(){var canvas=document.getElementById('test');`~
234 		`var context=canvas.getContext('2d');context.shadowOffsetY=value;}window.addEventListener("load",drawtest,true);</script>`));
235 */	}
236 
237 	// SetTransform() 	Resets the current transform to the identity matrix. Then runs transform()
238 auto setTransform(this O)(double a, double b, double c, double d, double e, double f) { this.js(pre~"setTransform(%s,%s,%s,%s,%s,%s);".format(a, b, c, d, e, f)); return cast(O)this; }
239 auto setTransform(this O)(string a, string b, string c, string d, string e, string f) { this.js(pre~"setTransform(%s,%s,%s,%s,%s,%s);".format(a, b, c, d, e, f)); return cast(O)this; }
240 
241 	// Stroke() 	Actually draws the path you have defined
242 	auto stroke(this O)() { this.js(pre~"stroke();"); return cast(O)this; }
243 
244 	//	StrokeRect 	Sets or returns the color, gradient, or pattern used to stroke the drawing
245 	auto strokeRect(this O)(int x, int y, int width, int height) { this.js(pre~"strokeRect(%s,%s,%s,%s);".format(x,y,width,height)); return cast(O)this;	}
246 	auto strokeRect(this O)(string x, string y, string width, string height) { this.js(pre~"strokeRect(%s,%s,%s,%s);".format(x,y,width,height)); return cast(O)this; }
247 	unittest {
248 /*		assert(Assert(H5Canvas("test", [""]).strokeRect("0","0","10","10"), `<canvas id="test"></canvas><script>function drawtest(){var canvas=document.getElementById('test');`~
249 		`var context=canvas.getContext('2d');context.strokeRect(0,0,10,10);}window.addEventListener("load",drawtest,true);</script>`));
250 */	}
251 	//	StrokeStyle 	Sets or returns the color, gradient, or pattern used for strokes
252 	auto strokeStyle(this O)(string style) { this.js(pre~"strokeStyle="~style~";"); return cast(O)this; }
253 	unittest {
254 /*		assert(Assert(H5Canvas("test", [""]).strokeStyle("value"), `<canvas id="test"></canvas><script>function drawtest(){var canvas=document.getElementById('test');`~
255 		`var context=canvas.getContext('2d');context.strokeStyle=value;}window.addEventListener("load",drawtest,true);</script>`));
256 */	}
257 
258 	// StrokeText() 	Draws text on the canvas (no fill)
259 	auto strokeText(this O)(string text, double x, double y) { this.js(pre~"strokeText(%s,%s,%s);".format(text, x, y)); return cast(O)this; }
260 	auto strokeText(this O)(string text, string x, string y) { this.js(pre~"strokeText(%s,%s,%s);".format(text, x, y)); return cast(O)this; }
261 	auto strokeText(this O)(string text, double x, double y, double maxWidth) { this.js(pre~"strokeText(%s,%s,%s,%s);".format(text, x, y, maxWidth)); return cast(O)this; }
262 	auto strokeText(this O)(string text, string x, string y, string maxWidth) { this.js(pre~"strokeText(%s,%s,%s,%s);".format(text, x, y, maxWidth)); return cast(O)this; }
263 
264 	// TextAlign 	Sets or returns the current alignment for text content
265 	enum TextAligns : string { 
266 		Start = "start", // Default. The text starts at the specified position
267 		End = "end", // The text ends at the specified position 
268 		Center = "center", // The center of the text is placed at the specified position 	
269 		Left = "left", // The text starts at the specified position 	
270 		Right = "right" // The text ends at the specified position 
271 	}
272 	auto textAlign(this O)(TextAligns anAlign) { this.js(pre~"textAlign='%s';".format(anAlign)); return cast(O)this; }
273 	auto textAlign(this O)(string anAlign) { this.js(pre~"textAlign=%s;".format(anAlign)); return cast(O)this; }
274 
275 	// TextBaseline 	Sets or returns the current text baseline used when drawing text
276 	enum TextBaselines : string { 
277 		ALphabetic = "alphabetic", // Default. The text baseline is the normal alphabetic baseline 
278 		Top = "top", // The text baseline is the top of the em square 
279 		Hanging = "hanging", // The text baseline is the hanging baseline 
280 		Middle = "middle", // 	The text baseline is the middle of the em square 
281 		Ideographic = "ideographic", // The text baseline is the ideographic baseline 
282 		Bottom = "bottom" // The text baseline is the bottom of the bounding box
283 	}
284 	auto textBaseline(this O)(TextBaselines aBaseline) { this.js(pre~"textBaseline = '%s';".format(aBaseline)); return cast(O)this; }
285 	auto textBaseline(this O)(string aBaseline) { this.js(pre~"textBaseline = '%s';".format(aBaseline)); return cast(O)this; }
286 
287 	// Translate() 	Remaps the (0,0) position on the canvas
288 	auto translate(this O)(double x, double y) { this.js(pre~"translate(%s,%s);".format(x, y)); return cast(O)this; }
289 	auto translate(this O)(string x, string y) { this.js(pre~"translate(%s,%s);".format(x, y)); return cast(O)this; }
290 
291 	// Transform() 	Replaces the current transformation matrix for the drawing
292 	auto transform(this O)(double a, double b, double c, double d, double e, double f) { this.js(pre~"transform(%s,%s,%s,%s,%s,%s);".format(a, b, c, d, e, f)); return cast(O)this; }
293 	auto transform(this O)(string a, string b, string c, string d, string e, string f) { this.js(pre~"transform(%s,%s,%s,%s,%s,%s);".format(a, b, c, d, e, f)); return cast(O)this; }
294 
295 	override string toString() {
296 		if (_id.length == 0) _id="canvas"~to!string(uniform(0, 1_000_000));
297 		auto drawFunc = `draw`~_id;
298 		_js = `function `~drawFunc~`(){var canvas=document.getElementById('`~_id~`');`~
299 		`var context=canvas.getContext('2d');`~_js~`}window.addEventListener("load",`~drawFunc~`,true);`;
300 		return super.toString;
301 	}
302 }
303 mixin(H5Short!"Canvas");
304 auto H5Canvas(string id, int width, int height, string style = "") { 
305 	return new DH5Canvas(id, width, height, style); 
306 }