22
33Class to create ** linear, radial, conic and elliptic gradients** and ** image patterns** as bitmaps without canvas
44
5- ** version 1.2.1 ** (13 kB minified)
5+ ** version 1.2.2 ** (13 kB minified)
66
77** API:**
88
@@ -23,6 +23,7 @@ grad.transform.reflectX();
2323grad .transform .reflectY ();
2424grad .transform .skewX (s);
2525grad .transform .skewY (s);
26+ grad .transform .transform (a, b, c, d, e, f);
2627grad .transform .reset ();
2728grad .transform .save ();
2829grad .transform .restore ();
@@ -41,6 +42,7 @@ pat.transform.reflectX();
4142pat .transform .reflectY ();
4243pat .transform .skewX (s);
4344pat .transform .skewY (s);
45+ pat .transform .transform (a, b, c, d, e, f);
4446pat .transform .reset ();
4547pat .transform .save ();
4648pat .transform .restore ();
@@ -53,6 +55,7 @@ pat.getBitmap(width, height);
5355
5456``` javascript
5557const w = 200 , h = 200 ;
58+ const Matrix = Gradient .Matrix ;
5659
5760function addColorStops (gradient )
5861{
@@ -63,6 +66,22 @@ function addColorStops(gradient)
6366 });
6467 return gradient;
6568}
69+ function fill_transformed_rect (ctx , x , y , w , h )
70+ {
71+ const m = ctx .getTransform ();
72+ const m2 = (new Matrix (m .a , m .c , m .e , m .b , m .d , m .f )).inv ();
73+ const p1 = m2 .transform (x, y),
74+ p2 = m2 .transform (x+ w, y),
75+ p3 = m2 .transform (x+ w, y+ h),
76+ p4 = m2 .transform (x, y+ h);
77+ ctx .beginPath ();
78+ ctx .moveTo (p1 .x , p1 .y );
79+ ctx .lineTo (p2 .x , p2 .y );
80+ ctx .lineTo (p3 .x , p3 .y );
81+ ctx .lineTo (p4 .x , p4 .y );
82+ ctx .closePath ();
83+ ctx .fill ();
84+ }
6685function drawLinearGradient (x1 , y1 , x2 , y2 )
6786{
6887 const canvas1 = document .getElementById (' linear1' );
@@ -107,26 +126,56 @@ function drawEllipticGradient(cx, cy, rx, ry, angle)
107126{
108127 const canvas1 = document .getElementById (' elliptic1' );
109128 const canvas2 = document .getElementById (' elliptic2' );
129+ const canvas3 = document .getElementById (' elliptic3' );
130+ const canvas4 = document .getElementById (' elliptic4' );
110131 const ctx1 = canvas1 .getContext (" 2d" );
111132 const ctx2 = canvas2 .getContext (" 2d" );
133+ const ctx3 = canvas3 .getContext (" 2d" );
134+ const ctx4 = canvas4 .getContext (" 2d" );
112135
113136 const r = Math .max (rx, ry), sx = rx/ r, sy = ry/ r;
114137
115138 const gradient1 = ctx1 .createRadialGradient (cx/ sx, cy/ sy, 0 , cx/ sx, cy/ sy, r);
116- const gradient2 = Gradient .createEllipticGradient (cx, cy, rx, ry, 0 /* angle*/ );
139+ const gradient2 = Gradient .createRadialGradient (cx/ sx, cy/ sy, 0 , cx/ sx, cy/ sy, r);
140+ const gradient3 = ctx3 .createRadialGradient (cx, cy, 0 , cx, cy, r);
141+ const gradient4 = Gradient .createEllipticGradient (cx, cy, rx, ry, angle);
117142
118143 addColorStops (gradient1);
119144 addColorStops (gradient2);
145+ addColorStops (gradient3);
146+ addColorStops (gradient4);
120147
121- // scale radial gradient1 to become an unrotated elliptic
148+ // transform radial gradient1 to become an unrotated elliptic
122149 ctx1 .scale (sx, sy);
123150 ctx1 .fillStyle = gradient1;
124- ctx1 .fillRect (0 , 0 , w/ sx, h/ sy);
125-
126- // gradient2 is true elliptic gradient
151+ fill_transformed_rect (ctx1, 0 , 0 , w, h);
152+
153+ // create a pattern from the gradient, just for fun
154+ const pattern2 = Gradient .createPattern ({
155+ data: gradient2 .getBitmap (w/ sx, h/ sy),
156+ width: Math .round (w/ sx),
157+ height: Math .round (h/ sy)
158+ }, ' no-repeat' );
159+ // gradient2/pattern2 is a transformed radial gradient
160+ // pattern2.transform.translate(-cx, -cy);
161+ pattern2 .transform .scale (sx, sy);
162+ // pattern2.transform.rotate(-angle);
163+ // pattern2.transform.translate(cx, cy);
127164 const imData2 = ctx2 .createImageData (w, h);
128- imData2 .data .set (gradient2 .getBitmap (w, h));
165+ imData2 .data .set (pattern2 .getBitmap (w, h));
129166 ctx2 .putImageData (imData2, 0 , 0 );
167+
168+ // transform radial gradient3 to become a rotated elliptic
169+ ctx3 .translate (cx, cy);
170+ ctx3 .rotate (- angle);
171+ ctx3 .translate (- cx* sx, - cy* sy);
172+ ctx3 .scale (sx, sy);
173+ ctx3 .fillStyle = gradient3;
174+ fill_transformed_rect (ctx3, 0 , 0 , w, h);
175+ // gradient4 is elliptic gradient
176+ const imData4 = ctx4 .createImageData (w, h);
177+ imData4 .data .set (gradient4 .getBitmap (w, h));
178+ ctx4 .putImageData (imData4, 0 , 0 );
130179}
131180function drawConicGradient (angle , cx , cy )
132181{
0 commit comments