diff --git a/build.xml b/build.xml index 46a550558..232c2575b 100644 --- a/build.xml +++ b/build.xml @@ -22,6 +22,7 @@ + diff --git a/readme.md b/readme.md index 5977f3923..8e1f7ee8d 100644 --- a/readme.md +++ b/readme.md @@ -37,6 +37,11 @@ For more information and examples, please visit the niklasvh) +* Simplified API, cleaned up code (niklasvh) + v0.33 - 2.3.2012 * SVG taint fix, and additional taint testing options for rendering (niklasvh) diff --git a/src/Renderer.js b/src/Renderer.js index eaf442210..d7fad2ede 100644 --- a/src/Renderer.js +++ b/src/Renderer.js @@ -8,15 +8,8 @@ _html2canvas.Renderer = function(parseQueue, options){ - var queue = [], - canvas, - usingFlashcanvas = false, - flashMaxSize = 2880, // flash bitmap limited to 2880x2880px // http://stackoverflow.com/questions/2033792/argumenterror-error-2015-invalid-bitmapdata - doc = document; - - - - + var queue = []; + function sortZ(zStack){ var subStacks = [], stackValues = [], @@ -63,411 +56,11 @@ _html2canvas.Renderer = function(parseQueue, options){ } - function canvasRenderer(zStack){ - - sortZ(zStack.zIndex); - - - var ctx = canvas.getContext("2d"), - storageContext, - i, - queueLen, - a, - newCanvas, - bounds, - testCanvas = document.createElement("canvas"), - hasCTX = ( testCanvas.getContext !== undefined ), - storageLen, - renderItem, - testctx = ( hasCTX ) ? testCanvas.getContext("2d") : {}, - safeImages = [], - fstyle; - - 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 = zStack.backgroundColor; - ctx.fillRect(0, 0, canvas.width, canvas.height); - ctx.fillStyle = fstyle; - - for (i = 0, queueLen = queue.length; i < queueLen; i+=1){ - - storageContext = queue.splice(0, 1)[0]; - storageContext.canvasPosition = storageContext.canvasPosition || {}; - - //this.canvasRenderContext(storageContext,parentctx); - - // set common settings for canvas - ctx.textBaseline = "bottom"; - - if (storageContext.clip){ - ctx.save(); - ctx.beginPath(); - // console.log(storageContext); - ctx.rect(storageContext.clip.left, storageContext.clip.top, storageContext.clip.width, storageContext.clip.height); - ctx.clip(); - - } - - if (storageContext.ctx.storage){ - - for (a = 0, storageLen = storageContext.ctx.storage.length; a < storageLen; a+=1){ - - renderItem = storageContext.ctx.storage[a]; - - - switch(renderItem.type){ - case "variable": - ctx[renderItem.name] = renderItem['arguments']; - break; - case "function": - if (renderItem.name === "fillRect") { - - if (!usingFlashcanvas || renderItem['arguments'][0] + renderItem['arguments'][2] < flashMaxSize && renderItem['arguments'][1] + renderItem['arguments'][3] < flashMaxSize) { - ctx.fillRect.apply( ctx, renderItem['arguments'] ); - } - }else if(renderItem.name === "fillText") { - if (!usingFlashcanvas || renderItem['arguments'][1] < flashMaxSize && renderItem['arguments'][2] < flashMaxSize) { - ctx.fillText.apply( ctx, renderItem['arguments'] ); - } - }else if(renderItem.name === "drawImage") { - - if (renderItem['arguments'][8] > 0 && renderItem['arguments'][7]){ - if ( hasCTX && options.taintTest ) { - if ( safeImages.indexOf( renderItem['arguments'][ 0 ].src ) === -1 ) { - testctx.drawImage( renderItem['arguments'][ 0 ], 0, 0 ); - try { - testctx.getImageData( 0, 0, 1, 1 ); - } catch(e) { - testCanvas = document.createElement("canvas"); - testctx = testCanvas.getContext("2d"); - continue; - } - - safeImages.push( renderItem['arguments'][ 0 ].src ); - - } - } - ctx.drawImage.apply( ctx, renderItem['arguments'] ); - } - } - - - break; - default: - - } - - } - - } - if (storageContext.clip){ - ctx.restore(); - } - - - - - } - h2clog("html2canvas: Renderer: Canvas renderer done - returning canvas obj"); - - // this.canvasRenderStorage(queue,this.ctx); - queueLen = options.elements.length; - if (queueLen === 1) { - 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 ); - canvas = null; - return newCanvas; - } - } /*else { - // TODO clip and resize multiple elements - - for ( i = 0; i < queueLen; i+=1 ) { - if (options.elements[ i ] instanceof Element) { - - } - - } - } - */ - - - - return canvas; + sortZ(parseQueue.zIndex); + if ( typeof options.renderer._create !== "function" ) { + throw Error("Invalid renderer defined"); } + return options.renderer._create( parseQueue, options, document, queue, _html2canvas ); - function svgRenderer(zStack){ - sortZ(zStack.zIndex); - - var svgNS = "http://www.w3.org/2000/svg", - svg = doc.createElementNS(svgNS, "svg"), - xlinkNS = "http://www.w3.org/1999/xlink", - defs = doc.createElementNS(svgNS, "defs"), - i, - a, - queueLen, - storageLen, - storageContext, - renderItem, - el, - settings = {}, - text, - fontStyle, - clipId = 0; - - svg.setAttribute("version", "1.1"); - svg.setAttribute("baseProfile", "full"); - - svg.setAttribute("viewBox", "0 0 " + Math.max(zStack.ctx.width, options.width) + " " + Math.max(zStack.ctx.height, options.height)); - svg.setAttribute("width", Math.max(zStack.ctx.width, options.width) + "px"); - svg.setAttribute("height", Math.max(zStack.ctx.height, options.height) + "px"); - svg.setAttribute("preserveAspectRatio", "none"); - svg.appendChild(defs); - - - - for (i = 0, queueLen = queue.length; i < queueLen; i+=1){ - - storageContext = queue.splice(0, 1)[0]; - storageContext.canvasPosition = storageContext.canvasPosition || {}; - - //this.canvasRenderContext(storageContext,parentctx); - - - /* - if (storageContext.clip){ - ctx.save(); - ctx.beginPath(); - // console.log(storageContext); - ctx.rect(storageContext.clip.left, storageContext.clip.top, storageContext.clip.width, storageContext.clip.height); - ctx.clip(); - - }*/ - - if (storageContext.ctx.storage){ - - for (a = 0, storageLen = storageContext.ctx.storage.length; a < storageLen; a+=1){ - - renderItem = storageContext.ctx.storage[a]; - - - - switch(renderItem.type){ - case "variable": - settings[renderItem.name] = renderItem['arguments']; - break; - case "function": - if (renderItem.name === "fillRect") { - - el = doc.createElementNS(svgNS, "rect"); - el.setAttribute("x", renderItem['arguments'][0]); - el.setAttribute("y", renderItem['arguments'][1]); - el.setAttribute("width", renderItem['arguments'][2]); - el.setAttribute("height", renderItem['arguments'][3]); - el.setAttribute("fill", settings.fillStyle); - svg.appendChild(el); - - } else if(renderItem.name === "fillText") { - el = doc.createElementNS(svgNS, "text"); - - fontStyle = settings.font.split(" "); - - el.style.fontVariant = fontStyle.splice(0, 1)[0]; - el.style.fontWeight = fontStyle.splice(0, 1)[0]; - el.style.fontStyle = fontStyle.splice(0, 1)[0]; - el.style.fontSize = fontStyle.splice(0, 1)[0]; - - el.setAttribute("x", renderItem['arguments'][1]); - el.setAttribute("y", renderItem['arguments'][2] - (parseInt(el.style.fontSize, 10) + 3)); - - el.setAttribute("fill", settings.fillStyle); - - - - - // TODO get proper baseline - el.style.dominantBaseline = "text-before-edge"; - el.style.fontFamily = fontStyle.join(" "); - - text = doc.createTextNode(renderItem['arguments'][0]); - el.appendChild(text); - - - svg.appendChild(el); - - - - } else if(renderItem.name === "drawImage") { - - if (renderItem['arguments'][8] > 0 && renderItem['arguments'][7]){ - - // TODO check whether even any clipping is necessary for this particular image - el = doc.createElementNS(svgNS, "clipPath"); - el.setAttribute("id", "clipId" + clipId); - - text = doc.createElementNS(svgNS, "rect"); - text.setAttribute("x", renderItem['arguments'][5] ); - text.setAttribute("y", renderItem['arguments'][6]); - - text.setAttribute("width", renderItem['arguments'][3]); - text.setAttribute("height", renderItem['arguments'][4]); - el.appendChild(text); - defs.appendChild(el); - - el = doc.createElementNS(svgNS, "image"); - el.setAttributeNS(xlinkNS, "xlink:href", renderItem['arguments'][0].src); - el.setAttribute("width", renderItem['arguments'][0].width); - el.setAttribute("height", renderItem['arguments'][0].height); - el.setAttribute("x", renderItem['arguments'][5] - renderItem['arguments'][1]); - el.setAttribute("y", renderItem['arguments'][6] - renderItem['arguments'][2]); - el.setAttribute("clip-path", "url(#clipId" + clipId + ")"); - // el.setAttribute("xlink:href", ); - - - el.setAttribute("preserveAspectRatio", "none"); - - svg.appendChild(el); - - - clipId += 1; - /* - ctx.drawImage( - renderItem['arguments'][0], - renderItem['arguments'][1], - renderItem['arguments'][2], - renderItem['arguments'][3], - renderItem['arguments'][4], - renderItem['arguments'][5], - renderItem['arguments'][6], - renderItem['arguments'][7], - renderItem['arguments'][8] - ); - */ - } - } - - - - break; - default: - - } - - } - - } - /* - if (storageContext.clip){ - ctx.restore(); - } - */ - - - - } - - - - - - - - - - - h2clog("html2canvas: Renderer: SVG Renderer done - returning SVG DOM obj"); - - return svg; - - } - - - //this.each(this.opts.renderOrder.split(" "),function(i,renderer){ - - //options.renderer = "svg"; - - switch(options.renderer.toLowerCase()){ - case "canvas": - canvas = doc.createElement('canvas'); - if (canvas.getContext){ - h2clog("html2canvas: Renderer: using canvas renderer"); - return canvasRenderer(parseQueue); - } else { - usingFlashcanvas = true; - h2clog("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 { - h2clog("html2canvas: Renderer: Can't track when flashcanvas is loaded"); - - } - - } else { - return func; - } - - })(script, function(){ - - if (typeof window.FlashCanvas !== "undefined") { - h2clog("html2canvas: Renderer: Flashcanvas initialized"); - window.FlashCanvas.initElement( canvas ); - canvasRenderer(parseQueue); - } - }); - - doc.body.appendChild( script ); - - return canvas; - } - break; - case "svg": - if (doc.createElementNS){ - h2clog("html2canvas: Renderer: using SVG renderer"); - return svgRenderer(parseQueue); - } - break; - - } - - - - //}); - - - return this; - - - }; diff --git a/src/Util.js b/src/Util.js index 2c22d5f01..e97125e23 100644 --- a/src/Util.js +++ b/src/Util.js @@ -30,15 +30,17 @@ html2canvas = function( elements, opts ) { // render options + flashcanvas: undefined, // path to flashcanvas 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); + options.renderer = options.renderer || html2canvas.Renderer.Canvas( options ); + _html2canvas.logging = options.logging; options.complete = function( images ) { @@ -82,3 +84,8 @@ html2canvas = function( elements, opts ) { log: h2clog }; }; + +html2canvas.log = h2clog; // for renderers +html2canvas.Renderer = { + Canvas: undefined // We are assuming this will be used +}; \ No newline at end of file diff --git a/src/renderers/SVG.js b/src/renderers/SVG.js new file mode 100644 index 000000000..835a62305 --- /dev/null +++ b/src/renderers/SVG.js @@ -0,0 +1,206 @@ +/* + html2canvas @VERSION@ + Copyright (c) 2011 Niklas von Hertzen. All rights reserved. + http://www.twitter.com/niklasvh + + Released under MIT License +*/ + + +// WARNING THIS file is outdated, and hasn't been tested in quite a while + +html2canvas.Renderer.SVG = function( options ) { + + options = options || {}; + + var doc = document, + svgNS = "http://www.w3.org/2000/svg", + svg = doc.createElementNS(svgNS, "svg"), + xlinkNS = "http://www.w3.org/1999/xlink", + defs = doc.createElementNS(svgNS, "defs"), + i, + a, + queueLen, + storageLen, + storageContext, + renderItem, + el, + settings = {}, + text, + fontStyle, + clipId = 0, + methods; + + + methods = { + _create: function( zStack, options, doc, queue, _html2canvas ) { + svg.setAttribute("version", "1.1"); + svg.setAttribute("baseProfile", "full"); + + svg.setAttribute("viewBox", "0 0 " + Math.max(zStack.ctx.width, options.width) + " " + Math.max(zStack.ctx.height, options.height)); + svg.setAttribute("width", Math.max(zStack.ctx.width, options.width) + "px"); + svg.setAttribute("height", Math.max(zStack.ctx.height, options.height) + "px"); + svg.setAttribute("preserveAspectRatio", "none"); + svg.appendChild(defs); + + + + for (i = 0, queueLen = queue.length; i < queueLen; i+=1){ + + storageContext = queue.splice(0, 1)[0]; + storageContext.canvasPosition = storageContext.canvasPosition || {}; + + //this.canvasRenderContext(storageContext,parentctx); + + + /* + if (storageContext.clip){ + ctx.save(); + ctx.beginPath(); + // console.log(storageContext); + ctx.rect(storageContext.clip.left, storageContext.clip.top, storageContext.clip.width, storageContext.clip.height); + ctx.clip(); + + }*/ + + if (storageContext.ctx.storage){ + + for (a = 0, storageLen = storageContext.ctx.storage.length; a < storageLen; a+=1){ + + renderItem = storageContext.ctx.storage[a]; + + + + switch(renderItem.type){ + case "variable": + settings[renderItem.name] = renderItem['arguments']; + break; + case "function": + if (renderItem.name === "fillRect") { + + el = doc.createElementNS(svgNS, "rect"); + el.setAttribute("x", renderItem['arguments'][0]); + el.setAttribute("y", renderItem['arguments'][1]); + el.setAttribute("width", renderItem['arguments'][2]); + el.setAttribute("height", renderItem['arguments'][3]); + el.setAttribute("fill", settings.fillStyle); + svg.appendChild(el); + + } else if(renderItem.name === "fillText") { + el = doc.createElementNS(svgNS, "text"); + + fontStyle = settings.font.split(" "); + + el.style.fontVariant = fontStyle.splice(0, 1)[0]; + el.style.fontWeight = fontStyle.splice(0, 1)[0]; + el.style.fontStyle = fontStyle.splice(0, 1)[0]; + el.style.fontSize = fontStyle.splice(0, 1)[0]; + + el.setAttribute("x", renderItem['arguments'][1]); + el.setAttribute("y", renderItem['arguments'][2] - (parseInt(el.style.fontSize, 10) + 3)); + + el.setAttribute("fill", settings.fillStyle); + + + + + // TODO get proper baseline + el.style.dominantBaseline = "text-before-edge"; + el.style.fontFamily = fontStyle.join(" "); + + text = doc.createTextNode(renderItem['arguments'][0]); + el.appendChild(text); + + + svg.appendChild(el); + + + + } else if(renderItem.name === "drawImage") { + + if (renderItem['arguments'][8] > 0 && renderItem['arguments'][7]){ + + // TODO check whether even any clipping is necessary for this particular image + el = doc.createElementNS(svgNS, "clipPath"); + el.setAttribute("id", "clipId" + clipId); + + text = doc.createElementNS(svgNS, "rect"); + text.setAttribute("x", renderItem['arguments'][5] ); + text.setAttribute("y", renderItem['arguments'][6]); + + text.setAttribute("width", renderItem['arguments'][3]); + text.setAttribute("height", renderItem['arguments'][4]); + el.appendChild(text); + defs.appendChild(el); + + el = doc.createElementNS(svgNS, "image"); + el.setAttributeNS(xlinkNS, "xlink:href", renderItem['arguments'][0].src); + el.setAttribute("width", renderItem['arguments'][0].width); + el.setAttribute("height", renderItem['arguments'][0].height); + el.setAttribute("x", renderItem['arguments'][5] - renderItem['arguments'][1]); + el.setAttribute("y", renderItem['arguments'][6] - renderItem['arguments'][2]); + el.setAttribute("clip-path", "url(#clipId" + clipId + ")"); + // el.setAttribute("xlink:href", ); + + + el.setAttribute("preserveAspectRatio", "none"); + + svg.appendChild(el); + + + clipId += 1; + /* + ctx.drawImage( + renderItem['arguments'][0], + renderItem['arguments'][1], + renderItem['arguments'][2], + renderItem['arguments'][3], + renderItem['arguments'][4], + renderItem['arguments'][5], + renderItem['arguments'][6], + renderItem['arguments'][7], + renderItem['arguments'][8] + ); + */ + } + } + + + + break; + default: + + } + + } + + } + /* + if (storageContext.clip){ + ctx.restore(); + } + */ + + + + } + + + + + + + + + + + h2clog("html2canvas: Renderer: SVG Renderer done - returning SVG DOM obj"); + + return svg; + } + }; + + return methods; + + +}; \ No newline at end of file diff --git a/src/renderers/canvas.js b/src/renderers/canvas.js new file mode 100644 index 000000000..2ea524f5d --- /dev/null +++ b/src/renderers/canvas.js @@ -0,0 +1,225 @@ +/* + html2canvas @VERSION@ + Copyright (c) 2011 Niklas von Hertzen. All rights reserved. + http://www.twitter.com/niklasvh + + Released under MIT License +*/ + +html2canvas.Renderer.Canvas = function( options ) { + + options = options || {}; + + var doc = document, + canvas = options.canvas || doc.createElement('canvas'), + usingFlashcanvas = false, + _createCalled = false, + canvasReadyToDraw = false, + methods, + flashMaxSize = 2880; // flash bitmap limited to 2880x2880px // http://stackoverflow.com/questions/2033792/argumenterror-error-2015-invalid-bitmapdata + + + if (canvas.getContext){ + html2canvas.log("html2canvas: Renderer: using canvas renderer"); + canvasReadyToDraw = true; + } else if ( options.flashcanvas !== undefined ){ + 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 window.FlashCanvas !== "undefined") { + html2canvas.log("html2canvas: Renderer: Flashcanvas initialized"); + window.FlashCanvas.initElement( canvas ); + + canvasReadyToDraw = true; + if ( _createCalled !== false ) { + methods._create.apply( null, _createCalled ); + } + } + }); + + doc.body.appendChild( script ); + + } + + methods = { + _create: function( zStack, options, doc, queue, _html2canvas ) { + + if ( !canvasReadyToDraw ) { + _createCalled = arguments; + return canvas; + } + + var ctx = canvas.getContext("2d"), + storageContext, + i, + queueLen, + a, + newCanvas, + bounds, + testCanvas = document.createElement("canvas"), + hasCTX = ( testCanvas.getContext !== undefined ), + storageLen, + renderItem, + testctx = ( hasCTX ) ? testCanvas.getContext("2d") : {}, + safeImages = [], + fstyle; + + 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 = zStack.backgroundColor; + ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.fillStyle = fstyle; + + for (i = 0, queueLen = queue.length; i < queueLen; i+=1){ + + storageContext = queue.splice(0, 1)[0]; + storageContext.canvasPosition = storageContext.canvasPosition || {}; + + //this.canvasRenderContext(storageContext,parentctx); + + // set common settings for canvas + ctx.textBaseline = "bottom"; + + if (storageContext.clip){ + ctx.save(); + ctx.beginPath(); + // console.log(storageContext); + ctx.rect(storageContext.clip.left, storageContext.clip.top, storageContext.clip.width, storageContext.clip.height); + ctx.clip(); + + } + + if (storageContext.ctx.storage){ + + for (a = 0, storageLen = storageContext.ctx.storage.length; a < storageLen; a+=1){ + + renderItem = storageContext.ctx.storage[a]; + + + switch(renderItem.type){ + case "variable": + ctx[renderItem.name] = renderItem['arguments']; + break; + case "function": + if (renderItem.name === "fillRect") { + + if (!usingFlashcanvas || renderItem['arguments'][0] + renderItem['arguments'][2] < flashMaxSize && renderItem['arguments'][1] + renderItem['arguments'][3] < flashMaxSize) { + ctx.fillRect.apply( ctx, renderItem['arguments'] ); + } + }else if(renderItem.name === "fillText") { + if (!usingFlashcanvas || renderItem['arguments'][1] < flashMaxSize && renderItem['arguments'][2] < flashMaxSize) { + ctx.fillText.apply( ctx, renderItem['arguments'] ); + } + }else if(renderItem.name === "drawImage") { + + if (renderItem['arguments'][8] > 0 && renderItem['arguments'][7]){ + if ( hasCTX && options.taintTest ) { + if ( safeImages.indexOf( renderItem['arguments'][ 0 ].src ) === -1 ) { + testctx.drawImage( renderItem['arguments'][ 0 ], 0, 0 ); + try { + testctx.getImageData( 0, 0, 1, 1 ); + } catch(e) { + testCanvas = doc.createElement("canvas"); + testctx = testCanvas.getContext("2d"); + continue; + } + + safeImages.push( renderItem['arguments'][ 0 ].src ); + + } + } + ctx.drawImage.apply( ctx, renderItem['arguments'] ); + } + } + + + break; + default: + + } + + } + + } + if (storageContext.clip){ + ctx.restore(); + } + + + + + } + h2clog("html2canvas: Renderer: Canvas renderer done - returning canvas obj"); + + queueLen = options.elements.length; + + if (queueLen === 1) { + 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 ); + canvas = null; + return newCanvas; + } + } /*else { + // TODO clip and resize multiple elements + + for ( i = 0; i < queueLen; i+=1 ) { + if (options.elements[ i ] instanceof Element) { + + } + + } + } + */ + + + + return canvas; + } + } + + return methods; + +}; \ No newline at end of file diff --git a/tests/test.js b/tests/test.js index 3fe1b1810..2e86ce4b7 100644 --- a/tests/test.js +++ b/tests/test.js @@ -8,7 +8,7 @@ (function(document, window) { var scrStart = ''; 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', 'renderers/Canvas', 'plugins/jquery.plugin.html2canvas'], i; for (i = 0; i < html2canvas.length; ++i) { document.write(scrStart + '../src/' + html2canvas[i] + '.js' + scrEnd); }