Permalink
Browse files

added flashcanvas integration and some legacy IE bug fixes

  • Loading branch information...
1 parent c4cc1fe commit b65357c55d0701017bafcd357bc654b54d458f8f @niklasvh committed Feb 25, 2012
Showing with 9,121 additions and 57 deletions.
  1. +8,966 −3 external/jquery-1.6.2.js
  2. +13 −3 src/Core.js
  3. +22 −6 src/Parse.js
  4. +26 −12 src/Preload.js
  5. +77 −21 src/Renderer.js
  6. +5 −4 src/plugins/jquery.plugin.html2canvas.js
  7. +11 −7 tests/images.html
  8. +1 −1 tests/test.js
View
Oops, something went wrong.
View
@@ -47,12 +47,14 @@ html2canvas.Util.Bounds = function getBounds (el) {
bounds.top = clientRect.top;
bounds.bottom = clientRect.bottom || (clientRect.top + clientRect.height);
bounds.left = clientRect.left;
- bounds.width = clientRect.width;
- bounds.height = clientRect.height;
+
+ // older IE doesn't have width/height, but top/bottom instead
+ bounds.width = clientRect.width || (clientRect.right - clientRect.left);
+ bounds.height = clientRect.height || (clientRect.bottom - clientRect.top);
return bounds;
- } /*else{
+ } /*else{
p = $(el).offset();
@@ -109,6 +111,14 @@ html2canvas.Util.getCSS = function (el, attribute) {
}*/
// val = $(el).css(attribute);
// }
+
+ /*
+ var val = $(el).css(attribute);
+
+ if (val === "medium") {
+ val = 3;
+ }*/
+
return $(el).css(attribute);
View
@@ -108,7 +108,8 @@ html2canvas.Parse = function (element, images, opts) {
var getCSS = html2canvas.Util.getCSS;
function getCSSInt(element, attribute) {
- return 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
}
// Drawing a rectangle
@@ -587,7 +588,7 @@ html2canvas.Parse = function (element, images, opts) {
borders.push({
width: getCSSInt(el, 'border' + sides[s] + 'Width'),
color: getCSS(el, 'border' + sides[s] + 'Color')
- });
+ });
}
return borders;
@@ -662,7 +663,13 @@ html2canvas.Parse = function (element, images, opts) {
for (i = 0, arrLen = cssArr.length; i < arrLen; i+=1){
style = cssArr[i];
+
+ try {
valueWrap.style[style] = getCSS(el, style);
+ } catch( e ) {
+ // Older IE has issues with "border"
+ html2canvas.log("html2canvas: Parse: Exception caught in renderFormValue: " + e.message);
+ }
}
@@ -702,13 +709,22 @@ html2canvas.Parse = function (element, images, opts) {
function getBackgroundPosition(el, bounds, image){
// TODO add support for multi image backgrounds
- var bgpos = getCSS(el, "backgroundPosition").split(",")[0] || "0 0",
- bgposition = bgpos.split(" "),
+ var bgposition = (function( bgp ){
+
+ if (bgp !== undefined) {
+ return (bgp.split(",")[0] || "0 0").split(" ");
+ } else {
+ // Older IE uses -x and -y
+ return [ getCSS(el, "backgroundPositionX"), getCSS(el, "backgroundPositionY") ];
+ }
+
+
+ })( getCSS(el, "backgroundPosition") ),
topPos,
left,
percentage,
val;
-
+
if (bgposition.length === 1){
val = bgposition;
@@ -1106,7 +1122,7 @@ html2canvas.Parse = function (element, images, opts) {
}
-
+
if (bgbounds.height > 0 && bgbounds.width > 0){
renderRect(
ctx,
View
@@ -63,9 +63,9 @@ html2canvas.Preload = function(element, opts){
function proxyGetImage(url, img){
var callback_name,
- scriptUrl = options.proxy,
- script,
- imgObj = images[url];
+ scriptUrl = options.proxy,
+ script,
+ imgObj = images[url];
link.href = url;
url = link.href; // work around for pages with base href="" set - WARNING: this may change the url -> so access imgObj from images map before changing that url!
@@ -180,8 +180,12 @@ html2canvas.Preload = function(element, opts){
if (elNodeType === 1 || elNodeType === undefined){
- background_image = html2canvas.Util.getCSS(el, 'backgroundImage');
-
+ // opera throws exception on external-content.html
+ try {
+ background_image = html2canvas.Util.getCSS(el, 'backgroundImage');
+ }catch(e) {
+ html2canvas.log("html2canvas: failed to get background-image - Exception: " + e.message);
+ }
if ( background_image && background_image !== "1" && background_image !== "none" ) {
// TODO add multi image background support
@@ -191,7 +195,10 @@ html2canvas.Preload = function(element, opts){
img = html2canvas.Generate.Gradient( background_image, html2canvas.Util.Bounds( el ) );
if ( img !== undefined ){
- images[background_image] = { img: img, succeeded: true };
+ images[background_image] = {
+ img: img,
+ succeeded: true
+ };
images.numTotal++;
images.numLoaded++;
start();
@@ -221,15 +228,20 @@ html2canvas.Preload = function(element, opts){
//Base64 src
img = new Image();
img.src = src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, '');
- images[src] = { img: img, succeeded: true };
+ images[src] = {
+ img: img,
+ succeeded: true
+ };
images.numTotal++;
images.numLoaded++;
start();
}else if ( isSameOrigin( src ) ) {
img = new Image();
- images[src] = { img: img };
+ images[src] = {
+ img: img
+ };
images.numTotal++;
img.onload = function() {
@@ -250,7 +262,9 @@ html2canvas.Preload = function(element, opts){
}else if ( options.proxy ){
// console.log('b'+src);
img = new Image();
- images[src] = { img: img };
+ images[src] = {
+ img: img
+ };
images.numTotal++;
proxyGetImage( src, img );
}
@@ -302,9 +316,9 @@ html2canvas.Preload = function(element, opts){
}
},
renderingDone: function() {
- if (timeoutTimer) {
- window.clearTimeout(timeoutTimer);
- }
+ if (timeoutTimer) {
+ window.clearTimeout(timeoutTimer);
+ }
}
};
View
@@ -15,6 +15,8 @@ html2canvas.Renderer = function(parseQueue, opts){
},
queue = [],
canvas,
+ usingFlashcanvas = false,
+ flashMaxSize = 2880, // flash bitmap limited to 2880x2880px // http://stackoverflow.com/questions/2033792/argumenterror-error-2015-invalid-bitmapdata
doc = document;
options = html2canvas.Util.Extend(opts, options);
@@ -83,9 +85,9 @@ html2canvas.Renderer = function(parseQueue, opts){
renderItem,
fstyle;
- canvas.width = options.width || zStack.ctx.width;
- canvas.height = options.height || zStack.ctx.height;
-
+ canvas.width = canvas.style.width = (!usingFlashcanvas) ? options.width || zStack.ctx.width : Math.min(flashMaxSize, (options.width || zStack.ctx.width) );
+ canvas.height = canvas.style.height = (!usingFlashcanvas) ? options.height || zStack.ctx.height : Math.min(flashMaxSize, (options.height || zStack.ctx.height) );
+
fstyle = ctx.fillStyle;
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, canvas.width, canvas.height);
@@ -116,29 +118,33 @@ html2canvas.Renderer = function(parseQueue, opts){
renderItem = storageContext.ctx.storage[a];
-
switch(renderItem.type){
case "variable":
ctx[renderItem.name] = renderItem['arguments'];
break;
case "function":
if (renderItem.name === "fillRect") {
-
- ctx.fillRect(
- renderItem['arguments'][0],
- renderItem['arguments'][1],
- renderItem['arguments'][2],
- renderItem['arguments'][3]
- );
+
+ if (!usingFlashcanvas || renderItem['arguments'][0] + renderItem['arguments'][2] < flashMaxSize && renderItem['arguments'][1] + renderItem['arguments'][3] < flashMaxSize) {
+ ctx.fillRect(
+ renderItem['arguments'][0],
+ renderItem['arguments'][1],
+ renderItem['arguments'][2],
+ renderItem['arguments'][3]
+ );
+ }
}else if(renderItem.name === "fillText") {
- // console.log(renderItem.arguments[0]);
- ctx.fillText(renderItem['arguments'][0],renderItem['arguments'][1],renderItem['arguments'][2]);
-
+ if (!usingFlashcanvas || renderItem['arguments'][1] < flashMaxSize && renderItem['arguments'][2] < flashMaxSize) {
+ ctx.fillText(
+ renderItem['arguments'][0],
+ renderItem['arguments'][1],
+ renderItem['arguments'][2]
+ );
+ }
}else if(renderItem.name === "drawImage") {
- // console.log(renderItem);
- // console.log(renderItem.arguments[0].width);
- if (renderItem['arguments'][8] > 0 && renderItem['arguments'][7]){
+
+ if (renderItem['arguments'][8] > 0 && renderItem['arguments'][7]){
ctx.drawImage(
renderItem['arguments'][0],
renderItem['arguments'][1],
@@ -149,7 +155,7 @@ html2canvas.Renderer = function(parseQueue, opts){
renderItem['arguments'][6],
renderItem['arguments'][7],
renderItem['arguments'][8]
- );
+ );
}
}
@@ -176,20 +182,21 @@ html2canvas.Renderer = function(parseQueue, opts){
queueLen = options.elements.length;
if (queueLen === 1) {
- if (options.elements[ 0 ] instanceof Element && options.elements[ 0 ].nodeName !== "BODY") {
+ if (typeof options.elements[ 0 ] === "object" && options.elements[ 0 ].nodeName !== "BODY" && usingFlashcanvas === false) {
// crop image to the bounds of selected (single) element
bounds = html2canvas.Util.Bounds( options.elements[ 0 ] );
newCanvas = doc.createElement('canvas');
newCanvas.width = bounds.width;
newCanvas.height = bounds.height;
ctx = newCanvas.getContext("2d");
+
ctx.drawImage( canvas, bounds.left, bounds.top, bounds.width, bounds.height, 0, 0, bounds.width, bounds.height );
delete canvas;
return newCanvas;
}
} else {
- // TODO clip and resize multiple elements
- /*
+ // TODO clip and resize multiple elements
+ /*
for ( i = 0; i < queueLen; i+=1 ) {
if (options.elements[ i ] instanceof Element) {
@@ -400,6 +407,55 @@ html2canvas.Renderer = function(parseQueue, opts){
if (canvas.getContext){
html2canvas.log("html2canvas: Renderer: using canvas renderer");
return canvasRenderer(parseQueue);
+ } else {
+ usingFlashcanvas = true;
+ html2canvas.log("html2canvas: Renderer: canvas not available, using flashcanvas");
+ var script = doc.createElement("script");
+ script.src = options.flashcanvas;
+
+ script.onload = (function(script, func){
+ var intervalFunc;
+
+ if (script.onload === undefined) {
+ // IE lack of support for script onload
+
+ if( script.onreadystatechange !== undefined ) {
+
+ intervalFunc = function() {
+ if (script.readyState !== "loaded" && script.readyState !== "complete") {
+ window.setTimeout( intervalFunc, 250 );
+
+ } else {
+ // it is loaded
+ func();
+
+ }
+
+ };
+
+ window.setTimeout( intervalFunc, 250 );
+
+ } else {
+ html2canvas.log("html2canvas: Renderer: Can't track when flashcanvas is loaded");
+
+ }
+
+ } else {
+ return func;
+ }
+
+ })(script, function(){
+
+ if (typeof FlashCanvas !== "undefined") {
+ html2canvas.log("html2canvas: Renderer: Flashcanvas initialized");
+ FlashCanvas.initElement( canvas );
+ canvasRenderer(parseQueue);
+ }
+ });
+
+ doc.body.appendChild( script );
+
+ return canvas;
}
break;
case "svg":
@@ -12,10 +12,10 @@
timer = date.getTime();
options = options || {};
options.elements = this;
+ options.flashcanvas = "../external/flashcanvas.min.js";
html2canvas.logging = options && options.logging;
- html2canvas.Preload(this[0], $.extend({
- complete: function(images){
+ options.complete = function(images){
var queue = html2canvas.Parse(this[0], images, options),
$canvas = $(html2canvas.Renderer(queue, options)),
finishTime = new Date();
@@ -31,8 +31,9 @@
throwMessage("Canvas Render " + ($canvas.is(':visible') ? "visible" : "hidden"));
});
throwMessage('Screenshot created in '+ ((finishTime.getTime()-timer)) + " ms<br />",4000);
- }
- }, options));
+
+ };
+ html2canvas.Preload(this[0], options);
function throwMessage(msg,duration){
window.clearTimeout(timeoutTimer);
Oops, something went wrong.

0 comments on commit b65357c

Please sign in to comment.