diff --git a/src/Generate.js b/src/Generate.js index 026a709..3dfa3c1 100644 --- a/src/Generate.js +++ b/src/Generate.js @@ -27,6 +27,7 @@ var reGradients = [ /* * TODO: Add IE10 vendor prefix (-ms) support * TODO: Add W3C gradient (linear-gradient) support + * TODO: Add old Webkit -webkit-gradient(radial, ...) support * TODO: Maybe some RegExp optimizations are possible ;o) */ _html2canvas.Generate.parseGradient = function(css, bounds) { @@ -114,7 +115,7 @@ _html2canvas.Generate.parseGradient = function(css, bounds) { case '-webkit-gradient': gradient = { - type: m1[2], + type: m1[2] === 'radial' ? 'circle' : m1[2], // TODO: Add radial gradient support for older mozilla definitions x0: 0, y0: 0, x1: 0, @@ -205,7 +206,7 @@ _html2canvas.Generate.parseGradient = function(css, bounds) { case '-o-radial-gradient': gradient = { - type: 'radial', + type: 'circle', x0: 0, y0: 0, x1: bounds.width, @@ -255,7 +256,7 @@ _html2canvas.Generate.parseGradient = function(css, bounds) { ); } else { // ellipse - h2clog('No ellipse gradient supported by now, cause canvas can´t draw ellipse :('); + gradient.type = m2[0]; gradient.rx = Math.max( gradient.cx, @@ -278,7 +279,7 @@ _html2canvas.Generate.parseGradient = function(css, bounds) { ); } else { // ellipse - h2clog('No ellipse gradient supported by now, cause canvas can´t draw ellipse :('); + gradient.type = m2[0]; gradient.rx = Math.min( gradient.cx, @@ -338,40 +339,78 @@ _html2canvas.Generate.Gradient = function(src, bounds) { img = new Image(); - if(gradient && gradient.type === 'linear'){ - grad = ctx.createLinearGradient(gradient.x0, gradient.y0, gradient.x1, gradient.y1); + if(gradient){ + if(gradient.type === 'linear'){ + grad = ctx.createLinearGradient(gradient.x0, gradient.y0, gradient.x1, gradient.y1); + + for (i = 0, len = gradient.colorStops.length; i < len; i+=1) { + try { + grad.addColorStop(gradient.colorStops[i].stop, gradient.colorStops[i].color); + } + catch(e) { + h2clog(['failed to add color stop: ', e, '; tried to add: ', gradient.colorStops[i], '; stop: ', i, '; in: ', src]); + } + } + + ctx.fillStyle = grad; + ctx.fillRect(0, 0, bounds.width, bounds.height); - for (i = 0, len = gradient.colorStops.length; i < len; i+=1) { - try { - grad.addColorStop(gradient.colorStops[i].stop, gradient.colorStops[i].color); + img.src = canvas.toDataURL(); + } else if(gradient.type === 'circle'){ + + grad = ctx.createRadialGradient(gradient.cx, gradient.cy, 0, gradient.cx, gradient.cy, gradient.rx); + + for (i = 0, len = gradient.colorStops.length; i < len; i+=1) { + try { + grad.addColorStop(gradient.colorStops[i].stop, gradient.colorStops[i].color); + } + catch(e) { + h2clog(['failed to add color stop: ', e, '; tried to add: ', gradient.colorStops[i], '; stop: ', i, '; in: ', src]); + } } - catch(e) { - h2clog(['failed to add color stop: ', e, '; tried to add: ', gradient.colorStops[i], '; stop: ', i, '; in: ', src]); + + ctx.fillStyle = grad; + ctx.fillRect(0, 0, bounds.width, bounds.height); + + img.src = canvas.toDataURL(); + } else if(gradient.type === 'ellipse'){ + + // draw circle + var canvasRadial = document.createElement('canvas'), + ctxRadial = canvasRadial.getContext('2d'), + ri = Math.max(gradient.rx, gradient.ry), + di = ri * 2, imgRadial; + + canvasRadial.width = canvasRadial.height = di; + + grad = ctxRadial.createRadialGradient(gradient.rx, gradient.ry, 0, gradient.rx, gradient.ry, ri); + + for (i = 0, len = gradient.colorStops.length; i < len; i+=1) { + try { + grad.addColorStop(gradient.colorStops[i].stop, gradient.colorStops[i].color); + } + catch(e) { + h2clog(['failed to add color stop: ', e, '; tried to add: ', gradient.colorStops[i], '; stop: ', i, '; in: ', src]); + } } + + ctxRadial.fillStyle = grad; + ctxRadial.fillRect(0, 0, di, di); + + ctx.fillStyle = gradient.colorStops[i - 1].color; + ctx.fillRect(0, 0, canvas.width, canvas.height); + + imgRadial = new Image(); + imgRadial.onload = function() { // wait until the image is filled + + // transform circle to ellipse + ctx.drawImage(imgRadial, gradient.cx - gradient.rx, gradient.cy - gradient.ry, 2 * gradient.rx, 2 * gradient.ry); + + img.src = canvas.toDataURL(); + + } + imgRadial.src = canvasRadial.toDataURL(); } - - ctx.fillStyle = grad; - ctx.fillRect(0, 0, bounds.width, bounds.height); - - img.src = canvas.toDataURL(); - } else if(gradient && gradient.type === 'radial'){ - - // TODO: Add support for "ellipsis" drawing - grad = ctx.createRadialGradient(gradient.cx, gradient.cy, 0, gradient.cx, gradient.cy, gradient.rx); - - for (i = 0, len = gradient.colorStops.length; i < len; i+=1) { - try { - grad.addColorStop(gradient.colorStops[i].stop, gradient.colorStops[i].color); - } - catch(e) { - h2clog(['failed to add color stop: ', e, '; tried to add: ', gradient.colorStops[i], '; stop: ', i, '; in: ', src]); - } - } - - ctx.fillStyle = grad; - ctx.fillRect(0, 0, bounds.width, bounds.height); - - img.src = canvas.toDataURL(); } return img; diff --git a/tests/background.html b/tests/background.html index 11e7793..4219f2d 100644 --- a/tests/background.html +++ b/tests/background.html @@ -170,18 +170,18 @@ background: radial-gradient(75% 19%, ellipse farthest-corner, #ababab, #0000ff 33%,#991f1f 100%); } .radialGradient7 { - background: -moz-radial-gradient(75% 19%, ellipse contain, #ababab, #0000ff 33%,#991f1f 100%); - background: -webkit-radial-gradient(75% 19%, ellipse contain, #ababab, #0000ff 33%,#991f1f 100%); - background: -o-radial-gradient(75% 19%, ellipse contain, #ababab, #0000ff 33%,#991f1f 100%); - background: -ms-radial-gradient(75% 19%, ellipse contain, #ababab, #0000ff 33%,#991f1f 100%); - background: radial-gradient(75% 19%, ellipse contain, #ababab, #0000ff 33%,#991f1f 100%); + background: -moz-radial-gradient(75% 19%, circle contain, #ababab, #0000ff 33%,#991f1f 100%); + background: -webkit-radial-gradient(75% 19%, circle contain, #ababab, #0000ff 33%,#991f1f 100%); + background: -o-radial-gradient(75% 19%, circle contain, #ababab, #0000ff 33%,#991f1f 100%); + background: -ms-radial-gradient(75% 19%, circle contain, #ababab, #0000ff 33%,#991f1f 100%); + background: radial-gradient(75% 19%, circle contain, #ababab, #0000ff 33%,#991f1f 100%); } .radialGradient8 { - background: -moz-radial-gradient(75% 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%); - background: -webkit-radial-gradient(75% 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%); - background: -o-radial-gradient(75% 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%); - background: -ms-radial-gradient(75% 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%); - background: radial-gradient(75% 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%); + background: -moz-radial-gradient(75% 19%, circle cover, #ababab, #0000ff 33%,#991f1f 100%); + background: -webkit-radial-gradient(75% 19%, circle cover, #ababab, #0000ff 33%,#991f1f 100%); + background: -o-radial-gradient(75% 19%, circle cover, #ababab, #0000ff 33%,#991f1f 100%); + background: -ms-radial-gradient(75% 19%, circle cover, #ababab, #0000ff 33%,#991f1f 100%); + background: radial-gradient(75% 19%, circle cover, #ababab, #0000ff 33%,#991f1f 100%); } .radialGradient9 { background: -moz-radial-gradient(right 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%); diff --git a/tests/qunit/unit/generate.js b/tests/qunit/unit/generate.js index 5201ba8..280f7e5 100644 --- a/tests/qunit/unit/generate.js +++ b/tests/qunit/unit/generate.js @@ -104,7 +104,7 @@ $(function() { ] }, { - type: "radial", + type: "ellipse", x0: 0, y0: 0, x1: 50, @@ -129,7 +129,7 @@ $(function() { ] }, { - type: "radial", + type: "circle", x0: 0, y0: 0, x1: 50, @@ -154,7 +154,7 @@ $(function() { ] }, { - type: "radial", + type: "ellipse", x0: 0, y0: 0, x1: 50, @@ -179,7 +179,7 @@ $(function() { ] }, { - type: "radial", + type: "circle", x0: 0, y0: 0, x1: 50, @@ -204,7 +204,7 @@ $(function() { ] }, { - type: "radial", + type: "ellipse", x0: 0, y0: 0, x1: 50, @@ -229,7 +229,7 @@ $(function() { ] }, { - type: "radial", + type: "circle", x0: 0, y0: 0, x1: 50,