mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
Compare commits
84 Commits
Author | SHA1 | Date | |
---|---|---|---|
c7d526c9ea | |||
bf994849e0 | |||
2dc8b9385e | |||
6ef6c79f24 | |||
3ad49efa00 | |||
c86d12b915 | |||
1447b031c6 | |||
e01d97df19 | |||
af60621d4f | |||
f485028d30 | |||
5878c201b3 | |||
b6d6f44678 | |||
19f505214b | |||
c24223ca85 | |||
b82be022b2 | |||
84a676403f | |||
afc358fb12 | |||
e925719151 | |||
b65357c55d | |||
c4cc1fe180 | |||
abea4a89da | |||
0cb252ada9 | |||
d5040e119a | |||
83363a5cf4 | |||
96db0b8ff4 | |||
b320dd306e | |||
36ff1ec7aa | |||
014c0ed98f | |||
45fa47100e | |||
db211317ff | |||
bbd75286a8 | |||
8bbbace790 | |||
3dec1cd4ab | |||
594f735d29 | |||
447db0c5f5 | |||
c57ed30c3e | |||
50f5f53e2b | |||
2fdab0d753 | |||
0d8937435d | |||
433d7ce81c | |||
4dba62e2fd | |||
2e494bde23 | |||
753ab77ef6 | |||
0d24b9a734 | |||
98c2bd638e | |||
0d370d09fb | |||
88174fe136 | |||
1c6469d29b | |||
ab5055ffad | |||
501f559783 | |||
f75456cc88 | |||
961f6caf21 | |||
097a4e58d7 | |||
73763c8114 | |||
1f7314747e | |||
4f49bd6e9b | |||
217a75c0f6 | |||
62fa6038e7 | |||
66d328d1e3 | |||
2ec7fda1f1 | |||
044b612d6e | |||
4aba46e247 | |||
91ac445fdf | |||
2a3d6a0a35 | |||
03495f851d | |||
16c74d1f8c | |||
74c7373362 | |||
7ee7d7fa67 | |||
962d5b8e8d | |||
2ca4b88702 | |||
ff635115dc | |||
a75f41c076 | |||
6dfb5299c9 | |||
a89b83cb11 | |||
52150b09cd | |||
61f71c1839 | |||
6fe3218b50 | |||
f0112ff3ab | |||
27ee971bba | |||
5ba5ef571c | |||
180cd38265 | |||
958cfdf4eb | |||
07c0c13cc1 | |||
7145d9303d |
11
.gitignore
vendored
11
.gitignore
vendored
@ -1,9 +1,14 @@
|
||||
/nbproject/
|
||||
/images/
|
||||
/external/
|
||||
/tests/templates/
|
||||
/tests/cache/
|
||||
/dist/
|
||||
/build/tmp.js
|
||||
/tests/flashcanvas.html
|
||||
/lib/
|
||||
/build/
|
||||
index.html
|
||||
image.jpg
|
||||
screenshots_local.html
|
||||
screenshots.html
|
||||
screenshots_local.html
|
||||
/.project
|
||||
/.settings/
|
||||
|
32
LICENSE
32
LICENSE
@ -1,21 +1,21 @@
|
||||
/*
|
||||
* The MIT License
|
||||
The MIT License
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
57
bookmarklet.html
Normal file
57
bookmarklet.html
Normal file
@ -0,0 +1,57 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>html2canvas Bookmarklet</title>
|
||||
<script type="text/javascript" src="external/jquery-1.6.2.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
var isDebug = false, origBookmarklet = '';
|
||||
function patchLinks() {
|
||||
var bookmarklet = origBookmarklet;
|
||||
if (isDebug) {
|
||||
bookmarklet = bookmarklet.replace('//DEBUG: ', '');
|
||||
}
|
||||
bookmarklet = bookmarklet.replace(/\s\/\/.*/g, ''); // remove single line comments
|
||||
bookmarklet = bookmarklet.replace(/[\u000A\u000D]+/g, ''); // remove all linebreaks
|
||||
bookmarklet = bookmarklet.replace(/\/\*.*?\*\//g, ''); // remove multi line comments
|
||||
bookmarklet = bookmarklet.replace(/\s\s+/g, ' '); // reduce multiple spaces to single spaces
|
||||
bookmarklet = bookmarklet.replace(/\s+=\s+/g, '=');
|
||||
$('a.bookmarklet').each(function(_, el) {
|
||||
el.href = $(el).attr('data-href') + bookmarklet;
|
||||
});
|
||||
}
|
||||
$(function() {
|
||||
$('input[type=checkbox]').bind('change', function() {
|
||||
isDebug = $(this).is(':checked');
|
||||
patchLinks();
|
||||
}).change();
|
||||
$.ajax('src/plugins/bookmarklet.js', {
|
||||
dataType: 'text',
|
||||
success: function(data, status, xhr) {
|
||||
origBookmarklet = data;
|
||||
patchLinks();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>html2canvas Bookmarklet</h1>
|
||||
<p>
|
||||
If you use a normal browser: drag the normal <a class="bookmarklet" data-href="javascript:">html2canvas</a> bookmarklet to your bookmarks toolbar.<br />
|
||||
If not use the following link: <a class="bookmarklet" data-href="#_remove_this_javascript:">bookmarklet for those special mobile devices</a>
|
||||
click / tap that link and then bookmark the page, edit the bookmark and remove the start up until including <code>#_remove_this_</code>
|
||||
part at the beginning of the URL, it must start with: <code>javascript:</code> to be correct.
|
||||
</p>
|
||||
<p>
|
||||
If you are using Firefox and the NoScript Addon: disable the ABE part of it,
|
||||
took me quite some time to figure out that the reason for an unreliable bookmarklet was in NoScript...
|
||||
</p>
|
||||
<h2>For Developers:</h2>
|
||||
<p>
|
||||
If you are a developer and want to debug locally (you need the source tree of your html2canvas at:
|
||||
<code>http(s)://localhost/html2canvas/</code>)
|
||||
check the following box to get the bookmarklet patched automatically ;)<br />
|
||||
<label>Debug bookmarklet: <input type="checkbox" /></label>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
120
build.xml
120
build.xml
@ -1,80 +1,100 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<project name="html2canvas" basedir=".">
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<project name="html2canvas" basedir="." default="build">
|
||||
<property name="src.dir" location="src"/>
|
||||
<property name="lib.dir" location="lib"/>
|
||||
<property name="lib.dir" location="../lib"/>
|
||||
<property name="build.dir" location="build"/>
|
||||
<property name="dist" location="dist"/>
|
||||
|
||||
|
||||
<property name="jquery-externs" value="jquery-1.4.4.externs.js"/>
|
||||
|
||||
|
||||
|
||||
<property name="JS_NAME" value="html2canvas.js"/>
|
||||
<property name="JS_NAME_MIN" value="html2canvas.min.js"/>
|
||||
<property name="JQUERY_PLUGIN_NAME" value="jquery.plugin.html2canvas.js"/>
|
||||
|
||||
<loadfile property="version" srcfile="version.txt" />
|
||||
|
||||
<path id="sourcefiles">
|
||||
<fileset dir="${src.dir}" includes="LICENSE"/>
|
||||
<fileset dir="." includes="LICENSE"/>
|
||||
<fileset dir="${src.dir}" includes="Core.js"/>
|
||||
<fileset dir="${src.dir}" includes="Background.js"/>
|
||||
<fileset dir="${src.dir}" includes="Border.js"/>
|
||||
<fileset dir="${src.dir}" includes="Draw.js"/>
|
||||
<fileset dir="${src.dir}" includes="Forms.js"/>
|
||||
<fileset dir="${src.dir}" includes="Images.js"/>
|
||||
<fileset dir="${src.dir}" includes="Renderer.js"/>
|
||||
<fileset dir="${src.dir}" includes="Lists.js"/>
|
||||
<fileset dir="${src.dir}" includes="Text.js"/>
|
||||
<fileset dir="${src.dir}" includes="Traversing.js"/>
|
||||
<fileset dir="${src.dir}" includes="Util.js"/>
|
||||
<filelist dir="${src.dir}">
|
||||
<file name="LICENSE"/>
|
||||
<file name="html2canvas-pre.txt"/>
|
||||
<file name="Core.js"/>
|
||||
<file name="Generate.js"/>
|
||||
<file name="Parse.js"/>
|
||||
<file name="Preload.js"/>
|
||||
<file name="Queue.js"/>
|
||||
<file name="Renderer.js"/>
|
||||
<file name="Util.js"/>
|
||||
<file name="html2canvas-post.txt"/>
|
||||
</filelist>
|
||||
</path>
|
||||
|
||||
|
||||
<path id="jquery-plugin">
|
||||
<fileset dir="${src.dir}" includes="LICENSE"/>
|
||||
<fileset dir="." includes="LICENSE"/>
|
||||
<fileset dir="${src.dir}/plugins" includes="${JQUERY_PLUGIN_NAME}"/>
|
||||
<fileset dir="${src.dir}/plugins" includes="${JQUERY_PLUGIN_NAME}"/>
|
||||
</path>
|
||||
|
||||
<path id="minified">
|
||||
<fileset dir="${src.dir}" includes="LICENSE"/>
|
||||
<fileset dir="${build.dir}" includes="tmp.js"/>
|
||||
</path>
|
||||
|
||||
<target name="plugins">
|
||||
|
||||
<target name="build-dir">
|
||||
<echo>Creating directory ${build.dir}...</echo>
|
||||
<mkdir dir="${build.dir}"/>
|
||||
</target>
|
||||
|
||||
<target name="plugins" depends="build-dir">
|
||||
<echo>Creating ${JQUERY_PLUGIN_NAME}...</echo>
|
||||
<concat fixlastline="yes" destfile="${build.dir}/${JQUERY_PLUGIN_NAME}">
|
||||
<path refid="jquery-plugin"/>
|
||||
</concat>
|
||||
<replaceregexp match="@VERSION@" replace="${version}" flags="g" byline="true" file="${build.dir}/${JQUERY_PLUGIN_NAME}" />
|
||||
</target>
|
||||
|
||||
|
||||
<target name="source">
|
||||
|
||||
<pathconvert property="prettty-sourcefiles" pathsep="${line.separator}" refid="sourcefiles"></pathconvert>
|
||||
|
||||
<target name="build" depends="build-dir,plugins">
|
||||
<echo>Concatenating files:${line.separator}${prettty-sourcefiles}${line.separator}into ${build.dir}/${JS_NAME}...</echo>
|
||||
<concat fixlastline="yes" destfile="${build.dir}/${JS_NAME}">
|
||||
<path refid="sourcefiles"/>
|
||||
</concat>
|
||||
<replaceregexp match="@VERSION@" replace="${version}" flags="g" byline="true" file="${build.dir}/${JS_NAME}" />
|
||||
</target>
|
||||
|
||||
|
||||
|
||||
<taskdef name="jscomp" classname="com.google.javascript.jscomp.ant.CompileTask"
|
||||
classpath="${lib.dir}/compiler.jar"/>
|
||||
|
||||
<target name="release">
|
||||
|
||||
<jscomp compilationLevel="simple" warning="verbose"
|
||||
debug="false"
|
||||
output="${build.dir}/tmp.js">
|
||||
classpath="${lib.dir}/compiler.jar" onerror="report"/>
|
||||
|
||||
<target name="syntaxcheck" depends="build-dir,build">
|
||||
<jscomp compilationLevel="simple" warning="verbose"
|
||||
debug="false"
|
||||
output="${build.dir}/${JS_NAME_MIN}.tmp">
|
||||
<externs dir="${lib.dir}">
|
||||
<file name="${jquery-externs}"/>
|
||||
<file name="${jquery-externs}"/>
|
||||
</externs>
|
||||
<sources dir="${build.dir}">
|
||||
<file name="${JS_NAME}" />
|
||||
<sources dir="${src.dir}">
|
||||
<!-- need to write them again here since the closure compiler doesn't understand filesets,... -->
|
||||
<file name="LICENSE"/>
|
||||
<file name="Core.js"/>
|
||||
<file name="Generate.js"/>
|
||||
<file name="Parse.js"/>
|
||||
<file name="Preload.js"/>
|
||||
<file name="Queue.js"/>
|
||||
<file name="Renderer.js"/>
|
||||
<file name="Util.js"/>
|
||||
</sources>
|
||||
</jscomp>
|
||||
|
||||
<concat fixlastline="yes" destfile="${build.dir}/${JS_NAME_MIN}">
|
||||
<path refid="minified"/>
|
||||
</concat>
|
||||
<delete file="${build.dir}/${JS_NAME_MIN}.tmp"></delete>
|
||||
</target>
|
||||
|
||||
<target name="release" depends="build-dir,build,syntaxcheck">
|
||||
<jscomp compilationLevel="simple" warning="verbose"
|
||||
debug="false"
|
||||
output="${build.dir}/${JS_NAME_MIN}">
|
||||
<externs dir="${lib.dir}">
|
||||
<file name="${jquery-externs}"/>
|
||||
</externs>
|
||||
<sources dir="${build.dir}">
|
||||
<file name="${JS_NAME}"/>
|
||||
</sources>
|
||||
</jscomp>
|
||||
<replaceregexp match="@VERSION@" replace="${version}" flags="g" byline="true" file="${build.dir}/${JS_NAME_MIN}" />
|
||||
</target>
|
||||
|
||||
<target name="clean">
|
||||
<delete dir="${build.dir}"></delete>
|
||||
</target>
|
||||
</project>
|
||||
|
||||
|
2159
build/html2canvas.js
2159
build/html2canvas.js
File diff suppressed because it is too large
Load Diff
55
build/html2canvas.min.js
vendored
55
build/html2canvas.min.js
vendored
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* html2canvas v0.27 <http://html2canvas.hertzen.com>
|
||||
* Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
|
||||
* http://www.twitter.com/niklasvh
|
||||
*
|
||||
* Released under MIT License
|
||||
*/
|
||||
|
||||
function html2canvas(a,b){this.opts=this.extendObj(b||{},{logging:!1,ready:function(a){document.body.appendChild(a.canvas)},storageReady:function(a){a.Renderer(a.contextStacks)},iframeDefault:"default",flashCanvasPath:"http://html2canvas.hertzen.com/external/flashcanvas/flashcanvas.js",renderViewport:!1,reorderZ:!0,throttle:!0,letterRendering:!1,proxyUrl:null,logger:function(a){window.console&&window.console.log?window.console.log(a):alert(a)},canvasWidth:0,canvasHeight:0,useOverflow:!0,renderOrder:"canvas flash html"});
|
||||
this.element=a;this.imagesLoaded=0;this.images=[];this.fontData=[];this.numDraws=0;this.contextStacks=[];this.ignoreElements="IFRAME|OBJECT|PARAM";this.needReorder=!1;this.blockElements=/(BR|PARAM)/;this.pageOrigin=window.location.protocol+window.location.host;this.queue=[];this.ignoreRe=RegExp("("+this.ignoreElements+")");this.support={rangeBounds:!1};if(document.createRange){var c=document.createRange();if(c.getBoundingClientRect){var d=document.createElement("boundtest");d.style.height="123px";
|
||||
d.style.display="block";document.getElementsByTagName("body")[0].appendChild(d);c.selectNode(d);if(c.getBoundingClientRect().height==123)this.support.rangeBounds=!0;document.getElementsByTagName("body")[0].removeChild(d)}}this.init();return this}
|
||||
html2canvas.prototype.init=function(){var a=this;this.log("Finding background-images");this.images.push("start");this.getImages(this.element);this.log("Finding images");this.each(this.element.ownerDocument.images,function(b,c){a.preloadImage(a.getAttr(c,"src"))});this.images.splice(0,1);this.images.length==0&&this.start()};
|
||||
html2canvas.prototype.start=function(){if(this.images.length==0||this.imagesLoaded==this.images.length/2){this.log("Finished loading "+this.imagesLoaded+" images, Started parsing");this.bodyOverflow=document.getElementsByTagName("body")[0].style.overflow;document.getElementsByTagName("body")[0].style.overflow="hidden";var a=new this.storageContext($(document).width(),$(document).height());a.opacity=this.getCSS(this.element,"opacity");this.parseElement(this.element,this.newElement(this.element,a))}};
|
||||
html2canvas.prototype.stackingContext=function(a){this.canvas=document.createElement("canvas");this.canvas.width=a;this.canvas.height=a;if(this.canvas.getContext)this.ctx=this.canvas.getContext("2d");this.ctx.textBaseline="bottom";return this.ctx};
|
||||
html2canvas.prototype.storageContext=function(a,b){this.storage=[];this.width=a;this.height=b;this.fillRect=function(a,b,e,f){this.storage.push({type:"function",name:"fillRect",arguments:[a,b,e,f]})};this.drawImage=function(a,b,e,f,g,h,i,j,m){this.storage.push({type:"function",name:"drawImage",arguments:[a,b,e,f,g,h,i,j,m]})};this.fillText=function(a,b,e){this.storage.push({type:"function",name:"fillText",arguments:[a,b,e]})};return this};
|
||||
html2canvas.prototype.finish=function(){this.log("Finished rendering");document.getElementsByTagName("body")[0].style.overflow=this.bodyOverflow;this.opts.ready(this)};
|
||||
html2canvas.prototype.drawBackground=function(a,b,c){var d=this.getCSS(a,"background-image").split(",")[0],e=this.getCSS(a,"background-repeat").split(",")[0];if(typeof d!="undefined"&&/^(1|none)$/.test(d)==!1&&/^(-webkit|-moz|linear-gradient|-o-)/.test(d)==!1){var d=this.backgroundImageUrl(d),f=this.loadImage(d),a=this.getBackgroundPosition(a,b,f);if(f)switch(e){case "repeat-x":this.drawbackgroundRepeatX(c,f,a,b.left,b.top,b.width,b.height);break;case "repeat-y":this.drawbackgroundRepeatY(c,f,a,b.left,
|
||||
b.top,b.width,b.height);break;case "no-repeat":var d=b.width-a.left,e=b.height-a.top,g=a.left,h=a.top,i=a.left+b.left,j=a.top+b.top;g<0?(g=Math.abs(g),i+=g,d=Math.min(b.width,f.width-g)):(d=Math.min(d,f.width),g=0);h<0?(h=Math.abs(h),j+=h,e=Math.min(b.height,f.height-h)):(e=Math.min(e,f.height),h=0);if(e>0&&d>0){this.drawImage(c,f,g,h,d,e,i,j,d,e);break}default:a.top-=Math.ceil(a.top/f.height)*f.height;for(d=b.top+a.top;d<b.height+b.top;)e=Math.min(f.height,b.height+b.top-d),e=Math.floor(d+f.height)>
|
||||
e+d?e+d-d:f.height,d<b.top?(g=b.top-d,d=b.top):g=0,this.drawbackgroundRepeatX(c,f,a,b.left,d,b.width,e),g>0&&(a.top+=g),d=Math.floor(d+f.height)-g}else this.log("Error loading background:"+d)}};html2canvas.prototype.backgroundImageUrl=function(a){a.substr(0,5)=='url("'?(a=a.substr(5),a=a.substr(0,a.length-2)):(a=a.substr(4),a=a.substr(0,a.length-1));return a};
|
||||
html2canvas.prototype.getBackgroundPosition=function(a,b,c){var d=(this.getCSS(a,"backgroundPosition").split(",")[0]||"0 0").split(" "),e;d.length==1&&(a=d,d=[],d[0]=a,d[1]=a);d[0].toString().indexOf("%")!=-1?(e=parseFloat(d[0])/100,a=b.width*e-c.width*e):a=parseInt(d[0],10);d[1].toString().indexOf("%")!=-1?(e=parseFloat(d[1])/100,b=b.height*e-c.height*e):b=parseInt(d[1],10);c={};c.top=b;c.left=a;return c};
|
||||
html2canvas.prototype.drawbackgroundRepeatY=function(a,b,c,d,e,f,g){var h=Math.min(b.width,f),i;c.top-=Math.ceil(c.top/b.height)*b.height;for(i=e+c.top;i<g+e;)f=Math.floor(i+b.height)>g+e?g+e-i:b.height,this.drawBackgroundRepeat(a,b,d+c.left,i,h,f,d,e),i=Math.floor(i+b.height)};
|
||||
html2canvas.prototype.drawbackgroundRepeatX=function(a,b,c,d,e,f,g){var g=Math.min(b.height,g),h,i;c.left-=Math.ceil(c.left/b.width)*b.width;for(i=d+c.left;i<f+d;)h=Math.floor(i+b.width)>f+d?f+d-i:b.width,this.drawBackgroundRepeat(a,b,i,e+c.top,h,g,d,e),i=Math.floor(i+b.width)};html2canvas.prototype.drawBackgroundRepeat=function(a,b,c,d,e,f,g,h){var i=0,j=0;g-c>0&&(i=g-c);h-d>0&&(j=h-d);this.drawImage(a,b,i,j,e-i,f-j,c+i,d+j,e-i,f-j)};
|
||||
html2canvas.prototype.getBorderData=function(a){var b=[],c=this;this.each(["top","right","bottom","left"],function(d,e){b.push({width:parseInt(c.getCSS(a,"border-"+e+"-width"),10),color:c.getCSS(a,"border-"+e+"-color")})});return b};
|
||||
html2canvas.prototype.drawBorders=function(a,b,c,d){var e=c.left,f=c.top,g=c.width,h=c.height,i=this.getBorderData(a),j=this;this.each(i,function(a,c){if(c.width>0){var k=e,o=f,n=g,p=h-i[2].width;switch(a){case 0:p=i[0].width;break;case 1:k=e+g-i[1].width;n=i[1].width;break;case 2:o=o+h-i[2].width;p=i[2].width;break;case 3:n=i[3].width}n={left:k,top:o,width:n,height:p};d&&(n=j.clipBounds(n,d));n.width>0&&n.height>0&&j.newRect(b,k,o,n.width,n.height,c.color)}});return i};
|
||||
html2canvas.prototype.newElement=function(a,b){var c=this.getBounds(a),d=c.left,e=c.top,f=c.width,g=c.height,h;h=this.getCSS(a,"background-color");var i=this.getCSS(a,"position"),b=b||{},j=this.setZ(this.getCSS(a,"zIndex"),i,b.zIndex,a.parentNode),m=this.getCSS(a,"opacity"),l={ctx:new this.storageContext,zIndex:j,opacity:m*b.opacity,cssPosition:i};if(b.clip)l.clip=$.extend({},b.clip),l.clip.height-=b.borders[2].width;if(this.opts.useOverflow&&/(hidden|scroll|auto)/.test(this.getCSS(a,"overflow"))&&
|
||||
!/(BODY)/i.test(a.nodeName))l.clip=l.clip?this.clipBounds(l.clip,c):c;i=j.children.push(l);m=j.children[i-1].ctx;this.setContextVariable(m,"globalAlpha",l.opacity);var k=this.drawBorders(a,m,c);l.borders=k;this.ignoreRe.test(a.nodeName)&&this.opts.iframeDefault!="transparent"&&(h=this.opts.iframeDefault=="default"?"#efefef":this.opts.iframeDefault);f={left:d+k[3].width,top:e+k[0].width,width:f-(k[1].width+k[3].width),height:g-(k[0].width+k[2].width)};l.clip&&(f=this.clipBounds(f,l.clip));f.height>
|
||||
0&&f.width>0&&(this.newRect(m,f.left,f.top,f.width,f.height,h),this.drawBackground(a,f,m));switch(a.nodeName){case "IMG":(h=this.loadImage(this.getAttr(a,"src")))?this.drawImage(m,h,0,0,h.width,h.height,d+parseInt(this.getCSS(a,"padding-left"),10)+k[3].width,e+parseInt(this.getCSS(a,"padding-top"),10)+k[0].width,c.width-(k[1].width+k[3].width+parseInt(this.getCSS(a,"padding-left"),10)+parseInt(this.getCSS(a,"padding-right"),10)),c.height-(k[0].width+k[2].width+parseInt(this.getCSS(a,"padding-top"),
|
||||
10)+parseInt(this.getCSS(a,"padding-bottom"),10))):this.log("Error loading <img>:"+this.getAttr(a,"src"));break;case "INPUT":/^(text|url|email|submit|button|reset)$/.test(a.type)&&a.value.length>0&&this.renderFormValue(a,c,l);break;case "TEXTAREA":a.value.length>0&&this.renderFormValue(a,c,l);break;case "SELECT":a.options.length>0&&this.renderFormValue(a,c,l);break;case "LI":this.drawListItem(a,l,f)}return j.children[i-1]};
|
||||
html2canvas.prototype.printText=function(a,b,c,d){this.trim(a).length>0&&(d.fillText(a,b,c),this.numDraws++)};html2canvas.prototype.newRect=function(a,b,c,d,e,f){f!="transparent"&&(this.setContextVariable(a,"fillStyle",f),a.fillRect(b,c,d,e),this.numDraws++)};html2canvas.prototype.drawImage=function(a,b,c,d,e,f,g,h,i,j){a.drawImage(b,c,d,e,f,g,h,i,j);this.numDraws++};
|
||||
html2canvas.prototype.renderFormValue=function(a,b,c){var d=document.createElement("valuewrap"),e=this;this.each(["lineHeight","textAlign","fontFamily","color","fontSize","paddingLeft","paddingTop","width","height","border","borderLeftWidth","borderTopWidth"],function(b,c){d.style[c]=e.getCSS(a,c)});d.style.borderColor="black";d.style.borderStyle="solid";d.style.display="block";d.style.position="absolute";if(/^(submit|reset|button|text|password)$/.test(a.type)||a.nodeName=="SELECT")d.style.lineHeight=
|
||||
e.getCSS(a,"height");d.style.top=b.top+"px";d.style.left=b.left+"px";b=document.createTextNode(a.nodeName=="SELECT"?a.options[a.selectedIndex].text:a.value);d.appendChild(b);$("body").append(d);this.newText(a,b,c);$(d).remove()};
|
||||
html2canvas.prototype.getImages=function(a){var b=this;this.ignoreRe.test(a.nodeName)||this.each($(a).contents(),function(a,d){RegExp("("+this.ignoreElements+")").test(d.nodeName)||b.getImages(d)});if(a.nodeType==1||typeof a.nodeType=="undefined")(a=this.getCSS(a,"background-image"))&&a!="1"&&a!="none"&&a.substring(0,7)!="-webkit"&&a.substring(0,3)!="-o-"&&a.substring(0,4)!="-moz"&&this.preloadImage(this.backgroundImageUrl(a.split(",")[0]))};
|
||||
html2canvas.prototype.loadImage=function(a){a=this.getIndex(this.images,a);return a!=-1?this.images[a+1]:!1};html2canvas.prototype.preloadImage=function(a){if(this.getIndex(this.images,a)==-1)if(this.isSameOrigin(a)){this.images.push(a);var b=new Image,c=this;$(b).load(function(){c.imagesLoaded++;c.start()});b.onerror=function(){c.images.splice(c.images.indexOf(b.src),2);c.start()};b.src=a;this.images.push(b)}else this.opts.proxyUrl&&(this.images.push(a),b=new Image,this.proxyGetImage(a,b),this.images.push(b))};
|
||||
html2canvas.prototype.proxyGetImage=function(a,b){var c=this,d=document.createElement("a");d.href=a;a=d.href;$.ajax({data:{xhr2:!1,url:a},url:this.opts.proxyUrl,dataType:"jsonp",success:function(d){d.substring(0,6)=="error:"?(c.images.splice(c.images.indexOf(a),2),c.start(),c.log("Proxy was unable to load "+a+" "+d)):(b.onload=function(){c.imagesLoaded++;c.start()},b.src=d)},error:function(){c.images.splice(c.images.indexOf(a),2);c.start()}})};
|
||||
html2canvas.prototype.Renderer=function(a){var b=this;this.log("Renderer initiated");this.each(this.opts.renderOrder.split(" "),function(c,d){switch(d){case "canvas":b.canvas=document.createElement("canvas");if(b.canvas.getContext)return b.canvasRenderer(a),b.log("Using canvas renderer"),!1;break;case "html":return b.log("Using HTML renderer"),!1}});return this};html2canvas.prototype.throttler=function(){};
|
||||
html2canvas.prototype.canvasRenderContext=function(a,b){b.textBaseline="bottom";var c=this;a.clip&&(b.save(),b.beginPath(),b.rect(a.clip.left,a.clip.top,a.clip.width,a.clip.height),b.clip());a.ctx.storage&&c.each(a.ctx.storage,function(a,e){switch(e.type){case "variable":b[e.name]=e.arguments;break;case "function":e.name=="fillRect"?b.fillRect(e.arguments[0],e.arguments[1],e.arguments[2],e.arguments[3]):e.name=="fillText"?b.fillText(e.arguments[0],e.arguments[1],e.arguments[2]):e.name=="drawImage"?
|
||||
e.arguments[8]>0&&e.arguments[7]&&b.drawImage(e.arguments[0],e.arguments[1],e.arguments[2],e.arguments[3],e.arguments[4],e.arguments[5],e.arguments[6],e.arguments[7],e.arguments[8]):c.log(e)}});a.clip&&b.restore()};html2canvas.prototype.canvasRenderStorage=function(a,b){for(;0<a.length;){var c=a.splice(0,1)[0];c.canvasPosition=c.canvasPosition||{};this.canvasRenderContext(c,b)}};
|
||||
html2canvas.prototype.canvasRenderer=function(a){this.sortZ(this.zStack);a=this.queue;this.canvas.width=Math.max($(document).width(),this.opts.canvasWidth);this.canvas.height=Math.max($(document).height(),this.opts.canvasHeight);this.ctx=this.canvas.getContext("2d");this.canvasRenderStorage(a,this.ctx)};html2canvas.prototype.setContextVariable=function(a,b,c){a.storage?a.storage.push({type:"variable",name:b,arguments:c}):a[b]=c};
|
||||
html2canvas.prototype.drawListItem=function(a,b,c){var d=this.getCSS(a,"list-style-position",!1);this.getListItem(a);var e=this.getCSS(a,"list-style-type",!1);if(/^(decimal|decimal-leading-zero|upper-alpha|upper-latin|upper-roman|lower-alpha|lower-greek|lower-latin|lower-roman)$/i.test(e)){var f=$(a).index()+1,g;e=="decimal"?g=f:e=="decimal-leading-zero"?g=f.toString().length==1?"0"+f.toString():f.toString():e=="upper-roman"?g=this.getListRoman(f):e=="lower-roman"?g=this.getListRoman(f).toLowerCase():
|
||||
e=="lower-alpha"?g=this.getListAlpha(f).toLowerCase():e=="upper-alpha"&&(g=this.getListAlpha(f));g+=". ";e=this.getListPosition(a,g);if(d=="inside")this.setFont(b.ctx,a,!1),a=c.left,c=e.bottom,this.printText(g,a,c,b.ctx)}};
|
||||
html2canvas.prototype.getListPosition=function(a,b){var c=document.createElement("boundelement");c.style.display="inline";var d=a.style.listStyleType;a.style.listStyleType="none";c.appendChild(document.createTextNode(b));a.insertBefore(c,a.firstChild);var e=this.getBounds(c);a.removeChild(c);a.style.listStyleType=d;return e};html2canvas.prototype.getListItem=function(){};html2canvas.prototype.getListAlpha=function(a){var b="";do b=String.fromCharCode(a%26+64)+b,a/=26;while(a*26>26);return b};
|
||||
html2canvas.prototype.getListRoman=function(a){var b=["M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"],c=[1E3,900,500,400,100,90,50,40,10,9,5,4,1],d="";if(!(a<=0||a>=4E3)){for(var e=0;e<b.length;e++)for(;a>=c[e];)a-=c[e],d+=b[e];return d}};
|
||||
html2canvas.prototype.newText=function(a,b,c){var c=c.ctx,d=this.getCSS(a,"font-family"),e=this.getCSS(a,"font-size"),f=this.getCSS(a,"color"),g=this.getCSS(a,"text-decoration"),h=this.getCSS(a,"text-align"),i=this.getCSS(a,"letter-spacing");b.nodeValue=this.textTransform(b.nodeValue,this.getCSS(a,"text-transform"));if(this.trim(b.nodeValue).length>0){if(g!="none")var j=this.fontMetrics(d,e);h=h.replace(["-webkit-auto"],["auto"]);d=this.opts.letterRendering==!1&&/^(left|right|justify|auto)$/.test(h)&&
|
||||
/^(normal|none)$/.test(i)?b.nodeValue.split(/(\b| )/):b.nodeValue.split("");this.setFont(c,a,!1);a=b;for(b=0;b<d.length;b++)if(typeof a.nodeValue=="string"){e=a.splitText(d[b].length);if(g!="none"||this.trim(a.nodeValue).length!=0){if(this.support.rangeBounds)document.createRange?(h=document.createRange(),h.selectNode(a)):h=document.body.createTextRange(),h=h.getBoundingClientRect()?h.getBoundingClientRect():{};else{var i=a.parentNode,m=document.createElement("wrapper"),l=a.cloneNode(!0);m.appendChild(a.cloneNode(!0));
|
||||
i.replaceChild(m,a);h=this.getBounds(m);i.replaceChild(l,m)}this.printText(a.nodeValue,h.left,h.bottom,c);switch(g){case "underline":this.newRect(c,h.left,Math.round(h.top+j.baseline+j.lineWidth),h.width,1,f);break;case "overline":this.newRect(c,h.left,h.top,h.width,1,f);break;case "line-through":this.newRect(c,h.left,Math.ceil(h.top+j.middle+j.lineWidth),h.width,1,f)}}a=e}}};
|
||||
html2canvas.prototype.setFont=function(a,b,c){var d=this.getCSS(b,"font-family"),e=this.getCSS(b,"font-size"),f=this.getCSS(b,"color"),g=this.getCSS(b,"font-weight"),h=this.getCSS(b,"font-style"),b=this.getCSS(b,"font-variant");switch(g){case 401:g="bold";break;case 400:g="normal"}d=b+" "+g+" "+h+" "+e+" "+d;this.setContextVariable(a,"fillStyle",f);this.setContextVariable(a,"font",d);c?this.setContextVariable(a,"textAlign","right"):this.setContextVariable(a,"textAlign","left")};
|
||||
html2canvas.prototype.fontMetrics=function(a,b){var c=this.fontData.indexOf(a+"-"+b);if(c>-1)return this.fontData[c+1];c=document.createElement("div");document.getElementsByTagName("body")[0].appendChild(c);$(c).css({visibility:"hidden",fontFamily:a,fontSize:b,margin:0,padding:0});var d=document.createElement("img");d.src="http://html2canvas.hertzen.com/images/8.jpg";d.width=1;d.height=1;$(d).css({margin:0,padding:0});var e=document.createElement("span");$(e).css({fontFamily:a,fontSize:b,margin:0,
|
||||
padding:0});e.appendChild(document.createTextNode("Hidden Text"));c.appendChild(e);c.appendChild(d);var f=d.offsetTop-e.offsetTop+1;c.removeChild(e);c.appendChild(document.createTextNode("Hidden Text"));$(c).css("line-height","normal");$(d).css("vertical-align","super");d={baseline:f,lineWidth:1,middle:d.offsetTop-c.offsetTop+1};this.fontData.push(a+"-"+b);this.fontData.push(d);$(c).remove();return d};
|
||||
html2canvas.prototype.textTransform=function(a,b){switch(b){case "lowercase":return a.toLowerCase();case "capitalize":return a.replace(/(^|\s|:|-|\(|\))([a-z])/g,function(a,b,e){return b+e.toUpperCase()});case "uppercase":return a.toUpperCase();default:return a}};html2canvas.prototype.trim=function(a){return a.replace(/^\s*/,"").replace(/\s*$/,"")};
|
||||
html2canvas.prototype.parseElement=function(a,b){var c=this;this.each(a.children,function(a,e){c.parsing(e,b)});this.log("Render queue stored");this.opts.storageReady(this);this.finish()};html2canvas.prototype.parsing=function(a,b){if(this.getCSS(a,"display")!="none"&&this.getCSS(a,"visibility")!="hidden"){var c=this,b=this.newElement(a,b)||b;this.ignoreRe.test(a.nodeName)||this.each(this.contentsInZ(a),function(d,e){e.nodeType==1?c.parsing(e,b):e.nodeType==3&&c.newText(a,e,b)})}};
|
||||
html2canvas.prototype.log=function(a){this.opts.logging&&this.opts.logger(a)};html2canvas.prototype.withinBounds=function(a,b){return!a?!0:(a.left<=b.left||b.left+b.width<a.left)&&(a.top<=b.top||b.top+b.height<a.top)};html2canvas.prototype.clipBounds=function(a,b){var c=Math.max(a.left,b.left),d=Math.max(a.top,b.top);return{left:c,top:d,width:Math.min(a.left+a.width,b.left+b.width)-c,height:Math.min(a.top+a.height,b.top+b.height)-d}};
|
||||
html2canvas.prototype.getBounds=function(a){window.scroll(0,0);if(a.getBoundingClientRect){var a=a.getBoundingClientRect(),b={};b.top=a.top;b.bottom=a.bottom||a.top+a.height;b.left=a.left;b.width=a.width;b.height=a.height;return b}else return b=$(a).offset(),{left:b.left+this.getCSS(a,"border-left-width",!0),top:b.top+this.getCSS(a,"border-top-width",!0),width:$(a).innerWidth(),height:$(a).innerHeight()}};
|
||||
html2canvas.prototype.each=function(a,b){for(var b=b||function(){},c=0;c<a.length;c++)if(b(c,a[c])===!1)break};html2canvas.prototype.contentsInZ=function(a){return $(a).contents()};html2canvas.prototype.getAttr=function(a,b){return a.getAttribute(b)};html2canvas.prototype.extendObj=function(a,b){for(var c in a)b[c]=a[c];return b};html2canvas.prototype.zContext=function(a){return{zindex:a,children:[]}};
|
||||
html2canvas.prototype.setZ=function(a,b,c){return!c?this.zStack=new this.zContext(0):a!="auto"?(this.needReorder=!0,a=new this.zContext(a),c.children.push(a),a):c};html2canvas.prototype.sortZ=function(a){var b=[],c=[],d=this;this.each(a.children,function(a,f){f.children&&f.children.length>0?(b.push(f),c.push(f.zindex)):d.queue.push(f)});c.sort(function(a,b){return a-b});this.each(c,function(a,c){for(var g=0;g<=b.length;g++)if(b[g].zindex==c){g=b.splice(g,1);d.sortZ(g[0]);break}})};
|
||||
html2canvas.prototype.getContents=function(a){return a.nodeName=="iframe"?a.contentDocument||a.contentWindow.document:a.childNodes};html2canvas.prototype.getCSS=function(a,b,c){return c?parseInt($(a).css(b),10):$(a).css(b)};html2canvas.prototype.getIndex=function(a,b){if(a.indexOf)return a.indexOf(b);else{for(var c=0;c<a.length;c++)if(this[c]==b)return c;return-1}};html2canvas.prototype.isSameOrigin=function(a){var b=document.createElement("a");b.href=a;return b.protocol+b.host==this.pageOrigin};
|
@ -1,118 +0,0 @@
|
||||
/*
|
||||
* html2canvas v0.25 <http://html2canvas.hertzen.com>
|
||||
* Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
|
||||
* http://www.twitter.com/niklasvh
|
||||
*
|
||||
* Released under MIT License
|
||||
*/
|
||||
|
||||
/*
|
||||
* The MIT License
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* jQuery helper plugin for examples and tests
|
||||
*/
|
||||
|
||||
(function( $ ){
|
||||
$.fn.html2canvas = function(options) {
|
||||
|
||||
var date = new Date();
|
||||
var message,
|
||||
timeoutTimer,
|
||||
timer = date.getTime();
|
||||
|
||||
var object = $.extend({},{
|
||||
logging: false,
|
||||
proxyUrl: "http://html2canvas.appspot.com/", // running html2canvas-python proxy
|
||||
ready: function(renderer) {
|
||||
|
||||
var finishTime = new Date();
|
||||
// console.log((finishTime.getTime()-timer)/1000);
|
||||
|
||||
|
||||
document.body.appendChild(renderer.canvas);
|
||||
|
||||
|
||||
|
||||
var canvas = $(renderer.canvas);
|
||||
canvas.css('position','absolute')
|
||||
.css('left',0).css('top',0);
|
||||
|
||||
|
||||
|
||||
// $('body').append(canvas);
|
||||
$(canvas).siblings().toggle();
|
||||
|
||||
throwMessage('Screenshot created in '+ ((finishTime.getTime()-timer)/1000) + " seconds<br />Total of "+renderer.numDraws+" draws performed",4000);
|
||||
|
||||
|
||||
$(window).click(function(){
|
||||
if (!canvas.is(':visible')){
|
||||
$(canvas).toggle().siblings().toggle();
|
||||
throwMessage("Canvas Render visible");
|
||||
} else{
|
||||
$(canvas).siblings().toggle();
|
||||
$(canvas).toggle();
|
||||
throwMessage("Canvas Render hidden");
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
},options)
|
||||
|
||||
new html2canvas(this.get(0), object);
|
||||
|
||||
|
||||
function throwMessage(msg,duration){
|
||||
|
||||
window.clearTimeout(timeoutTimer);
|
||||
timeoutTimer = window.setTimeout(function(){
|
||||
message.fadeOut(function(){
|
||||
message.remove();
|
||||
});
|
||||
},duration || 2000);
|
||||
$(message).remove();
|
||||
message = $('<div />').html(msg).css({
|
||||
margin:0,
|
||||
padding:10,
|
||||
background: "#000",
|
||||
opacity:0.7,
|
||||
position:"fixed",
|
||||
top:10,
|
||||
right:10,
|
||||
fontFamily: 'Tahoma' ,
|
||||
color:'#fff',
|
||||
fontSize:12,
|
||||
borderRadius:12,
|
||||
width:'auto',
|
||||
height:'auto',
|
||||
textAlign:'center',
|
||||
textDecoration:'none'
|
||||
}).hide().fadeIn().appendTo('body');
|
||||
}
|
||||
|
||||
};
|
||||
})( jQuery );
|
||||
|
@ -6,6 +6,15 @@
|
||||
<script type="text/javascript">
|
||||
$(window).ready(function() {
|
||||
$('body').html2canvas();
|
||||
|
||||
/*
|
||||
var queue = html2canvas.Parse();
|
||||
|
||||
console.log(queue);
|
||||
var canvas = html2canvas.Renderer(queue);
|
||||
|
||||
$('body').append(canvas);*/
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
1194
external/flashcanvas.js
vendored
Normal file
1194
external/flashcanvas.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
28
external/flashcanvas.min.js
vendored
Normal file
28
external/flashcanvas.min.js
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* FlashCanvas
|
||||
*
|
||||
* Copyright (c) 2009 Tim Cameron Ryan
|
||||
* Copyright (c) 2009-2011 FlashCanvas Project
|
||||
* Released under the MIT/X License
|
||||
*/
|
||||
window.ActiveXObject&&!window.CanvasRenderingContext2D&&function(h,j){function D(a){this.code=a;this.message=T[a]}function U(a){this.width=a}function E(a){this.id=a.C++}function t(a){this.G=a;this.id=a.C++}function u(a,b){this.canvas=a;this.B=b;this.d=a.uniqueID;this.D();this.C=0;this.t="";var c=this;setInterval(function(){n[c.d]===0&&c.e()},30)}function A(){if(j.readyState==="complete"){j.detachEvent(F,A);for(var a=j.getElementsByTagName(r),b=0,c=a.length;b<c;++b)B.initElement(a[b])}}function G(){var a=
|
||||
event.srcElement,b=a.parentNode;a.blur();b.focus()}function H(){var a=event.propertyName;if(a==="width"||a==="height"){var b=event.srcElement,c=b[a],d=parseInt(c,10);if(isNaN(d)||d<0)d=a==="width"?300:150;if(c===d){b.style[a]=d+"px";b.getContext("2d").I(b.width,b.height)}else b[a]=d}}function I(){h.detachEvent(J,I);for(var a in s){var b=s[a],c=b.firstChild,d;for(d in c)if(typeof c[d]==="function")c[d]=k;for(d in b)if(typeof b[d]==="function")b[d]=k;c.detachEvent(K,G);b.detachEvent(L,H)}h[M]=k;h[N]=
|
||||
k;h[O]=k;h[C]=k;h[P]=k}function V(){var a=j.getElementsByTagName("script");a=a[a.length-1];return j.documentMode>=8?a.src:a.getAttribute("src",4)}function v(a){return(""+a).replace(/&/g,"&").replace(/</g,"<")}function W(a){return a.toLowerCase()}function i(a){throw new D(a);}function Q(a){var b=parseInt(a.width,10),c=parseInt(a.height,10);if(isNaN(b)||b<0)b=300;if(isNaN(c)||c<0)c=150;a.width=b;a.height=c}var k=null,r="canvas",M="CanvasRenderingContext2D",N="CanvasGradient",O="CanvasPattern",
|
||||
C="FlashCanvas",P="G_vmlCanvasManager",K="onfocus",L="onpropertychange",F="onreadystatechange",J="onunload",w=((h[C+"Options"]||{}).swfPath||V().replace(/[^\/]+$/,""))+"flashcanvas.swf",e=new function(a){for(var b=0,c=a.length;b<c;b++)this[a[b]]=b}(["toDataURL","save","restore","scale","rotate","translate","transform","setTransform","globalAlpha","globalCompositeOperation","strokeStyle","fillStyle","createLinearGradient","createRadialGradient","createPattern","lineWidth","lineCap","lineJoin","miterLimit",
|
||||
"shadowOffsetX","shadowOffsetY","shadowBlur","shadowColor","clearRect","fillRect","strokeRect","beginPath","closePath","moveTo","lineTo","quadraticCurveTo","bezierCurveTo","arcTo","rect","arc","fill","stroke","clip","isPointInPath","font","textAlign","textBaseline","fillText","strokeText","measureText","drawImage","createImageData","getImageData","putImageData","addColorStop","direction","resize"]),x={},n={},s={},y={};u.prototype={save:function(){this.b();this.c();this.m();this.l();this.z();this.w();
|
||||
this.F.push([this.f,this.g,this.A,this.u,this.j,this.h,this.i,this.k,this.p,this.q,this.n,this.o,this.v,this.r,this.s]);this.a.push(e.save)},restore:function(){var a=this.F;if(a.length){a=a.pop();this.globalAlpha=a[0];this.globalCompositeOperation=a[1];this.strokeStyle=a[2];this.fillStyle=a[3];this.lineWidth=a[4];this.lineCap=a[5];this.lineJoin=a[6];this.miterLimit=a[7];this.shadowOffsetX=a[8];this.shadowOffsetY=a[9];this.shadowBlur=a[10];this.shadowColor=a[11];this.font=a[12];this.textAlign=a[13];
|
||||
this.textBaseline=a[14]}this.a.push(e.restore)},scale:function(a,b){this.a.push(e.scale,a,b)},rotate:function(a){this.a.push(e.rotate,a)},translate:function(a,b){this.a.push(e.translate,a,b)},transform:function(a,b,c,d,f,g){this.a.push(e.transform,a,b,c,d,f,g)},setTransform:function(a,b,c,d,f,g){this.a.push(e.setTransform,a,b,c,d,f,g)},b:function(){var a=this.a;if(this.f!==this.globalAlpha){this.f=this.globalAlpha;a.push(e.globalAlpha,this.f)}if(this.g!==this.globalCompositeOperation){this.g=this.globalCompositeOperation;
|
||||
a.push(e.globalCompositeOperation,this.g)}},m:function(){if(this.A!==this.strokeStyle){var a=this.A=this.strokeStyle;this.a.push(e.strokeStyle,typeof a==="object"?a.id:a)}},l:function(){if(this.u!==this.fillStyle){var a=this.u=this.fillStyle;this.a.push(e.fillStyle,typeof a==="object"?a.id:a)}},createLinearGradient:function(a,b,c,d){isFinite(a)&&isFinite(b)&&isFinite(c)&&isFinite(d)||i(9);this.a.push(e.createLinearGradient,a,b,c,d);return new t(this)},createRadialGradient:function(a,b,c,d,f,g){isFinite(a)&&
|
||||
isFinite(b)&&isFinite(c)&&isFinite(d)&&isFinite(f)&&isFinite(g)||i(9);if(c<0||g<0)i(1);this.a.push(e.createRadialGradient,a,b,c,d,f,g);return new t(this)},createPattern:function(a,b){a||i(17);var c=a.tagName,d,f=this.d;if(c){c=c.toLowerCase();if(c==="img")d=a.getAttribute("src",2);else if(c===r||c==="video")return;else i(17)}else if(a.src)d=a.src;else i(17);b==="repeat"||b==="no-repeat"||b==="repeat-x"||b==="repeat-y"||b===""||b===k||i(12);this.a.push(e.createPattern,v(d),b);if(x[f]){this.e();++n[f]}return new E(this)},
|
||||
z:function(){var a=this.a;if(this.j!==this.lineWidth){this.j=this.lineWidth;a.push(e.lineWidth,this.j)}if(this.h!==this.lineCap){this.h=this.lineCap;a.push(e.lineCap,this.h)}if(this.i!==this.lineJoin){this.i=this.lineJoin;a.push(e.lineJoin,this.i)}if(this.k!==this.miterLimit){this.k=this.miterLimit;a.push(e.miterLimit,this.k)}},c:function(){var a=this.a;if(this.p!==this.shadowOffsetX){this.p=this.shadowOffsetX;a.push(e.shadowOffsetX,this.p)}if(this.q!==this.shadowOffsetY){this.q=this.shadowOffsetY;
|
||||
a.push(e.shadowOffsetY,this.q)}if(this.n!==this.shadowBlur){this.n=this.shadowBlur;a.push(e.shadowBlur,this.n)}if(this.o!==this.shadowColor){this.o=this.shadowColor;a.push(e.shadowColor,this.o)}},clearRect:function(a,b,c,d){this.a.push(e.clearRect,a,b,c,d)},fillRect:function(a,b,c,d){this.b();this.c();this.l();this.a.push(e.fillRect,a,b,c,d)},strokeRect:function(a,b,c,d){this.b();this.c();this.m();this.z();this.a.push(e.strokeRect,a,b,c,d)},beginPath:function(){this.a.push(e.beginPath)},closePath:function(){this.a.push(e.closePath)},
|
||||
moveTo:function(a,b){this.a.push(e.moveTo,a,b)},lineTo:function(a,b){this.a.push(e.lineTo,a,b)},quadraticCurveTo:function(a,b,c,d){this.a.push(e.quadraticCurveTo,a,b,c,d)},bezierCurveTo:function(a,b,c,d,f,g){this.a.push(e.bezierCurveTo,a,b,c,d,f,g)},arcTo:function(a,b,c,d,f){f<0&&isFinite(f)&&i(1);this.a.push(e.arcTo,a,b,c,d,f)},rect:function(a,b,c,d){this.a.push(e.rect,a,b,c,d)},arc:function(a,b,c,d,f,g){c<0&&isFinite(c)&&i(1);this.a.push(e.arc,a,b,c,d,f,g?1:0)},fill:function(){this.b();this.c();
|
||||
this.l();this.a.push(e.fill)},stroke:function(){this.b();this.c();this.m();this.z();this.a.push(e.stroke)},clip:function(){this.a.push(e.clip)},w:function(){var a=this.a;if(this.v!==this.font)try{var b=y[this.d];b.style.font=this.v=this.font;var c=b.currentStyle;a.push(e.font,[c.fontStyle,c.fontWeight,b.offsetHeight,c.fontFamily].join(" "))}catch(d){}if(this.r!==this.textAlign){this.r=this.textAlign;a.push(e.textAlign,this.r)}if(this.s!==this.textBaseline){this.s=this.textBaseline;a.push(e.textBaseline,
|
||||
this.s)}if(this.t!==this.canvas.currentStyle.direction){this.t=this.canvas.currentStyle.direction;a.push(e.direction,this.t)}},fillText:function(a,b,c,d){this.b();this.l();this.c();this.w();this.a.push(e.fillText,v(a),b,c,d===void 0?Infinity:d)},strokeText:function(a,b,c,d){this.b();this.m();this.c();this.w();this.a.push(e.strokeText,v(a),b,c,d===void 0?Infinity:d)},measureText:function(a){var b=y[this.d];try{b.style.font=this.font}catch(c){}b.innerText=a.replace(/[ \n\f\r]/g,"\t");return new U(b.offsetWidth)},
|
||||
drawImage:function(a,b,c,d,f,g,o,l,z){a||i(17);var p=a.tagName,m,q=arguments.length,R=this.d;if(p){p=p.toLowerCase();if(p==="img")m=a.getAttribute("src",2);else if(p===r||p==="video")return;else i(17)}else if(a.src)m=a.src;else i(17);this.b();this.c();m=v(m);if(q===3)this.a.push(e.drawImage,q,m,b,c);else if(q===5)this.a.push(e.drawImage,q,m,b,c,d,f);else if(q===9){if(d===0||f===0)i(1);this.a.push(e.drawImage,q,m,b,c,d,f,g,o,l,z)}else return;if(x[R]){this.e();++n[R]}},D:function(){this.globalAlpha=
|
||||
this.f=1;this.globalCompositeOperation=this.g="source-over";this.fillStyle=this.u=this.strokeStyle=this.A="#000000";this.lineWidth=this.j=1;this.lineCap=this.h="butt";this.lineJoin=this.i="miter";this.miterLimit=this.k=10;this.shadowBlur=this.n=this.shadowOffsetY=this.q=this.shadowOffsetX=this.p=0;this.shadowColor=this.o="rgba(0, 0, 0, 0.0)";this.font=this.v="10px sans-serif";this.textAlign=this.r="start";this.textBaseline=this.s="alphabetic";this.a=[];this.F=[]},H:function(){var a=this.a;this.a=
|
||||
[];return a},e:function(){var a=this.H();if(a.length>0)return eval(this.B.CallFunction('<invoke name="executeCommand" returntype="javascript"><arguments><string>'+a.join("�")+"</string></arguments></invoke>"))},I:function(a,b){this.e();this.D();if(a>0)this.B.width=a;if(b>0)this.B.height=b;this.a.push(e.resize,a,b)}};t.prototype={addColorStop:function(a,b){if(isNaN(a)||a<0||a>1)i(1);this.G.a.push(e.addColorStop,this.id,a,b)}};D.prototype=Error();var T={1:"INDEX_SIZE_ERR",9:"NOT_SUPPORTED_ERR",11:"INVALID_STATE_ERR",
|
||||
12:"SYNTAX_ERR",17:"TYPE_MISMATCH_ERR",18:"SECURITY_ERR"},B={initElement:function(a){if(a.getContext)return a;var b=a.uniqueID,c="external"+b;x[b]=false;n[b]=1;Q(a);a.innerHTML='<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="'+location.protocol+'//fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="100%" height="100%" id="'+c+'"><param name="allowScriptAccess" value="always"><param name="flashvars" value="id='+c+'"><param name="wmode" value="transparent"></object><span style="margin:0;padding:0;border:0;display:inline-block;position:static;height:1em;overflow:visible;white-space:nowrap"></span>';
|
||||
s[b]=a;var d=a.firstChild;y[b]=a.lastChild;var f=j.body.contains;if(f(a))d.movie=w;else var g=setInterval(function(){if(f(a)){clearInterval(g);d.movie=w}},0);if(j.compatMode==="BackCompat"||!h.XMLHttpRequest)y[b].style.overflow="hidden";var o=new u(a,d);a.getContext=function(l){return l==="2d"?o:k};a.toDataURL=function(l,z){(""+l).replace(/[A-Z]+/g,W)==="image/jpeg"?o.a.push(e.toDataURL,l,typeof z==="number"?z:""):o.a.push(e.toDataURL,l);return o.e()};d.attachEvent(K,G);return a},saveImage:function(a){a.firstChild.saveImage()},
|
||||
setOptions:function(){},trigger:function(a,b){s[a].fireEvent("on"+b)},unlock:function(a,b){n[a]&&--n[a];if(b){var c=s[a],d=c.firstChild,f,g;Q(c);f=c.width;g=c.height;c.style.width=f+"px";c.style.height=g+"px";if(f>0)d.width=f;if(g>0)d.height=g;d.resize(f,g);c.attachEvent(L,H);x[a]=true}}};j.createElement(r);j.createStyleSheet().cssText=r+"{display:inline-block;overflow:hidden;width:300px;height:150px}";j.readyState==="complete"?A():j.attachEvent(F,A);h.attachEvent(J,I);if(w.indexOf(location.protocol+
|
||||
"//"+location.host+"/")===0){var S=new ActiveXObject("Microsoft.XMLHTTP");S.open("GET",w,false);S.send(k)}h[M]=u;h[N]=t;h[O]=E;h[C]=B;h[P]={init:function(){},init_:function(){},initElement:B.initElement};keep=u.measureText}(window,document);
|
BIN
external/flashcanvas.swf
vendored
Normal file
BIN
external/flashcanvas.swf
vendored
Normal file
Binary file not shown.
BIN
lib/compiler.jar
BIN
lib/compiler.jar
Binary file not shown.
File diff suppressed because it is too large
Load Diff
20
readme.md
20
readme.md
@ -33,4 +33,22 @@ There are still a lot of CSS properties missing, including most CSS3 properties
|
||||
|
||||
### Examples ###
|
||||
|
||||
For more information and examples, please visit the <a href="http://html2canvas.hertzen.com">homepage</a> or try the <a href="http://html2canvas.hertzen.com/screenshots.html">test console</a>.
|
||||
For more information and examples, please visit the <a href="http://html2canvas.hertzen.com">homepage</a> or try the <a href="http://html2canvas.hertzen.com/screenshots.html">test console</a>.
|
||||
|
||||
### Changelog ###
|
||||
|
||||
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>)
|
||||
* Added support for CORS images and option to create canvas as tainted (<a href="https://github.com/niklasvh/html2canvas/commit/3ad49efa0032cde25c6ed32a39e35d1505d3b2ef">niklasvh</a>)
|
||||
* Improved minification saved ~1K! (<a href="https://github.com/cobexer/html2canvas/commit/b82be022b2b9240bd503e078ac980bde2b953e43">cobexer</a>)
|
||||
* Added integrated support for Flashcanvas (<a href="https://github.com/niklasvh/html2canvas/commit/e9257191519f67d74fd5e364d8dee3c0963ba5fc">niklasvh</a>)
|
||||
* Fixed a variety of legacy IE bugs (<a href="https://github.com/niklasvh/html2canvas/commit/b65357c55d0701017bafcd357bc654b54d458f8f">niklasvh</a>)
|
||||
|
||||
v0.32 - 20.2.2012
|
||||
|
||||
* Added changelog!
|
||||
* Added bookmarklet (<a href="https://github.com/niklasvh/html2canvas/commit/b320dd306e1a2d32a3bc5a71b6ebf6d8c060cde5">cobexer</a>)
|
||||
* Option to select single element to render (<a href="https://github.com/niklasvh/html2canvas/commit/0cb252ada91c84ef411288b317c03e97da1f12ad">niklasvh</a>)
|
||||
* Fixed closure compiler warnings (<a href="https://github.com/niklasvh/html2canvas/commit/36ff1ec7aadcbdf66851a0b77f0b9e87e4a8e4a1">cobexer</a>)
|
||||
* Enable profiling in FF (<a href="https://github.com/niklasvh/html2canvas/commit/bbd75286a8406cf9e5aea01fdb7950d547edefb9">cobexer</a>)
|
||||
|
@ -184,8 +184,29 @@
|
||||
|
||||
$(iframe.contentWindow).load(function(){
|
||||
|
||||
timer = date.getTime();
|
||||
// timer = date.getTime();
|
||||
|
||||
var date = new Date();
|
||||
var message,
|
||||
timeoutTimer,
|
||||
timer = date.getTime();
|
||||
var body = $(iframe).contents().find('body')[0];
|
||||
var preload = html2canvas.Preload(body, {
|
||||
"complete": function(images){
|
||||
|
||||
var queue = html2canvas.Parse(body, images);
|
||||
|
||||
|
||||
var canvas = $(html2canvas.Renderer(queue));
|
||||
var finishTime = new Date();
|
||||
|
||||
|
||||
$("#content").empty().append(canvas);
|
||||
|
||||
// throwMessage('Screenshot created in '+ ((finishTime.getTime()-timer)/1000) + " seconds<br />",4000);
|
||||
}
|
||||
});
|
||||
/*
|
||||
$(iframe).contents().find('body').html2canvas({
|
||||
canvasHeight: d.body.scrollHeight,
|
||||
canvasWidth: d.body.scrollWidth,
|
||||
@ -226,48 +247,51 @@
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
});*/
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
$('base').attr('href',urlParts.protocol+"//"+urlParts.hostname+"/");
|
||||
html = html.replace("<head>","<head><base href='"+urlParts.protocol+"//"+urlParts.hostname+"/' />");
|
||||
if ($("#disablejs").prop('checked')){
|
||||
html = html.replace(/\<script/gi,"<!--<script");
|
||||
html = html.replace(/\<\/script\>/gi,"<\/script>-->");
|
||||
}
|
||||
// console.log(html);
|
||||
d.write(html);
|
||||
$('base').attr('href',urlParts.protocol+"//"+urlParts.hostname+"/");
|
||||
var base = "<base href='"+urlParts.protocol+"//"+urlParts.hostname+"/' />";
|
||||
var headIdx = html.indexOf('<head');
|
||||
var endHeadIdx = html.indexOf('>', headIdx);
|
||||
html = html.substring(0, endHeadIdx + 1) + base + html.substring(endHeadIdx + 1);
|
||||
if ($("#disablejs").prop('checked')){
|
||||
html = html.replace(/\<script/gi,"<!--<script");
|
||||
html = html.replace(/\<\/script\>/gi,"<\/script>-->");
|
||||
}
|
||||
// console.log(html);
|
||||
d.write(html);
|
||||
|
||||
d.close();
|
||||
d.close();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
|
||||
|
||||
var _gaq = _gaq || [];_gaq.push(['_setAccount', 'UA-188600-10']);_gaq.push(['_trackPageview']);(function() {var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);})();
|
||||
var _gaq = _gaq || [];_gaq.push(['_setAccount', 'UA-188600-10']);_gaq.push(['_trackPageview']);(function() {var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);})();
|
||||
|
||||
</script>
|
||||
<base />
|
||||
</head>
|
||||
<body>
|
||||
<!-- <div style="background:red;padding:10px;color:#fff">
|
||||
App engine proxy is <a href="http://twitter.com/#!/Niklasvh/status/96265826713350144">temporarily out of use</a> due to exceeded bandwidth use. Please try again tomorrow or meanwhile check other examples <a href="http://html2canvas.hertzen.com/">here</a>.
|
||||
</div>-->
|
||||
|
||||
<!-- <div style="background:red;padding:10px;color:#fff">
|
||||
App engine proxy is <a href="http://twitter.com/#!/Niklasvh/status/96265826713350144">temporarily out of use</a> due to exceeded bandwidth use. Please try again tomorrow or meanwhile check other examples <a href="http://html2canvas.hertzen.com/">here</a>.
|
||||
</div>-->
|
||||
|
||||
<div style="float:left;width:500px;">
|
||||
<h1>JavaScript screenshot creator</h1>
|
||||
<label for="url">Website URL:</label>
|
||||
@ -308,14 +332,12 @@
|
||||
<li><a href="http://www.youtube.com/">youtube.com</a></li>
|
||||
<li><a href="http://www.cnn.com/">cnn.com</a></li>
|
||||
|
||||
<li><a href="http://www.engadget.com/">engadget.com (lot of elements, very slow)</a></li>
|
||||
<li><a href="http://www.engadget.com/">engadget.com (lot of elements, very slow)</a></li>
|
||||
<li><a href="http://eu.battle.net/en/">battle.net</a></li>
|
||||
|
||||
|
||||
</ul>
|
||||
<div style="float:left;">
|
||||
<textarea id="logger"></textarea>
|
||||
</div>
|
||||
|
||||
<div id="about"><b> About</b><br />
|
||||
The whole screenshot is created with JavaScript. The only server interaction that is happening on this page is the proxy for loading the external pages/images into JSONP/CORS enabled page and onwards onto the JavaScript renderer script.
|
||||
There are a lot of problems of loading external pages, even with a proxy, and as such many pages will not render at all. If you wish to try the script properly, I recommend you get a copy of the source from <a href="https://github.com/niklasvh/html2canvas">here</a> instead.
|
||||
|
@ -1,300 +0,0 @@
|
||||
|
||||
|
||||
html2canvas.prototype.drawBackground = function(el,bounds,ctx){
|
||||
|
||||
// TODO add support for multi background-images
|
||||
var background_image = this.getCSS(el,"background-image").split(",")[0];
|
||||
var background_repeat = this.getCSS(el,"background-repeat").split(",")[0];
|
||||
|
||||
if (typeof background_image != "undefined" && /^(1|none)$/.test(background_image)==false && /^(-webkit|-moz|linear-gradient|-o-)/.test(background_image)==false){
|
||||
|
||||
background_image = this.backgroundImageUrl(background_image);
|
||||
var image = this.loadImage(background_image);
|
||||
|
||||
|
||||
var bgp = this.getBackgroundPosition(el,bounds,image),
|
||||
bgy;
|
||||
|
||||
if (image){
|
||||
switch(background_repeat){
|
||||
|
||||
case "repeat-x":
|
||||
this.drawbackgroundRepeatX(ctx,image,bgp,bounds.left,bounds.top,bounds.width,bounds.height);
|
||||
break;
|
||||
|
||||
case "repeat-y":
|
||||
this.drawbackgroundRepeatY(ctx,image,bgp,bounds.left,bounds.top,bounds.width,bounds.height);
|
||||
break;
|
||||
|
||||
case "no-repeat":
|
||||
/*
|
||||
this.drawBackgroundRepeat(
|
||||
ctx,
|
||||
image,
|
||||
bgp.left+bounds.left, // sx
|
||||
bgp.top+bounds.top, // sy
|
||||
Math.min(bounds.width,image.width),
|
||||
Math.min(bounds.height,image.height),
|
||||
bounds.left,
|
||||
bounds.top
|
||||
);*/
|
||||
|
||||
|
||||
// console.log($(el).css('background-image'));
|
||||
var bgw = bounds.width-bgp.left,
|
||||
bgh = bounds.height-bgp.top,
|
||||
bgsx = bgp.left,
|
||||
bgsy = bgp.top,
|
||||
bgdx = bgp.left+bounds.left,
|
||||
bgdy = bgp.top+bounds.top;
|
||||
|
||||
//
|
||||
// bgw = Math.min(bgw,image.width);
|
||||
// bgh = Math.min(bgh,image.height);
|
||||
|
||||
if (bgsx<0){
|
||||
bgsx = Math.abs(bgsx);
|
||||
bgdx += bgsx;
|
||||
bgw = Math.min(bounds.width,image.width-bgsx);
|
||||
}else{
|
||||
bgw = Math.min(bgw,image.width);
|
||||
bgsx = 0;
|
||||
}
|
||||
|
||||
if (bgsy<0){
|
||||
bgsy = Math.abs(bgsy);
|
||||
bgdy += bgsy;
|
||||
// bgh = bgh-bgsy;
|
||||
bgh = Math.min(bounds.height,image.height-bgsy);
|
||||
}else{
|
||||
bgh = Math.min(bgh,image.height);
|
||||
bgsy = 0;
|
||||
}
|
||||
|
||||
|
||||
// bgh = Math.abs(bgh);
|
||||
// bgw = Math.abs(bgw);
|
||||
if (bgh>0 && bgw > 0){
|
||||
this.drawImage(
|
||||
ctx,
|
||||
image,
|
||||
bgsx, // source X : 0
|
||||
bgsy, // source Y : 1695
|
||||
bgw, // source Width : 18
|
||||
bgh, // source Height : 1677
|
||||
bgdx, // destination X :906
|
||||
bgdy, // destination Y : 1020
|
||||
bgw, // destination width : 18
|
||||
bgh // destination height : 1677
|
||||
);
|
||||
|
||||
// ctx.drawImage(image,(bounds.left+bgp.left),(bounds.top+bgp.top));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
var height,
|
||||
add;
|
||||
|
||||
|
||||
bgp.top = bgp.top-Math.ceil(bgp.top/image.height)*image.height;
|
||||
|
||||
|
||||
for(bgy=(bounds.top+bgp.top);bgy<bounds.height+bounds.top;){
|
||||
|
||||
|
||||
|
||||
var h = Math.min(image.height,(bounds.height+bounds.top)-bgy);
|
||||
|
||||
|
||||
if ( Math.floor(bgy+image.height)>h+bgy){
|
||||
height = (h+bgy)-bgy;
|
||||
}else{
|
||||
height = image.height;
|
||||
}
|
||||
// console.log(height);
|
||||
|
||||
if (bgy<bounds.top){
|
||||
add = bounds.top-bgy;
|
||||
bgy = bounds.top;
|
||||
|
||||
}else{
|
||||
add = 0;
|
||||
}
|
||||
|
||||
this.drawbackgroundRepeatX(ctx,image,bgp,bounds.left,bgy,bounds.width,height);
|
||||
if (add>0){
|
||||
bgp.top += add;
|
||||
}
|
||||
bgy = Math.floor(bgy+image.height)-add;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
}else{
|
||||
|
||||
this.log("Error loading background:" + background_image);
|
||||
//console.log(images);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Function to retrieve the actual src of a background-image
|
||||
*/
|
||||
|
||||
html2canvas.prototype.backgroundImageUrl = function(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 to retrieve background-position, both in pixels and %
|
||||
*/
|
||||
|
||||
html2canvas.prototype.getBackgroundPosition = function(el,bounds,image){
|
||||
// TODO add support for multi image backgrounds
|
||||
|
||||
var bgpos = this.getCSS(el,"backgroundPosition").split(",")[0] || "0 0";
|
||||
// var bgpos = $(el).css("backgroundPosition") || "0 0";
|
||||
var bgposition = bgpos.split(" "),
|
||||
topPos,
|
||||
left,
|
||||
percentage;
|
||||
|
||||
if (bgposition.length==1){
|
||||
var val = bgposition,
|
||||
bgposition = [];
|
||||
|
||||
bgposition[0] = val,
|
||||
bgposition[1] = val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (bgposition[0].toString().indexOf("%")!=-1){
|
||||
|
||||
percentage = (parseFloat(bgposition[0])/100);
|
||||
left = ((bounds.width * percentage)-(image.width*percentage));
|
||||
|
||||
}else{
|
||||
left = parseInt(bgposition[0],10);
|
||||
}
|
||||
|
||||
if (bgposition[1].toString().indexOf("%")!=-1){
|
||||
|
||||
percentage = (parseFloat(bgposition[1])/100);
|
||||
topPos = ((bounds.height * percentage)-(image.height*percentage));
|
||||
}else{
|
||||
|
||||
topPos = parseInt(bgposition[1],10);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
var returnObj = {}
|
||||
/*
|
||||
"top": topPos,
|
||||
"left": left
|
||||
};*/
|
||||
|
||||
|
||||
returnObj.top = topPos;
|
||||
returnObj.left = left;
|
||||
|
||||
|
||||
|
||||
return returnObj;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
html2canvas.prototype.drawbackgroundRepeatY = function(ctx,image,bgp,x,y,w,h){
|
||||
|
||||
var height,
|
||||
width = Math.min(image.width,w),bgy;
|
||||
|
||||
bgp.top = bgp.top-Math.ceil(bgp.top/image.height)*image.height;
|
||||
|
||||
|
||||
for(bgy=(y+bgp.top);bgy<h+y;){
|
||||
|
||||
|
||||
if ( Math.floor(bgy+image.height)>h+y){
|
||||
height = (h+y)-bgy;
|
||||
}else{
|
||||
height = image.height;
|
||||
}
|
||||
this.drawBackgroundRepeat(ctx,image,x+bgp.left,bgy,width,height,x,y);
|
||||
|
||||
bgy = Math.floor(bgy+image.height);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
html2canvas.prototype.drawbackgroundRepeatX = function(ctx,image,bgp,x,y,w,h){
|
||||
|
||||
var height = Math.min(image.height,h),
|
||||
width,bgx;
|
||||
|
||||
|
||||
bgp.left = bgp.left-Math.ceil(bgp.left/image.width)*image.width;
|
||||
|
||||
|
||||
for(bgx=(x+bgp.left);bgx<w+x;){
|
||||
|
||||
if (Math.floor(bgx+image.width)>w+x){
|
||||
width = (w+x)-bgx;
|
||||
}else{
|
||||
width = image.width;
|
||||
}
|
||||
|
||||
this.drawBackgroundRepeat(ctx,image,bgx,(y+bgp.top),width,height,x,y);
|
||||
|
||||
bgx = Math.floor(bgx+image.width);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
html2canvas.prototype.drawBackgroundRepeat = function(ctx,image,x,y,width,height,elx,ely){
|
||||
var sourceX = 0,
|
||||
sourceY=0;
|
||||
if (elx-x>0){
|
||||
sourceX = elx-x;
|
||||
}
|
||||
|
||||
if (ely-y>0){
|
||||
sourceY = ely-y;
|
||||
}
|
||||
|
||||
this.drawImage(
|
||||
ctx,
|
||||
image,
|
||||
sourceX, // source X
|
||||
sourceY, // source Y
|
||||
width-sourceX, // source Width
|
||||
height-sourceY, // source Height
|
||||
x+sourceX, // destination X
|
||||
y+sourceY, // destination Y
|
||||
width-sourceX, // destination width
|
||||
height-sourceY // destination height
|
||||
);
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Function to provide border details for an element
|
||||
*/
|
||||
|
||||
html2canvas.prototype.getBorderData = function(el){
|
||||
|
||||
var borders = [];
|
||||
var _ = this;
|
||||
this.each(["top","right","bottom","left"],function(i,borderSide){
|
||||
borders.push({
|
||||
width: parseInt(_.getCSS(el,'border-'+borderSide+'-width'),10),
|
||||
color: _.getCSS(el,'border-'+borderSide+'-color')
|
||||
});
|
||||
});
|
||||
|
||||
return borders;
|
||||
|
||||
}
|
||||
|
||||
html2canvas.prototype.drawBorders = function(el,ctx, bounds,clip){
|
||||
|
||||
|
||||
var x = bounds.left;
|
||||
var y = bounds.top;
|
||||
var w = bounds.width;
|
||||
var h = bounds.height;
|
||||
|
||||
/*
|
||||
* TODO add support for different border-style's than solid
|
||||
*/
|
||||
var borders = this.getBorderData(el);
|
||||
var _ = this;
|
||||
|
||||
this.each(borders,function(borderSide,borderData){
|
||||
if (borderData.width>0){
|
||||
var bx = x,
|
||||
by = y,
|
||||
bw = w,
|
||||
bh = h-(borders[2].width);
|
||||
switch(borderSide){
|
||||
case 0:
|
||||
// top border
|
||||
bh = borders[0].width;
|
||||
break;
|
||||
case 1:
|
||||
// right border
|
||||
bx = x+w-(borders[1].width);
|
||||
bw = borders[1].width;
|
||||
break;
|
||||
case 2:
|
||||
// bottom border
|
||||
by = (by+h)-(borders[2].width);
|
||||
bh = borders[2].width;
|
||||
break;
|
||||
case 3:
|
||||
// left border
|
||||
bw = borders[3].width;
|
||||
break;
|
||||
}
|
||||
|
||||
var borderBounds = {
|
||||
left:bx,
|
||||
top:by,
|
||||
width: bw,
|
||||
height:bh
|
||||
};
|
||||
|
||||
if (clip){
|
||||
borderBounds = _.clipBounds(borderBounds,clip);
|
||||
}
|
||||
|
||||
|
||||
if (borderBounds.width>0 && borderBounds.height>0){
|
||||
_.newRect(ctx,bx,by,borderBounds.width,borderBounds.height,borderData.color);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return borders;
|
||||
|
||||
};
|
388
src/Core.js
388
src/Core.js
@ -1,260 +1,148 @@
|
||||
/**
|
||||
* Creates a render of the element el
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
function html2canvas(el, userOptions) {
|
||||
|
||||
var options = userOptions || {};
|
||||
|
||||
|
||||
this.opts = this.extendObj(options, {
|
||||
logging: false,
|
||||
ready: function (stack) {
|
||||
document.body.appendChild(stack.canvas);
|
||||
},
|
||||
storageReady: function(obj){
|
||||
obj.Renderer(obj.contextStacks);
|
||||
},
|
||||
iframeDefault: "default",
|
||||
flashCanvasPath: "http://html2canvas.hertzen.com/external/flashcanvas/flashcanvas.js",
|
||||
renderViewport: false,
|
||||
reorderZ: true,
|
||||
throttle:true,
|
||||
letterRendering:false,
|
||||
proxyUrl: null,
|
||||
logger: function(a){
|
||||
if (window.console && window.console.log){
|
||||
window.console.log(a);
|
||||
}else{
|
||||
alert(a);
|
||||
}
|
||||
},
|
||||
canvasWidth:0,
|
||||
canvasHeight:0,
|
||||
useOverflow: true,
|
||||
renderOrder: "canvas flash html"
|
||||
});
|
||||
|
||||
this.element = el;
|
||||
|
||||
var imageLoaded,
|
||||
canvas,
|
||||
ctx,
|
||||
bgx,
|
||||
bgy,
|
||||
image;
|
||||
this.imagesLoaded = 0;
|
||||
this.images = [];
|
||||
this.fontData = [];
|
||||
this.numDraws = 0;
|
||||
this.contextStacks = [];
|
||||
this.ignoreElements = "IFRAME|OBJECT|PARAM";
|
||||
this.needReorder = false;
|
||||
this.blockElements = new RegExp("(BR|PARAM)");
|
||||
this.pageOrigin = window.location.protocol + window.location.host;
|
||||
this.queue = [];
|
||||
|
||||
this.ignoreRe = new RegExp("("+this.ignoreElements+")");
|
||||
|
||||
|
||||
this.support = {
|
||||
rangeBounds: false
|
||||
|
||||
};
|
||||
|
||||
// Test whether we can use ranges to measure bounding boxes
|
||||
// Opera doesn't provide valid bounds.height/bottom even though it supports the method.
|
||||
|
||||
|
||||
if (document.createRange){
|
||||
var r = document.createRange();
|
||||
//this.support.rangeBounds = new Boolean(r.getBoundingClientRect);
|
||||
if (r.getBoundingClientRect){
|
||||
var testElement = document.createElement('boundtest');
|
||||
testElement.style.height = "123px";
|
||||
testElement.style.display = "block";
|
||||
document.getElementsByTagName('body')[0].appendChild(testElement);
|
||||
|
||||
r.selectNode(testElement);
|
||||
var rangeBounds = r.getBoundingClientRect();
|
||||
var rangeHeight = rangeBounds.height;
|
||||
|
||||
if (rangeHeight==123){
|
||||
this.support.rangeBounds = true;
|
||||
}
|
||||
document.getElementsByTagName('body')[0].removeChild(testElement);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Start script
|
||||
this.init();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
html2canvas.prototype.init = function(){
|
||||
|
||||
var _ = this;
|
||||
/*
|
||||
this.ctx = new this.stackingContext($(document).width(),$(document).height());
|
||||
|
||||
if (!this.ctx){
|
||||
// canvas not initialized, let's kill it here
|
||||
this.log('Canvas not available');
|
||||
return;
|
||||
}
|
||||
|
||||
this.canvas = this.ctx.canvas;
|
||||
*/
|
||||
this.log('Finding background-images');
|
||||
|
||||
this.images.push('start');
|
||||
|
||||
this.getImages(this.element);
|
||||
|
||||
this.log('Finding images');
|
||||
// console.log(this.element.ownerDocument);
|
||||
|
||||
|
||||
|
||||
this.each(this.element.ownerDocument.images,function(i,e){
|
||||
_.preloadImage(_.getAttr(e,'src'));
|
||||
});
|
||||
this.images.splice(0,1);
|
||||
// console.log(this.images);
|
||||
if (this.images.length == 0){
|
||||
this.start();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether all assets have been loaded and start traversing the DOM
|
||||
*/
|
||||
|
||||
html2canvas.prototype.start = function(){
|
||||
// console.log(this.images);
|
||||
if (this.images.length == 0 || this.imagesLoaded==this.images.length/2){
|
||||
|
||||
this.log('Finished loading '+this.imagesLoaded+' images, Started parsing');
|
||||
this.bodyOverflow = document.getElementsByTagName('body')[0].style.overflow;
|
||||
document.getElementsByTagName('body')[0].style.overflow = "hidden";
|
||||
var rootStack = new this.storageContext($(document).width(),$(document).height());
|
||||
rootStack.opacity = this.getCSS(this.element,"opacity");
|
||||
var stack = this.newElement(this.element,rootStack);
|
||||
|
||||
|
||||
this.parseElement(this.element,stack);
|
||||
html2canvas @VERSION@ <http://html2canvas.hertzen.com>
|
||||
Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
|
||||
http://www.twitter.com/niklasvh
|
||||
|
||||
Released under MIT License
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
var _html2canvas = {},
|
||||
html2canvas;
|
||||
|
||||
|
||||
function h2clog(a) {
|
||||
if (_html2canvas.logging && window.console && window.console.log) {
|
||||
window.console.log(a);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_html2canvas.Util = {};
|
||||
|
||||
html2canvas.prototype.stackingContext = function(width,height){
|
||||
this.canvas = document.createElement('canvas');
|
||||
|
||||
|
||||
this.canvas.width = width;
|
||||
this.canvas.height = width;
|
||||
_html2canvas.Util.backgroundImage = function (src) {
|
||||
|
||||
if (/data:image\/.*;base64,/i.test( src ) || /^(-webkit|-moz|linear-gradient|-o-)/.test( src )) {
|
||||
return src;
|
||||
}
|
||||
|
||||
if (!this.canvas.getContext){
|
||||
if (src.toLowerCase().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;
|
||||
};
|
||||
|
||||
_html2canvas.Util.Bounds = function getBounds (el) {
|
||||
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;
|
||||
|
||||
// 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{
|
||||
|
||||
// TODO include Flashcanvas
|
||||
/*
|
||||
var script = document.createElement('script');
|
||||
script.type = "text/javascript";
|
||||
script.src = this.opts.flashCanvasPath;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(script, s);
|
||||
|
||||
if (typeof FlashCanvas != "undefined") {
|
||||
|
||||
FlashCanvas.initElement(this.canvas);
|
||||
this.ctx = this.canvas.getContext('2d');
|
||||
} */
|
||||
|
||||
}else{
|
||||
this.ctx = this.canvas.getContext('2d');
|
||||
}
|
||||
|
||||
// set common settings for canvas
|
||||
this.ctx.textBaseline = "bottom";
|
||||
|
||||
return this.ctx;
|
||||
|
||||
p = $(el).offset();
|
||||
|
||||
}
|
||||
|
||||
html2canvas.prototype.storageContext = function(width,height){
|
||||
this.storage = [];
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
//this.zIndex;
|
||||
|
||||
// todo simplify this whole section
|
||||
this.fillRect = function(x, y, w, h){
|
||||
this.storage.push(
|
||||
{
|
||||
type: "function",
|
||||
name:"fillRect",
|
||||
arguments:[x,y,w,h]
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
this.drawImage = function(image,sx,sy,sw,sh,dx,dy,dw,dh){
|
||||
this.storage.push(
|
||||
{
|
||||
type: "function",
|
||||
name:"drawImage",
|
||||
arguments:[image,sx,sy,sw,sh,dx,dy,dw,dh]
|
||||
});
|
||||
};
|
||||
|
||||
this.fillText = function(currentText,x,y){
|
||||
|
||||
this.storage.push(
|
||||
{
|
||||
type: "function",
|
||||
name:"fillText",
|
||||
arguments:[currentText,x,y]
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Finished rendering, send callback
|
||||
*/
|
||||
|
||||
html2canvas.prototype.finish = function(){
|
||||
|
||||
this.log("Finished rendering");
|
||||
|
||||
document.getElementsByTagName('body')[0].style.overflow = this.bodyOverflow;
|
||||
/*
|
||||
if (this.opts.renderViewport){
|
||||
// let's crop it to viewport only then
|
||||
var newCanvas = document.createElement('canvas');
|
||||
var newctx = newCanvas.getContext('2d');
|
||||
newCanvas.width = window.innerWidth;
|
||||
newCanvas.height = window.innerHeight;
|
||||
return {
|
||||
left: p.left + getCSS(el,"borderLeftWidth", true),
|
||||
top: p.top + getCSS(el,"borderTopWidth", true),
|
||||
width:$(el).innerWidth(),
|
||||
height:$(el).innerHeight()
|
||||
};
|
||||
|
||||
}*/
|
||||
this.opts.ready(this);
|
||||
}
|
||||
|
||||
} */
|
||||
};
|
||||
|
||||
_html2canvas.Util.getCSS = function (el, attribute) {
|
||||
// return jQuery(el).css(attribute);
|
||||
/*
|
||||
var val,
|
||||
left,
|
||||
rsLeft = el.runtimeStyle && el.runtimeStyle[ attribute ],
|
||||
style = el.style;
|
||||
|
||||
if ( el.currentStyle ) {
|
||||
val = el.currentStyle[ attribute ];
|
||||
} else if (window.getComputedStyle) {
|
||||
val = document.defaultView.getComputedStyle(el, null)[ attribute ];
|
||||
}
|
||||
*/
|
||||
// Check if we are not dealing with pixels, (Opera has issues with this)
|
||||
// Ported from jQuery css.js
|
||||
// From the awesome hack by Dean Edwards
|
||||
// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
|
||||
|
||||
// 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 ) ) {
|
||||
/*
|
||||
// Remember the original values
|
||||
left = style.left;
|
||||
|
||||
// Put in the new values to get a computed value out
|
||||
if ( rsLeft ) {
|
||||
el.runtimeStyle.left = el.currentStyle.left;
|
||||
}
|
||||
style.left = attribute === "fontSize" ? "1em" : (val || 0);
|
||||
val = style.pixelLeft + "px";
|
||||
|
||||
// Revert the changed values
|
||||
style.left = left;
|
||||
if ( rsLeft ) {
|
||||
el.runtimeStyle.left = rsLeft;
|
||||
}*/
|
||||
// val = $(el).css(attribute);
|
||||
// }
|
||||
|
||||
/*
|
||||
var val = $(el).css(attribute);
|
||||
|
||||
if (val === "medium") {
|
||||
val = 3;
|
||||
}*/
|
||||
|
||||
return $(el).css(attribute);
|
||||
|
||||
|
||||
};
|
||||
|
||||
_html2canvas.Util.Extend = function (options, defaults) {
|
||||
var key;
|
||||
for (key in options) {
|
||||
if (options.hasOwnProperty(key)) {
|
||||
defaults[key] = options[key];
|
||||
}
|
||||
}
|
||||
return defaults;
|
||||
};
|
||||
|
||||
_html2canvas.Util.Children = function(el) {
|
||||
// $(el).contents() !== el.childNodes, Opera / IE have issues with that
|
||||
var children;
|
||||
try {
|
||||
children = $(el).contents();
|
||||
} catch (ex) {
|
||||
h2clog("html2canvas.Util.Children failed with exception: " + ex.message);
|
||||
children = [];
|
||||
}
|
||||
return children;
|
||||
};
|
||||
|
226
src/Draw.js
226
src/Draw.js
@ -1,226 +0,0 @@
|
||||
html2canvas.prototype.newElement = function(el,parentStack){
|
||||
|
||||
var bounds = this.getBounds(el);
|
||||
|
||||
var x = bounds.left;
|
||||
var y = bounds.top;
|
||||
var w = bounds.width;
|
||||
var h = bounds.height;
|
||||
var _ = this,
|
||||
image;
|
||||
var bgcolor = this.getCSS(el,"background-color");
|
||||
|
||||
var cssPosition = this.getCSS(el,"position");
|
||||
parentStack = parentStack || {};
|
||||
|
||||
//var zindex = this.formatZ(this.getCSS(el,"zIndex"),cssPosition,parentStack.zIndex,el.parentNode);
|
||||
|
||||
var zindex = this.setZ(this.getCSS(el,"zIndex"),cssPosition,parentStack.zIndex,el.parentNode);
|
||||
|
||||
//console.log(el.nodeName+":"+zindex+":"+this.getCSS(el,"position")+":"+this.numDraws+":"+this.getCSS(el,"z-index"))
|
||||
|
||||
var opacity = this.getCSS(el,"opacity");
|
||||
|
||||
|
||||
var stack = {
|
||||
ctx: new this.storageContext(),
|
||||
zIndex: zindex,
|
||||
opacity: opacity*parentStack.opacity,
|
||||
cssPosition: cssPosition
|
||||
};
|
||||
|
||||
|
||||
|
||||
// TODO correct overflow for absolute content residing under a static position
|
||||
if (parentStack.clip){
|
||||
stack.clip = $.extend({}, parentStack.clip);
|
||||
//stack.clip = parentStack.clip;
|
||||
stack.clip.height = stack.clip.height - parentStack.borders[2].width;
|
||||
}
|
||||
|
||||
|
||||
if (this.opts.useOverflow && /(hidden|scroll|auto)/.test(this.getCSS(el,"overflow")) && !/(BODY)/i.test(el.nodeName)){
|
||||
if (stack.clip){
|
||||
stack.clip = this.clipBounds(stack.clip,bounds);
|
||||
}else{
|
||||
stack.clip = bounds;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
/*
|
||||
var stackLength = this.contextStacks.push(stack);
|
||||
|
||||
var ctx = this.contextStacks[stackLength-1].ctx;
|
||||
*/
|
||||
|
||||
var stackLength = zindex.children.push(stack);
|
||||
|
||||
var ctx = zindex.children[stackLength-1].ctx;
|
||||
|
||||
this.setContextVariable(ctx,"globalAlpha",stack.opacity);
|
||||
|
||||
// draw element borders
|
||||
var borders = this.drawBorders(el, ctx, bounds);
|
||||
stack.borders = borders;
|
||||
|
||||
// let's modify clip area for child elements, so borders dont get overwritten
|
||||
|
||||
/*
|
||||
if (stack.clip){
|
||||
stack.clip.width = stack.clip.width-(borders[1].width);
|
||||
stack.clip.height = stack.clip.height-(borders[2].width);
|
||||
}
|
||||
*/
|
||||
if (this.ignoreRe.test(el.nodeName) && this.opts.iframeDefault != "transparent"){
|
||||
if (this.opts.iframeDefault=="default"){
|
||||
bgcolor = "#efefef";
|
||||
/*
|
||||
* TODO write X over frame
|
||||
*/
|
||||
}else{
|
||||
bgcolor = this.opts.iframeDefault;
|
||||
}
|
||||
}
|
||||
|
||||
// draw base element bgcolor
|
||||
|
||||
var bgbounds = {
|
||||
left: x+borders[3].width,
|
||||
top: y+borders[0].width,
|
||||
width: w-(borders[1].width+borders[3].width),
|
||||
height: h-(borders[0].width+borders[2].width)
|
||||
};
|
||||
|
||||
//if (this.withinBounds(stack.clip,bgbounds)){
|
||||
|
||||
if (stack.clip){
|
||||
bgbounds = this.clipBounds(bgbounds,stack.clip);
|
||||
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
if (bgbounds.height>0 && bgbounds.width>0){
|
||||
this.newRect(
|
||||
ctx,
|
||||
bgbounds.left,
|
||||
bgbounds.top,
|
||||
bgbounds.width,
|
||||
bgbounds.height,
|
||||
bgcolor
|
||||
);
|
||||
|
||||
this.drawBackground(el,bgbounds,ctx);
|
||||
}
|
||||
|
||||
switch(el.nodeName){
|
||||
case "IMG":
|
||||
image = _.loadImage(_.getAttr(el,'src'));
|
||||
if (image){
|
||||
// console.log(image.width);
|
||||
this.drawImage(
|
||||
ctx,
|
||||
image,
|
||||
0, //sx
|
||||
0, //sy
|
||||
image.width, //sw
|
||||
image.height, //sh
|
||||
x+parseInt(_.getCSS(el,'padding-left'),10) + borders[3].width, //dx
|
||||
y+parseInt(_.getCSS(el,'padding-top'),10) + borders[0].width, // dy
|
||||
bounds.width - (borders[1].width + borders[3].width + parseInt(_.getCSS(el,'padding-left'),10) + parseInt(_.getCSS(el,'padding-right'),10)), //dw
|
||||
bounds.height - (borders[0].width + borders[2].width + parseInt(_.getCSS(el,'padding-top'),10) + parseInt(_.getCSS(el,'padding-bottom'),10)) //dh
|
||||
);
|
||||
|
||||
}else {
|
||||
this.log("Error loading <img>:" + _.getAttr(el,'src'));
|
||||
}
|
||||
break;
|
||||
case "INPUT":
|
||||
// TODO add all relevant type's, i.e. HTML5 new stuff
|
||||
// todo add support for placeholder attribute for browsers which support it
|
||||
if (/^(text|url|email|submit|button|reset)$/.test(el.type) && el.value.length > 0){
|
||||
|
||||
this.renderFormValue(el,bounds,stack);
|
||||
|
||||
|
||||
/*
|
||||
this just doesn't work well enough
|
||||
|
||||
this.newText(el,{
|
||||
nodeValue:el.value,
|
||||
splitText: function(){
|
||||
return this;
|
||||
},
|
||||
formValue:true
|
||||
},stack);
|
||||
*/
|
||||
}
|
||||
break;
|
||||
case "TEXTAREA":
|
||||
if (el.value.length > 0){
|
||||
this.renderFormValue(el,bounds,stack);
|
||||
}
|
||||
break;
|
||||
case "SELECT":
|
||||
if (el.options.length > 0){
|
||||
this.renderFormValue(el,bounds,stack);
|
||||
}
|
||||
break;
|
||||
case "LI":
|
||||
this.drawListItem(el,stack,bgbounds);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// return this.contextStacks[stackLength-1];
|
||||
return zindex.children[stackLength-1];
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Function to draw the text on the canvas
|
||||
*/
|
||||
|
||||
html2canvas.prototype.printText = function(currentText,x,y,ctx){
|
||||
if (this.trim(currentText).length>0){
|
||||
|
||||
ctx.fillText(currentText,x,y);
|
||||
this.numDraws++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Drawing a rectangle
|
||||
html2canvas.prototype.newRect = function(ctx,x,y,w,h,bgcolor){
|
||||
|
||||
if (bgcolor!="transparent"){
|
||||
this.setContextVariable(ctx,"fillStyle",bgcolor);
|
||||
ctx.fillRect (x, y, w, h);
|
||||
this.numDraws++;
|
||||
}
|
||||
}
|
||||
|
||||
html2canvas.prototype.drawImage = function(ctx,image,sx,sy,sw,sh,dx,dy,dw,dh){
|
||||
ctx.drawImage(
|
||||
image,
|
||||
sx, //sx
|
||||
sy, //sy
|
||||
sw, //sw
|
||||
sh, //sh
|
||||
dx, //dx
|
||||
dy, // dy
|
||||
dw, //dw
|
||||
dh //dh
|
||||
);
|
||||
this.numDraws++;
|
||||
|
||||
}
|
38
src/Forms.js
38
src/Forms.js
@ -1,38 +0,0 @@
|
||||
html2canvas.prototype.renderFormValue = function(el,bounds,stack){
|
||||
|
||||
var valueWrap = document.createElement('valuewrap'),
|
||||
_ = this;
|
||||
|
||||
this.each(['lineHeight','textAlign','fontFamily','color','fontSize','paddingLeft','paddingTop','width','height','border','borderLeftWidth','borderTopWidth'],function(i,style){
|
||||
valueWrap.style[style] = _.getCSS(el,style);
|
||||
});
|
||||
|
||||
valueWrap.style.borderColor = "black";
|
||||
valueWrap.style.borderStyle = "solid";
|
||||
valueWrap.style.display = "block";
|
||||
valueWrap.style.position = "absolute";
|
||||
if (/^(submit|reset|button|text|password)$/.test(el.type) || el.nodeName == "SELECT"){
|
||||
valueWrap.style.lineHeight = _.getCSS(el,"height");
|
||||
}
|
||||
|
||||
|
||||
valueWrap.style.top = bounds.top+"px";
|
||||
valueWrap.style.left = bounds.left+"px";
|
||||
if (el.nodeName == "SELECT"){
|
||||
// TODO increase accuracy of text position
|
||||
var textValue = el.options[el.selectedIndex].text;
|
||||
} else{
|
||||
var textValue = el.value;
|
||||
|
||||
}
|
||||
var textNode = document.createTextNode(textValue);
|
||||
|
||||
valueWrap.appendChild(textNode);
|
||||
$('body').append(valueWrap);
|
||||
|
||||
this.newText(el,textNode,stack);
|
||||
|
||||
$(valueWrap).remove();
|
||||
|
||||
|
||||
}
|
162
src/Generate.js
Normal file
162
src/Generate.js
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
html2canvas @VERSION@ <http://html2canvas.hertzen.com>
|
||||
Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
|
||||
http://www.twitter.com/niklasvh
|
||||
|
||||
Released under MIT License
|
||||
*/
|
||||
|
||||
_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 = input.indexOf(",", j) + 1;
|
||||
if (j === 0) {
|
||||
break;
|
||||
}
|
||||
// while (j++ < input.length && input.charAt( j ) !== ',') {}
|
||||
} else {
|
||||
color += chr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( (tmp = src.match(/-webkit-linear-gradient\((.*)\)/)) !== null ) {
|
||||
|
||||
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+)[%]{0,1} (\d+)[%]{0,1}, (\d+)[%]{0,1} (\d+)[%]{0,1}, from\((.*)\), to\((.*)\)\)/)) !== null ) {
|
||||
|
||||
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+)[%]{0,1} (\d+)[%]{0,1}, (.*)\)/)) !== null ) {
|
||||
|
||||
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) {
|
||||
try {
|
||||
lingrad.addColorStop(increment * i, steps[i]);
|
||||
}
|
||||
catch(e) {
|
||||
h2clog(['failed to add color stop: ', e, '; tried to add: ', steps[i], '; stop: ', i, '; in: ', src]);
|
||||
}
|
||||
}
|
||||
|
||||
ctx.fillStyle = lingrad;
|
||||
|
||||
// draw shapes
|
||||
ctx.fillRect(0, 0, bounds.width,bounds.height);
|
||||
|
||||
img = new Image();
|
||||
img.src = canvas.toDataURL();
|
||||
|
||||
return img;
|
||||
|
||||
};
|
||||
|
||||
_html2canvas.Generate.ListAlpha = function(number) {
|
||||
var tmp = "",
|
||||
modulus;
|
||||
|
||||
do {
|
||||
modulus = number % 26;
|
||||
tmp = String.fromCharCode((modulus) + 64) + tmp;
|
||||
number = number / 26;
|
||||
}while((number*26) > 26);
|
||||
|
||||
return tmp;
|
||||
};
|
||||
|
||||
_html2canvas.Generate.ListRoman = function(number) {
|
||||
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],
|
||||
roman = "",
|
||||
v,
|
||||
len = romanArray.length;
|
||||
|
||||
if (number <= 0 || number >= 4000) {
|
||||
return number;
|
||||
}
|
||||
|
||||
for (v=0; v < len; v+=1) {
|
||||
while (number >= decimal[v]) {
|
||||
number -= decimal[v];
|
||||
roman += romanArray[v];
|
||||
}
|
||||
}
|
||||
|
||||
return roman;
|
||||
|
||||
};
|
129
src/Images.js
129
src/Images.js
@ -1,129 +0,0 @@
|
||||
/*
|
||||
* Function to find all images from <img> and background-image
|
||||
*/
|
||||
html2canvas.prototype.getImages = function(el) {
|
||||
|
||||
var self = this;
|
||||
|
||||
if (!this.ignoreRe.test(el.nodeName)){
|
||||
// TODO remove jQuery dependancy
|
||||
this.each($(el).contents(),function(i,element){
|
||||
var ignRe = new RegExp("("+this.ignoreElements+")");
|
||||
if (!ignRe.test(element.nodeName)){
|
||||
self.getImages(element);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (el.nodeType==1 || typeof el.nodeType == "undefined"){
|
||||
var background_image = this.getCSS(el,'background-image');
|
||||
|
||||
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
|
||||
var src = this.backgroundImageUrl(background_image.split(",")[0]);
|
||||
this.preloadImage(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Load image from storage
|
||||
*/
|
||||
|
||||
html2canvas.prototype.loadImage = function(src){
|
||||
|
||||
var imgIndex = this.getIndex(this.images,src);
|
||||
if (imgIndex!=-1){
|
||||
return this.images[imgIndex+1];
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
html2canvas.prototype.preloadImage = function(src){
|
||||
|
||||
|
||||
if (this.getIndex(this.images,src)==-1){
|
||||
if (this.isSameOrigin(src)){
|
||||
this.images.push(src);
|
||||
// console.log('a'+src);
|
||||
var img = new Image();
|
||||
// TODO remove jQuery dependancy
|
||||
var _ = this;
|
||||
$(img).load(function(){
|
||||
_.imagesLoaded++;
|
||||
_.start();
|
||||
|
||||
});
|
||||
img.onerror = function(){
|
||||
_.images.splice(_.images.indexOf(img.src),2);
|
||||
// _.imagesLoaded++;
|
||||
_.start();
|
||||
}
|
||||
img.src = src;
|
||||
this.images.push(img);
|
||||
}else if (this.opts.proxyUrl){
|
||||
// console.log('b'+src);
|
||||
this.images.push(src);
|
||||
var img = new Image();
|
||||
this.proxyGetImage(src,img);
|
||||
this.images.push(img);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
html2canvas.prototype.proxyGetImage = function(url,img){
|
||||
var _ = this;
|
||||
|
||||
var link = document.createElement("a");
|
||||
link.href = url;
|
||||
url = link.href; // work around for pages with base href="" set
|
||||
|
||||
|
||||
// todo remove jQuery dependency and enable xhr2 requests where available (no need for base64 / json)
|
||||
$.ajax({
|
||||
data:{
|
||||
xhr2:false,
|
||||
url:url
|
||||
},
|
||||
url: this.opts.proxyUrl,
|
||||
dataType: "jsonp",
|
||||
success: function(a){
|
||||
|
||||
if (a.substring(0,6)=="error:"){
|
||||
_.images.splice(_.images.indexOf(url),2);
|
||||
_.start();
|
||||
_.log('Proxy was unable to load '+url+' '+a);
|
||||
}else{
|
||||
// document.createElement(a);
|
||||
// console.log(img);
|
||||
img.onload = function(){
|
||||
// console.log('w'+img.width);
|
||||
_.imagesLoaded++;
|
||||
_.start();
|
||||
|
||||
}
|
||||
|
||||
img.src = a;
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
error: function(){
|
||||
|
||||
_.images.splice(_.images.indexOf(url),2);
|
||||
// _.imagesLoaded++;
|
||||
_.start();
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
}
|
14
src/LICENSE
14
src/LICENSE
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* html2canvas v0.27 <http://html2canvas.hertzen.com>
|
||||
* Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
|
||||
* http://www.twitter.com/niklasvh
|
||||
*
|
||||
* Released under MIT License
|
||||
*/
|
||||
/**
|
||||
@license html2canvas @VERSION@ <http://html2canvas.hertzen.com>
|
||||
Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
|
||||
http://www.twitter.com/niklasvh
|
||||
|
||||
Released under MIT License
|
||||
*/
|
121
src/Lists.js
121
src/Lists.js
@ -1,121 +0,0 @@
|
||||
html2canvas.prototype.drawListItem = function(element,stack,elBounds){
|
||||
|
||||
|
||||
var position = this.getCSS(element,"list-style-position",false);
|
||||
|
||||
|
||||
var item = this.getListItem(element),
|
||||
x,
|
||||
y;
|
||||
|
||||
var type = this.getCSS(element,"list-style-type",false);
|
||||
|
||||
if (/^(decimal|decimal-leading-zero|upper-alpha|upper-latin|upper-roman|lower-alpha|lower-greek|lower-latin|lower-roman)$/i.test(type)){
|
||||
// TODO remove jQuery dependency
|
||||
var currentIndex = $(element).index()+1,
|
||||
text;
|
||||
|
||||
if (type == "decimal"){
|
||||
text = currentIndex;
|
||||
}else if (type == "decimal-leading-zero"){
|
||||
if (currentIndex.toString().length == 1){
|
||||
text = currentIndex = "0" + currentIndex.toString();
|
||||
}else{
|
||||
text = currentIndex.toString();
|
||||
}
|
||||
|
||||
}else if (type == "upper-roman"){
|
||||
text = this.getListRoman(currentIndex);
|
||||
}else if (type == "lower-roman"){
|
||||
text = this.getListRoman(currentIndex).toLowerCase();
|
||||
}else if (type == "lower-alpha"){
|
||||
text = this.getListAlpha(currentIndex).toLowerCase();
|
||||
}else if (type == "upper-alpha"){
|
||||
text = this.getListAlpha(currentIndex);
|
||||
}
|
||||
|
||||
text += ". ";
|
||||
var listBounds = this.getListPosition(element,text);
|
||||
|
||||
if (position == "inside"){
|
||||
this.setFont(stack.ctx,element,false);
|
||||
x = elBounds.left;
|
||||
}else{
|
||||
return; /* 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
|
||||
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"
|
||||
*/
|
||||
this.setFont(stack.ctx,element,true);
|
||||
x = elBounds.left-10;
|
||||
}
|
||||
|
||||
y = listBounds.bottom;
|
||||
|
||||
|
||||
this.printText(text, x, y, stack.ctx);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
html2canvas.prototype.getListPosition = function(element,val){
|
||||
var boundElement = document.createElement("boundelement");
|
||||
boundElement.style.display = "inline";
|
||||
//boundElement.style.width = "1px";
|
||||
//boundElement.style.height = "1px";
|
||||
|
||||
var type = element.style.listStyleType;
|
||||
element.style.listStyleType = "none";
|
||||
|
||||
boundElement.appendChild(document.createTextNode(val));
|
||||
|
||||
|
||||
element.insertBefore(boundElement,element.firstChild);
|
||||
|
||||
|
||||
var bounds = this.getBounds(boundElement);
|
||||
element.removeChild(boundElement);
|
||||
element.style.listStyleType = type;
|
||||
return bounds;
|
||||
|
||||
|
||||
}
|
||||
|
||||
html2canvas.prototype.getListItem = function(element){
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
html2canvas.prototype.getListAlpha = function(number){
|
||||
var tmp = "";
|
||||
do{
|
||||
var modulus = number % 26;
|
||||
tmp = String.fromCharCode((modulus) + 64) + tmp;
|
||||
number = number / 26;
|
||||
}while((number*26) > 26);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
html2canvas.prototype.getListRoman = function(number){
|
||||
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],
|
||||
roman = "";
|
||||
|
||||
if (number <= 0 || number >= 4000) return;
|
||||
for (var v=0; v<romanArray.length; v++) {
|
||||
while (number >= decimal[v]) {
|
||||
number -= decimal[v];
|
||||
roman += romanArray[v];
|
||||
}
|
||||
}
|
||||
|
||||
return roman;
|
||||
|
||||
|
||||
}
|
1270
src/Parse.js
Normal file
1270
src/Parse.js
Normal file
File diff suppressed because it is too large
Load Diff
347
src/Preload.js
Normal file
347
src/Preload.js
Normal file
@ -0,0 +1,347 @@
|
||||
/*
|
||||
html2canvas @VERSION@ <http://html2canvas.hertzen.com>
|
||||
Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
|
||||
http://www.twitter.com/niklasvh
|
||||
|
||||
Released under MIT License
|
||||
*/
|
||||
|
||||
_html2canvas.Preload = function(element, options){
|
||||
|
||||
var images = {
|
||||
numLoaded: 0, // also failed are counted here
|
||||
numFailed: 0,
|
||||
numTotal: 0,
|
||||
cleanupDone: false
|
||||
},
|
||||
pageOrigin,
|
||||
methods,
|
||||
i,
|
||||
count = 0,
|
||||
doc = element.ownerDocument,
|
||||
domImages = doc.images, // TODO probably should limit it to images present in the element only
|
||||
imgLen = domImages.length,
|
||||
link = doc.createElement("a"),
|
||||
supportCORS = (function( img ){
|
||||
return (img.crossOrigin !== undefined);
|
||||
})(new Image()),
|
||||
timeoutTimer;
|
||||
|
||||
link.href = window.location.href;
|
||||
pageOrigin = link.protocol + link.host;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
element = element || doc.body;
|
||||
|
||||
function isSameOrigin(url){
|
||||
link.href = url;
|
||||
link.href = link.href; // YES, BELIEVE IT OR NOT, that is required for IE9 - http://jsfiddle.net/niklasvh/2e48b/
|
||||
var origin = link.protocol + link.host;
|
||||
return (origin === pageOrigin);
|
||||
}
|
||||
|
||||
function start(){
|
||||
h2clog("html2canvas: start: images: " + images.numLoaded + " / " + images.numTotal + " (failed: " + images.numFailed + ")");
|
||||
if (!images.firstRun && images.numLoaded >= images.numTotal){
|
||||
|
||||
/*
|
||||
this.log('Finished loading '+this.imagesLoaded+' images, Started parsing');
|
||||
this.bodyOverflow = document.getElementsByTagName('body')[0].style.overflow;
|
||||
document.getElementsByTagName('body')[0].style.overflow = "hidden";
|
||||
*/
|
||||
if (typeof options.complete === "function"){
|
||||
options.complete(images);
|
||||
}
|
||||
|
||||
h2clog("Finished loading images: # " + images.numTotal + " (failed: " + images.numFailed + ")");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO modify proxy to serve images with CORS enabled, where available
|
||||
function proxyGetImage(url, img, imageObj){
|
||||
var callback_name,
|
||||
scriptUrl = options.proxy,
|
||||
script;
|
||||
|
||||
link.href = url;
|
||||
url = link.href; // work around for pages with base href="" set - WARNING: this may change the url
|
||||
|
||||
callback_name = 'html2canvas_' + (count++);
|
||||
imageObj.callbackname = callback_name;
|
||||
|
||||
if (scriptUrl.indexOf("?") > -1) {
|
||||
scriptUrl += "&";
|
||||
} else {
|
||||
scriptUrl += "?";
|
||||
}
|
||||
scriptUrl += 'url=' + encodeURIComponent(url) + '&callback=' + callback_name;
|
||||
script = doc.createElement("script");
|
||||
|
||||
window[callback_name] = function(a){
|
||||
if (a.substring(0,6) === "error:"){
|
||||
imageObj.succeeded = false;
|
||||
images.numLoaded++;
|
||||
images.numFailed++;
|
||||
start();
|
||||
} else {
|
||||
setImageLoadHandlers(img, imageObj);
|
||||
img.src = a;
|
||||
}
|
||||
window[callback_name] = undefined; // to work with IE<9 // NOTE: that the undefined callback property-name still exists on the window object (for IE<9)
|
||||
try {
|
||||
delete window[callback_name]; // for all browser that support this
|
||||
} catch(ex) {}
|
||||
script.parentNode.removeChild(script);
|
||||
script = null;
|
||||
delete imageObj.script;
|
||||
delete imageObj.callbackname;
|
||||
};
|
||||
|
||||
script.setAttribute("type", "text/javascript");
|
||||
script.setAttribute("src", scriptUrl);
|
||||
imageObj.script = script;
|
||||
window.document.body.appendChild(script);
|
||||
|
||||
}
|
||||
|
||||
function getImages (el) {
|
||||
|
||||
|
||||
|
||||
// if (!this.ignoreRe.test(el.nodeName)){
|
||||
//
|
||||
|
||||
var contents = _html2canvas.Util.Children(el),
|
||||
i,
|
||||
contentsLen = contents.length,
|
||||
background_image,
|
||||
src,
|
||||
img,
|
||||
elNodeType = false;
|
||||
|
||||
for (i = 0; i < contentsLen; i+=1 ){
|
||||
// var ignRe = new RegExp("("+this.ignoreElements+")");
|
||||
// if (!ignRe.test(element.nodeName)){
|
||||
getImages(contents[i]);
|
||||
// }
|
||||
}
|
||||
|
||||
// }
|
||||
try {
|
||||
elNodeType = el.nodeType;
|
||||
} catch (ex) {
|
||||
elNodeType = false;
|
||||
h2clog("html2canvas: failed to access some element's nodeType - Exception: " + ex.message);
|
||||
}
|
||||
|
||||
if (elNodeType === 1 || elNodeType === undefined){
|
||||
|
||||
// opera throws exception on external-content.html
|
||||
try {
|
||||
background_image = _html2canvas.Util.getCSS(el, 'backgroundImage');
|
||||
}catch(e) {
|
||||
h2clog("html2canvas: failed to get background-image - Exception: " + e.message);
|
||||
}
|
||||
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[background_image] = {
|
||||
img: img,
|
||||
succeeded: true
|
||||
};
|
||||
images.numTotal++;
|
||||
images.numLoaded++;
|
||||
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); */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setImageLoadHandlers(img, imageObj) {
|
||||
img.onload = function() {
|
||||
if ( imageObj.timer !== undefined ) {
|
||||
// CORS succeeded
|
||||
window.clearTimeout( imageObj.timer );
|
||||
}
|
||||
images.numLoaded++;
|
||||
imageObj.succeeded = true;
|
||||
start();
|
||||
};
|
||||
img.onerror = function() {
|
||||
|
||||
if (img.crossOrigin === "anonymous") {
|
||||
// CORS failed
|
||||
window.clearTimeout( imageObj.timer );
|
||||
|
||||
// let's try with proxy instead
|
||||
if ( options.proxy ) {
|
||||
var src = img.src;
|
||||
img = new Image();
|
||||
imageObj.img = img;
|
||||
img.src = src;
|
||||
|
||||
proxyGetImage( img.src, img, imageObj );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
images.numLoaded++;
|
||||
images.numFailed++;
|
||||
imageObj.succeeded = false;
|
||||
start();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
methods = {
|
||||
loadImage: function( src ) {
|
||||
var img, imageObj;
|
||||
if ( src && images[src] === undefined ) {
|
||||
img = new Image();
|
||||
if ( src.match(/data:image\/.*;base64,/i) ) {
|
||||
img.src = src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, '');
|
||||
imageObj = images[src] = {
|
||||
img: img
|
||||
};
|
||||
images.numTotal++;
|
||||
setImageLoadHandlers(img, imageObj);
|
||||
} else if ( isSameOrigin( src ) || options.allowTaint === true ) {
|
||||
imageObj = images[src] = {
|
||||
img: img
|
||||
};
|
||||
images.numTotal++;
|
||||
setImageLoadHandlers(img, imageObj);
|
||||
img.src = src;
|
||||
} else if ( supportCORS && !options.allowTaint && options.useCORS ) {
|
||||
// attempt to load with CORS
|
||||
|
||||
img.crossOrigin = "anonymous";
|
||||
imageObj = images[src] = {
|
||||
img: img
|
||||
};
|
||||
images.numTotal++;
|
||||
setImageLoadHandlers(img, imageObj);
|
||||
img.src = src;
|
||||
|
||||
// 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();
|
||||
|
||||
} else if ( options.proxy ) {
|
||||
imageObj = images[src] = {
|
||||
img: img
|
||||
};
|
||||
images.numTotal++;
|
||||
proxyGetImage( src, img, imageObj );
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
cleanupDOM: function(cause) {
|
||||
var img, src;
|
||||
if (!images.cleanupDone) {
|
||||
if (cause && typeof cause === "string") {
|
||||
h2clog("html2canvas: Cleanup because: " + cause);
|
||||
} else {
|
||||
h2clog("html2canvas: Cleanup after timeout: " + options.timeout + " ms.");
|
||||
}
|
||||
|
||||
for (src in images) {
|
||||
if (images.hasOwnProperty(src)) {
|
||||
img = images[src];
|
||||
if (typeof img === "object" && img.callbackname && img.succeeded === undefined) {
|
||||
// cancel proxy image request
|
||||
window[img.callbackname] = undefined; // to work with IE<9 // NOTE: that the undefined callback property-name still exists on the window object (for IE<9)
|
||||
try {
|
||||
delete window[img.callbackname]; // for all browser that support this
|
||||
} catch(ex) {}
|
||||
if (img.script && img.script.parentNode) {
|
||||
img.script.setAttribute("src", "about:blank"); // try to cancel running request
|
||||
img.script.parentNode.removeChild(img.script);
|
||||
}
|
||||
images.numLoaded++;
|
||||
images.numFailed++;
|
||||
h2clog("html2canvas: Cleaned up failed img: '" + src + "' Steps: " + images.numLoaded + " / " + images.numTotal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cancel any pending requests
|
||||
if(window.stop !== undefined) {
|
||||
window.stop();
|
||||
} else if(document.execCommand !== undefined) {
|
||||
document.execCommand("Stop", false);
|
||||
}
|
||||
if (document.close !== undefined) {
|
||||
document.close();
|
||||
}
|
||||
images.cleanupDone = true;
|
||||
if (!(cause && typeof cause === "string")) {
|
||||
start();
|
||||
}
|
||||
}
|
||||
},
|
||||
renderingDone: function() {
|
||||
if (timeoutTimer) {
|
||||
window.clearTimeout(timeoutTimer);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
if (options.timeout > 0) {
|
||||
timeoutTimer = window.setTimeout(methods.cleanupDOM, options.timeout);
|
||||
}
|
||||
h2clog('html2canvas: Preload starts: finding background-images');
|
||||
images.firstRun = true;
|
||||
|
||||
getImages( element );
|
||||
|
||||
h2clog('html2canvas: Preload: Finding images');
|
||||
// load <img> images
|
||||
for (i = 0; i < imgLen; i+=1){
|
||||
methods.loadImage( domImages[i].getAttribute( "src" ) );
|
||||
}
|
||||
|
||||
images.firstRun = false;
|
||||
h2clog('html2canvas: Preload: Done.');
|
||||
if ( images.numTotal === images.numLoaded ) {
|
||||
start();
|
||||
}
|
||||
|
||||
return methods;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
43
src/Queue.js
Normal file
43
src/Queue.js
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
html2canvas @VERSION@ <http://html2canvas.hertzen.com>
|
||||
Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
|
||||
http://www.twitter.com/niklasvh
|
||||
|
||||
Released under MIT License
|
||||
*/
|
||||
function h2cRenderContext(width, height) {
|
||||
var storage = [];
|
||||
return {
|
||||
storage: storage,
|
||||
width: width,
|
||||
height: height,
|
||||
fillRect: function () {
|
||||
storage.push({
|
||||
type: "function",
|
||||
name: "fillRect",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
drawImage: function () {
|
||||
storage.push({
|
||||
type: "function",
|
||||
name: "drawImage",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
fillText: function () {
|
||||
storage.push({
|
||||
type: "function",
|
||||
name: "fillText",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
setVariable: function (variable, value) {
|
||||
storage.push({
|
||||
type: "variable",
|
||||
name: variable,
|
||||
'arguments': value
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
765
src/Renderer.js
765
src/Renderer.js
@ -1,348 +1,473 @@
|
||||
html2canvas.prototype.Renderer = function(queue){
|
||||
|
||||
var _ = this;
|
||||
/*
|
||||
html2canvas @VERSION@ <http://html2canvas.hertzen.com>
|
||||
Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
|
||||
http://www.twitter.com/niklasvh
|
||||
|
||||
Released under MIT License
|
||||
*/
|
||||
_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;
|
||||
|
||||
this.log('Renderer initiated');
|
||||
|
||||
|
||||
|
||||
this.each(this.opts.renderOrder.split(" "),function(i,renderer){
|
||||
function sortZ(zStack){
|
||||
var subStacks = [],
|
||||
stackValues = [],
|
||||
zStackChildren = zStack.children,
|
||||
s,
|
||||
i,
|
||||
stackLen,
|
||||
zValue,
|
||||
zLen,
|
||||
stackChild,
|
||||
b,
|
||||
subStackLen;
|
||||
|
||||
switch(renderer){
|
||||
case "canvas":
|
||||
_.canvas = document.createElement('canvas');
|
||||
if (_.canvas.getContext){
|
||||
_.canvasRenderer(queue);
|
||||
_.log('Using canvas renderer');
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case "flash":
|
||||
/*
|
||||
var script = document.createElement('script');
|
||||
script.type = "text/javascript";
|
||||
script.src = _.opts.flashCanvasPath;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(script, s);
|
||||
|
||||
|
||||
if (typeof FlashCanvas != "undefined") {
|
||||
_.canvas = initCanvas(document.getElementById("testflash"));
|
||||
FlashCanvas.initElement(_.canvas);
|
||||
_.ctx = _.canvas.getContext("2d");
|
||||
// _.canvas = document.createElement('canvas');
|
||||
//
|
||||
_.log('Using Flashcanvas renderer');
|
||||
_.canvasRenderer(queue);
|
||||
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
break;
|
||||
case "html":
|
||||
// TODO add renderer
|
||||
_.log("Using HTML renderer");
|
||||
return false;
|
||||
break;
|
||||
|
||||
|
||||
|
||||
for (s = 0, zLen = zStackChildren.length; s < zLen; s+=1){
|
||||
|
||||
stackChild = zStackChildren[s];
|
||||
|
||||
if (stackChild.children && stackChild.children.length > 0){
|
||||
subStacks.push(stackChild);
|
||||
stackValues.push(stackChild.zindex);
|
||||
}else{
|
||||
queue.push(stackChild);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
stackValues.sort(function(a, b) {
|
||||
return a - b;
|
||||
});
|
||||
|
||||
// this.log('No renderer chosen, rendering quit');
|
||||
return this;
|
||||
|
||||
// this.canvasRenderer(queue);
|
||||
|
||||
/*
|
||||
if (!this.canvas.getContext){
|
||||
|
||||
|
||||
}*/
|
||||
// TODO include Flashcanvas
|
||||
/*
|
||||
var script = document.createElement('script');
|
||||
script.type = "text/javascript";
|
||||
script.src = this.opts.flashCanvasPath;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(script, s);
|
||||
|
||||
if (typeof FlashCanvas != "undefined") {
|
||||
for (i = 0, stackLen = stackValues.length; i < stackLen; i+=1){
|
||||
zValue = stackValues[i];
|
||||
for (b = 0, subStackLen = subStacks.length; b <= subStackLen; b+=1){
|
||||
|
||||
FlashCanvas.initElement(this.canvas);
|
||||
this.ctx = this.canvas.getContext('2d');
|
||||
} */
|
||||
|
||||
}
|
||||
|
||||
|
||||
html2canvas.prototype.throttler = function(queue){
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
html2canvas.prototype.canvasRenderContext = function(storageContext,ctx){
|
||||
|
||||
// set common settings for canvas
|
||||
ctx.textBaseline = "bottom";
|
||||
var _ = this;
|
||||
|
||||
|
||||
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){
|
||||
_.each(storageContext.ctx.storage,function(a,renderItem){
|
||||
|
||||
|
||||
switch(renderItem.type){
|
||||
case "variable":
|
||||
ctx[renderItem.name] = renderItem.arguments;
|
||||
if (subStacks[b].zindex === zValue){
|
||||
stackChild = subStacks.splice(b, 1);
|
||||
sortZ(stackChild[0]);
|
||||
break;
|
||||
case "function":
|
||||
if (renderItem.name=="fillRect"){
|
||||
|
||||
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]);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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){
|
||||
|
||||
}else if(renderItem.name=="drawImage"){
|
||||
// console.log(renderItem);
|
||||
// console.log(renderItem.arguments[0].width);
|
||||
if (renderItem.arguments[8] > 0 && renderItem.arguments[7]){
|
||||
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]
|
||||
);
|
||||
}
|
||||
}else{
|
||||
_.log(renderItem);
|
||||
}
|
||||
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:
|
||||
break;
|
||||
default:
|
||||
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
if (storageContext.clip){
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
html2canvas.prototype.canvasRenderContextChildren = function(storageContext,parentctx){
|
||||
var ctx = storageContext.canvas.getContext('2d');
|
||||
|
||||
storageContext.canvasPosition = storageContext.canvasPosition || {};
|
||||
this.canvasRenderContext(storageContext,ctx);
|
||||
|
||||
|
||||
for (var s = 0; s<this.queue.length;){
|
||||
if (storageContext.parentStack && this.queue[s].canvas === storageContext.parentStack.canvas){
|
||||
var substorageContext = this.queue.splice(s,1)[0];
|
||||
}
|
||||
|
||||
if (substorageContext.ctx.storage[5] && substorageContext.ctx.storage[5].arguments[0]=="Highlights"){
|
||||
console.log('ssssssadasda');
|
||||
}
|
||||
|
||||
this.canvasRenderContextChildren(substorageContext,ctx);
|
||||
// this.canvasRenderContext(substorageContext,ctx);
|
||||
// this.canvasRenderStorage(this.queue,ctx);
|
||||
|
||||
|
||||
}else{
|
||||
s++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (storageContext.ctx.storage[5] && storageContext.ctx.storage[5].arguments[0]=="Highlights"){
|
||||
$('body').append(parentctx.canvas);
|
||||
}
|
||||
//var parentctx = this.canvas.getContext("2d");
|
||||
|
||||
if (storageContext.canvas.width>0 && storageContext.canvas.height > 0){
|
||||
parentctx.drawImage(storageContext.canvas,(storageContext.canvasPosition.x || 0),(storageContext.canvasPosition.y || 0));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
*/
|
||||
html2canvas.prototype.canvasRenderStorage = function(queue,parentctx){
|
||||
|
||||
|
||||
|
||||
|
||||
for (var i = 0; i<queue.length;){
|
||||
var storageContext = queue.splice(0,1)[0];
|
||||
|
||||
|
||||
|
||||
// storageContext.removeOverflow = storageContext.removeOverflow || {};
|
||||
/*
|
||||
if (storageContext.canvas){
|
||||
this.canvasRenderContextChildren(storageContext,parentctx);
|
||||
|
||||
var ctx = storageContext.canvas.getContext('2d');
|
||||
|
||||
storageContext.canvasPosition = storageContext.canvasPosition || {};
|
||||
this.canvasRenderContext(storageContext,ctx);
|
||||
|
||||
for (var s = 0; s<this.queue.length;){
|
||||
if (this.queue[s].canvas === storageContext.canvas){
|
||||
var substorageContext = this.queue.splice(s,1)[0];
|
||||
substorageContext.canvasPosition = storageContext.canvasPosition || {};
|
||||
|
||||
this.canvasRenderContext(substorageContext,ctx);
|
||||
// this.canvasRenderStorage(this.queue,ctx);
|
||||
|
||||
}else{
|
||||
s++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if (storageContext.clip){
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
|
||||
//var parentctx = this.canvas.getContext("2d");
|
||||
|
||||
if (storageContext.canvas.width>0 && storageContext.canvas.height > 0){
|
||||
parentctx.drawImage(storageContext.canvas,(storageContext.canvasPosition.x || 0),(storageContext.canvasPosition.y || 0));
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
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;
|
||||
}
|
||||
ctx = parentctx;
|
||||
|
||||
}else{
|
||||
} /*else {
|
||||
// TODO clip and resize multiple elements
|
||||
|
||||
for ( i = 0; i < queueLen; i+=1 ) {
|
||||
if (options.elements[ i ] instanceof Element) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
storageContext.canvasPosition = storageContext.canvasPosition || {};
|
||||
this.canvasRenderContext(storageContext,parentctx);
|
||||
// }
|
||||
|
||||
|
||||
/*
|
||||
if (storageContext.newCanvas){
|
||||
var ctx = _.canvas.getContext("2d");
|
||||
ctx.drawImage(canvas,(storageContext.removeOverflow.left || 0),(storageContext.removeOverflow.top || 0));
|
||||
_.ctx = ctx;
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
|
||||
return canvas;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
html2canvas.prototype.canvasRenderer = function(queue){
|
||||
var _ = this;
|
||||
this.sortZ(this.zStack);
|
||||
queue = this.queue;
|
||||
//console.log(queue);
|
||||
|
||||
//queue = this.sortQueue(queue);
|
||||
|
||||
|
||||
|
||||
function svgRenderer(zStack){
|
||||
sortZ(zStack.zIndex);
|
||||
|
||||
|
||||
this.canvas.width = Math.max($(document).width(),this.opts.canvasWidth);
|
||||
this.canvas.height = Math.max($(document).height(),this.opts.canvasHeight);
|
||||
|
||||
this.ctx = this.canvas.getContext("2d");
|
||||
|
||||
this.canvasRenderStorage(queue,this.ctx);
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* Sort elements based on z-index and position attributes
|
||||
*/
|
||||
|
||||
/*
|
||||
html2canvas.prototype.sortQueue = function(queue){
|
||||
if (!this.opts.reorderZ || !this.needReorder) return queue;
|
||||
|
||||
var longest = 0;
|
||||
this.each(queue,function(i,e){
|
||||
if (longest<e.zIndex.length){
|
||||
longest = e.zIndex.length;
|
||||
}
|
||||
});
|
||||
|
||||
var counter = 0;
|
||||
//console.log(((queue.length).toString().length)-(count.length).toString().length);
|
||||
this.each(queue,function(i,e){
|
||||
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;
|
||||
|
||||
var more = ((queue.length).toString().length)-((counter).toString().length);
|
||||
while(longest>e.zIndex.length){
|
||||
e.zIndex += "0";
|
||||
}
|
||||
e.zIndex = e.zIndex+counter;
|
||||
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);
|
||||
|
||||
while((longest+more+(counter).toString().length)>e.zIndex.length){
|
||||
e.zIndex += "0";
|
||||
}
|
||||
counter++;
|
||||
// console.log(e.zIndex);
|
||||
});
|
||||
|
||||
|
||||
|
||||
for (i = 0, queueLen = queue.length; i < queueLen; i+=1){
|
||||
|
||||
storageContext = queue.splice(0, 1)[0];
|
||||
storageContext.canvasPosition = storageContext.canvasPosition || {};
|
||||
|
||||
//this.canvasRenderContext(storageContext,parentctx);
|
||||
|
||||
|
||||
|
||||
queue = queue.sort(function(a,b){
|
||||
/*
|
||||
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 (a.zIndex < b.zIndex) return -1;
|
||||
if (a.zIndex > b.zIndex) return 1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
|
||||
}*/
|
||||
|
||||
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);
|
||||
|
||||
|
||||
return queue;
|
||||
}
|
||||
*/
|
||||
} 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(" ");
|
||||
|
||||
html2canvas.prototype.setContextVariable = function(ctx,variable,value){
|
||||
if (!ctx.storage){
|
||||
ctx[variable] = value;
|
||||
}else{
|
||||
ctx.storage.push(
|
||||
{
|
||||
type: "variable",
|
||||
name:variable,
|
||||
arguments:value
|
||||
});
|
||||
}
|
||||
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;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
288
src/Text.js
288
src/Text.js
@ -1,288 +0,0 @@
|
||||
|
||||
html2canvas.prototype.newText = function(el,textNode,stack,form){
|
||||
var ctx = stack.ctx;
|
||||
var family = this.getCSS(el,"font-family");
|
||||
var size = this.getCSS(el,"font-size");
|
||||
var color = this.getCSS(el,"color");
|
||||
|
||||
|
||||
|
||||
var text_decoration = this.getCSS(el,"text-decoration");
|
||||
var text_align = this.getCSS(el,"text-align");
|
||||
|
||||
|
||||
var letter_spacing = this.getCSS(el,"letter-spacing");
|
||||
|
||||
// apply text-transform:ation to the text
|
||||
textNode.nodeValue = this.textTransform(textNode.nodeValue,this.getCSS(el,"text-transform"));
|
||||
var text = this.trim(textNode.nodeValue);
|
||||
|
||||
//text = $.trim(text);
|
||||
if (text.length>0){
|
||||
|
||||
|
||||
|
||||
if (text_decoration!="none"){
|
||||
var metrics = this.fontMetrics(family,size);
|
||||
|
||||
}
|
||||
|
||||
var renderList,
|
||||
renderWords = false;
|
||||
|
||||
|
||||
text_align = text_align.replace(["-webkit-auto"],["auto"])
|
||||
|
||||
|
||||
if (this.opts.letterRendering == false && /^(left|right|justify|auto)$/.test(text_align) && /^(normal|none)$/.test(letter_spacing)){
|
||||
// this.setContextVariable(ctx,"textAlign",text_align);
|
||||
renderWords = true;
|
||||
renderList = textNode.nodeValue.split(/(\b| )/);
|
||||
|
||||
}else{
|
||||
// this.setContextVariable(ctx,"textAlign","left");
|
||||
renderList = textNode.nodeValue.split("");
|
||||
}
|
||||
|
||||
this.setFont(ctx,el,false);
|
||||
|
||||
|
||||
/*
|
||||
if (stack.clip){
|
||||
ctx.rect (stack.clip.left, stack.clip.top, stack.clip.width, stack.clip.height);
|
||||
ctx.clip();
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
var oldTextNode = textNode;
|
||||
for(var c=0;c<renderList.length;c++){
|
||||
|
||||
|
||||
// IE 9 bug
|
||||
if (typeof oldTextNode.nodeValue != "string"){
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO only do the splitting for non-range prints
|
||||
var newTextNode = oldTextNode.splitText(renderList[c].length);
|
||||
|
||||
if (text_decoration!="none" || this.trim(oldTextNode.nodeValue).length != 0){
|
||||
|
||||
|
||||
|
||||
|
||||
if (this.support.rangeBounds){
|
||||
// getBoundingClientRect is supported for ranges
|
||||
if (document.createRange){
|
||||
var range = document.createRange();
|
||||
range.selectNode(oldTextNode);
|
||||
}else{
|
||||
// TODO add IE support
|
||||
var range = document.body.createTextRange();
|
||||
}
|
||||
if (range.getBoundingClientRect()){
|
||||
var bounds = range.getBoundingClientRect();
|
||||
}else{
|
||||
var bounds = {};
|
||||
}
|
||||
}else{
|
||||
// it isn't supported, so let's wrap it inside an element instead and the bounds there
|
||||
|
||||
var parent = oldTextNode.parentNode;
|
||||
var wrapElement = document.createElement('wrapper');
|
||||
var backupText = oldTextNode.cloneNode(true);
|
||||
wrapElement.appendChild(oldTextNode.cloneNode(true));
|
||||
parent.replaceChild(wrapElement,oldTextNode);
|
||||
|
||||
var bounds = this.getBounds(wrapElement);
|
||||
|
||||
parent.replaceChild(backupText,wrapElement);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// console.log(range);
|
||||
// console.log("'"+oldTextNode.nodeValue+"'"+bounds.left)
|
||||
this.printText(oldTextNode.nodeValue,bounds.left,bounds.bottom,ctx);
|
||||
|
||||
switch(text_decoration) {
|
||||
case "underline":
|
||||
// Draws a line at the baseline of the font
|
||||
// TODO As some browsers display the line as more than 1px if the font-size is big, need to take that into account both in position and size
|
||||
this.newRect(ctx,bounds.left,Math.round(bounds.top+metrics.baseline+metrics.lineWidth),bounds.width,1,color);
|
||||
break;
|
||||
case "overline":
|
||||
this.newRect(ctx,bounds.left,bounds.top,bounds.width,1,color);
|
||||
break;
|
||||
case "line-through":
|
||||
// TODO try and find exact position for line-through
|
||||
this.newRect(ctx,bounds.left,Math.ceil(bounds.top+metrics.middle+metrics.lineWidth),bounds.width,1,color);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
oldTextNode = newTextNode;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
html2canvas.prototype.setFont = function(ctx,el,align){
|
||||
|
||||
var family = this.getCSS(el,"font-family");
|
||||
var size = this.getCSS(el,"font-size");
|
||||
var color = this.getCSS(el,"color");
|
||||
|
||||
var bold = this.getCSS(el,"font-weight");
|
||||
var font_style = this.getCSS(el,"font-style");
|
||||
var font_variant = this.getCSS(el,"font-variant");
|
||||
|
||||
switch(bold){
|
||||
case 401:
|
||||
bold = "bold";
|
||||
break;
|
||||
case 400:
|
||||
bold = "normal";
|
||||
break;
|
||||
}
|
||||
|
||||
var font = font_variant+" "+bold+" "+font_style+" "+size+" "+family;
|
||||
|
||||
|
||||
this.setContextVariable(ctx,"fillStyle",color);
|
||||
this.setContextVariable(ctx,"font",font);
|
||||
if (align){
|
||||
this.setContextVariable(ctx,"textAlign","right");
|
||||
}else{
|
||||
this.setContextVariable(ctx,"textAlign","left");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function to find baseline for font with a specicic size
|
||||
*/
|
||||
html2canvas.prototype.fontMetrics = function(font,fontSize){
|
||||
|
||||
|
||||
var findMetrics = this.fontData.indexOf(font+"-"+fontSize);
|
||||
|
||||
if (findMetrics>-1){
|
||||
return this.fontData[findMetrics+1];
|
||||
}
|
||||
|
||||
var container = document.createElement('div');
|
||||
document.getElementsByTagName('body')[0].appendChild(container);
|
||||
|
||||
// jquery to speed this up, TODO remove jquery dependancy
|
||||
$(container).css({
|
||||
visibility:'hidden',
|
||||
fontFamily:font,
|
||||
fontSize:fontSize,
|
||||
margin:0,
|
||||
padding:0
|
||||
});
|
||||
|
||||
|
||||
|
||||
var img = document.createElement('img');
|
||||
|
||||
// TODO add another image
|
||||
img.src = "http://html2canvas.hertzen.com/images/8.jpg";
|
||||
img.width = 1;
|
||||
img.height = 1;
|
||||
|
||||
$(img).css({
|
||||
margin:0,
|
||||
padding:0
|
||||
});
|
||||
var span = document.createElement('span');
|
||||
|
||||
$(span).css({
|
||||
fontFamily:font,
|
||||
fontSize:fontSize,
|
||||
margin:0,
|
||||
padding:0
|
||||
});
|
||||
|
||||
|
||||
span.appendChild(document.createTextNode('Hidden Text'));
|
||||
container.appendChild(span);
|
||||
container.appendChild(img);
|
||||
var baseline = (img.offsetTop-span.offsetTop)+1;
|
||||
|
||||
container.removeChild(span);
|
||||
container.appendChild(document.createTextNode('Hidden Text'));
|
||||
|
||||
$(container).css('line-height','normal');
|
||||
$(img).css("vertical-align","super");
|
||||
var middle = (img.offsetTop-container.offsetTop)+1;
|
||||
|
||||
var metricsObj = {
|
||||
baseline: baseline,
|
||||
lineWidth: 1,
|
||||
middle: middle
|
||||
};
|
||||
|
||||
|
||||
this.fontData.push(font+"-"+fontSize);
|
||||
this.fontData.push(metricsObj);
|
||||
|
||||
$(container).remove();
|
||||
|
||||
|
||||
|
||||
return metricsObj;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Function to apply text-transform attribute to text
|
||||
*/
|
||||
html2canvas.prototype.textTransform = function(text,transform){
|
||||
switch(transform){
|
||||
case "lowercase":
|
||||
return text.toLowerCase();
|
||||
break;
|
||||
|
||||
case "capitalize":
|
||||
return text.replace( /(^|\s|:|-|\(|\))([a-z])/g , function(m,p1,p2){
|
||||
return p1+p2.toUpperCase();
|
||||
} );
|
||||
break;
|
||||
|
||||
case "uppercase":
|
||||
return text.toUpperCase();
|
||||
break;
|
||||
default:
|
||||
return text;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*Function to trim whitespace from text
|
||||
*/
|
||||
html2canvas.prototype.trim = function(text) {
|
||||
return text.replace(/^\s*/, "").replace(/\s*$/, "");
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
|
||||
|
||||
html2canvas.prototype.parseElement = function(element,stack){
|
||||
var _ = this;
|
||||
this.each(element.children,function(index,el){
|
||||
_.parsing(el,stack);
|
||||
});
|
||||
|
||||
this.log('Render queue stored');
|
||||
this.opts.storageReady(this);
|
||||
this.finish();
|
||||
}
|
||||
|
||||
|
||||
|
||||
html2canvas.prototype.parsing = function(el,stack){
|
||||
|
||||
if (this.getCSS(el,'display') != "none" && this.getCSS(el,'visibility')!="hidden"){
|
||||
|
||||
var _ = this;
|
||||
|
||||
stack = this.newElement(el,stack) || stack;
|
||||
|
||||
var ctx = stack.ctx;
|
||||
|
||||
if (!this.ignoreRe.test(el.nodeName)){
|
||||
// TODO remove jQuery dependancy
|
||||
this.each(this.contentsInZ(el),function(cid,node){
|
||||
|
||||
if (node.nodeType==1){
|
||||
// element
|
||||
_.parsing(node,stack);
|
||||
}else if (node.nodeType==3){
|
||||
_.newText(el,node,stack);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
339
src/Util.js
339
src/Util.js
@ -1,285 +1,82 @@
|
||||
|
||||
// Simple logger
|
||||
html2canvas.prototype.log = function(a){
|
||||
if (this.opts.logging){
|
||||
|
||||
this.opts.logger(a);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
html2canvas.prototype.withinBounds = function(src,dst){
|
||||
if (!src) return true;
|
||||
// return true;
|
||||
return (
|
||||
(src.left <= dst.left || dst.left+dst.width < src.left) &&
|
||||
(src.top <= dst.top || dst.top+dst.height < src.top)
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
html2canvas.prototype.clipBounds = function(src,dst){
|
||||
|
||||
var x = Math.max(src.left,dst.left);
|
||||
var y = Math.max(src.top,dst.top);
|
||||
|
||||
var x2 = Math.min((src.left+src.width),(dst.left+dst.width));
|
||||
var y2 = Math.min((src.top+src.height),(dst.top+dst.height));
|
||||
|
||||
return {
|
||||
left:x,
|
||||
top:y,
|
||||
width:x2-x,
|
||||
height:y2-y
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function to provide bounds for element
|
||||
* @return {Bounds} object with position and dimension information
|
||||
*/
|
||||
html2canvas.prototype.getBounds = function(el){
|
||||
|
||||
window.scroll(0,0);
|
||||
|
||||
if (el.getBoundingClientRect){
|
||||
var clientRect = el.getBoundingClientRect();
|
||||
var bounds = {};
|
||||
// need to create new object, as clientrect bounds can't be modified, thanks pufuwozu
|
||||
// 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{
|
||||
|
||||
// TODO remove jQuery dependancy
|
||||
var p = $(el).offset();
|
||||
|
||||
return {
|
||||
left: p.left + this.getCSS(el,"border-left-width",true),
|
||||
top: p.top + this.getCSS(el,"border-top-width",true),
|
||||
width:$(el).innerWidth(),
|
||||
height:$(el).innerHeight()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Function for looping through array
|
||||
*/
|
||||
html2canvas.prototype.each = function(arrayLoop,callbackFunc){
|
||||
callbackFunc = callbackFunc || function(){};
|
||||
for (var i=0;i<arrayLoop.length;i++){
|
||||
if (callbackFunc(i,arrayLoop[i]) === false) return;
|
||||
}
|
||||
}
|
||||
html2canvas @VERSION@ <http://html2canvas.hertzen.com>
|
||||
Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
|
||||
http://www.twitter.com/niklasvh
|
||||
|
||||
|
||||
/*
|
||||
* Function to get childNodes of an element in the order they should be rendered (based on z-index)
|
||||
* reference http://www.w3.org/TR/CSS21/zindex.html
|
||||
*/
|
||||
|
||||
html2canvas.prototype.contentsInZ = function(el){
|
||||
|
||||
// TODO remove jQuery dependency
|
||||
|
||||
var contents = $(el).contents();
|
||||
|
||||
return contents;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function for fetching the element attribute
|
||||
*/
|
||||
html2canvas.prototype.getAttr = function(el,attribute){
|
||||
return el.getAttribute(attribute);
|
||||
//return $(el).attr(attribute);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function to extend object
|
||||
*/
|
||||
html2canvas.prototype.extendObj = function(options,defaults){
|
||||
for (var key in options){
|
||||
defaults[key] = options[key];
|
||||
}
|
||||
return defaults;
|
||||
}
|
||||
|
||||
/*
|
||||
*todo remove this function
|
||||
html2canvas.prototype.leadingZero = function(num,size){
|
||||
|
||||
var s = "000000000" + num;
|
||||
return s.substr(s.length-size);
|
||||
}
|
||||
Released under MIT License
|
||||
*/
|
||||
|
||||
html2canvas.prototype.zContext = function(zindex){
|
||||
return {
|
||||
zindex: zindex,
|
||||
children: []
|
||||
}
|
||||
|
||||
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,
|
||||
|
||||
html2canvas.prototype.setZ = function(zindex,position,parentZ,parentNode){
|
||||
// TODO fix static elements overlapping relative/absolute elements under same stack, if they are defined after them
|
||||
if (!parentZ){
|
||||
this.zStack = new this.zContext(0);
|
||||
return this.zStack;
|
||||
}
|
||||
// render options
|
||||
|
||||
width: null,
|
||||
height: null,
|
||||
renderer: "canvas",
|
||||
taintTest: true // do a taint test with all images before applying to canvas
|
||||
|
||||
};
|
||||
|
||||
if (zindex!="auto"){
|
||||
this.needReorder = true;
|
||||
var newContext = new this.zContext(zindex);
|
||||
parentZ.children.push(newContext);
|
||||
|
||||
return newContext;
|
||||
|
||||
}else {
|
||||
return parentZ;
|
||||
}
|
||||
options = _html2canvas.Util.Extend(opts, options);
|
||||
|
||||
}
|
||||
|
||||
html2canvas.prototype.sortZ = function(zStack){
|
||||
var subStacks = [];
|
||||
var stackValues = [];
|
||||
var _ = this;
|
||||
|
||||
this.each(zStack.children, function(i,stackChild){
|
||||
if (stackChild.children && stackChild.children.length > 0){
|
||||
subStacks.push(stackChild);
|
||||
stackValues.push(stackChild.zindex);
|
||||
}else{
|
||||
|
||||
|
||||
_.queue.push(stackChild);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
stackValues.sort(function(a,b){
|
||||
return a - b
|
||||
});
|
||||
|
||||
this.each(stackValues, function(i,zValue){
|
||||
for (var s = 0;s<=subStacks.length;s++){
|
||||
if (subStacks[s].zindex == zValue){
|
||||
var stackChild = subStacks.splice(s,1);
|
||||
_.sortZ(stackChild[0]);
|
||||
break;
|
||||
|
||||
_html2canvas.logging = options.logging;
|
||||
options.complete = function( images ) {
|
||||
if (typeof options.onpreloaded === "function") {
|
||||
if ( options.onpreloaded( images ) === false ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
*todo remove this function
|
||||
|
||||
html2canvas.prototype.formatZ = function(zindex,position,parentZ,parentNode){
|
||||
|
||||
if (!parentZ){
|
||||
parentZ = "0";
|
||||
}
|
||||
|
||||
|
||||
if (position!="static" && parentZ.charAt(0)=="0"){
|
||||
this.needReorder = true;
|
||||
parentZ = "1"+parentZ.slice(1);
|
||||
}
|
||||
|
||||
if (zindex=="auto"){
|
||||
var parentPosition = this.getCSS(parentNode,"position");
|
||||
if (parentPosition!="static" && typeof parentPosition != "undefined"){
|
||||
zindex = 0;
|
||||
queue = _html2canvas.Parse( elements, images, options);
|
||||
|
||||
if (typeof options.onparsed === "function") {
|
||||
if ( options.onparsed( queue ) === false ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else{
|
||||
return parentZ;
|
||||
|
||||
canvas = _html2canvas.Renderer(queue, options);
|
||||
|
||||
if (typeof options.onrendered === "function") {
|
||||
options.onrendered( canvas );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
var b = this.leadingZero(this.numDraws,9);
|
||||
// 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 );
|
||||
|
||||
|
||||
var s = this.leadingZero(zindex+1,9);
|
||||
|
||||
// var s = "000000000" + num;
|
||||
return parentZ+""+""+s+""+b;
|
||||
|
||||
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Get element childNodes
|
||||
*/
|
||||
|
||||
html2canvas.prototype.getContents = function(el){
|
||||
return (el.nodeName == "iframe" ) ?
|
||||
el.contentDocument || el.contentWindow.document :
|
||||
el.childNodes;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function for fetching the css attribute
|
||||
* TODO remove jQuery dependancy
|
||||
*/
|
||||
html2canvas.prototype.getCSS = function(el,attribute,intOnly){
|
||||
if (intOnly){
|
||||
return parseInt($(el).css(attribute),10);
|
||||
}else{
|
||||
return $(el).css(attribute);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
html2canvas.prototype.getIndex = function(array,src){
|
||||
|
||||
if (array.indexOf){
|
||||
return array.indexOf(src);
|
||||
}else{
|
||||
for(var i = 0; i < array.length; i++){
|
||||
if(this[i] == src) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
html2canvas.prototype.isSameOrigin = function(url){
|
||||
var link = document.createElement("a");
|
||||
link.href = url;
|
||||
|
||||
return ((link.protocol + link.host) == this.pageOrigin);
|
||||
}
|
||||
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
|
||||
};
|
||||
};
|
||||
|
2
src/html2canvas-post.txt
Normal file
2
src/html2canvas-post.txt
Normal file
@ -0,0 +1,2 @@
|
||||
window.html2canvas = html2canvas;
|
||||
}(window, document));
|
1
src/html2canvas-pre.txt
Normal file
1
src/html2canvas-pre.txt
Normal file
@ -0,0 +1 @@
|
||||
(function(window, document, undefined){
|
74
src/plugins/bookmarklet.js
Normal file
74
src/plugins/bookmarklet.js
Normal file
@ -0,0 +1,74 @@
|
||||
(function() {
|
||||
/* options, customize to your needs */
|
||||
var server = '//html2canvas.hertzen.com/js',
|
||||
proxy = '//html2canvas.appspot.com',
|
||||
debug = false,
|
||||
profile = false;
|
||||
//DEBUG: server = 'http://localhost/html2canvas'; debug = true;
|
||||
var debugFiles = [
|
||||
'external/jquery-1.6.2.min',
|
||||
'src/Core',
|
||||
'src/Generate',
|
||||
'src/Parse',
|
||||
'src/Preload',
|
||||
'src/Queue',
|
||||
'src/Renderer',
|
||||
'src/plugins/jquery.plugin.html2canvas'
|
||||
],
|
||||
relFiles = [
|
||||
'//code.jquery.com/jquery-1.6.4.js',
|
||||
'html2canvas',
|
||||
'jquery.plugin.html2canvas'
|
||||
],
|
||||
i = 0, el = null;
|
||||
var loader = {
|
||||
index: 0,
|
||||
head: document.getElementsByTagName('head')[0],
|
||||
statusline: document.createElement('div'),
|
||||
files: (debug ? debugFiles : relFiles),
|
||||
onload: function () {
|
||||
var _ = this;
|
||||
if (_.index < _.files.length) {
|
||||
var el = document.createElement('script');
|
||||
el.type = 'text/javascript';
|
||||
el.onload = function() {
|
||||
_.onload();
|
||||
};
|
||||
el.onerror = function() {
|
||||
_.statusline.style.color = 'red';
|
||||
_.statusline.innerHTML = _.statusline.innerHTML + ' failed';
|
||||
_.statusline.onclick = function() {
|
||||
_.statusline.parentNode.removeChild(_.statusline);
|
||||
};
|
||||
};
|
||||
if (_.files[_.index].substr(0, 2) === '//') {
|
||||
el.src = _.files[_.index];
|
||||
}
|
||||
else {
|
||||
el.src = server + '/' + _.files[_.index] + '.js';
|
||||
}
|
||||
_.head.appendChild(el);
|
||||
++_.index;
|
||||
_.statusline.innerHTML = 'html2canvas: loading "' + el.src + '" ' + _.index + ' / ' + _.files.length + '...';
|
||||
}
|
||||
else {
|
||||
_.statusline.parentNode.removeChild(_.statusline);
|
||||
delete _.statusline;
|
||||
$(document.documentElement).html2canvas({
|
||||
logging: debug,
|
||||
profile: profile
|
||||
});
|
||||
}
|
||||
}
|
||||
}, statusline = loader.statusline;
|
||||
statusline.style.position = 'fixed';
|
||||
statusline.style.bottom = '0px';
|
||||
statusline.style.right = '20px';
|
||||
statusline.style.backgroundColor = 'white';
|
||||
statusline.style.border = '1px solid black';
|
||||
statusline.style.borderBottomWidth = '0px';
|
||||
statusline.style.padding = '2px 5px';
|
||||
statusline.style.zIndex = 9999999;
|
||||
document.body.appendChild(statusline);
|
||||
loader.onload();
|
||||
}());
|
@ -1,70 +1,63 @@
|
||||
|
||||
/*
|
||||
* jQuery helper plugin for examples and tests
|
||||
*/
|
||||
|
||||
(function( $ ){
|
||||
$.fn.html2canvas = function(options) {
|
||||
|
||||
var date = new Date();
|
||||
var message,
|
||||
timeoutTimer,
|
||||
if (options && options.profile && window.console && window.console.profile) {
|
||||
console.profile();
|
||||
}
|
||||
var date = new Date(),
|
||||
html2obj,
|
||||
$message = null,
|
||||
timeoutTimer = false,
|
||||
timer = date.getTime();
|
||||
|
||||
var object = $.extend({},{
|
||||
logging: false,
|
||||
proxyUrl: "http://html2canvas.appspot.com/", // running html2canvas-python proxy
|
||||
ready: function(renderer) {
|
||||
|
||||
var finishTime = new Date();
|
||||
// console.log((finishTime.getTime()-timer)/1000);
|
||||
|
||||
options = options || {};
|
||||
options.elements = this;
|
||||
|
||||
document.body.appendChild(renderer.canvas);
|
||||
|
||||
|
||||
|
||||
var canvas = $(renderer.canvas);
|
||||
canvas.css('position','absolute')
|
||||
.css('left',0).css('top',0);
|
||||
|
||||
options.onrendered = function( canvas ) {
|
||||
var $canvas = $(canvas),
|
||||
finishTime = new Date();
|
||||
|
||||
|
||||
// $('body').append(canvas);
|
||||
$(canvas).siblings().toggle();
|
||||
|
||||
throwMessage('Screenshot created in '+ ((finishTime.getTime()-timer)/1000) + " seconds<br />Total of "+renderer.numDraws+" draws performed",4000);
|
||||
|
||||
|
||||
$(window).click(function(){
|
||||
if (!canvas.is(':visible')){
|
||||
$(canvas).toggle().siblings().toggle();
|
||||
throwMessage("Canvas Render visible");
|
||||
} else{
|
||||
$(canvas).siblings().toggle();
|
||||
$(canvas).toggle();
|
||||
throwMessage("Canvas Render hidden");
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
if (options && options.profile && window.console && window.console.profileEnd) {
|
||||
console.profileEnd();
|
||||
}
|
||||
$canvas.css({
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
top: 0
|
||||
}).appendTo(document.body);
|
||||
$canvas.siblings().toggle();
|
||||
|
||||
$(window).click(function(){
|
||||
$canvas.toggle().siblings().toggle();
|
||||
throwMessage("Canvas Render " + ($canvas.is(':visible') ? "visible" : "hidden"));
|
||||
});
|
||||
throwMessage('Screenshot created in '+ ((finishTime.getTime()-timer)) + " ms<br />",4000);
|
||||
|
||||
},options)
|
||||
|
||||
new html2canvas(this.get(0), object);
|
||||
|
||||
// test if canvas is read-able
|
||||
try {
|
||||
$canvas[0].toDataURL();
|
||||
} catch(e) {
|
||||
if ($canvas[0].nodeName.toLowerCase() === "canvas") {
|
||||
// TODO, maybe add a bit less offensive way to present this, but still something that can easily be noticed
|
||||
alert("Canvas is tainted, unable to read data");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
html2obj = html2canvas(this[0], options);
|
||||
|
||||
function throwMessage(msg,duration){
|
||||
|
||||
window.clearTimeout(timeoutTimer);
|
||||
timeoutTimer = window.setTimeout(function(){
|
||||
message.fadeOut(function(){
|
||||
message.remove();
|
||||
});
|
||||
$message.fadeOut(function(){
|
||||
$message.remove();
|
||||
$message = null;
|
||||
});
|
||||
},duration || 2000);
|
||||
$(message).remove();
|
||||
message = $('<div />').html(msg).css({
|
||||
if ($message)
|
||||
$message.remove();
|
||||
$message = $('<div />').html(msg).css({
|
||||
margin:0,
|
||||
padding:10,
|
||||
background: "#000",
|
||||
@ -72,17 +65,17 @@
|
||||
position:"fixed",
|
||||
top:10,
|
||||
right:10,
|
||||
fontFamily: 'Tahoma' ,
|
||||
fontFamily: 'Tahoma',
|
||||
color:'#fff',
|
||||
fontSize:12,
|
||||
borderRadius:12,
|
||||
width:'auto',
|
||||
height:'auto',
|
||||
textAlign:'center',
|
||||
textDecoration:'none'
|
||||
}).hide().fadeIn().appendTo('body');
|
||||
textDecoration:'none',
|
||||
display:'none'
|
||||
}).appendTo(document.body).fadeIn();
|
||||
html2obj.log(msg);
|
||||
}
|
||||
|
||||
};
|
||||
})( jQuery );
|
||||
|
@ -8,27 +8,15 @@
|
||||
<head>
|
||||
<title>Background attribute tests</title>
|
||||
<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="../build/html2canvas.js"></script>
|
||||
<script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).ready(function() {
|
||||
|
||||
$('body').html2canvas({
|
||||
logging:true
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
<style>
|
||||
|
||||
.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 +26,40 @@
|
||||
margin:10px;
|
||||
border:1px solid #000;
|
||||
}
|
||||
|
||||
|
||||
.small, .medium{
|
||||
clear:both;
|
||||
}
|
||||
|
||||
|
||||
div{
|
||||
display:block;
|
||||
}
|
||||
|
||||
.encoded {
|
||||
background:url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCABLAEsDAREAAhEBAxEB/8QAHAAAAgMBAQEBAAAAAAAAAAAABQcEBggCAwAJ/8QANxAAAgECBQEHAQUIAwEAAAAAAQIDBBEABQYSITEHExQiQVFhcTKBkbHBCCNCUnLR4fAWYqLx/8QAGwEAAQUBAQAAAAAAAAAAAAAAAQIDBAUGAAf/xAAzEQACAgECAwQHCAMAAAAAAAAAAQIDEQQhEjFBIlFhcRMUgZGhsdEFFSNCUsHh8DKi8f/aAAwDAQACEQMRAD8AxREirbfKlv6rYxDz0R6mmj2eohpqrLKmGVTJTVsEpG65sHF8dBSakpLmn8hq5pxTXRo0DlaCn1dB7eJZfxxD0b/FiyFqVmmQ1Yo/KMaRFBIj5tCTFSG3SsgP/sf3x0t0JTJtLTlJa0FSP31+R/0TCcYG8nM0Q9sLAQJoRzgnECoiFjggB7RC5wsSZHTLaGCQpJBSq68EbQ1sUjst72bdU1dy9x1mlPQJlNQY0p+9Rd67YwDcG/HGBVK12JPOPMF1darbUVt4GgoazdmeW1YNxKaea/8AUoJxVafsTj4P9xm5cVcvJjjhljjlRZDtBPt1xqlzMu3tsNjSulMrziigkVUkUOHK9RcdD8Ys6owcStsnJMsFV2ZUrxVDRqQ0luSL9P8AH5YcdUWhtWtC91T2e1mWRPUQx740BLKt7/X6YhTqcd0S4WKWxQZhiOPA+ccYICAy3Y4UAyXS/uwFXLGFv5kX++KCWHu5m6i3y4SbI7y0k0bZbZHQqTtT2/qw3FRUk1P5/QVJtxa4X8PqNHIanxmndMzg+Z6KEc+6kqfyxG4MXuPiyFJ4qcn3F5o9RGrzPbI5aRz6np7D2GLpSbfiZ9xWMD20Fq5MlgpF72PdNIyGE8OFFvMPjn7/ALsWlE3FIrbYcTH5keaw11MtnVz063xZqWSvccMkZhRwT08m4KRY3BwibSW4uCeTJ+qKA5PnuYURBXuZmVQ/Xbe6n8CMVTWGWXQATOCCLjBAQXbzHphQkyTS5XE1HTXpttTtPfB5bruvxt+LdcUc7e08PY3dcez2luTIsm3GwjhF+OW/xhl3eLHuHwLpo1pn0lkrRh5no2qICkSGRmZJSQAo6khhxhmxS9azFc8P3kLsqiUZeQ3dPafhmrFkU7HUh3Exsyi9269LeuL2Me0ZWUsIM6p7EKjtkzTLXi1XVaWaEvfwSkmqJZdq7Qy9LdSeOeD6WlSRAm8YbNDN2f6ry6lpqXRGq6RqjLXjapgzaiM3i4woPdK6sCpYXs3NuOuJXBjkR3JNbjRy+KvkpF8bEaaV1tYi5/8AuI0k2tx1NLkYQ/aB1XmucdrGeHLNQ5jl+X07ikjiptiITGNrNfaSSWvyTf7gMUt2olGxxjyRe0Uw9GnOOWxXyVuoVLM+rc7kBvYeIC2/BcNeszew+qK1+UGTVmdGRj/yjPV+PGH+2HVqJ94PRV/pQtos+1SPs0WVi/S5kP64S9PpespfAlLUaz9Efj9QtkEmuc/roaajgycB2AaRo5NsY9WJB6DHeraVvCcm/Z9BM9Vq4rMlFL2/Dc0dp7L4dO5eKWl6k7pJtoVpGtyxA6dOgxIqpVawipuvldLMgtRzIjbDJsBYeW32sSlAiNkLtI7Y6nRkMcOWGeKYKqrMsO8Ru91Qkeo3bfKP1wpN8XDEXCtSWWGv2Le1nXk2qJn1VXjNVrHWJJpy3euIRtLcKAFAO0X6k8Di+Jzmk4xiQ5UWRUnYsGvO23thyvs60bUVIq0GcV1O4yykU3ldyNvegeiITck8XFuThOqvhRXxN7vkDSUTvsUUtlzPzdzqecS940zOzkvI7HlmuSxPyeuMfF5e/M1/CkerKFiaZQZIiN19wJ+oGE5T2Ow2QGkhc7u7fn6YWmDhYMnyDLGBanrp43JG8TQhx09CtrYs5aaPSTIEPtKf54L2PHzyXrRmVQZTlJZFQyyctIqlbj0HOHKqvRrfdkbUah3yzyXcWnK6lK4Ps+0h2snqDiXFZITeA/leTSV1ZGii537DZbgAjn64kRhljbkkhqt+zkmo6ekLx0s61ZNJJT1se5GABNn4IN/0BxIlpctSi8MajqOcZLKG32e9immtA6berly+nVqaF3ip4dyxR2UndybliR1J4Fhh6FSj2p7sZna32Y8jM+faKzjU2YNmWZ54tZmFSAZJ54mdiB0A6WUDoBYYoZ6C62XHZYm34MtofaNNceCFbS80B6jskrWRQmb0e8g3D07gLb7zfCPuufSa9zF/elfWD96Kzn2iZ8mjqFmmjd46hoN5tGsjKBu2BjubhlPAsAet8Vl+mlTlt9f7jr+xa1aiNuMLpn+9Clyaan3tt7vbfjzjEbLJWUUxqqxBtdR6e+NJgy/IZmlKiTMdPpO8RiuWsL/aAPUYUlsBvvO8glmi1LHGEURzAhh6gAXGFxW4mT2HbpOhTxSSOGWNrbghBJ+behxOgiLKRobSWo6fJKGE11YYYmO9TI/mP8J2jkkm1uP1xNTSW5F3b2CGp9UxHTGZVCkmnaMokbdTu8vP44alPIBCxkKFHJsStwfS5FsN5AfSSkpMyXEaAFiebLwCfxOCAomrshgGofFzw0UVPVoHlqJgu+NhZJG5IFhwbnnzcemKfVVQVnHJJZ69f748zQaO6cqlFNvG2Onev+chT1MEwqZfDyQdxuOwVDhZAL9CPjpjOvbkzQLxFk8TpIA6kpe7WHpjTYMrnI49KVVHmGX0cdOsnhwLI5Ujc3sB1Nr9elz64dSBkFZ+9To7PaatqwsNNFUhWk3G0YY28xP8PNyfS+OinGRzawa07E4IaySCaVVeOQdOoBHS/vixqIFnMtnb8tatHpxcpjgepjqHlKzOYwU2bSoYA26g9PTBtWcYG4y4XuU4Z9mE+TJl88cMUJ2FlDFzcG9gbDi+GEmFyT5AWSInvFFyFJHHXp/nBE5PHLA0Ek9M7EtNEYw59T8/76YMe46W+5W9dd+cm76IWMDhZbRxuAkg2tuDgggMFuBzyeuIesjmviXTwT2fmWOhklY4Pr5815Cxly+GRwxy+lclQdypMoPA5spKj7iR7YoJVtPHAv8AZfLK9xpI2Jr/ACfwItT2YTToVjCsTx5W639Mah0dxkVbgjZVojV+nqhXyeKOeON9yxzuFHwASeAOTb3OBGqaFemj1Gpn2VVuudD51kdRkcFDPWqIvE1dTG7qLLd1CX5JDDn64kcDwMuxE3sNoNWdnarltd3FZRx37mYVQOxFAsGH2r9eelrYEISiGVkZLI3M/wBRTallp5p9qLGuyNAb2FuTf5OHWskdsATRb1L2Fgf9/XCcHZIrRHxJHsdxHryPyIwMCiPLAwa9gHS4t7m/GOwcQ66natgqaSQeWqjaJSSP4hcG5vYggdQbH3wmUOOLj3jlcuCal3CIqWplqJAaWGNtxJSSdkYH1upVbG/wMZnixtlL2r+PkazhT33+P8jGy5iViYnzWBv841hjwplh3RwX9SXPyS2OQcBNpWpYZWiO096E6X8u61vwxyE9AplEjLPmLBjdQFHwOOMFdRL5BOjdmijJJJAU/wC/gMcgs6pnLIpJuTUAH6XtgndWjwy1Qc1qeP5fzwFzO6EOR28dSDcfPVhW56j93x+eB1CBdXVEtLmmWiJzGDOQbH03DCJbNBXJiU1zUyUGtc+p6dzDBFXzqkacBQJDYDGV1F9kLpxi9k38zbaaqE6ISkt2kf/Z");
|
||||
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>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="medium">
|
||||
<div class="linearGradient"> </div>
|
||||
<div class="linearGradient2"> </div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="medium">
|
||||
<div style="background:url(image.jpg);"></div>
|
||||
<div style="background:url(image.jpg) repeat-x;"></div>
|
||||
@ -63,8 +72,8 @@
|
||||
<div style="background:url(image.jpg) repeat-y;"></div>
|
||||
<div style="background:url(image.jpg) no-repeat;"></div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="medium">
|
||||
<div style="background:url(image.jpg) center center;"></div>
|
||||
<div style="background:url(image.jpg) repeat-x center center;"></div>
|
||||
@ -72,27 +81,29 @@
|
||||
<div style="background:url(image.jpg) no-repeat center center;"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="small">
|
||||
|
||||
<div class="small">
|
||||
<div style="background:url(image.jpg) center center;"></div>
|
||||
<div style="background:url(image.jpg) repeat-x center center;"></div>
|
||||
<div style="background:url(image.jpg) repeat-y center center;"></div>
|
||||
<div style="background:url(image.jpg) no-repeat center center;"></div>
|
||||
</div>
|
||||
|
||||
<div class="medium">
|
||||
<div class="medium">
|
||||
<div style="background:url(image.jpg) 50px 50px;"></div>
|
||||
<div style="background:url(image.jpg) repeat-x 50px 50px;"></div>
|
||||
<div style="background:url(image.jpg) repeat-y 50px 50px;"></div>
|
||||
<div style="background:url(image.jpg) no-repeat 50px 50px;"></div>
|
||||
</div>
|
||||
|
||||
<div class="medium">
|
||||
|
||||
<div class="medium">
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
<div class="medium">
|
||||
<div class="encoded"></div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
@ -6,21 +6,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>z-index tests #2</title>
|
||||
<title>border tests</title>
|
||||
<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="../build/html2canvas.js"></script>
|
||||
<script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).ready(function() {
|
||||
|
||||
$('body').html2canvas({
|
||||
logging:true
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
<style type="text/css">
|
||||
|
||||
div { font: 12px Arial; }
|
||||
@ -34,7 +23,7 @@
|
||||
#div1,#div3 {
|
||||
height: 80px;
|
||||
position: relative;
|
||||
border: 1px dashed #669966;
|
||||
border: 23px double #669966;
|
||||
background-color: #ccffcc;
|
||||
padding-left: 5px;
|
||||
}
|
||||
@ -43,10 +32,10 @@
|
||||
opacity: 0.8;
|
||||
position: absolute;
|
||||
width: 150px;
|
||||
height: 200px;
|
||||
height: 201px;
|
||||
top: 20px;
|
||||
left: 170px;
|
||||
border: 1px dashed #990000;
|
||||
border: 20px dotted #990000;
|
||||
background-color: #ffdddd;
|
||||
text-align: center;
|
||||
}
|
||||
@ -58,14 +47,14 @@
|
||||
height: 70px;
|
||||
top: 65px;
|
||||
left: 50px;
|
||||
border: 1px dashed #000099;
|
||||
border: 15px dashed #000099;
|
||||
background-color: #ddddff;
|
||||
text-align: left;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
#div5{
|
||||
border: 1px dashed #669966;
|
||||
border: 15px dashed #669966;
|
||||
background-color: #ccffcc;
|
||||
padding-left: 5px;
|
||||
position:relative;
|
||||
@ -101,7 +90,7 @@
|
||||
|
||||
<br />
|
||||
|
||||
<div id="div3">
|
||||
<div id="div3" style="background-image:url(image.jpg)">
|
||||
<br /><span class="bold">DIV #3</span>
|
||||
<br />position: relative;
|
||||
<br />z-index: 1;
|
||||
|
@ -3,18 +3,9 @@
|
||||
<head>
|
||||
<title>External content tests</title>
|
||||
<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.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">
|
||||
$(window).ready(function() {
|
||||
$('body').html2canvas();
|
||||
});
|
||||
</script>
|
||||
|
||||
<link href="#" type="text/css" rel="stylesheet">
|
||||
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Iframe</h1>
|
||||
|
@ -10,14 +10,7 @@
|
||||
<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="../build/html2canvas.js"></script>
|
||||
<script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).ready(function() {
|
||||
$('body').html2canvas();
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
46
tests/image.svg
Normal file
46
tests/image.svg
Normal file
@ -0,0 +1,46 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="252.89000pt" width="493.28000pt" version="1.0" y="0.00000000" x="0.00000000" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<linearGradient id="lg0">
|
||||
<stop style="stop-color:#ff0000;stop-opacity:1.0000000" offset="0.00000000"/>
|
||||
<stop style="stop-color:#00ff00;stop-opacity:1.0000000" offset="0.50000000"/>
|
||||
<stop style="stop-color:#0000ff;stop-opacity:1.0000000" offset="1.0000000"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="lg1">
|
||||
<stop style="stop-color:#ff0000;stop-opacity:0.27450982" offset="0.00000000"/>
|
||||
<stop style="stop-color:#ff0000;stop-opacity:1.0000000" offset="1.0000000"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="rd0" fx="550.28571" fy="155.11731" xlink:href="#lg1" gradientUnits="userSpaceOnUse" cy="155.11731" cx="550.28571" gradientTransform="matrix(0.652228,-1.522906,1.403595,0.601129,-26.34767,869.2927)" r="127.00000"/>
|
||||
<radialGradient id="rd1" fx="492.85715" fy="379.50504" xlink:href="#lg3" gradientUnits="userSpaceOnUse" cy="379.50504" cx="492.85715" gradientTransform="matrix(0.944964,4.150569e-2,-4.340623e-2,0.988234,43.59757,-15.99113)" r="184.96443"/>
|
||||
<radialGradient id="rd2" fx="449.12918" fy="345.23175" xlink:href="#lg2" gradientUnits="userSpaceOnUse" cy="345.23175" cx="449.12918" gradientTransform="matrix(1.06455,-4.457048e-3,4.186833e-3,1.000012,-30.43703,1.997764)" r="184.96443"/>
|
||||
<linearGradient id="lg2">
|
||||
<stop style="stop-color:#fa4;stop-opacity:1" offset="0"/>
|
||||
<stop style="stop-color:#c3791f;stop-opacity:1" offset="0.5"/>
|
||||
<stop style="stop-color:#935000;stop-opacity:1" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="lg3">
|
||||
<stop style="stop-color:black;stop-opacity:1" offset="0"/>
|
||||
<stop style="stop-color:black;stop-opacity:1" offset="0.5"/>
|
||||
<stop style="stop-color:black;stop-opacity:1" offset="0.75"/>
|
||||
<stop style="stop-color:black;stop-opacity:0.72164947" offset="0.875"/>
|
||||
<stop style="stop-color:black;stop-opacity:0.50515461" offset="0.9375"/>
|
||||
<stop style="stop-color:black;stop-opacity:0.3298969" offset="0.96875"/>
|
||||
<stop style="stop-color:black;stop-opacity:0" offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path d="M300 252.36218C300 307.59065 255.22847 352.36218 200 352.36218 144.77153 352.36218 100 307.59065 100 252.36218 100 197.13371 144.77153 152.36218 200 152.36218 255.22847 152.36218 300 197.13371 300 252.36218L300 252.36218z" style="fill:#00ffff;fill-opacity:0.49999997;fill-rule:evenodd;stroke:#00ffff;stroke-width:4.0000000;stroke-linecap:butt;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000" transform="translate(-91.79890,-143.8324)"/>
|
||||
<path d="M500 252.36218C500 307.59065 455.22847 352.36218 400 352.36218 344.77153 352.36218 300 307.59065 300 252.36218 300 197.13371 344.77153 152.36218 400 152.36218 455.22847 152.36218 500 197.13371 500 252.36218L500 252.36218z" style="fill:#ffff00;fill-opacity:0.49999997;fill-rule:evenodd;stroke:#ffff00;stroke-width:4.0000000;stroke-linecap:butt;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000" transform="translate(-242.7989,-42.83241)"/>
|
||||
<path d="M400 452.36218C400 507.59065 355.22847 552.36218 300 552.36218 244.77153 552.36218 200 507.59065 200 452.36218 200 397.13371 244.77153 352.36218 300 352.36218 355.22847 352.36218 400 397.13371 400 452.36218L400 452.36218z" style="fill:#ff00ff;fill-opacity:0.49999997;fill-rule:evenodd;stroke:#ff00ff;stroke-width:4.0000000;stroke-linecap:butt;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000" transform="translate(-90.79890,-342.8324)"/>
|
||||
<rect style="fill:url(#rd0);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000;stroke-width:4.0000000;stroke-linecap:butt;stroke-miterlimit:4.0000000;stroke-dasharray:8.0000000 4.0000000;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000" rx="41.428570" ry="41.428570" transform="translate(6.201104,5.167586)" width="250.00000" y="2.3621826" x="351.00000" height="150.00000"/>
|
||||
<text style="font-size:72px;font-style:oblique;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr;text-anchor:start;fill:#fff;fill-opacity:0.49999997;stroke:#000;stroke-width:3.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:6.0000000 3.0000000;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans" xml:space="preserve" transform="translate(6.201104,5.167586)" y="101.34265" x="398.91016"><tspan y="101.34265" x="398.91016">SVG</tspan></text>
|
||||
<g transform="matrix(0.403355,0.000000,0.000000,0.403355,284.7118,53.56855)">
|
||||
<path style="fill:url(#rd1);fill-opacity:1.0000000;stroke:none;stroke-width:4.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000" d="M675.82158 379.50504A182.96443 182.96443 0 1 0 309.89272 379.50504 182.96443 182.96443 0 1 0 675.82158 379.50504z" transform="translate(25.71677,42.14162)"/>
|
||||
<path style="fill:url(#rd2);fill-opacity:1.0000000;stroke:none;stroke-width:4.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000" d="M675.82158 379.50504A182.96443 182.96443 0 1 0 309.89272 379.50504 182.96443 182.96443 0 1 0 675.82158 379.50504z" transform="translate(3.000000,1.000000)"/>
|
||||
<path style="color:#000;fill:#000;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:4.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000;marker:none" d="M448.21432 203.83901C450.36313 204.6315 453.75174 205.94795 456.34375 207.71875 458.93576 209.48955 460.70727 211.5991 460.84375 214 461.1565 219.5018 462.73056 224.22855 456.3125 234.21875 449.89444 244.20895 435.16134 259.07637 402.75 282.4375 341.89198 326.30215 327.69756 419.11497 324.82774 445.4561L327.9384 453.22053C327.9384 453.22053 336.06337 335.44254 405.09375 285.6875 437.69027 262.19289 452.72065 247.17079 459.65625 236.375 466.59185 225.57921 465.12192 218.64356 464.84375 213.75 464.60642 209.57479 461.69349 206.55518 458.59375 204.4375 457.315 203.56388 455.94644 202.87002 454.65334 202.2368L448.21432 203.83901z"/>
|
||||
<path style="color:#000;fill:#000;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:4.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000;marker:none" d="M509.01528 198.02937C499.53358 209.87282 477.91722 245.5091 465.15625 336.75 449.39628 449.43374 450.70852 546.83082 450.91598 557.84038L454.9375 558.75C454.9375 558.75 452.43678 456.60195 469.125 337.28125 482.74755 239.88008 506.43369 206.85787 513.90048 198.46178 513.90048 198.46178 509.01528 198.02937 509.01528 198.02937z"/>
|
||||
<path style="color:#000;fill:#000;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:4.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000;marker:none" d="M556.6875 211.625C547.0438 211.8095 537.01703 214.51544 529.96875 222.90625 520.74474 233.88721 520.91652 245.76284 524.5 256.1875 528.08348 266.61216 534.88069 275.92531 538.96875 282.875 541.20112 286.67003 547.45814 295.57779 555.4375 309.1875 563.41686 322.79721 573.02573 340.97669 581.71875 362.78125 599.10479 406.39038 612.72572 464.47037 601.9375 529.59375 601.9375 529.59375 606.5655 526.08172 606.5655 526.08172 616.26061 461.73706 602.63933 404.42832 585.4375 361.28125 576.65129 339.24295 566.92996 320.8949 558.875 307.15625 550.82004 293.4176 544.35231 284.15204 542.40625 280.84375 538.13746 273.5868 531.59217 264.50677 528.28125 254.875 524.97033 245.24323 524.70586 235.41118 533.03125 225.5 541.18293 215.79562 554.20308 214.66443 565.5625 216.125 576.92192 217.58557 586.26153 221.51972 586.26153 221.51972 586.26153 221.51972 568.49535 212.55885 568.49535 212.55885 567.63548 212.41794 566.98202 212.27046 566.09375 212.15625 563.09277 211.77039 559.90207 211.5635 556.6875 211.625z"/>
|
||||
<path style="color:#000;fill:#000;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:4.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000;marker:none" d="M458.15625 224.96875C424.33124 226.01594 399.1972 233.81099 381.5 242.40625 376.05652 245.05007 371.36415 247.88263 367.2855 250.51507 362.72383 255.08465 357.48708 260.80582 350.5625 269.40625 350.5625 269.40625 360.3001 257.14641 383.25 246 406.1999 234.85359 442.22471 224.97829 494.53125 230.375 599.18056 241.17215 643.20884 296.98475 675.71875 347 675.71875 347 673.37503 336.37355 673.37503 336.37355 641.03129 288.32441 594.99108 236.69798 494.9375 226.375 481.69006 225.0082 469.43125 224.61969 458.15625 224.96875z"/>
|
||||
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 9.0 KiB |
@ -5,13 +5,21 @@
|
||||
<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="../build/html2canvas.js"></script>
|
||||
<script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).ready(function() {
|
||||
$('body').html2canvas();
|
||||
});
|
||||
function setUp() {
|
||||
if ($('#testcanvas')[0].getContext) {
|
||||
var ctx = $('#testcanvas')[0].getContext('2d');
|
||||
|
||||
ctx.fillStyle = "rgb(200,0,0)";
|
||||
ctx.fillRect (10, 10, 55, 50);
|
||||
|
||||
ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
|
||||
ctx.fillRect (30, 30, 55, 50);
|
||||
} else {
|
||||
$('#testcanvas').remove();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@ -35,23 +43,30 @@
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<img src="image.jpg" />
|
||||
<img src="image.jpg" style="width:50px;height:400px;" />
|
||||
<img src="image.jpg" style="width:500px;" />
|
||||
<img src="image.jpg" style="width:500px;height:40px;" />
|
||||
|
||||
|
||||
<img src="image.jpg" style="padding:20px;border:5px solid black;" />
|
||||
|
||||
<img src="image.jpg" style="padding-bottom:20px;border-top:5px solid black;clear:both;" />
|
||||
|
||||
|
||||
<img src="image.jpg" style="padding-top:20px;border-top:5px solid black;clear:both;width:50px;" />
|
||||
<img src="image.jpg" style="padding-top:20px;border-top:5px solid black;clear:both;width:50px;height:25px;" />
|
||||
|
||||
<img src="image.jpg" style="width:0px;height:0px;border:1px solid black" />
|
||||
<img src="image.jpg" style="width:0px;height:0px;" />
|
||||
|
||||
<img src="image.jpg" />
|
||||
<img src="image.jpg" style="width:50px;height:400px;" />
|
||||
<img src="image.jpg" style="width:500px;" />
|
||||
<img src="image.jpg" style="width:500px;height:40px;" />
|
||||
|
||||
|
||||
<img src="image.jpg" style="padding:20px;border:5px solid black;" />
|
||||
|
||||
<img src="image.jpg" style="padding-bottom:20px;border-top:5px solid black;clear:both;" />
|
||||
|
||||
|
||||
<img src="image.jpg" style="padding-top:20px;border-top:5px solid black;clear:both;width:50px;" />
|
||||
<img src="image.jpg" style="padding-top:20px;border-top:5px solid black;clear:both;width:50px;height:25px;" />
|
||||
|
||||
<img src="image.jpg" style="width:0px;height:0px;border:1px solid black" />
|
||||
<img src="image.jpg" style="width:0px;height:0px;" />
|
||||
|
||||
<canvas id="testcanvas" style="width:100px;height:100px;"></canvas>
|
||||
<br />
|
||||
Image without src attribute, should not crash:
|
||||
<img style="width:50px;height:50px;border:1px solid red;display:block;" />
|
||||
|
||||
SVG taints image:<br /> <!-- http://fi.wikipedia.org/wiki/Tiedosto:Svg.svg -->
|
||||
<img src="image.svg" />
|
||||
</body>
|
||||
</html>
|
||||
|
@ -8,22 +8,15 @@
|
||||
<head>
|
||||
<title>List tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
|
||||
<script type="text/javascript" src="test.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/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).ready(function() {
|
||||
function setUp() {
|
||||
var supportedTypes = ["decimal","decimal-leading-zero","upper-roman","lower-roman","lower-alpha","upper-alpha"];
|
||||
for (var i = 1;i<=100;i++){
|
||||
|
||||
$('#dynamic').append($('<li />').text(i).css('list-style-type',supportedTypes[Math.round(Math.random()*supportedTypes.length)]));
|
||||
}
|
||||
|
||||
|
||||
$('body').html2canvas();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
186
tests/origin.html
Normal file
186
tests/origin.html
Normal file
@ -0,0 +1,186 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<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/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$('#bar').html2canvas();
|
||||
// var ss = $('ul').offset();
|
||||
// alert(ss.left);
|
||||
});
|
||||
</script>
|
||||
<title>
|
||||
display/box/float/clear test
|
||||
</title>
|
||||
<style type="text/css">
|
||||
/* last modified: 1 Dec 98 */
|
||||
|
||||
html {
|
||||
font: 10px/1 Verdana, sans-serif;
|
||||
background-color: blue;
|
||||
color: white;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 1.5em;
|
||||
border: .5em solid black;
|
||||
padding: 0;
|
||||
width: 48em;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
dl {
|
||||
margin: 0;
|
||||
border: 0;
|
||||
padding: .5em;
|
||||
}
|
||||
|
||||
dt {
|
||||
background-color: rgb(204,0,0);
|
||||
margin: 0;
|
||||
padding: 1em;
|
||||
width: 10.638%; /* refers to parent element's width of 47em. = 5em or 50px */
|
||||
height: 28em;
|
||||
border: .5em solid black;
|
||||
float: left;
|
||||
}
|
||||
|
||||
dd {
|
||||
float: right;
|
||||
margin: 0 0 0 1em;
|
||||
border: 1em solid black;
|
||||
padding: 1em;
|
||||
width: 34em;
|
||||
height: 27em;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
display: block; /* i.e., suppress marker */
|
||||
color: black;
|
||||
height: 9em;
|
||||
width: 5em;
|
||||
margin: 0;
|
||||
border: .5em solid black;
|
||||
padding: 1em;
|
||||
float: left;
|
||||
background-color: #FC0;
|
||||
}
|
||||
|
||||
#bar {
|
||||
background-color: black;
|
||||
color: white;
|
||||
width: 41.17%; /* = 14em */
|
||||
border: 0;
|
||||
margin: 0 1em;
|
||||
}
|
||||
|
||||
#baz {
|
||||
margin: 1em 0;
|
||||
border: 0;
|
||||
padding: 1em;
|
||||
width: 10em;
|
||||
height: 10em;
|
||||
background-color: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
form {
|
||||
margin: 0;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
form p {
|
||||
line-height: 1.9;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 1em 1em 1em 2em;
|
||||
border-width: 1em 1.5em 2em .5em;
|
||||
border-style: solid;
|
||||
border-color: black;
|
||||
padding: 1em 0;
|
||||
width: 5em;
|
||||
height: 9em;
|
||||
float: left;
|
||||
background-color: #FC0;
|
||||
color: black;
|
||||
}
|
||||
|
||||
address {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
h1 {
|
||||
background-color: black;
|
||||
color: white;
|
||||
float: left;
|
||||
margin: 1em 0;
|
||||
border: 0;
|
||||
padding: 1em;
|
||||
width: 10em;
|
||||
height: 10em;
|
||||
font-weight: normal;
|
||||
font-size: 1em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<dl>
|
||||
<dt>
|
||||
toggle
|
||||
</dt>
|
||||
<dd>
|
||||
<ul>
|
||||
<li>
|
||||
the way
|
||||
</li>
|
||||
<li id="bar">
|
||||
<p>
|
||||
the world ends
|
||||
</p>
|
||||
<form action="./" method="get">
|
||||
<p>
|
||||
bang
|
||||
<input type="radio" name="foo" value="off">
|
||||
</p>
|
||||
<p>
|
||||
whimper
|
||||
<input type="radio" name="foo2" value="on">
|
||||
</p>
|
||||
</form>
|
||||
</li>
|
||||
<li>
|
||||
i grow old
|
||||
</li>
|
||||
<li id="baz">
|
||||
pluot?
|
||||
</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<address>
|
||||
bar maids,
|
||||
</address>
|
||||
</blockquote>
|
||||
<h1>
|
||||
sing to me, erbarme dich
|
||||
</h1>
|
||||
</dd>
|
||||
</dl>
|
||||
<p style="color: black; font-size: 1em; line-height: 1.3em; clear: both">
|
||||
This is a nonsensical document, but syntactically valid HTML 4.0. All 100% conformant CSS1 agents should be able to render the document elements above this paragraph <b>indistinguishably</b> (to the pixel) from this reference rendering, (except font rasterization and form widgets). All discrepancies should be traceable to CSS1 implementation shortcomings. Once you have finished evaluating this test, you can return to the <A HREF="sec5526c.htm" style="text-decoration:none">parent page</A>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
@ -4,16 +4,7 @@
|
||||
<title>Overflow tests</title>
|
||||
<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="../build/html2canvas.js"></script>
|
||||
<script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).ready(function() {
|
||||
$('body').html2canvas({letterRendering:true});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
<style>
|
||||
.small{
|
||||
font-size:14px;
|
||||
@ -40,8 +31,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<h1>Overflow: visible</h1>
|
||||
<div>
|
||||
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like <b>Aldus PageMaker</b> including versions of Lorem Ipsum.
|
||||
<div> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like <b>Aldus PageMaker</b> including versions of Lorem Ipsum.
|
||||
</div>
|
||||
|
||||
<h1>Overflow: hidden</h1>
|
||||
|
@ -3,18 +3,9 @@
|
||||
<head>
|
||||
<title>External content tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
|
||||
|
||||
<script type="text/javascript" src="../external/jquery-1.6.2.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">
|
||||
$(window).ready(function() {
|
||||
$('body').html2canvas();
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
|
||||
<base href="http://www.google.com/" />
|
||||
<base href="http://www.google.com/" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>External image</h1>
|
||||
@ -23,5 +14,8 @@
|
||||
<h1>External image (using <base> href)</h1>
|
||||
<img src="/logos/2011/gregormendel11-res.jpg" />
|
||||
|
||||
<h1>External image (CORS)</h1>
|
||||
<img src="http://publishmydata.com/assets/home/blue_bg.png" />
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
28
tests/test.js
Normal file
28
tests/test.js
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
html2canvas @VERSION@ <http://html2canvas.hertzen.com>
|
||||
Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
|
||||
http://www.twitter.com/niklasvh
|
||||
|
||||
Released under MIT License
|
||||
*/
|
||||
(function(document, window) {
|
||||
var scrStart = '<script type="text/javascript" src="', scrEnd = '"></script>';
|
||||
document.write(scrStart + '../external/jquery-1.6.2.js' + scrEnd);
|
||||
var html2canvas = ['Core', 'Generate', 'Parse', 'Preload', 'Queue', 'Renderer', 'Util', 'plugins/jquery.plugin.html2canvas'], i;
|
||||
for (i = 0; i < html2canvas.length; ++i) {
|
||||
document.write(scrStart + '../src/' + html2canvas[i] + '.js' + scrEnd);
|
||||
}
|
||||
window.onload = function() {
|
||||
if (window.setUp) {
|
||||
window.setUp();
|
||||
}
|
||||
setTimeout(function() {
|
||||
$(document.body).html2canvas({
|
||||
flashcanvas: "../external/flashcanvas.min.js",
|
||||
logging: true,
|
||||
profile: true,
|
||||
useCORS: true
|
||||
});
|
||||
}, 100);
|
||||
};
|
||||
}(document, window));
|
@ -10,28 +10,17 @@
|
||||
<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="../build/html2canvas.js"></script>
|
||||
<script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).ready(function() {
|
||||
function setUp() {
|
||||
$('body').empty();
|
||||
$.each(['arial','verdana','tahoma','courier new'],function(i,e){
|
||||
|
||||
var div = $('<div />').css('font-family',e).appendTo('body');
|
||||
|
||||
for(var i=0;i<=20;i++){
|
||||
$('<div />').text('Testing texts').css('margin-top',1).css('border','1px solid black').css('font-size',(16+i*6)).appendTo(div);
|
||||
}
|
||||
|
||||
for(var i=0;i<=20;i++){
|
||||
$('<div />').text('Testing texts').css('margin-top',1).css('border','1px solid black').css('font-size',(16+i*6)).appendTo(div);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
window.setTimeout(function(){
|
||||
$('body').html2canvas();
|
||||
},100);
|
||||
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
@ -10,28 +10,18 @@
|
||||
<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="../build/html2canvas.js"></script>
|
||||
<script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).ready(function() {
|
||||
function setUp() {
|
||||
$('body').empty();
|
||||
$.each(['arial','verdana','tahoma','courier new'],function(i,e){
|
||||
|
||||
var div = $('<div />').css('font-family',e).appendTo('body');
|
||||
|
||||
for(var i=0;i<=20;i++){
|
||||
$('<div />').text('Testing texts').css('margin-top',1).css('border','1px solid black').css('font-size',(16+i*6)).appendTo(div);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
window.setTimeout(function(){
|
||||
$('body').html2canvas();
|
||||
},100);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
@ -10,29 +10,18 @@
|
||||
<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="../build/html2canvas.js"></script>
|
||||
<script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).ready(function() {
|
||||
|
||||
function setUp() {
|
||||
$('body').empty();
|
||||
$.each(['arial','verdana','tahoma','courier new'],function(i,e){
|
||||
|
||||
var div = $('<div />').css('font-family',e).appendTo('body');
|
||||
|
||||
for(var i=0;i<=20;i++){
|
||||
$('<div />').text('Testing texts').css('margin-top',1).css('border','1px solid black').css('font-size',(16+i*6)).appendTo(div);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
window.setTimeout(function(){
|
||||
$('body').html2canvas();
|
||||
},100);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
@ -10,15 +10,7 @@
|
||||
<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="../build/html2canvas.js"></script>
|
||||
<script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).ready(function() {
|
||||
$('body').html2canvas();
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
<style>
|
||||
.small{
|
||||
font-size:14px;
|
||||
|
@ -10,15 +10,7 @@
|
||||
<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="../build/html2canvas.js"></script>
|
||||
<script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).ready(function() {
|
||||
new html2canvas($('body').get(0));
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
<style>
|
||||
div{
|
||||
border:2px solid black;
|
||||
|
@ -9,18 +9,7 @@
|
||||
<title>z-index tests #1</title>
|
||||
<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="../build/html2canvas.js?12"></script>
|
||||
<script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).ready(function() {
|
||||
|
||||
$('body').html2canvas({
|
||||
logging:true
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
<style>
|
||||
|
||||
div { font: 12px Arial; }
|
||||
|
@ -9,18 +9,7 @@
|
||||
<title>z-index tests #2</title>
|
||||
<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="../build/html2canvas.js"></script>
|
||||
<script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).ready(function() {
|
||||
|
||||
$('body').html2canvas({
|
||||
logging:true
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
<style type="text/css">
|
||||
|
||||
div { font: 12px Arial; }
|
||||
|
@ -9,18 +9,7 @@
|
||||
<title>z-index tests #3</title>
|
||||
<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="../build/html2canvas.js"></script>
|
||||
<script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).ready(function() {
|
||||
|
||||
$('body').html2canvas({
|
||||
logging:true
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
<style type="text/css">
|
||||
|
||||
div { font: 12px Arial; }
|
||||
|
1
version.txt
Normal file
1
version.txt
Normal file
@ -0,0 +1 @@
|
||||
v0.33
|
Reference in New Issue
Block a user