Skip to content

Commit 1ad7ed3

Browse files
committed
Merge pull request niklasvh#77 from SunboX/background-gradients
ellipse gradient generation should now work
2 parents d7f4509 + 106b5ff commit 1ad7ed3

File tree

3 files changed

+87
-48
lines changed

3 files changed

+87
-48
lines changed

src/Generate.js

Lines changed: 71 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ var reGradients = [
2727
/*
2828
* TODO: Add IE10 vendor prefix (-ms) support
2929
* TODO: Add W3C gradient (linear-gradient) support
30+
* TODO: Add old Webkit -webkit-gradient(radial, ...) support
3031
* TODO: Maybe some RegExp optimizations are possible ;o)
3132
*/
3233
_html2canvas.Generate.parseGradient = function(css, bounds) {
@@ -114,7 +115,7 @@ _html2canvas.Generate.parseGradient = function(css, bounds) {
114115
case '-webkit-gradient':
115116

116117
gradient = {
117-
type: m1[2],
118+
type: m1[2] === 'radial' ? 'circle' : m1[2], // TODO: Add radial gradient support for older mozilla definitions
118119
x0: 0,
119120
y0: 0,
120121
x1: 0,
@@ -205,7 +206,7 @@ _html2canvas.Generate.parseGradient = function(css, bounds) {
205206
case '-o-radial-gradient':
206207

207208
gradient = {
208-
type: 'radial',
209+
type: 'circle',
209210
x0: 0,
210211
y0: 0,
211212
x1: bounds.width,
@@ -255,7 +256,7 @@ _html2canvas.Generate.parseGradient = function(css, bounds) {
255256
);
256257
} else { // ellipse
257258

258-
h2clog('No ellipse gradient supported by now, cause canvas can´t draw ellipse :(');
259+
gradient.type = m2[0];
259260

260261
gradient.rx = Math.max(
261262
gradient.cx,
@@ -278,7 +279,7 @@ _html2canvas.Generate.parseGradient = function(css, bounds) {
278279
);
279280
} else { // ellipse
280281

281-
h2clog('No ellipse gradient supported by now, cause canvas can´t draw ellipse :(');
282+
gradient.type = m2[0];
282283

283284
gradient.rx = Math.min(
284285
gradient.cx,
@@ -338,40 +339,78 @@ _html2canvas.Generate.Gradient = function(src, bounds) {
338339

339340
img = new Image();
340341

341-
if(gradient && gradient.type === 'linear'){
342-
grad = ctx.createLinearGradient(gradient.x0, gradient.y0, gradient.x1, gradient.y1);
343-
344-
for (i = 0, len = gradient.colorStops.length; i < len; i+=1) {
345-
try {
346-
grad.addColorStop(gradient.colorStops[i].stop, gradient.colorStops[i].color);
347-
}
348-
catch(e) {
349-
h2clog(['failed to add color stop: ', e, '; tried to add: ', gradient.colorStops[i], '; stop: ', i, '; in: ', src]);
342+
if(gradient){
343+
if(gradient.type === 'linear'){
344+
grad = ctx.createLinearGradient(gradient.x0, gradient.y0, gradient.x1, gradient.y1);
345+
346+
for (i = 0, len = gradient.colorStops.length; i < len; i+=1) {
347+
try {
348+
grad.addColorStop(gradient.colorStops[i].stop, gradient.colorStops[i].color);
349+
}
350+
catch(e) {
351+
h2clog(['failed to add color stop: ', e, '; tried to add: ', gradient.colorStops[i], '; stop: ', i, '; in: ', src]);
352+
}
350353
}
351-
}
354+
355+
ctx.fillStyle = grad;
356+
ctx.fillRect(0, 0, bounds.width, bounds.height);
352357

353-
ctx.fillStyle = grad;
354-
ctx.fillRect(0, 0, bounds.width, bounds.height);
355-
356-
img.src = canvas.toDataURL();
357-
} else if(gradient && gradient.type === 'radial'){
358-
359-
// TODO: Add support for "ellipsis" drawing
360-
grad = ctx.createRadialGradient(gradient.cx, gradient.cy, 0, gradient.cx, gradient.cy, gradient.rx);
358+
img.src = canvas.toDataURL();
359+
} else if(gradient.type === 'circle'){
360+
361+
grad = ctx.createRadialGradient(gradient.cx, gradient.cy, 0, gradient.cx, gradient.cy, gradient.rx);
362+
363+
for (i = 0, len = gradient.colorStops.length; i < len; i+=1) {
364+
try {
365+
grad.addColorStop(gradient.colorStops[i].stop, gradient.colorStops[i].color);
366+
}
367+
catch(e) {
368+
h2clog(['failed to add color stop: ', e, '; tried to add: ', gradient.colorStops[i], '; stop: ', i, '; in: ', src]);
369+
}
370+
}
371+
372+
ctx.fillStyle = grad;
373+
ctx.fillRect(0, 0, bounds.width, bounds.height);
361374

362-
for (i = 0, len = gradient.colorStops.length; i < len; i+=1) {
363-
try {
364-
grad.addColorStop(gradient.colorStops[i].stop, gradient.colorStops[i].color);
375+
img.src = canvas.toDataURL();
376+
} else if(gradient.type === 'ellipse'){
377+
378+
// draw circle
379+
var canvasRadial = document.createElement('canvas'),
380+
ctxRadial = canvasRadial.getContext('2d'),
381+
ri = Math.max(gradient.rx, gradient.ry),
382+
di = ri * 2, imgRadial;
383+
384+
canvasRadial.width = canvasRadial.height = di;
385+
386+
grad = ctxRadial.createRadialGradient(gradient.rx, gradient.ry, 0, gradient.rx, gradient.ry, ri);
387+
388+
for (i = 0, len = gradient.colorStops.length; i < len; i+=1) {
389+
try {
390+
grad.addColorStop(gradient.colorStops[i].stop, gradient.colorStops[i].color);
391+
}
392+
catch(e) {
393+
h2clog(['failed to add color stop: ', e, '; tried to add: ', gradient.colorStops[i], '; stop: ', i, '; in: ', src]);
394+
}
365395
}
366-
catch(e) {
367-
h2clog(['failed to add color stop: ', e, '; tried to add: ', gradient.colorStops[i], '; stop: ', i, '; in: ', src]);
396+
397+
ctxRadial.fillStyle = grad;
398+
ctxRadial.fillRect(0, 0, di, di);
399+
400+
ctx.fillStyle = gradient.colorStops[i - 1].color;
401+
ctx.fillRect(0, 0, canvas.width, canvas.height);
402+
403+
imgRadial = new Image();
404+
imgRadial.onload = function() { // wait until the image is filled
405+
406+
// transform circle to ellipse
407+
ctx.drawImage(imgRadial, gradient.cx - gradient.rx, gradient.cy - gradient.ry, 2 * gradient.rx, 2 * gradient.ry);
408+
409+
img.src = canvas.toDataURL();
410+
368411
}
412+
imgRadial.src = canvasRadial.toDataURL();
369413
}
370-
371-
ctx.fillStyle = grad;
372-
ctx.fillRect(0, 0, bounds.width, bounds.height);
373-
374-
img.src = canvas.toDataURL();
375414
}
376415

377416
return img;

tests/background.html

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -170,18 +170,18 @@
170170
background: radial-gradient(75% 19%, ellipse farthest-corner, #ababab, #0000ff 33%,#991f1f 100%);
171171
}
172172
.radialGradient7 {
173-
background: -moz-radial-gradient(75% 19%, ellipse contain, #ababab, #0000ff 33%,#991f1f 100%);
174-
background: -webkit-radial-gradient(75% 19%, ellipse contain, #ababab, #0000ff 33%,#991f1f 100%);
175-
background: -o-radial-gradient(75% 19%, ellipse contain, #ababab, #0000ff 33%,#991f1f 100%);
176-
background: -ms-radial-gradient(75% 19%, ellipse contain, #ababab, #0000ff 33%,#991f1f 100%);
177-
background: radial-gradient(75% 19%, ellipse contain, #ababab, #0000ff 33%,#991f1f 100%);
173+
background: -moz-radial-gradient(75% 19%, circle contain, #ababab, #0000ff 33%,#991f1f 100%);
174+
background: -webkit-radial-gradient(75% 19%, circle contain, #ababab, #0000ff 33%,#991f1f 100%);
175+
background: -o-radial-gradient(75% 19%, circle contain, #ababab, #0000ff 33%,#991f1f 100%);
176+
background: -ms-radial-gradient(75% 19%, circle contain, #ababab, #0000ff 33%,#991f1f 100%);
177+
background: radial-gradient(75% 19%, circle contain, #ababab, #0000ff 33%,#991f1f 100%);
178178
}
179179
.radialGradient8 {
180-
background: -moz-radial-gradient(75% 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%);
181-
background: -webkit-radial-gradient(75% 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%);
182-
background: -o-radial-gradient(75% 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%);
183-
background: -ms-radial-gradient(75% 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%);
184-
background: radial-gradient(75% 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%);
180+
background: -moz-radial-gradient(75% 19%, circle cover, #ababab, #0000ff 33%,#991f1f 100%);
181+
background: -webkit-radial-gradient(75% 19%, circle cover, #ababab, #0000ff 33%,#991f1f 100%);
182+
background: -o-radial-gradient(75% 19%, circle cover, #ababab, #0000ff 33%,#991f1f 100%);
183+
background: -ms-radial-gradient(75% 19%, circle cover, #ababab, #0000ff 33%,#991f1f 100%);
184+
background: radial-gradient(75% 19%, circle cover, #ababab, #0000ff 33%,#991f1f 100%);
185185
}
186186
.radialGradient9 {
187187
background: -moz-radial-gradient(right 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%);

tests/qunit/unit/generate.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ $(function() {
104104
]
105105
},
106106
{
107-
type: "radial",
107+
type: "ellipse",
108108
x0: 0,
109109
y0: 0,
110110
x1: 50,
@@ -129,7 +129,7 @@ $(function() {
129129
]
130130
},
131131
{
132-
type: "radial",
132+
type: "circle",
133133
x0: 0,
134134
y0: 0,
135135
x1: 50,
@@ -154,7 +154,7 @@ $(function() {
154154
]
155155
},
156156
{
157-
type: "radial",
157+
type: "ellipse",
158158
x0: 0,
159159
y0: 0,
160160
x1: 50,
@@ -179,7 +179,7 @@ $(function() {
179179
]
180180
},
181181
{
182-
type: "radial",
182+
type: "circle",
183183
x0: 0,
184184
y0: 0,
185185
x1: 50,
@@ -204,7 +204,7 @@ $(function() {
204204
]
205205
},
206206
{
207-
type: "radial",
207+
type: "ellipse",
208208
x0: 0,
209209
y0: 0,
210210
x1: 50,
@@ -229,7 +229,7 @@ $(function() {
229229
]
230230
},
231231
{
232-
type: "radial",
232+
type: "circle",
233233
x0: 0,
234234
y0: 0,
235235
x1: 50,

0 commit comments

Comments
 (0)