mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
Added some support for CSS gradients (by cthackers)
This commit is contained in:
parent
0701d49e76
commit
008ad63555
@ -18,6 +18,7 @@
|
|||||||
<fileset dir="${src.dir}" includes="LICENSE"/>
|
<fileset dir="${src.dir}" includes="LICENSE"/>
|
||||||
<fileset dir="." includes="LICENSE"/>
|
<fileset dir="." includes="LICENSE"/>
|
||||||
<fileset dir="${src.dir}" includes="Core.js"/>
|
<fileset dir="${src.dir}" includes="Core.js"/>
|
||||||
|
<fileset dir="${src.dir}" includes="Generate.js"/>
|
||||||
<fileset dir="${src.dir}" includes="Parse.js"/>
|
<fileset dir="${src.dir}" includes="Parse.js"/>
|
||||||
<fileset dir="${src.dir}" includes="Preload.js"/>
|
<fileset dir="${src.dir}" includes="Preload.js"/>
|
||||||
<fileset dir="${src.dir}" includes="Queue.js"/>
|
<fileset dir="${src.dir}" includes="Queue.js"/>
|
||||||
|
@ -42,7 +42,11 @@ html2canvas.Util = {};
|
|||||||
|
|
||||||
html2canvas.Util.backgroundImage = function (src) {
|
html2canvas.Util.backgroundImage = function (src) {
|
||||||
|
|
||||||
if ( src.substr(0, 5) === 'url("' ) {
|
if (/data:image\/.*;base64,/i.test( src ) || /^(-webkit|-moz|linear-gradient|-o-)/.test( src )) {
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src.toLowerCase().substr( 0, 5 ) === 'url("') {
|
||||||
src = src.substr( 5 );
|
src = src.substr( 5 );
|
||||||
src = src.substr( 0, src.length - 2 );
|
src = src.substr( 0, src.length - 2 );
|
||||||
} else {
|
} else {
|
||||||
@ -53,6 +57,41 @@ html2canvas.Util.backgroundImage = function (src) {
|
|||||||
return src;
|
return src;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
html2canvas.Util.Bounds = function getBounds (el) {
|
||||||
|
|
||||||
|
window.scroll(0,0);
|
||||||
|
var clientRect,
|
||||||
|
bounds = {};
|
||||||
|
|
||||||
|
if (el.getBoundingClientRect){
|
||||||
|
clientRect = el.getBoundingClientRect();
|
||||||
|
|
||||||
|
|
||||||
|
// TODO add scroll position to bounds, so no scrolling of window necessary
|
||||||
|
bounds.top = clientRect.top;
|
||||||
|
bounds.bottom = clientRect.bottom || (clientRect.top + clientRect.height);
|
||||||
|
bounds.left = clientRect.left;
|
||||||
|
bounds.width = clientRect.width;
|
||||||
|
bounds.height = clientRect.height;
|
||||||
|
|
||||||
|
return bounds;
|
||||||
|
|
||||||
|
} /*else{
|
||||||
|
|
||||||
|
|
||||||
|
p = $(el).offset();
|
||||||
|
|
||||||
|
return {
|
||||||
|
left: p.left + getCSS(el,"borderLeftWidth", true),
|
||||||
|
top: p.top + getCSS(el,"borderTopWidth", true),
|
||||||
|
width:$(el).innerWidth(),
|
||||||
|
height:$(el).innerHeight()
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} */
|
||||||
|
}
|
||||||
|
|
||||||
html2canvas.Util.getCSS = function (el, attribute) {
|
html2canvas.Util.getCSS = function (el, attribute) {
|
||||||
// return jQuery(el).css(attribute);
|
// return jQuery(el).css(attribute);
|
||||||
/*
|
/*
|
||||||
@ -113,6 +152,115 @@ html2canvas.Util.Children = function(el) {
|
|||||||
// $(el).contents() !== el.childNodes, Opera / IE have issues with that
|
// $(el).contents() !== el.childNodes, Opera / IE have issues with that
|
||||||
return $(el).contents();
|
return $(el).contents();
|
||||||
}
|
}
|
||||||
|
html2canvas.Generate = {};
|
||||||
|
|
||||||
|
html2canvas.Generate.Gradient = function(src, bounds) {
|
||||||
|
var canvas = document.createElement('canvas'),
|
||||||
|
ctx = canvas.getContext('2d'),
|
||||||
|
tmp,
|
||||||
|
p0 = 0,
|
||||||
|
p1 = 0,
|
||||||
|
p2 = 0,
|
||||||
|
p3 = 0,
|
||||||
|
steps = [],
|
||||||
|
position,
|
||||||
|
i,
|
||||||
|
len,
|
||||||
|
lingrad,
|
||||||
|
increment,
|
||||||
|
p,
|
||||||
|
img;
|
||||||
|
|
||||||
|
canvas.width = bounds.width;
|
||||||
|
canvas.height = bounds.height;
|
||||||
|
|
||||||
|
|
||||||
|
function getColors(input) {
|
||||||
|
var j = -1,
|
||||||
|
color = '',
|
||||||
|
chr;
|
||||||
|
|
||||||
|
while( j++ < input.length ) {
|
||||||
|
chr = input.charAt( j );
|
||||||
|
if (chr === ')') {
|
||||||
|
color += chr;
|
||||||
|
steps.push( color );
|
||||||
|
color = '';
|
||||||
|
j+=2;
|
||||||
|
} else {
|
||||||
|
color += chr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( tmp = src.match(/-webkit-linear-gradient\((.*)\)/) ) {
|
||||||
|
|
||||||
|
position = tmp[1].split( ",", 1 )[0];
|
||||||
|
getColors( tmp[1].substr( position.length + 2 ) );
|
||||||
|
position = position.split(' ');
|
||||||
|
|
||||||
|
for (p = 0; p < position.length; p+=1) {
|
||||||
|
|
||||||
|
switch(position[p]) {
|
||||||
|
case 'top':
|
||||||
|
p3 = bounds.height;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'right':
|
||||||
|
p0 = bounds.width;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'bottom':
|
||||||
|
p1 = bounds.height;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'left':
|
||||||
|
p2 = bounds.width;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (tmp = src.match(/-webkit-gradient\(linear, (\d+)% (\d+)\%, (\d+)% (\d+)%, from\((.*)\), to\((.*)\)\)/)) {
|
||||||
|
|
||||||
|
p0 = (tmp[1] * bounds.width) / 100;
|
||||||
|
p1 = (tmp[2] * bounds.height) / 100;
|
||||||
|
p2 = (tmp[3] * bounds.width) / 100;
|
||||||
|
p3 = (tmp[4] * bounds.height) / 100;
|
||||||
|
|
||||||
|
steps.push(tmp[5]);
|
||||||
|
steps.push(tmp[6]);
|
||||||
|
|
||||||
|
} else if (tmp = src.match(/-moz-linear-gradient\((\d+)% (\d+)%, (.*)\)/)) {
|
||||||
|
|
||||||
|
p0 = (tmp[1] * bounds.width) / 100;
|
||||||
|
p1 = (tmp[2] * bounds.width) / 100;
|
||||||
|
p2 = bounds.width - p0;
|
||||||
|
p3 = bounds.height - p1;
|
||||||
|
getColors( tmp[3] );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lingrad = ctx.createLinearGradient( p0, p1, p2, p3 );
|
||||||
|
increment = 1 / (steps.length - 1);
|
||||||
|
|
||||||
|
for (i = 0, len = steps.length; i < len; i+=1) {
|
||||||
|
lingrad.addColorStop(increment * i, steps[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.fillStyle = lingrad;
|
||||||
|
|
||||||
|
// draw shapes
|
||||||
|
ctx.fillRect(0, 0, bounds.width,bounds.height);
|
||||||
|
|
||||||
|
img = new Image();
|
||||||
|
img.src = canvas.toDataURL();
|
||||||
|
|
||||||
|
return img;
|
||||||
|
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* New function for traversing elements
|
* New function for traversing elements
|
||||||
*/
|
*/
|
||||||
@ -231,41 +379,6 @@ html2canvas.Parse = function (element, images, opts) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function getBounds (el) {
|
|
||||||
|
|
||||||
window.scroll(0,0);
|
|
||||||
var clientRect,
|
|
||||||
bounds = {};
|
|
||||||
|
|
||||||
if (el.getBoundingClientRect){
|
|
||||||
clientRect = el.getBoundingClientRect();
|
|
||||||
|
|
||||||
|
|
||||||
// TODO add scroll position to bounds, so no scrolling of window necessary
|
|
||||||
bounds.top = clientRect.top;
|
|
||||||
bounds.bottom = clientRect.bottom || (clientRect.top + clientRect.height);
|
|
||||||
bounds.left = clientRect.left;
|
|
||||||
bounds.width = clientRect.width;
|
|
||||||
bounds.height = clientRect.height;
|
|
||||||
|
|
||||||
return bounds;
|
|
||||||
|
|
||||||
} /*else{
|
|
||||||
|
|
||||||
|
|
||||||
p = $(el).offset();
|
|
||||||
|
|
||||||
return {
|
|
||||||
left: p.left + getCSS(el,"borderLeftWidth", true),
|
|
||||||
top: p.top + getCSS(el,"borderTopWidth", true),
|
|
||||||
width:$(el).innerWidth(),
|
|
||||||
height:$(el).innerHeight()
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} */
|
|
||||||
}
|
|
||||||
|
|
||||||
function textTransform (text, transform) {
|
function textTransform (text, transform) {
|
||||||
switch(transform){
|
switch(transform){
|
||||||
case "lowercase":
|
case "lowercase":
|
||||||
@ -494,7 +607,7 @@ html2canvas.Parse = function (element, images, opts) {
|
|||||||
wrapElement.appendChild(oldTextNode.cloneNode(true));
|
wrapElement.appendChild(oldTextNode.cloneNode(true));
|
||||||
parent.replaceChild(wrapElement, oldTextNode);
|
parent.replaceChild(wrapElement, oldTextNode);
|
||||||
|
|
||||||
bounds = getBounds(wrapElement);
|
bounds = html2canvas.Util.Bounds(wrapElement);
|
||||||
|
|
||||||
textValue = oldTextNode.nodeValue;
|
textValue = oldTextNode.nodeValue;
|
||||||
|
|
||||||
@ -604,19 +717,6 @@ html2canvas.Parse = function (element, images, opts) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function backgroundUrl (src){
|
|
||||||
if (src.substr(0,5) === 'url("'){
|
|
||||||
src = src.substr(5);
|
|
||||||
src = src.substr(0,src.length-2);
|
|
||||||
}else{
|
|
||||||
src = src.substr(4);
|
|
||||||
src = src.substr(0,src.length-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return src;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function renderBorders(el, ctx, bounds, clip){
|
function renderBorders(el, ctx, bounds, clip){
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -896,7 +996,7 @@ html2canvas.Parse = function (element, images, opts) {
|
|||||||
function renderBackground(el,bounds,ctx){
|
function renderBackground(el,bounds,ctx){
|
||||||
|
|
||||||
// TODO add support for multi background-images
|
// TODO add support for multi background-images
|
||||||
var background_image = getCSS(el, "backgroundImage", false).split(",")[0],
|
var background_image = getCSS(el, "backgroundImage", false),
|
||||||
background_repeat = getCSS(el, "backgroundRepeat", false).split(",")[0],
|
background_repeat = getCSS(el, "backgroundRepeat", false).split(",")[0],
|
||||||
image,
|
image,
|
||||||
bgp,
|
bgp,
|
||||||
@ -911,9 +1011,14 @@ html2canvas.Parse = function (element, images, opts) {
|
|||||||
height,
|
height,
|
||||||
add;
|
add;
|
||||||
|
|
||||||
if (typeof background_image !== "undefined" && /^(1|none)$/.test(background_image) === false && /^(-webkit|-moz|linear-gradient|-o-)/.test(background_image)===false){
|
// if (typeof background_image !== "undefined" && /^(1|none)$/.test(background_image) === false && /^(-webkit|-moz|linear-gradient|-o-)/.test(background_image)===false){
|
||||||
|
|
||||||
background_image = backgroundUrl(background_image);
|
if ( !/data:image\/.*;base64,/i.test(background_image) && !/^(-webkit|-moz|linear-gradient|-o-)/.test(background_image) ) {
|
||||||
|
background_image = background_image.split(",")[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( typeof background_image !== "undefined" && /^(1|none)$/.test( background_image ) === false ) {
|
||||||
|
background_image = html2canvas.Util.backgroundImage( background_image );
|
||||||
image = loadImage( background_image );
|
image = loadImage( background_image );
|
||||||
|
|
||||||
|
|
||||||
@ -1049,7 +1154,7 @@ html2canvas.Parse = function (element, images, opts) {
|
|||||||
|
|
||||||
function renderElement(el, parentStack){
|
function renderElement(el, parentStack){
|
||||||
|
|
||||||
var bounds = getBounds(el),
|
var bounds = html2canvas.Util.Bounds(el),
|
||||||
x = bounds.left,
|
x = bounds.left,
|
||||||
y = bounds.top,
|
y = bounds.top,
|
||||||
w = bounds.width,
|
w = bounds.width,
|
||||||
@ -1437,7 +1542,9 @@ html2canvas.Preload = function(element, opts){
|
|||||||
i,
|
i,
|
||||||
contentsLen = contents.length,
|
contentsLen = contents.length,
|
||||||
background_image,
|
background_image,
|
||||||
src;
|
src,
|
||||||
|
img;
|
||||||
|
|
||||||
for (i = 0; i < contentsLen; i+=1 ){
|
for (i = 0; i < contentsLen; i+=1 ){
|
||||||
// var ignRe = new RegExp("("+this.ignoreElements+")");
|
// var ignRe = new RegExp("("+this.ignoreElements+")");
|
||||||
// if (!ignRe.test(element.nodeName)){
|
// if (!ignRe.test(element.nodeName)){
|
||||||
@ -1451,10 +1558,32 @@ html2canvas.Preload = function(element, opts){
|
|||||||
|
|
||||||
background_image = html2canvas.Util.getCSS(el, 'backgroundImage');
|
background_image = html2canvas.Util.getCSS(el, 'backgroundImage');
|
||||||
|
|
||||||
|
if ( background_image && background_image !== "1" && background_image !== "none" ) {
|
||||||
|
|
||||||
|
// TODO add multi image background support
|
||||||
|
|
||||||
|
if (background_image.substring(0,7) === "-webkit" || background_image.substring(0,3) === "-o-" || background_image.substring(0,4) === "-moz") {
|
||||||
|
|
||||||
|
img = html2canvas.Generate.Gradient( background_image, html2canvas.Util.Bounds( el ) );
|
||||||
|
|
||||||
|
if ( img !== undefined ){
|
||||||
|
images.push(background_image);
|
||||||
|
images.push(img);
|
||||||
|
imagesLoaded++;
|
||||||
|
start();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
src = html2canvas.Util.backgroundImage(background_image.match(/data:image\/.*;base64,/i) ? background_image : background_image.split(",")[0]);
|
||||||
|
methods.loadImage(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if (background_image && background_image !== "1" && background_image !== "none" && background_image.substring(0,7) !== "-webkit" && background_image.substring(0,3)!== "-o-" && background_image.substring(0,4) !== "-moz"){
|
if (background_image && background_image !== "1" && background_image !== "none" && background_image.substring(0,7) !== "-webkit" && background_image.substring(0,3)!== "-o-" && background_image.substring(0,4) !== "-moz"){
|
||||||
// TODO add multi image background support
|
// TODO add multi image background support
|
||||||
src = html2canvas.Util.backgroundImage(background_image.split(",")[0]);
|
src = html2canvas.Util.backgroundImage(background_image.split(",")[0]);
|
||||||
methods.loadImage(src);
|
methods.loadImage(src); */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1463,14 +1592,18 @@ html2canvas.Preload = function(element, opts){
|
|||||||
loadImage: function( src ) {
|
loadImage: function( src ) {
|
||||||
var img;
|
var img;
|
||||||
if ( getIndex(images, src) === -1 ) {
|
if ( getIndex(images, src) === -1 ) {
|
||||||
if(src.substr(0, 5) === 'data:'){
|
if ( src.match(/data:image\/.*;base64,/i) ) {
|
||||||
|
|
||||||
//Base64 src
|
//Base64 src
|
||||||
images.push(src);
|
|
||||||
img = new Image();
|
img = new Image();
|
||||||
img.src = src;
|
img.src = src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, '');
|
||||||
|
|
||||||
|
images.push( src );
|
||||||
images.push( img );
|
images.push( img );
|
||||||
|
|
||||||
imagesLoaded+=1;
|
imagesLoaded+=1;
|
||||||
start();
|
start();
|
||||||
|
|
||||||
}else if ( isSameOrigin( src ) ) {
|
}else if ( isSameOrigin( src ) ) {
|
||||||
|
|
||||||
images.push( src );
|
images.push( src );
|
||||||
|
41
src/Core.js
41
src/Core.js
@ -12,7 +12,11 @@ html2canvas.Util = {};
|
|||||||
|
|
||||||
html2canvas.Util.backgroundImage = function (src) {
|
html2canvas.Util.backgroundImage = function (src) {
|
||||||
|
|
||||||
if ( src.substr(0, 5) === 'url("' ) {
|
if (/data:image\/.*;base64,/i.test( src ) || /^(-webkit|-moz|linear-gradient|-o-)/.test( src )) {
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src.toLowerCase().substr( 0, 5 ) === 'url("') {
|
||||||
src = src.substr( 5 );
|
src = src.substr( 5 );
|
||||||
src = src.substr( 0, src.length - 2 );
|
src = src.substr( 0, src.length - 2 );
|
||||||
} else {
|
} else {
|
||||||
@ -23,6 +27,41 @@ html2canvas.Util.backgroundImage = function (src) {
|
|||||||
return src;
|
return src;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
html2canvas.Util.Bounds = function getBounds (el) {
|
||||||
|
|
||||||
|
window.scroll(0,0);
|
||||||
|
var clientRect,
|
||||||
|
bounds = {};
|
||||||
|
|
||||||
|
if (el.getBoundingClientRect){
|
||||||
|
clientRect = el.getBoundingClientRect();
|
||||||
|
|
||||||
|
|
||||||
|
// TODO add scroll position to bounds, so no scrolling of window necessary
|
||||||
|
bounds.top = clientRect.top;
|
||||||
|
bounds.bottom = clientRect.bottom || (clientRect.top + clientRect.height);
|
||||||
|
bounds.left = clientRect.left;
|
||||||
|
bounds.width = clientRect.width;
|
||||||
|
bounds.height = clientRect.height;
|
||||||
|
|
||||||
|
return bounds;
|
||||||
|
|
||||||
|
} /*else{
|
||||||
|
|
||||||
|
|
||||||
|
p = $(el).offset();
|
||||||
|
|
||||||
|
return {
|
||||||
|
left: p.left + getCSS(el,"borderLeftWidth", true),
|
||||||
|
top: p.top + getCSS(el,"borderTopWidth", true),
|
||||||
|
width:$(el).innerWidth(),
|
||||||
|
height:$(el).innerHeight()
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} */
|
||||||
|
}
|
||||||
|
|
||||||
html2canvas.Util.getCSS = function (el, attribute) {
|
html2canvas.Util.getCSS = function (el, attribute) {
|
||||||
// return jQuery(el).css(attribute);
|
// return jQuery(el).css(attribute);
|
||||||
/*
|
/*
|
||||||
|
109
src/Generate.js
Normal file
109
src/Generate.js
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
html2canvas.Generate = {};
|
||||||
|
|
||||||
|
html2canvas.Generate.Gradient = function(src, bounds) {
|
||||||
|
var canvas = document.createElement('canvas'),
|
||||||
|
ctx = canvas.getContext('2d'),
|
||||||
|
tmp,
|
||||||
|
p0 = 0,
|
||||||
|
p1 = 0,
|
||||||
|
p2 = 0,
|
||||||
|
p3 = 0,
|
||||||
|
steps = [],
|
||||||
|
position,
|
||||||
|
i,
|
||||||
|
len,
|
||||||
|
lingrad,
|
||||||
|
increment,
|
||||||
|
p,
|
||||||
|
img;
|
||||||
|
|
||||||
|
canvas.width = bounds.width;
|
||||||
|
canvas.height = bounds.height;
|
||||||
|
|
||||||
|
|
||||||
|
function getColors(input) {
|
||||||
|
var j = -1,
|
||||||
|
color = '',
|
||||||
|
chr;
|
||||||
|
|
||||||
|
while( j++ < input.length ) {
|
||||||
|
chr = input.charAt( j );
|
||||||
|
if (chr === ')') {
|
||||||
|
color += chr;
|
||||||
|
steps.push( color );
|
||||||
|
color = '';
|
||||||
|
j+=2;
|
||||||
|
} else {
|
||||||
|
color += chr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( tmp = src.match(/-webkit-linear-gradient\((.*)\)/) ) {
|
||||||
|
|
||||||
|
position = tmp[1].split( ",", 1 )[0];
|
||||||
|
getColors( tmp[1].substr( position.length + 2 ) );
|
||||||
|
position = position.split(' ');
|
||||||
|
|
||||||
|
for (p = 0; p < position.length; p+=1) {
|
||||||
|
|
||||||
|
switch(position[p]) {
|
||||||
|
case 'top':
|
||||||
|
p3 = bounds.height;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'right':
|
||||||
|
p0 = bounds.width;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'bottom':
|
||||||
|
p1 = bounds.height;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'left':
|
||||||
|
p2 = bounds.width;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (tmp = src.match(/-webkit-gradient\(linear, (\d+)% (\d+)\%, (\d+)% (\d+)%, from\((.*)\), to\((.*)\)\)/)) {
|
||||||
|
|
||||||
|
p0 = (tmp[1] * bounds.width) / 100;
|
||||||
|
p1 = (tmp[2] * bounds.height) / 100;
|
||||||
|
p2 = (tmp[3] * bounds.width) / 100;
|
||||||
|
p3 = (tmp[4] * bounds.height) / 100;
|
||||||
|
|
||||||
|
steps.push(tmp[5]);
|
||||||
|
steps.push(tmp[6]);
|
||||||
|
|
||||||
|
} else if (tmp = src.match(/-moz-linear-gradient\((\d+)% (\d+)%, (.*)\)/)) {
|
||||||
|
|
||||||
|
p0 = (tmp[1] * bounds.width) / 100;
|
||||||
|
p1 = (tmp[2] * bounds.width) / 100;
|
||||||
|
p2 = bounds.width - p0;
|
||||||
|
p3 = bounds.height - p1;
|
||||||
|
getColors( tmp[3] );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lingrad = ctx.createLinearGradient( p0, p1, p2, p3 );
|
||||||
|
increment = 1 / (steps.length - 1);
|
||||||
|
|
||||||
|
for (i = 0, len = steps.length; i < len; i+=1) {
|
||||||
|
lingrad.addColorStop(increment * i, steps[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.fillStyle = lingrad;
|
||||||
|
|
||||||
|
// draw shapes
|
||||||
|
ctx.fillRect(0, 0, bounds.width,bounds.height);
|
||||||
|
|
||||||
|
img = new Image();
|
||||||
|
img.src = canvas.toDataURL();
|
||||||
|
|
||||||
|
return img;
|
||||||
|
|
||||||
|
}
|
63
src/Parse.js
63
src/Parse.js
@ -116,41 +116,6 @@ html2canvas.Parse = function (element, images, opts) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function getBounds (el) {
|
|
||||||
|
|
||||||
window.scroll(0,0);
|
|
||||||
var clientRect,
|
|
||||||
bounds = {};
|
|
||||||
|
|
||||||
if (el.getBoundingClientRect){
|
|
||||||
clientRect = el.getBoundingClientRect();
|
|
||||||
|
|
||||||
|
|
||||||
// TODO add scroll position to bounds, so no scrolling of window necessary
|
|
||||||
bounds.top = clientRect.top;
|
|
||||||
bounds.bottom = clientRect.bottom || (clientRect.top + clientRect.height);
|
|
||||||
bounds.left = clientRect.left;
|
|
||||||
bounds.width = clientRect.width;
|
|
||||||
bounds.height = clientRect.height;
|
|
||||||
|
|
||||||
return bounds;
|
|
||||||
|
|
||||||
} /*else{
|
|
||||||
|
|
||||||
|
|
||||||
p = $(el).offset();
|
|
||||||
|
|
||||||
return {
|
|
||||||
left: p.left + getCSS(el,"borderLeftWidth", true),
|
|
||||||
top: p.top + getCSS(el,"borderTopWidth", true),
|
|
||||||
width:$(el).innerWidth(),
|
|
||||||
height:$(el).innerHeight()
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} */
|
|
||||||
}
|
|
||||||
|
|
||||||
function textTransform (text, transform) {
|
function textTransform (text, transform) {
|
||||||
switch(transform){
|
switch(transform){
|
||||||
case "lowercase":
|
case "lowercase":
|
||||||
@ -379,7 +344,7 @@ html2canvas.Parse = function (element, images, opts) {
|
|||||||
wrapElement.appendChild(oldTextNode.cloneNode(true));
|
wrapElement.appendChild(oldTextNode.cloneNode(true));
|
||||||
parent.replaceChild(wrapElement, oldTextNode);
|
parent.replaceChild(wrapElement, oldTextNode);
|
||||||
|
|
||||||
bounds = getBounds(wrapElement);
|
bounds = html2canvas.Util.Bounds(wrapElement);
|
||||||
|
|
||||||
textValue = oldTextNode.nodeValue;
|
textValue = oldTextNode.nodeValue;
|
||||||
|
|
||||||
@ -489,19 +454,6 @@ html2canvas.Parse = function (element, images, opts) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function backgroundUrl (src){
|
|
||||||
if (src.substr(0,5) === 'url("'){
|
|
||||||
src = src.substr(5);
|
|
||||||
src = src.substr(0,src.length-2);
|
|
||||||
}else{
|
|
||||||
src = src.substr(4);
|
|
||||||
src = src.substr(0,src.length-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return src;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function renderBorders(el, ctx, bounds, clip){
|
function renderBorders(el, ctx, bounds, clip){
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -781,7 +733,7 @@ html2canvas.Parse = function (element, images, opts) {
|
|||||||
function renderBackground(el,bounds,ctx){
|
function renderBackground(el,bounds,ctx){
|
||||||
|
|
||||||
// TODO add support for multi background-images
|
// TODO add support for multi background-images
|
||||||
var background_image = getCSS(el, "backgroundImage", false).split(",")[0],
|
var background_image = getCSS(el, "backgroundImage", false),
|
||||||
background_repeat = getCSS(el, "backgroundRepeat", false).split(",")[0],
|
background_repeat = getCSS(el, "backgroundRepeat", false).split(",")[0],
|
||||||
image,
|
image,
|
||||||
bgp,
|
bgp,
|
||||||
@ -796,9 +748,14 @@ html2canvas.Parse = function (element, images, opts) {
|
|||||||
height,
|
height,
|
||||||
add;
|
add;
|
||||||
|
|
||||||
if (typeof background_image !== "undefined" && /^(1|none)$/.test(background_image) === false && /^(-webkit|-moz|linear-gradient|-o-)/.test(background_image)===false){
|
// if (typeof background_image !== "undefined" && /^(1|none)$/.test(background_image) === false && /^(-webkit|-moz|linear-gradient|-o-)/.test(background_image)===false){
|
||||||
|
|
||||||
background_image = backgroundUrl(background_image);
|
if ( !/data:image\/.*;base64,/i.test(background_image) && !/^(-webkit|-moz|linear-gradient|-o-)/.test(background_image) ) {
|
||||||
|
background_image = background_image.split(",")[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( typeof background_image !== "undefined" && /^(1|none)$/.test( background_image ) === false ) {
|
||||||
|
background_image = html2canvas.Util.backgroundImage( background_image );
|
||||||
image = loadImage( background_image );
|
image = loadImage( background_image );
|
||||||
|
|
||||||
|
|
||||||
@ -934,7 +891,7 @@ html2canvas.Parse = function (element, images, opts) {
|
|||||||
|
|
||||||
function renderElement(el, parentStack){
|
function renderElement(el, parentStack){
|
||||||
|
|
||||||
var bounds = getBounds(el),
|
var bounds = html2canvas.Util.Bounds(el),
|
||||||
x = bounds.left,
|
x = bounds.left,
|
||||||
y = bounds.top,
|
y = bounds.top,
|
||||||
w = bounds.width,
|
w = bounds.width,
|
||||||
|
@ -147,7 +147,9 @@ html2canvas.Preload = function(element, opts){
|
|||||||
i,
|
i,
|
||||||
contentsLen = contents.length,
|
contentsLen = contents.length,
|
||||||
background_image,
|
background_image,
|
||||||
src;
|
src,
|
||||||
|
img;
|
||||||
|
|
||||||
for (i = 0; i < contentsLen; i+=1 ){
|
for (i = 0; i < contentsLen; i+=1 ){
|
||||||
// var ignRe = new RegExp("("+this.ignoreElements+")");
|
// var ignRe = new RegExp("("+this.ignoreElements+")");
|
||||||
// if (!ignRe.test(element.nodeName)){
|
// if (!ignRe.test(element.nodeName)){
|
||||||
@ -161,10 +163,32 @@ html2canvas.Preload = function(element, opts){
|
|||||||
|
|
||||||
background_image = html2canvas.Util.getCSS(el, 'backgroundImage');
|
background_image = html2canvas.Util.getCSS(el, 'backgroundImage');
|
||||||
|
|
||||||
|
if ( background_image && background_image !== "1" && background_image !== "none" ) {
|
||||||
|
|
||||||
|
// TODO add multi image background support
|
||||||
|
|
||||||
|
if (background_image.substring(0,7) === "-webkit" || background_image.substring(0,3) === "-o-" || background_image.substring(0,4) === "-moz") {
|
||||||
|
|
||||||
|
img = html2canvas.Generate.Gradient( background_image, html2canvas.Util.Bounds( el ) );
|
||||||
|
|
||||||
|
if ( img !== undefined ){
|
||||||
|
images.push(background_image);
|
||||||
|
images.push(img);
|
||||||
|
imagesLoaded++;
|
||||||
|
start();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
src = html2canvas.Util.backgroundImage(background_image.match(/data:image\/.*;base64,/i) ? background_image : background_image.split(",")[0]);
|
||||||
|
methods.loadImage(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if (background_image && background_image !== "1" && background_image !== "none" && background_image.substring(0,7) !== "-webkit" && background_image.substring(0,3)!== "-o-" && background_image.substring(0,4) !== "-moz"){
|
if (background_image && background_image !== "1" && background_image !== "none" && background_image.substring(0,7) !== "-webkit" && background_image.substring(0,3)!== "-o-" && background_image.substring(0,4) !== "-moz"){
|
||||||
// TODO add multi image background support
|
// TODO add multi image background support
|
||||||
src = html2canvas.Util.backgroundImage(background_image.split(",")[0]);
|
src = html2canvas.Util.backgroundImage(background_image.split(",")[0]);
|
||||||
methods.loadImage(src);
|
methods.loadImage(src); */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,14 +197,18 @@ html2canvas.Preload = function(element, opts){
|
|||||||
loadImage: function( src ) {
|
loadImage: function( src ) {
|
||||||
var img;
|
var img;
|
||||||
if ( getIndex(images, src) === -1 ) {
|
if ( getIndex(images, src) === -1 ) {
|
||||||
if(src.substr(0, 5) === 'data:'){
|
if ( src.match(/data:image\/.*;base64,/i) ) {
|
||||||
|
|
||||||
//Base64 src
|
//Base64 src
|
||||||
images.push(src);
|
|
||||||
img = new Image();
|
img = new Image();
|
||||||
img.src = src;
|
img.src = src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, '');
|
||||||
|
|
||||||
|
images.push( src );
|
||||||
images.push( img );
|
images.push( img );
|
||||||
|
|
||||||
imagesLoaded+=1;
|
imagesLoaded+=1;
|
||||||
start();
|
start();
|
||||||
|
|
||||||
}else if ( isSameOrigin( src ) ) {
|
}else if ( isSameOrigin( src ) ) {
|
||||||
|
|
||||||
images.push( src );
|
images.push( src );
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>Background attribute tests</title>
|
<title>Background attribute tests</title>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
<link href="#" type="text/css" rel="stylesheet">
|
|
||||||
<script type="text/javascript" src="../external/jquery-1.6.2.min.js"></script>
|
<script type="text/javascript" src="../external/jquery-1.6.2.min.js"></script>
|
||||||
<script type="text/javascript" src="../build/html2canvas.js"></script>
|
<script type="text/javascript" src="../build/html2canvas.js"></script>
|
||||||
<script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
|
<script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
|
||||||
@ -46,10 +46,31 @@
|
|||||||
div{
|
div{
|
||||||
display:block;
|
display:block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.encoded {
|
||||||
|
background:url("data:image/jpeg;base64,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");
|
||||||
|
background-position: center center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.linearGradient {
|
||||||
|
/*background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgb(255, 0, 0)), to(rgb(0, 0, 255)));*/
|
||||||
|
background: -webkit-linear-gradient(top left, #f00, #00f, #BADA55, rgba(0, 0, 255,0.5));
|
||||||
|
background: -moz-linear-gradient(top right, #f00, #00f, #BADA55, rgba(0, 0, 255,0.5));
|
||||||
|
}
|
||||||
|
|
||||||
|
.linearGradient2 {
|
||||||
|
background: -webkit-gradient(linear, 0% 0, 0% 100%, from(rgb(252, 252, 252)), to(rgb(232, 232, 232)));
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<div class="medium">
|
||||||
|
<div class="linearGradient"> </div>
|
||||||
|
<div class="linearGradient2"> </div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="medium">
|
<div class="medium">
|
||||||
<div style="background:url(image.jpg);"></div>
|
<div style="background:url(image.jpg);"></div>
|
||||||
@ -88,11 +109,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="medium">
|
<div class="medium">
|
||||||
|
|
||||||
<div style="background:url(image.jpg) no-repeat -15% 25px;"></div>
|
<div style="background:url(image.jpg) no-repeat -15% 25px;"></div>
|
||||||
<div style="background-image:url(image.jpg), url(image2.jpg); background-repeat: repeat-x; background-position: 50px 50px, 100px 100px;"></div>
|
<div style="background-image:url(image.jpg), url(image2.jpg); background-repeat: repeat-x; background-position: 50px 50px, 100px 100px;"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="medium">
|
||||||
|
<div class="encoded"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
Loading…
x
Reference in New Issue
Block a user