simplified API and cleaned up code

This commit is contained in:
Niklas von Hertzen 2012-03-02 18:05:03 +02:00
parent bf994849e0
commit c7d526c9ea
11 changed files with 203 additions and 143 deletions

View File

@ -37,7 +37,7 @@ For more information and examples, please visit the <a href="http://html2canvas.
### Changelog ### ### Changelog ###
v0.33 - v0.33 - 2.3.2012
* SVG taint fix, and additional taint testing options for rendering (<a href="https://github.com/niklasvh/html2canvas/commit/2dc8b9385e656696cb019d615bdfa1d98b17d5d4">niklasvh</a>) * SVG taint fix, and additional taint testing options for rendering (<a href="https://github.com/niklasvh/html2canvas/commit/2dc8b9385e656696cb019d615bdfa1d98b17d5d4">niklasvh</a>)
* Added support for CORS images and option to create canvas as tainted (<a href="https://github.com/niklasvh/html2canvas/commit/3ad49efa0032cde25c6ed32a39e35d1505d3b2ef">niklasvh</a>) * Added support for CORS images and option to create canvas as tainted (<a href="https://github.com/niklasvh/html2canvas/commit/3ad49efa0032cde25c6ed32a39e35d1505d3b2ef">niklasvh</a>)

View File

@ -5,22 +5,21 @@
Released under MIT License Released under MIT License
*/ */
"use strict";
var html2canvas = {}; var _html2canvas = {},
html2canvas;
html2canvas.logging = false;
function h2clog(a) { function h2clog(a) {
if (html2canvas.logging && window.console && window.console.log) { if (_html2canvas.logging && window.console && window.console.log) {
window.console.log(a); window.console.log(a);
} }
} }
html2canvas.log = h2clog; // for compatibility with the jquery plugin _html2canvas.Util = {};
html2canvas.Util = {}; _html2canvas.Util.backgroundImage = function (src) {
html2canvas.Util.backgroundImage = function (src) {
if (/data:image\/.*;base64,/i.test( src ) || /^(-webkit|-moz|linear-gradient|-o-)/.test( src )) { if (/data:image\/.*;base64,/i.test( src ) || /^(-webkit|-moz|linear-gradient|-o-)/.test( src )) {
return src; return src;
@ -37,7 +36,7 @@ html2canvas.Util.backgroundImage = function (src) {
return src; return src;
}; };
html2canvas.Util.Bounds = function getBounds (el) { _html2canvas.Util.Bounds = function getBounds (el) {
var clientRect, var clientRect,
bounds = {}; bounds = {};
@ -70,9 +69,9 @@ html2canvas.Util.Bounds = function getBounds (el) {
} */ } */
} };
html2canvas.Util.getCSS = function (el, attribute) { _html2canvas.Util.getCSS = function (el, attribute) {
// return jQuery(el).css(attribute); // return jQuery(el).css(attribute);
/* /*
var val, var val,
@ -126,7 +125,7 @@ html2canvas.Util.getCSS = function (el, attribute) {
}; };
html2canvas.Util.Extend = function (options, defaults) { _html2canvas.Util.Extend = function (options, defaults) {
var key; var key;
for (key in options) { for (key in options) {
if (options.hasOwnProperty(key)) { if (options.hasOwnProperty(key)) {
@ -136,7 +135,7 @@ html2canvas.Util.Extend = function (options, defaults) {
return defaults; return defaults;
}; };
html2canvas.Util.Children = function(el) { _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
var children; var children;
try { try {

View File

@ -6,11 +6,11 @@
Released under MIT License Released under MIT License
*/ */
html2canvas.Generate = {}; _html2canvas.Generate = {};
html2canvas.Generate.Gradient = function(src, bounds) { _html2canvas.Generate.Gradient = function(src, bounds) {
var canvas = document.createElement('canvas'), var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d'), ctx = canvas.getContext('2d'),
tmp, tmp,
@ -35,22 +35,24 @@ html2canvas.Generate.Gradient = function(src, bounds) {
var j = -1, var j = -1,
color = '', color = '',
chr; chr;
while( j++ < input.length ) { while( j++ < input.length ) {
chr = input.charAt( j ); chr = input.charAt( j );
if (chr === ')') { if (chr === ')') {
color += chr; color += chr;
steps.push( color ); steps.push( color );
color = ''; color = '';
while (j++ < input.length && input.charAt( j ) !== ',') { j = input.indexOf(",", j) + 1;
if (j === 0) {
break;
} }
// while (j++ < input.length && input.charAt( j ) !== ',') {}
} else { } else {
color += chr; color += chr;
} }
} }
} }
if ( tmp = src.match(/-webkit-linear-gradient\((.*)\)/) ) { if ( (tmp = src.match(/-webkit-linear-gradient\((.*)\)/)) !== null ) {
position = tmp[1].split( ",", 1 )[0]; position = tmp[1].split( ",", 1 )[0];
getColors( tmp[1].substr( position.length + 2 ) ); getColors( tmp[1].substr( position.length + 2 ) );
@ -78,7 +80,7 @@ html2canvas.Generate.Gradient = function(src, bounds) {
} }
} else if (tmp = src.match(/-webkit-gradient\(linear, (\d+)[%]{0,1} (\d+)[%]{0,1}, (\d+)[%]{0,1} (\d+)[%]{0,1}, from\((.*)\), to\((.*)\)\)/)) { } else if ( (tmp = src.match(/-webkit-gradient\(linear, (\d+)[%]{0,1} (\d+)[%]{0,1}, (\d+)[%]{0,1} (\d+)[%]{0,1}, from\((.*)\), to\((.*)\)\)/)) !== null ) {
p0 = (tmp[1] * bounds.width) / 100; p0 = (tmp[1] * bounds.width) / 100;
p1 = (tmp[2] * bounds.height) / 100; p1 = (tmp[2] * bounds.height) / 100;
@ -88,7 +90,7 @@ html2canvas.Generate.Gradient = function(src, bounds) {
steps.push(tmp[5]); steps.push(tmp[5]);
steps.push(tmp[6]); steps.push(tmp[6]);
} else if (tmp = src.match(/-moz-linear-gradient\((\d+)[%]{0,1} (\d+)[%]{0,1}, (.*)\)/)) { } else if ( (tmp = src.match(/-moz-linear-gradient\((\d+)[%]{0,1} (\d+)[%]{0,1}, (.*)\)/)) !== null ) {
p0 = (tmp[1] * bounds.width) / 100; p0 = (tmp[1] * bounds.width) / 100;
p1 = (tmp[2] * bounds.width) / 100; p1 = (tmp[2] * bounds.width) / 100;
@ -122,9 +124,9 @@ html2canvas.Generate.Gradient = function(src, bounds) {
return img; return img;
} };
html2canvas.Generate.ListAlpha = function(number) { _html2canvas.Generate.ListAlpha = function(number) {
var tmp = "", var tmp = "",
modulus; modulus;
@ -135,9 +137,9 @@ html2canvas.Generate.ListAlpha = function(number) {
}while((number*26) > 26); }while((number*26) > 26);
return tmp; return tmp;
} };
html2canvas.Generate.ListRoman = function(number) { _html2canvas.Generate.ListRoman = function(number) {
var romanArray = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"], var romanArray = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"],
decimal = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1], decimal = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1],
roman = "", roman = "",
@ -157,4 +159,4 @@ html2canvas.Generate.ListRoman = function(number) {
return roman; return roman;
} };

View File

@ -10,9 +10,8 @@
* New function for traversing elements * New function for traversing elements
*/ */
html2canvas.Parse = function (element, images, opts) { _html2canvas.Parse = function (element, images, options) {
window.scroll(0,0); window.scroll(0,0);
opts = opts || {};
// select body by default // select body by default
if (element === undefined) { if (element === undefined) {
@ -24,12 +23,7 @@ html2canvas.Parse = function (element, images, opts) {
rangeBounds: false rangeBounds: false
}, },
options = {
iframeDefault: "default",
ignoreElements: "IFRAME|OBJECT|PARAM",
useOverflow: true,
letterRendering: false
},
needReorder = false, needReorder = false,
numDraws = 0, numDraws = 0,
fontData = {}, fontData = {},
@ -47,7 +41,7 @@ html2canvas.Parse = function (element, images, opts) {
children, children,
childrenLen; childrenLen;
options = html2canvas.Util.Extend(opts, options);
images = images || {}; images = images || {};
@ -106,7 +100,7 @@ html2canvas.Parse = function (element, images, opts) {
} }
var getCSS = html2canvas.Util.getCSS; var getCSS = _html2canvas.Util.getCSS;
function getCSSInt(element, attribute) { function getCSSInt(element, attribute) {
var val = parseInt(getCSS(element, attribute), 10); var val = parseInt(getCSS(element, attribute), 10);
return (isNaN(val)) ? 0 : val; // borders in old IE are throwing 'medium' for demo.html return (isNaN(val)) ? 0 : val; // borders in old IE are throwing 'medium' for demo.html
@ -354,7 +348,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 = html2canvas.Util.Bounds(wrapElement); bounds = _html2canvas.Util.Bounds(wrapElement);
textValue = oldTextNode.nodeValue; textValue = oldTextNode.nodeValue;
@ -416,7 +410,7 @@ html2canvas.Parse = function (element, images, opts) {
element.insertBefore(boundElement, element.firstChild); element.insertBefore(boundElement, element.firstChild);
bounds = html2canvas.Util.Bounds( boundElement ); bounds = _html2canvas.Util.Bounds( boundElement );
element.removeChild( boundElement ); element.removeChild( boundElement );
element.style.listStyleType = type; element.style.listStyleType = type;
return bounds; return bounds;
@ -453,16 +447,16 @@ html2canvas.Parse = function (element, images, opts) {
} }
break; break;
case "upper-roman": case "upper-roman":
text = html2canvas.Generate.ListRoman( currentIndex ); text = _html2canvas.Generate.ListRoman( currentIndex );
break; break;
case "lower-roman": case "lower-roman":
text = html2canvas.Generate.ListRoman( currentIndex ).toLowerCase(); text = _html2canvas.Generate.ListRoman( currentIndex ).toLowerCase();
break; break;
case "lower-alpha": case "lower-alpha":
text = html2canvas.Generate.ListAlpha( currentIndex ).toLowerCase(); text = _html2canvas.Generate.ListAlpha( currentIndex ).toLowerCase();
break; break;
case "upper-alpha": case "upper-alpha":
text = html2canvas.Generate.ListAlpha( currentIndex ); text = _html2canvas.Generate.ListAlpha( currentIndex );
break; break;
} }
@ -495,20 +489,21 @@ html2canvas.Parse = function (element, images, opts) {
}else{ }else{
return; return;
/* /*
TODO really need to figure out some more accurate way to try and find the position. TODO really need to figure out some more accurate way to try and find the position.
as defined in http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-position, it does not even have a specified "correct" position, so each browser as defined in http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-position, it does not even have a specified "correct" position, so each browser
may display it whatever way it feels like. may display it whatever way it feels like.
"The position of the list-item marker adjacent to floats is undefined in CSS 2.1. CSS 2.1 does not specify the precise location of the marker box or its position in the painting order" "The position of the list-item marker adjacent to floats is undefined in CSS 2.1. CSS 2.1 does not specify the precise location of the marker box or its position in the painting order"
*/
ctx.setVariable("textAlign", "right"); ctx.setVariable("textAlign", "right");
// this.setFont(stack.ctx, element, true); // this.setFont(stack.ctx, element, true);
x = elBounds.left - 10; x = elBounds.left - 10;
*/
} }
y = listBounds.bottom; y = listBounds.bottom;
drawText(text, x, y, ctx) drawText(text, x, y, ctx);
} }
@ -517,12 +512,12 @@ html2canvas.Parse = function (element, images, opts) {
} }
function loadImage (src){ function loadImage (src){
var img = images[src]; var img = images[src];
if (img && img.succeeded === true) { if (img && img.succeeded === true) {
return img.img; return img.img;
} else { } else {
return false; return false;
} }
} }
@ -548,15 +543,15 @@ html2canvas.Parse = function (element, images, opts) {
function setZ(zIndex, parentZ){ function setZ(zIndex, parentZ){
// TODO fix static elements overlapping relative/absolute elements under same stack, if they are defined after them // TODO fix static elements overlapping relative/absolute elements under same stack, if they are defined after them
var newContext;
if (!parentZ){ if (!parentZ){
this.zStack = h2czContext(0); newContext = h2czContext(0);
return this.zStack; return newContext;
} }
if (zIndex !== "auto"){ if (zIndex !== "auto"){
needReorder = true; needReorder = true;
var newContext = h2czContext(zIndex); newContext = h2czContext(zIndex);
parentZ.children.push(newContext); parentZ.children.push(newContext);
return newContext; return newContext;
@ -669,7 +664,7 @@ html2canvas.Parse = function (element, images, opts) {
style = cssArr[i]; style = cssArr[i];
try { try {
valueWrap.style[style] = getCSS(el, style); valueWrap.style[style] = getCSS(el, style);
} catch( e ) { } catch( e ) {
// Older IE has issues with "border" // Older IE has issues with "border"
h2clog("html2canvas: Parse: Exception caught in renderFormValue: " + e.message); h2clog("html2canvas: Parse: Exception caught in renderFormValue: " + e.message);
@ -718,8 +713,8 @@ html2canvas.Parse = function (element, images, opts) {
if (bgp !== undefined) { if (bgp !== undefined) {
return (bgp.split(",")[0] || "0 0").split(" "); return (bgp.split(",")[0] || "0 0").split(" ");
} else { } else {
// Older IE uses -x and -y // Older IE uses -x and -y
return [ getCSS(el, "backgroundPositionX"), getCSS(el, "backgroundPositionY") ]; return [ getCSS(el, "backgroundPositionX"), getCSS(el, "backgroundPositionY") ];
} }
@ -882,7 +877,7 @@ html2canvas.Parse = function (element, images, opts) {
} }
if ( typeof background_image !== "undefined" && /^(1|none)$/.test( background_image ) === false ) { if ( typeof background_image !== "undefined" && /^(1|none)$/.test( background_image ) === false ) {
background_image = html2canvas.Util.backgroundImage( background_image ); background_image = _html2canvas.Util.backgroundImage( background_image );
image = loadImage( background_image ); image = loadImage( background_image );
@ -945,9 +940,7 @@ html2canvas.Parse = function (element, images, opts) {
bgsy = 0; bgsy = 0;
} }
// bgh = Math.abs(bgh);
// bgw = Math.abs(bgw);
if (bgh>0 && bgw > 0){ if (bgh>0 && bgw > 0){
renderImage( renderImage(
ctx, ctx,
@ -961,9 +954,7 @@ html2canvas.Parse = function (element, images, opts) {
bgw, // destination width : 18 bgw, // destination width : 18
bgh // destination height : 1677 bgh // destination height : 1677
); );
// ctx.drawImage(image,(bounds.left+bgp.left),(bounds.top+bgp.top));
} }
break; break;
default: default:
@ -1017,7 +1008,7 @@ html2canvas.Parse = function (element, images, opts) {
function renderElement(el, parentStack){ function renderElement(el, parentStack){
var bounds = html2canvas.Util.Bounds(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,
@ -1066,7 +1057,7 @@ html2canvas.Parse = function (element, images, opts) {
// TODO correct overflow for absolute content residing under a static position // TODO correct overflow for absolute content residing under a static position
if (parentStack.clip){ if (parentStack.clip){
stack.clip = html2canvas.Util.Extend( {}, parentStack.clip ); stack.clip = _html2canvas.Util.Extend( {}, parentStack.clip );
//stack.clip = parentStack.clip; //stack.clip = parentStack.clip;
// stack.clip.height = stack.clip.height - parentStack.borders[2].width; // stack.clip.height = stack.clip.height - parentStack.borders[2].width;
} }
@ -1219,7 +1210,7 @@ html2canvas.Parse = function (element, images, opts) {
y + paddingTop + borders[0].width, // dy y + paddingTop + borders[0].width, // dy
bounds.width - (borders[1].width + borders[3].width + paddingLeft + paddingRight), //dw bounds.width - (borders[1].width + borders[3].width + paddingLeft + paddingRight), //dw
bounds.height - (borders[0].width + borders[2].width + paddingTop + paddingBottom) //dh bounds.height - (borders[0].width + borders[2].width + paddingTop + paddingBottom) //dh
); );
break; break;
} }
@ -1238,7 +1229,7 @@ html2canvas.Parse = function (element, images, opts) {
ctx = stack.ctx; ctx = stack.ctx;
if ( !ignoreElementsRegExp.test( el.nodeName ) ) { if ( !ignoreElementsRegExp.test( el.nodeName ) ) {
var elementChildren = html2canvas.Util.Children( el ), var elementChildren = _html2canvas.Util.Children( el ),
i, i,
node, node,
childrenLen; childrenLen;
@ -1276,4 +1267,4 @@ function h2czContext(zindex) {
zindex: zindex, zindex: zindex,
children: [] children: []
}; };
}; }

View File

@ -6,15 +6,9 @@
Released under MIT License Released under MIT License
*/ */
html2canvas.Preload = function(element, opts){ _html2canvas.Preload = function(element, options){
var options = { var images = {
proxy: "http://html2canvas.appspot.com/",
timeout: 0, // no timeout
useCORS: false, // try to load images as CORS (where available), before falling back to proxy
allowTaint: false // whether to allow images to taint the canvas, won't need proxy if set to true
},
images = {
numLoaded: 0, // also failed are counted here numLoaded: 0, // also failed are counted here
numFailed: 0, numFailed: 0,
numTotal: 0, numTotal: 0,
@ -35,9 +29,9 @@ html2canvas.Preload = function(element, opts){
link.href = window.location.href; link.href = window.location.href;
pageOrigin = link.protocol + link.host; pageOrigin = link.protocol + link.host;
opts = opts || {};
options = html2canvas.Util.Extend(opts, options);
@ -121,7 +115,7 @@ html2canvas.Preload = function(element, opts){
// if (!this.ignoreRe.test(el.nodeName)){ // if (!this.ignoreRe.test(el.nodeName)){
// //
var contents = html2canvas.Util.Children(el), var contents = _html2canvas.Util.Children(el),
i, i,
contentsLen = contents.length, contentsLen = contents.length,
background_image, background_image,
@ -148,7 +142,7 @@ html2canvas.Preload = function(element, opts){
// opera throws exception on external-content.html // opera throws exception on external-content.html
try { try {
background_image = html2canvas.Util.getCSS(el, 'backgroundImage'); background_image = _html2canvas.Util.getCSS(el, 'backgroundImage');
}catch(e) { }catch(e) {
h2clog("html2canvas: failed to get background-image - Exception: " + e.message); h2clog("html2canvas: failed to get background-image - Exception: " + e.message);
} }
@ -158,7 +152,7 @@ html2canvas.Preload = function(element, opts){
if (background_image.substring(0,7) === "-webkit" || background_image.substring(0,3) === "-o-" || background_image.substring(0,4) === "-moz") { 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 ) ); img = _html2canvas.Generate.Gradient( background_image, _html2canvas.Util.Bounds( el ) );
if ( img !== undefined ){ if ( img !== undefined ){
images[background_image] = { images[background_image] = {
@ -172,8 +166,8 @@ html2canvas.Preload = function(element, opts){
} }
} else { } else {
src = html2canvas.Util.backgroundImage(background_image.match(/data:image\/.*;base64,/i) ? background_image : background_image.split(",")[0]); src = _html2canvas.Util.backgroundImage(background_image.match(/data:image\/.*;base64,/i) ? background_image : background_image.split(",")[0]);
methods.loadImage(src); methods.loadImage(src);
} }
/* /*
@ -198,7 +192,7 @@ html2canvas.Preload = function(element, opts){
img.onerror = function() { img.onerror = function() {
if (img.crossOrigin === "anonymous") { if (img.crossOrigin === "anonymous") {
// CORS failed // CORS failed
window.clearTimeout( imageObj.timer ); window.clearTimeout( imageObj.timer );
// let's try with proxy instead // let's try with proxy instead
@ -222,14 +216,6 @@ html2canvas.Preload = function(element, opts){
}; };
} }
// work around for https://bugs.webkit.org/show_bug.cgi?id=80028
function isComplete() {
if (!this.img.complete) {
this.timer = window.setTimeout(this.img.customComplete, 100)
} else {
this.img.onerror();
}
}
methods = { methods = {
loadImage: function( src ) { loadImage: function( src ) {
@ -238,11 +224,15 @@ html2canvas.Preload = function(element, opts){
img = new Image(); img = new Image();
if ( src.match(/data:image\/.*;base64,/i) ) { if ( src.match(/data:image\/.*;base64,/i) ) {
img.src = src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, ''); img.src = src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, '');
imageObj = images[src] = { img: img }; imageObj = images[src] = {
img: img
};
images.numTotal++; images.numTotal++;
setImageLoadHandlers(img, imageObj); setImageLoadHandlers(img, imageObj);
} else if ( isSameOrigin( src ) || options.allowTaint === true ) { } else if ( isSameOrigin( src ) || options.allowTaint === true ) {
imageObj = images[src] = { img: img }; imageObj = images[src] = {
img: img
};
images.numTotal++; images.numTotal++;
setImageLoadHandlers(img, imageObj); setImageLoadHandlers(img, imageObj);
img.src = src; img.src = src;
@ -250,16 +240,27 @@ html2canvas.Preload = function(element, opts){
// attempt to load with CORS // attempt to load with CORS
img.crossOrigin = "anonymous"; img.crossOrigin = "anonymous";
imageObj = images[src] = { img: img }; imageObj = images[src] = {
img: img
};
images.numTotal++; images.numTotal++;
setImageLoadHandlers(img, imageObj); setImageLoadHandlers(img, imageObj);
img.src = src; img.src = src;
img.customComplete = isComplete.bind(imageObj); // work around for https://bugs.webkit.org/show_bug.cgi?id=80028
img.customComplete = function () {
if (!this.img.complete) {
this.timer = window.setTimeout(this.img.customComplete, 100);
} else {
this.img.onerror();
}
}.bind(imageObj);
img.customComplete(); img.customComplete();
} else if ( options.proxy ) { } else if ( options.proxy ) {
imageObj = images[src] = { img: img }; imageObj = images[src] = {
img: img
};
images.numTotal++; images.numTotal++;
proxyGetImage( src, img, imageObj ); proxyGetImage( src, img, imageObj );
} }

View File

@ -5,22 +5,15 @@
Released under MIT License Released under MIT License
*/ */
html2canvas.Renderer = function(parseQueue, opts){ _html2canvas.Renderer = function(parseQueue, options){
var options = { var queue = [],
"width": null,
"height": null,
"renderer": "canvas",
"taintTest": true // do a taint test with all images before applying to canvas
},
queue = [],
canvas, canvas,
usingFlashcanvas = false, usingFlashcanvas = false,
flashMaxSize = 2880, // flash bitmap limited to 2880x2880px // http://stackoverflow.com/questions/2033792/argumenterror-error-2015-invalid-bitmapdata flashMaxSize = 2880, // flash bitmap limited to 2880x2880px // http://stackoverflow.com/questions/2033792/argumenterror-error-2015-invalid-bitmapdata
doc = document; doc = document;
options = html2canvas.Util.Extend(opts, options);
@ -185,27 +178,27 @@ html2canvas.Renderer = function(parseQueue, opts){
if (queueLen === 1) { if (queueLen === 1) {
if (typeof options.elements[ 0 ] === "object" && options.elements[ 0 ].nodeName !== "BODY" && usingFlashcanvas === false) { if (typeof options.elements[ 0 ] === "object" && options.elements[ 0 ].nodeName !== "BODY" && usingFlashcanvas === false) {
// crop image to the bounds of selected (single) element // crop image to the bounds of selected (single) element
bounds = html2canvas.Util.Bounds( options.elements[ 0 ] ); bounds = _html2canvas.Util.Bounds( options.elements[ 0 ] );
newCanvas = doc.createElement('canvas'); newCanvas = doc.createElement('canvas');
newCanvas.width = bounds.width; newCanvas.width = bounds.width;
newCanvas.height = bounds.height; newCanvas.height = bounds.height;
ctx = newCanvas.getContext("2d"); ctx = newCanvas.getContext("2d");
ctx.drawImage( canvas, bounds.left, bounds.top, bounds.width, bounds.height, 0, 0, bounds.width, bounds.height ); ctx.drawImage( canvas, bounds.left, bounds.top, bounds.width, bounds.height, 0, 0, bounds.width, bounds.height );
delete canvas; canvas = null;
return newCanvas; return newCanvas;
} }
} else { } /*else {
// TODO clip and resize multiple elements // TODO clip and resize multiple elements
/*
for ( i = 0; i < queueLen; i+=1 ) { for ( i = 0; i < queueLen; i+=1 ) {
if (options.elements[ i ] instanceof Element) { if (options.elements[ i ] instanceof Element) {
} }
}*/ }
} }
*/

View File

@ -4,4 +4,79 @@
http://www.twitter.com/niklasvh http://www.twitter.com/niklasvh
Released under MIT License Released under MIT License
*/ */
html2canvas = function( elements, opts ) {
var queue,
canvas,
options = {
// general
logging: false,
// preload options
proxy: "http://html2canvas.appspot.com/",
timeout: 0, // no timeout
useCORS: false, // try to load images as CORS (where available), before falling back to proxy
allowTaint: false, // whether to allow images to taint the canvas, won't need proxy if set to true
// parse options
iframeDefault: "default",
ignoreElements: "IFRAME|OBJECT|PARAM",
useOverflow: true,
letterRendering: false,
// render options
width: null,
height: null,
renderer: "canvas",
taintTest: true // do a taint test with all images before applying to canvas
};
options = _html2canvas.Util.Extend(opts, options);
_html2canvas.logging = options.logging;
options.complete = function( images ) {
if (typeof options.onpreloaded === "function") {
if ( options.onpreloaded( images ) === false ) {
return;
}
}
queue = _html2canvas.Parse( elements, images, options);
if (typeof options.onparsed === "function") {
if ( options.onparsed( queue ) === false ) {
return;
}
}
canvas = _html2canvas.Renderer(queue, options);
if (typeof options.onrendered === "function") {
options.onrendered( canvas );
}
};
// for pages without images, we still want this to be async, i.e. return methods before executing
window.setTimeout( function(){
_html2canvas.Preload( elements, options );
}, 0 );
return {
render: function( queue, opts ) {
return _html2canvas.Renderer( queue, _html2canvas.Util.Extend(opts, options) );
},
parse: function( elements, images, opts ) {
return _html2canvas.Parse( elements, images, _html2canvas.Util.Extend(opts, options) );
},
preload: function( elements, opts ) {
return _html2canvas.Preload( elements, _html2canvas.Util.Extend(opts, options) );
},
log: h2clog
};
};

View File

@ -1,6 +1,6 @@
(function() { (function() {
/* options, customize to your needs */ /* options, customize to your needs */
var server = '//html2canvas.hertzen.com/build', var server = '//html2canvas.hertzen.com/js',
proxy = '//html2canvas.appspot.com', proxy = '//html2canvas.appspot.com',
debug = false, debug = false,
profile = false; profile = false;

View File

@ -7,17 +7,15 @@
console.profile(); console.profile();
} }
var date = new Date(), var date = new Date(),
html2obj,
$message = null, $message = null,
timeoutTimer = false, timeoutTimer = false,
timer = date.getTime(); timer = date.getTime();
options = options || {}; options = options || {};
options.elements = this; options.elements = this;
options.flashcanvas = "../external/flashcanvas.min.js";
options.onrendered = function( canvas ) {
html2canvas.logging = options && options.logging; var $canvas = $(canvas),
options.complete = function(images){
var queue = html2canvas.Parse(this[0], images, options),
$canvas = $(html2canvas.Renderer(queue, options)),
finishTime = new Date(); finishTime = new Date();
if (options && options.profile && window.console && window.console.profileEnd) { if (options && options.profile && window.console && window.console.profileEnd) {
@ -45,9 +43,9 @@
alert("Canvas is tainted, unable to read data"); alert("Canvas is tainted, unable to read data");
} }
} }
}; };
html2canvas.Preload(this[0], options);
html2obj = html2canvas(this[0], options);
function throwMessage(msg,duration){ function throwMessage(msg,duration){
window.clearTimeout(timeoutTimer); window.clearTimeout(timeoutTimer);
@ -77,7 +75,7 @@
textDecoration:'none', textDecoration:'none',
display:'none' display:'none'
}).appendTo(document.body).fadeIn(); }).appendTo(document.body).fadeIn();
html2canvas.log(msg); html2obj.log(msg);
} }
}; };
})( jQuery ); })( jQuery );

View File

@ -6,22 +6,23 @@
Released under MIT License Released under MIT License
*/ */
(function(document, window) { (function(document, window) {
var scrStart = '<script type="text/javascript" src="', scrEnd = '"></script>'; var scrStart = '<script type="text/javascript" src="', scrEnd = '"></script>';
document.write(scrStart + '../external/jquery-1.6.2.js' + scrEnd); document.write(scrStart + '../external/jquery-1.6.2.js' + scrEnd);
var html2canvas = ['Core', 'Generate', 'Parse', 'Preload', 'Queue', 'Renderer', 'Util', 'plugins/jquery.plugin.html2canvas'], i; var html2canvas = ['Core', 'Generate', 'Parse', 'Preload', 'Queue', 'Renderer', 'Util', 'plugins/jquery.plugin.html2canvas'], i;
for (i = 0; i < html2canvas.length; ++i) { for (i = 0; i < html2canvas.length; ++i) {
document.write(scrStart + '../src/' + html2canvas[i] + '.js' + scrEnd); document.write(scrStart + '../src/' + html2canvas[i] + '.js' + scrEnd);
}
window.onload = function() {
if (window.setUp) {
window.setUp();
} }
setTimeout(function() { window.onload = function() {
$(document.body).html2canvas({ if (window.setUp) {
logging: true, window.setUp();
profile: true, }
useCORS: true setTimeout(function() {
}); $(document.body).html2canvas({
}, 100); flashcanvas: "../external/flashcanvas.min.js",
}; logging: true,
profile: true,
useCORS: true
});
}, 100);
};
}(document, window)); }(document, window));

View File

@ -1 +1 @@
v0.32 v0.33