diff --git a/build.xml b/build.xml index 552a5f0..af799cd 100644 --- a/build.xml +++ b/build.xml @@ -18,6 +18,7 @@ + diff --git a/build/html2canvas.js b/build/html2canvas.js index 9baf3e0..33c94bc 100644 --- a/build/html2canvas.js +++ b/build/html2canvas.js @@ -42,7 +42,11 @@ html2canvas.Util = {}; 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( 0, src.length - 2 ); } else { @@ -53,6 +57,41 @@ html2canvas.Util.backgroundImage = function (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) { // return jQuery(el).css(attribute); /* @@ -75,8 +114,8 @@ html2canvas.Util.getCSS = function (el, attribute) { // If we're not dealing with a regular pixel number // but a number that has a weird ending, we need to convert it to pixels - // if ( !/^-?\d+(?:px)?$/i.test( val ) && /^-?\d/.test( val ) ) { - /* + // if ( !/^-?\d+(?:px)?$/i.test( val ) && /^-?\d/.test( val ) ) { + /* // Remember the original values left = style.left; @@ -92,8 +131,8 @@ html2canvas.Util.getCSS = function (el, attribute) { if ( rsLeft ) { el.runtimeStyle.left = rsLeft; }*/ - val = $(el).css(attribute); - // } + val = $(el).css(attribute); + // } return val; @@ -113,6 +152,115 @@ html2canvas.Util.Children = function(el) { // $(el).contents() !== el.childNodes, Opera / IE have issues with that 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 */ @@ -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) { switch(transform){ case "lowercase": @@ -494,7 +607,7 @@ html2canvas.Parse = function (element, images, opts) { wrapElement.appendChild(oldTextNode.cloneNode(true)); parent.replaceChild(wrapElement, oldTextNode); - bounds = getBounds(wrapElement); + bounds = html2canvas.Util.Bounds(wrapElement); 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){ /* @@ -896,7 +996,7 @@ html2canvas.Parse = function (element, images, opts) { function renderBackground(el,bounds,ctx){ // 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], image, bgp, @@ -911,24 +1011,29 @@ html2canvas.Parse = function (element, images, opts) { height, add; - 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); - image = loadImage(background_image); + // if (typeof background_image !== "undefined" && /^(1|none)$/.test(background_image) === false && /^(-webkit|-moz|linear-gradient|-o-)/.test(background_image)===false){ + + 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 ); bgp = getBackgroundPosition(el, bounds, image); - if (image){ - switch(background_repeat){ + if ( image ){ + switch ( background_repeat ) { case "repeat-x": - renderBackgroundRepeatX(ctx, image, bgp, bounds.left, bounds.top, bounds.width, bounds.height); + renderBackgroundRepeatX( ctx, image, bgp, bounds.left, bounds.top, bounds.width, bounds.height ); break; case "repeat-y": - renderBackgroundRepeatY(ctx, image, bgp, bounds.left, bounds.top, bounds.width, bounds.height); + renderBackgroundRepeatY( ctx, image, bgp, bounds.left, bounds.top, bounds.width, bounds.height ); break; case "no-repeat": @@ -1049,7 +1154,7 @@ html2canvas.Parse = function (element, images, opts) { function renderElement(el, parentStack){ - var bounds = getBounds(el), + var bounds = html2canvas.Util.Bounds(el), x = bounds.left, y = bounds.top, w = bounds.width, @@ -1099,8 +1204,8 @@ html2canvas.Parse = function (element, images, opts) { if (parentStack.clip){ stack.clip = html2canvas.Util.Extend( {}, parentStack.clip ); - //stack.clip = parentStack.clip; - // stack.clip.height = stack.clip.height - parentStack.borders[2].width; + //stack.clip = parentStack.clip; + // stack.clip.height = stack.clip.height - parentStack.borders[2].width; } @@ -1131,7 +1236,7 @@ html2canvas.Parse = function (element, images, opts) { stack.clip.width = stack.clip.width-(borders[1].width); stack.clip.height = stack.clip.height-(borders[2].width); } - */ + */ if (ignoreElementsRegExp.test(el.nodeName) && options.iframeDefault !== "transparent"){ if (options.iframeDefault === "default"){ bgcolor = "#efefef"; @@ -1219,7 +1324,7 @@ html2canvas.Parse = function (element, images, opts) { }, formValue:true },stack); - */ + */ } break; case "TEXTAREA": @@ -1379,7 +1484,7 @@ html2canvas.Preload = function(element, opts){ img.src = a; } - delete window[callback_name]; + delete window[callback_name]; }; count += 1; @@ -1437,7 +1542,9 @@ html2canvas.Preload = function(element, opts){ i, contentsLen = contents.length, background_image, - src; + src, + img; + for (i = 0; i < contentsLen; i+=1 ){ // var ignRe = new RegExp("("+this.ignoreElements+")"); // if (!ignRe.test(element.nodeName)){ @@ -1450,52 +1557,78 @@ html2canvas.Preload = function(element, opts){ if (el.nodeType === 1 || el.nodeType === undefined){ 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"){ // TODO add multi image background support src = html2canvas.Util.backgroundImage(background_image.split(",")[0]); - methods.loadImage(src); + methods.loadImage(src); */ } } } methods = { - loadImage: function(src){ + loadImage: function( src ) { var img; - if (getIndex(images, src) === -1){ - if(src.substr(0, 5) === 'data:'){ - //Base64 src - images.push(src); + if ( getIndex(images, src) === -1 ) { + if ( src.match(/data:image\/.*;base64,/i) ) { + + //Base64 src img = new Image(); - img.src = src; - images.push(img); + img.src = src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, ''); + + images.push( src ); + images.push( img ); + imagesLoaded+=1; start(); - }else if (isSameOrigin(src)){ + + }else if ( isSameOrigin( src ) ) { - images.push(src); + images.push( src ); img = new Image(); - img.onload = function(){ + img.onload = function() { imagesLoaded+=1; start(); }; - img.onerror = function(){ - images.splice(getIndex(images, img.src), 2); + img.onerror = function() { + images.splice( getIndex( images, img.src ), 2 ); start(); }; img.src = src; images.push(img); - }else if (options.proxy){ + }else if ( options.proxy ){ // console.log('b'+src); - images.push(src); + images.push( src ); img = new Image(); - proxyGetImage(src, img); - images.push(img); + proxyGetImage( src, img ); + images.push( img ); } } @@ -1507,18 +1640,18 @@ html2canvas.Preload = function(element, opts){ // add something to array images.push('start'); - getImages(element); + getImages( element ); // load images for (i = 0; i < imgLen; i+=1){ - methods.loadImage(domImages[i].getAttribute("src")); + methods.loadImage( domImages[i].getAttribute( "src" ) ); } // remove 'start' - images.splice(0,1); + images.splice(0, 1); - if (images.length === 0){ + if ( images.length === 0 ) { start(); } diff --git a/src/Core.js b/src/Core.js index 296fbc6..e5ccaad 100644 --- a/src/Core.js +++ b/src/Core.js @@ -12,7 +12,11 @@ html2canvas.Util = {}; 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( 0, src.length - 2 ); } else { @@ -23,6 +27,41 @@ html2canvas.Util.backgroundImage = function (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) { // return jQuery(el).css(attribute); /* @@ -45,8 +84,8 @@ html2canvas.Util.getCSS = function (el, attribute) { // If we're not dealing with a regular pixel number // but a number that has a weird ending, we need to convert it to pixels - // if ( !/^-?\d+(?:px)?$/i.test( val ) && /^-?\d/.test( val ) ) { - /* + // if ( !/^-?\d+(?:px)?$/i.test( val ) && /^-?\d/.test( val ) ) { + /* // Remember the original values left = style.left; @@ -62,8 +101,8 @@ html2canvas.Util.getCSS = function (el, attribute) { if ( rsLeft ) { el.runtimeStyle.left = rsLeft; }*/ - val = $(el).css(attribute); - // } + val = $(el).css(attribute); + // } return val; diff --git a/src/Generate.js b/src/Generate.js new file mode 100644 index 0000000..4d76d97 --- /dev/null +++ b/src/Generate.js @@ -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; + +} \ No newline at end of file diff --git a/src/Parse.js b/src/Parse.js index 094b3e0..a2463b8 100644 --- a/src/Parse.js +++ b/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) { switch(transform){ case "lowercase": @@ -379,7 +344,7 @@ html2canvas.Parse = function (element, images, opts) { wrapElement.appendChild(oldTextNode.cloneNode(true)); parent.replaceChild(wrapElement, oldTextNode); - bounds = getBounds(wrapElement); + bounds = html2canvas.Util.Bounds(wrapElement); 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){ /* @@ -781,7 +733,7 @@ html2canvas.Parse = function (element, images, opts) { function renderBackground(el,bounds,ctx){ // 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], image, bgp, @@ -796,24 +748,29 @@ html2canvas.Parse = function (element, images, opts) { height, add; - 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); - image = loadImage(background_image); + // if (typeof background_image !== "undefined" && /^(1|none)$/.test(background_image) === false && /^(-webkit|-moz|linear-gradient|-o-)/.test(background_image)===false){ + + 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 ); bgp = getBackgroundPosition(el, bounds, image); - if (image){ - switch(background_repeat){ + if ( image ){ + switch ( background_repeat ) { case "repeat-x": - renderBackgroundRepeatX(ctx, image, bgp, bounds.left, bounds.top, bounds.width, bounds.height); + renderBackgroundRepeatX( ctx, image, bgp, bounds.left, bounds.top, bounds.width, bounds.height ); break; case "repeat-y": - renderBackgroundRepeatY(ctx, image, bgp, bounds.left, bounds.top, bounds.width, bounds.height); + renderBackgroundRepeatY( ctx, image, bgp, bounds.left, bounds.top, bounds.width, bounds.height ); break; case "no-repeat": @@ -934,7 +891,7 @@ html2canvas.Parse = function (element, images, opts) { function renderElement(el, parentStack){ - var bounds = getBounds(el), + var bounds = html2canvas.Util.Bounds(el), x = bounds.left, y = bounds.top, w = bounds.width, @@ -984,8 +941,8 @@ html2canvas.Parse = function (element, images, opts) { if (parentStack.clip){ stack.clip = html2canvas.Util.Extend( {}, parentStack.clip ); - //stack.clip = parentStack.clip; - // stack.clip.height = stack.clip.height - parentStack.borders[2].width; + //stack.clip = parentStack.clip; + // stack.clip.height = stack.clip.height - parentStack.borders[2].width; } @@ -1016,7 +973,7 @@ html2canvas.Parse = function (element, images, opts) { stack.clip.width = stack.clip.width-(borders[1].width); stack.clip.height = stack.clip.height-(borders[2].width); } - */ + */ if (ignoreElementsRegExp.test(el.nodeName) && options.iframeDefault !== "transparent"){ if (options.iframeDefault === "default"){ bgcolor = "#efefef"; @@ -1104,7 +1061,7 @@ html2canvas.Parse = function (element, images, opts) { }, formValue:true },stack); - */ + */ } break; case "TEXTAREA": diff --git a/src/Preload.js b/src/Preload.js index d8c93ce..1465b25 100644 --- a/src/Preload.js +++ b/src/Preload.js @@ -89,7 +89,7 @@ html2canvas.Preload = function(element, opts){ img.src = a; } - delete window[callback_name]; + delete window[callback_name]; }; count += 1; @@ -147,7 +147,9 @@ html2canvas.Preload = function(element, opts){ i, contentsLen = contents.length, background_image, - src; + src, + img; + for (i = 0; i < contentsLen; i+=1 ){ // var ignRe = new RegExp("("+this.ignoreElements+")"); // if (!ignRe.test(element.nodeName)){ @@ -160,52 +162,78 @@ html2canvas.Preload = function(element, opts){ if (el.nodeType === 1 || el.nodeType === undefined){ 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"){ // TODO add multi image background support src = html2canvas.Util.backgroundImage(background_image.split(",")[0]); - methods.loadImage(src); + methods.loadImage(src); */ } } } methods = { - loadImage: function(src){ + loadImage: function( src ) { var img; - if (getIndex(images, src) === -1){ - if(src.substr(0, 5) === 'data:'){ - //Base64 src - images.push(src); + if ( getIndex(images, src) === -1 ) { + if ( src.match(/data:image\/.*;base64,/i) ) { + + //Base64 src img = new Image(); - img.src = src; - images.push(img); + img.src = src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, ''); + + images.push( src ); + images.push( img ); + imagesLoaded+=1; start(); - }else if (isSameOrigin(src)){ + + }else if ( isSameOrigin( src ) ) { - images.push(src); + images.push( src ); img = new Image(); - img.onload = function(){ + img.onload = function() { imagesLoaded+=1; start(); }; - img.onerror = function(){ - images.splice(getIndex(images, img.src), 2); + img.onerror = function() { + images.splice( getIndex( images, img.src ), 2 ); start(); }; img.src = src; images.push(img); - }else if (options.proxy){ + }else if ( options.proxy ){ // console.log('b'+src); - images.push(src); + images.push( src ); img = new Image(); - proxyGetImage(src, img); - images.push(img); + proxyGetImage( src, img ); + images.push( img ); } } @@ -217,18 +245,18 @@ html2canvas.Preload = function(element, opts){ // add something to array images.push('start'); - getImages(element); + getImages( element ); // load images for (i = 0; i < imgLen; i+=1){ - methods.loadImage(domImages[i].getAttribute("src")); + methods.loadImage( domImages[i].getAttribute( "src" ) ); } // remove 'start' - images.splice(0,1); + images.splice(0, 1); - if (images.length === 0){ + if ( images.length === 0 ) { start(); } diff --git a/tests/background.html b/tests/background.html index a77c63f..165ef0a 100644 --- a/tests/background.html +++ b/tests/background.html @@ -8,7 +8,7 @@ Background attribute tests - + @@ -26,9 +26,9 @@ .small div{ width:100px; height:100px; - float:left; - margin:10px; - border:1px solid #000; + float:left; + margin:10px; + border:1px solid #000; } .medium div{ @@ -38,19 +38,40 @@ margin:10px; border:1px solid #000; } - + .small, .medium{ clear:both; } - + div{ 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))); + } - +
+
 
+
 
+
+ + +
@@ -63,8 +84,8 @@
- - + +
@@ -72,27 +93,29 @@
- -
+ +
-
+
-
- +
- - + +
+
+
+ - + \ No newline at end of file