mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
added support for form element text value rendering
This commit is contained in:
parent
1c55fa256e
commit
86c1ee1601
@ -21,6 +21,7 @@
|
|||||||
<fileset dir="${src.dir}" includes="Background.js"/>
|
<fileset dir="${src.dir}" includes="Background.js"/>
|
||||||
<fileset dir="${src.dir}" includes="Border.js"/>
|
<fileset dir="${src.dir}" includes="Border.js"/>
|
||||||
<fileset dir="${src.dir}" includes="Draw.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="Images.js"/>
|
||||||
<fileset dir="${src.dir}" includes="Renderer.js"/>
|
<fileset dir="${src.dir}" includes="Renderer.js"/>
|
||||||
<fileset dir="${src.dir}" includes="Text.js"/>
|
<fileset dir="${src.dir}" includes="Text.js"/>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* html2canvas v0.26 <http://html2canvas.hertzen.com>
|
* html2canvas v0.27 <http://html2canvas.hertzen.com>
|
||||||
* Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
|
* Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
|
||||||
* http://www.twitter.com/niklasvh
|
* http://www.twitter.com/niklasvh
|
||||||
*
|
*
|
||||||
@ -737,7 +737,7 @@ html2canvas.prototype.newElement = function(el,parentStack){
|
|||||||
stack.clip.width = stack.clip.width-(borders[1].width);
|
stack.clip.width = stack.clip.width-(borders[1].width);
|
||||||
stack.clip.height = stack.clip.height-(borders[2].width);
|
stack.clip.height = stack.clip.height-(borders[2].width);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
if (this.ignoreRe.test(el.nodeName) && this.opts.iframeDefault != "transparent"){
|
if (this.ignoreRe.test(el.nodeName) && this.opts.iframeDefault != "transparent"){
|
||||||
if (this.opts.iframeDefault=="default"){
|
if (this.opts.iframeDefault=="default"){
|
||||||
bgcolor = "#efefef";
|
bgcolor = "#efefef";
|
||||||
@ -780,26 +780,59 @@ html2canvas.prototype.newElement = function(el,parentStack){
|
|||||||
this.drawBackground(el,bgbounds,ctx);
|
this.drawBackground(el,bgbounds,ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (el.nodeName=="IMG"){
|
switch(el.nodeName){
|
||||||
image = _.loadImage(_.getAttr(el,'src'));
|
case "IMG":
|
||||||
if (image){
|
image = _.loadImage(_.getAttr(el,'src'));
|
||||||
// console.log(image.width);
|
if (image){
|
||||||
this.drawImage(
|
// console.log(image.width);
|
||||||
ctx,
|
this.drawImage(
|
||||||
image,
|
ctx,
|
||||||
0, //sx
|
image,
|
||||||
0, //sy
|
0, //sx
|
||||||
image.width, //sw
|
0, //sy
|
||||||
image.height, //sh
|
image.width, //sw
|
||||||
x+parseInt(_.getCSS(el,'padding-left'),10) + borders[3].width, //dx
|
image.height, //sh
|
||||||
y+parseInt(_.getCSS(el,'padding-top'),10) + borders[0].width, // dy
|
x+parseInt(_.getCSS(el,'padding-left'),10) + borders[3].width, //dx
|
||||||
bounds.width - (borders[1].width + borders[3].width + parseInt(_.getCSS(el,'padding-left'),10) + parseInt(_.getCSS(el,'padding-right'),10)), //dw
|
y+parseInt(_.getCSS(el,'padding-top'),10) + borders[0].width, // dy
|
||||||
bounds.height - (borders[0].width + borders[2].width + parseInt(_.getCSS(el,'padding-top'),10) + parseInt(_.getCSS(el,'padding-bottom'),10)) //dh
|
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 {
|
}else {
|
||||||
this.log("Error loading <img>:" + _.getAttr(el,'src'));
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -816,8 +849,8 @@ html2canvas.prototype.newElement = function(el,parentStack){
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function to draw the text on the canvas
|
* Function to draw the text on the canvas
|
||||||
*/
|
*/
|
||||||
|
|
||||||
html2canvas.prototype.printText = function(currentText,x,y,ctx){
|
html2canvas.prototype.printText = function(currentText,x,y,ctx){
|
||||||
if (this.trim(currentText).length>0){
|
if (this.trim(currentText).length>0){
|
||||||
@ -852,6 +885,44 @@ html2canvas.prototype.drawImage = function(ctx,image,sx,sy,sw,sh,dx,dy,dw,dh){
|
|||||||
);
|
);
|
||||||
this.numDraws++;
|
this.numDraws++;
|
||||||
|
|
||||||
|
}
|
||||||
|
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();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Function to find all images from <img> and background-image
|
* Function to find all images from <img> and background-image
|
||||||
@ -1331,7 +1402,7 @@ html2canvas.prototype.setContextVariable = function(ctx,variable,value){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
html2canvas.prototype.newText = function(el,textNode,stack){
|
html2canvas.prototype.newText = function(el,textNode,stack,form){
|
||||||
var ctx = stack.ctx;
|
var ctx = stack.ctx;
|
||||||
var family = this.getCSS(el,"font-family");
|
var family = this.getCSS(el,"font-family");
|
||||||
var size = this.getCSS(el,"font-size");
|
var size = this.getCSS(el,"font-size");
|
||||||
@ -1346,7 +1417,7 @@ html2canvas.prototype.newText = function(el,textNode,stack){
|
|||||||
|
|
||||||
|
|
||||||
var letter_spacing = this.getCSS(el,"letter-spacing");
|
var letter_spacing = this.getCSS(el,"letter-spacing");
|
||||||
|
|
||||||
// apply text-transform:ation to the text
|
// apply text-transform:ation to the text
|
||||||
textNode.nodeValue = this.textTransform(textNode.nodeValue,this.getCSS(el,"text-transform"));
|
textNode.nodeValue = this.textTransform(textNode.nodeValue,this.getCSS(el,"text-transform"));
|
||||||
var text = this.trim(textNode.nodeValue);
|
var text = this.trim(textNode.nodeValue);
|
||||||
@ -1400,79 +1471,81 @@ html2canvas.prototype.newText = function(el,textNode,stack){
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var oldTextNode = textNode;
|
|
||||||
for(var c=0;c<renderList.length;c++){
|
|
||||||
|
|
||||||
// TODO only do the splitting for non-range prints
|
|
||||||
var newTextNode = oldTextNode.splitText(renderList[c].length);
|
var oldTextNode = textNode;
|
||||||
|
for(var c=0;c<renderList.length;c++){
|
||||||
|
|
||||||
|
// 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 (text_decoration!="none" || this.trim(oldTextNode.nodeValue).length != 0){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (this.support.rangeBounds){
|
if (this.support.rangeBounds){
|
||||||
// getBoundingClientRect is supported for ranges
|
// getBoundingClientRect is supported for ranges
|
||||||
if (document.createRange){
|
if (document.createRange){
|
||||||
var range = document.createRange();
|
var range = document.createRange();
|
||||||
range.selectNode(oldTextNode);
|
range.selectNode(oldTextNode);
|
||||||
|
}else{
|
||||||
|
// TODO add IE support
|
||||||
|
var range = document.body.createTextRange();
|
||||||
|
}
|
||||||
|
if (range.getBoundingClientRect()){
|
||||||
|
var bounds = range.getBoundingClientRect();
|
||||||
|
}else{
|
||||||
|
var bounds = {};
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
// TODO add IE support
|
// it isn't supported, so let's wrap it inside an element instead and the bounds there
|
||||||
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 parent = oldTextNode.parentNode;
|
||||||
var wrapElement = document.createElement('wrapper');
|
var wrapElement = document.createElement('wrapper');
|
||||||
var backupText = oldTextNode.cloneNode(true);
|
var backupText = oldTextNode.cloneNode(true);
|
||||||
wrapElement.appendChild(oldTextNode.cloneNode(true));
|
wrapElement.appendChild(oldTextNode.cloneNode(true));
|
||||||
parent.replaceChild(wrapElement,oldTextNode);
|
parent.replaceChild(wrapElement,oldTextNode);
|
||||||
|
|
||||||
var bounds = this.getBounds(wrapElement);
|
var bounds = this.getBounds(wrapElement);
|
||||||
|
|
||||||
|
|
||||||
parent.replaceChild(backupText,wrapElement);
|
parent.replaceChild(backupText,wrapElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// console.log(range);
|
// console.log(range);
|
||||||
// console.log("'"+oldTextNode.nodeValue+"'"+bounds.left)
|
// console.log("'"+oldTextNode.nodeValue+"'"+bounds.left)
|
||||||
this.printText(oldTextNode.nodeValue,bounds.left,bounds.bottom,ctx);
|
this.printText(oldTextNode.nodeValue,bounds.left,bounds.bottom,ctx);
|
||||||
|
|
||||||
switch(text_decoration) {
|
switch(text_decoration) {
|
||||||
case "underline":
|
case "underline":
|
||||||
// Draws a line at the baseline of the font
|
// 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
|
// 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);
|
this.newRect(ctx,bounds.left,Math.round(bounds.top+metrics.baseline+metrics.lineWidth),bounds.width,1,color);
|
||||||
break;
|
break;
|
||||||
case "overline":
|
case "overline":
|
||||||
this.newRect(ctx,bounds.left,bounds.top,bounds.width,1,color);
|
this.newRect(ctx,bounds.left,bounds.top,bounds.width,1,color);
|
||||||
break;
|
break;
|
||||||
case "line-through":
|
case "line-through":
|
||||||
// TODO try and find exact position for 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);
|
this.newRect(ctx,bounds.left,Math.ceil(bounds.top+metrics.middle+metrics.lineWidth),bounds.width,1,color);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
oldTextNode = newTextNode;
|
oldTextNode = newTextNode;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1663,18 +1736,18 @@ html2canvas.prototype.withinBounds = function(src,dst){
|
|||||||
|
|
||||||
html2canvas.prototype.clipBounds = function(src,dst){
|
html2canvas.prototype.clipBounds = function(src,dst){
|
||||||
|
|
||||||
var x = Math.max(src.left,dst.left);
|
var x = Math.max(src.left,dst.left);
|
||||||
var y = Math.max(src.top,dst.top);
|
var y = Math.max(src.top,dst.top);
|
||||||
|
|
||||||
var x2 = Math.min((src.left+src.width),(dst.left+dst.width));
|
var x2 = Math.min((src.left+src.width),(dst.left+dst.width));
|
||||||
var y2 = Math.min((src.top+src.height),(dst.top+dst.height));
|
var y2 = Math.min((src.top+src.height),(dst.top+dst.height));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
left:x,
|
left:x,
|
||||||
top:y,
|
top:y,
|
||||||
width:x2-x,
|
width:x2-x,
|
||||||
height:y2-y
|
height:y2-y
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1706,8 +1779,8 @@ html2canvas.prototype.getBounds = function(el){
|
|||||||
var p = $(el).offset();
|
var p = $(el).offset();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
left: p.left + parseInt(this.getCSS(el,"border-left-width"),10),
|
left: p.left + this.getCSS(el,"border-left-width",true),
|
||||||
top: p.top + parseInt(this.getCSS(el,"border-top-width"),10),
|
top: p.top + this.getCSS(el,"border-top-width",true),
|
||||||
width:$(el).innerWidth(),
|
width:$(el).innerWidth(),
|
||||||
height:$(el).innerHeight()
|
height:$(el).innerHeight()
|
||||||
}
|
}
|
||||||
@ -1786,7 +1859,7 @@ html2canvas.prototype.formatZ = function(zindex,position,parentZ,parentNode){
|
|||||||
if (parentPosition!="static" && typeof parentPosition != "undefined"){
|
if (parentPosition!="static" && typeof parentPosition != "undefined"){
|
||||||
zindex = 0;
|
zindex = 0;
|
||||||
}
|
}
|
||||||
/*else{
|
/*else{
|
||||||
return parentZ;
|
return parentZ;
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
@ -1818,8 +1891,12 @@ html2canvas.prototype.getContents = function(el){
|
|||||||
* Function for fetching the css attribute
|
* Function for fetching the css attribute
|
||||||
* TODO remove jQuery dependancy
|
* TODO remove jQuery dependancy
|
||||||
*/
|
*/
|
||||||
html2canvas.prototype.getCSS = function(el,attribute){
|
html2canvas.prototype.getCSS = function(el,attribute,intOnly){
|
||||||
return $(el).css(attribute);
|
if (intOnly){
|
||||||
|
return parseInt($(el).css(attribute),10);
|
||||||
|
}else{
|
||||||
|
return $(el).css(attribute);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
15
build/html2canvas.min.js
vendored
15
build/html2canvas.min.js
vendored
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* html2canvas v0.26 <http://html2canvas.hertzen.com>
|
* html2canvas v0.27 <http://html2canvas.hertzen.com>
|
||||||
* Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
|
* Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
|
||||||
* http://www.twitter.com/niklasvh
|
* http://www.twitter.com/niklasvh
|
||||||
*
|
*
|
||||||
@ -24,8 +24,11 @@ html2canvas.prototype.getBorderData=function(a){var b=[],c=this;this.each(["top"
|
|||||||
html2canvas.prototype.drawBorders=function(a,b,c,d){var e=c.left,f=c.top,h=c.width,i=c.height,g=this.getBorderData(a),j=this;this.each(g,function(a,c){if(c.width>0){var n=e,o=f,m=h,p=i-g[2].width;switch(a){case 0:p=g[0].width;break;case 1:n=e+h-g[1].width;m=g[1].width;break;case 2:o=o+i-g[2].width;p=g[2].width;break;case 3:m=g[3].width}m={left:n,top:o,width:m,height:p};d&&(m=j.clipBounds(m,d));m.width>0&&m.height>0&&j.newRect(b,n,o,m.width,m.height,c.color)}});return g};
|
html2canvas.prototype.drawBorders=function(a,b,c,d){var e=c.left,f=c.top,h=c.width,i=c.height,g=this.getBorderData(a),j=this;this.each(g,function(a,c){if(c.width>0){var n=e,o=f,m=h,p=i-g[2].width;switch(a){case 0:p=g[0].width;break;case 1:n=e+h-g[1].width;m=g[1].width;break;case 2:o=o+i-g[2].width;p=g[2].width;break;case 3:m=g[3].width}m={left:n,top:o,width:m,height:p};d&&(m=j.clipBounds(m,d));m.width>0&&m.height>0&&j.newRect(b,n,o,m.width,m.height,c.color)}});return g};
|
||||||
html2canvas.prototype.newElement=function(a,b){var c=this.getBounds(a),d=c.left,e=c.top,f=c.width,h=c.height,i;i=this.getCSS(a,"background-color");var g=this.getCSS(a,"position"),b=b||{},j=this.formatZ(this.getCSS(a,"zIndex"),g,b.zIndex,a.parentNode),k=this.getCSS(a,"opacity"),l={ctx:new this.storageContext,zIndex:j,opacity:k*b.opacity,cssPosition:g};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"))&&
|
html2canvas.prototype.newElement=function(a,b){var c=this.getBounds(a),d=c.left,e=c.top,f=c.width,h=c.height,i;i=this.getCSS(a,"background-color");var g=this.getCSS(a,"position"),b=b||{},j=this.formatZ(this.getCSS(a,"zIndex"),g,b.zIndex,a.parentNode),k=this.getCSS(a,"opacity"),l={ctx:new this.storageContext,zIndex:j,opacity:k*b.opacity,cssPosition:g};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;g=this.contextStacks.push(l);j=this.contextStacks[g-1].ctx;this.setContextVariable(j,"globalAlpha",l.opacity);k=this.drawBorders(a,j,c);l.borders=k;this.ignoreRe.test(a.nodeName)&&this.opts.iframeDefault!="transparent"&&(i=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:h-(k[0].width+k[2].width)};l.clip&&(f=this.clipBounds(f,l.clip));
|
!/(BODY)/i.test(a.nodeName))l.clip=l.clip?this.clipBounds(l.clip,c):c;g=this.contextStacks.push(l);j=this.contextStacks[g-1].ctx;this.setContextVariable(j,"globalAlpha",l.opacity);k=this.drawBorders(a,j,c);l.borders=k;this.ignoreRe.test(a.nodeName)&&this.opts.iframeDefault!="transparent"&&(i=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:h-(k[0].width+k[2].width)};l.clip&&(f=this.clipBounds(f,l.clip));
|
||||||
f.height>0&&f.width>0&&(this.newRect(j,f.left,f.top,f.width,f.height,i),this.drawBackground(a,f,j));a.nodeName=="IMG"&&((i=this.loadImage(this.getAttr(a,"src")))?this.drawImage(j,i,0,0,i.width,i.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"),
|
f.height>0&&f.width>0&&(this.newRect(j,f.left,f.top,f.width,f.height,i),this.drawBackground(a,f,j));switch(a.nodeName){case "IMG":(i=this.loadImage(this.getAttr(a,"src")))?this.drawImage(j,i,0,0,i.width,i.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")));return this.contextStacks[g-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,h,i,g,j){a.drawImage(b,c,d,e,f,h,i,g,j);this.numDraws++};
|
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)}return this.contextStacks[g-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,h,i,g,j){a.drawImage(b,c,d,e,f,h,i,g,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))};
|
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))};
|
||||||
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.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.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()}})};
|
||||||
@ -44,7 +47,7 @@ padding:0});e.appendChild(document.createTextNode("Hidden Text"));c.appendChild(
|
|||||||
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.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.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.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.left=a.left;b.width=a.width;b.height=a.height;return b}else return b=$(a).offset(),{left:b.left+parseInt(this.getCSS(a,"border-left-width"),10),top:b.top+parseInt(this.getCSS(a,"border-top-width"),10),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.getBounds=function(a){window.scroll(0,0);if(a.getBoundingClientRect){var a=a.getBoundingClientRect(),b={};b.top=a.top;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.leadingZero=function(a,b){var c="000000000"+a;return c.substr(c.length-b)};
|
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.leadingZero=function(a,b){var c="000000000"+a;return c.substr(c.length-b)};
|
||||||
html2canvas.prototype.formatZ=function(a,b,c,d){c||(c="0");if(b!="static"&&c.charAt(0)=="0")this.needReorder=!0,c="1"+c.slice(1);a=="auto"&&(b=this.getCSS(d,"position"),b!="static"&&typeof b!="undefined"&&(a=0));b=this.leadingZero(this.numDraws,9);a=this.leadingZero(a+1,9);return c+""+a+""+b};html2canvas.prototype.getContents=function(a){return a.nodeName=="iframe"?a.contentDocument||a.contentWindow.document:a.childNodes};html2canvas.prototype.getCSS=function(a,b){return $(a).css(b)};
|
html2canvas.prototype.formatZ=function(a,b,c,d){c||(c="0");if(b!="static"&&c.charAt(0)=="0")this.needReorder=!0,c="1"+c.slice(1);a=="auto"&&(b=this.getCSS(d,"position"),b!="static"&&typeof b!="undefined"&&(a=0));b=this.leadingZero(this.numDraws,9);a=this.leadingZero(a+1,9);return c+""+a+""+b};html2canvas.prototype.getContents=function(a){return a.nodeName=="iframe"?a.contentDocument||a.contentWindow.document:a.childNodes};
|
||||||
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};
|
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};
|
||||||
|
77
src/Draw.js
77
src/Draw.js
@ -63,7 +63,7 @@ html2canvas.prototype.newElement = function(el,parentStack){
|
|||||||
stack.clip.width = stack.clip.width-(borders[1].width);
|
stack.clip.width = stack.clip.width-(borders[1].width);
|
||||||
stack.clip.height = stack.clip.height-(borders[2].width);
|
stack.clip.height = stack.clip.height-(borders[2].width);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
if (this.ignoreRe.test(el.nodeName) && this.opts.iframeDefault != "transparent"){
|
if (this.ignoreRe.test(el.nodeName) && this.opts.iframeDefault != "transparent"){
|
||||||
if (this.opts.iframeDefault=="default"){
|
if (this.opts.iframeDefault=="default"){
|
||||||
bgcolor = "#efefef";
|
bgcolor = "#efefef";
|
||||||
@ -106,26 +106,59 @@ html2canvas.prototype.newElement = function(el,parentStack){
|
|||||||
this.drawBackground(el,bgbounds,ctx);
|
this.drawBackground(el,bgbounds,ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (el.nodeName=="IMG"){
|
switch(el.nodeName){
|
||||||
image = _.loadImage(_.getAttr(el,'src'));
|
case "IMG":
|
||||||
if (image){
|
image = _.loadImage(_.getAttr(el,'src'));
|
||||||
// console.log(image.width);
|
if (image){
|
||||||
this.drawImage(
|
// console.log(image.width);
|
||||||
ctx,
|
this.drawImage(
|
||||||
image,
|
ctx,
|
||||||
0, //sx
|
image,
|
||||||
0, //sy
|
0, //sx
|
||||||
image.width, //sw
|
0, //sy
|
||||||
image.height, //sh
|
image.width, //sw
|
||||||
x+parseInt(_.getCSS(el,'padding-left'),10) + borders[3].width, //dx
|
image.height, //sh
|
||||||
y+parseInt(_.getCSS(el,'padding-top'),10) + borders[0].width, // dy
|
x+parseInt(_.getCSS(el,'padding-left'),10) + borders[3].width, //dx
|
||||||
bounds.width - (borders[1].width + borders[3].width + parseInt(_.getCSS(el,'padding-left'),10) + parseInt(_.getCSS(el,'padding-right'),10)), //dw
|
y+parseInt(_.getCSS(el,'padding-top'),10) + borders[0].width, // dy
|
||||||
bounds.height - (borders[0].width + borders[2].width + parseInt(_.getCSS(el,'padding-top'),10) + parseInt(_.getCSS(el,'padding-bottom'),10)) //dh
|
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 {
|
}else {
|
||||||
this.log("Error loading <img>:" + _.getAttr(el,'src'));
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -142,8 +175,8 @@ html2canvas.prototype.newElement = function(el,parentStack){
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function to draw the text on the canvas
|
* Function to draw the text on the canvas
|
||||||
*/
|
*/
|
||||||
|
|
||||||
html2canvas.prototype.printText = function(currentText,x,y,ctx){
|
html2canvas.prototype.printText = function(currentText,x,y,ctx){
|
||||||
if (this.trim(currentText).length>0){
|
if (this.trim(currentText).length>0){
|
||||||
|
38
src/Forms.js
Normal file
38
src/Forms.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
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();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* html2canvas v0.26 <http://html2canvas.hertzen.com>
|
* html2canvas v0.27 <http://html2canvas.hertzen.com>
|
||||||
* Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
|
* Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
|
||||||
* http://www.twitter.com/niklasvh
|
* http://www.twitter.com/niklasvh
|
||||||
*
|
*
|
||||||
|
106
src/Text.js
106
src/Text.js
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
html2canvas.prototype.newText = function(el,textNode,stack){
|
html2canvas.prototype.newText = function(el,textNode,stack,form){
|
||||||
var ctx = stack.ctx;
|
var ctx = stack.ctx;
|
||||||
var family = this.getCSS(el,"font-family");
|
var family = this.getCSS(el,"font-family");
|
||||||
var size = this.getCSS(el,"font-size");
|
var size = this.getCSS(el,"font-size");
|
||||||
@ -14,7 +14,7 @@ html2canvas.prototype.newText = function(el,textNode,stack){
|
|||||||
|
|
||||||
|
|
||||||
var letter_spacing = this.getCSS(el,"letter-spacing");
|
var letter_spacing = this.getCSS(el,"letter-spacing");
|
||||||
|
|
||||||
// apply text-transform:ation to the text
|
// apply text-transform:ation to the text
|
||||||
textNode.nodeValue = this.textTransform(textNode.nodeValue,this.getCSS(el,"text-transform"));
|
textNode.nodeValue = this.textTransform(textNode.nodeValue,this.getCSS(el,"text-transform"));
|
||||||
var text = this.trim(textNode.nodeValue);
|
var text = this.trim(textNode.nodeValue);
|
||||||
@ -68,79 +68,81 @@ html2canvas.prototype.newText = function(el,textNode,stack){
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var oldTextNode = textNode;
|
|
||||||
for(var c=0;c<renderList.length;c++){
|
|
||||||
|
|
||||||
// TODO only do the splitting for non-range prints
|
|
||||||
var newTextNode = oldTextNode.splitText(renderList[c].length);
|
var oldTextNode = textNode;
|
||||||
|
for(var c=0;c<renderList.length;c++){
|
||||||
|
|
||||||
|
// 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 (text_decoration!="none" || this.trim(oldTextNode.nodeValue).length != 0){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (this.support.rangeBounds){
|
if (this.support.rangeBounds){
|
||||||
// getBoundingClientRect is supported for ranges
|
// getBoundingClientRect is supported for ranges
|
||||||
if (document.createRange){
|
if (document.createRange){
|
||||||
var range = document.createRange();
|
var range = document.createRange();
|
||||||
range.selectNode(oldTextNode);
|
range.selectNode(oldTextNode);
|
||||||
|
}else{
|
||||||
|
// TODO add IE support
|
||||||
|
var range = document.body.createTextRange();
|
||||||
|
}
|
||||||
|
if (range.getBoundingClientRect()){
|
||||||
|
var bounds = range.getBoundingClientRect();
|
||||||
|
}else{
|
||||||
|
var bounds = {};
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
// TODO add IE support
|
// it isn't supported, so let's wrap it inside an element instead and the bounds there
|
||||||
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 parent = oldTextNode.parentNode;
|
||||||
var wrapElement = document.createElement('wrapper');
|
var wrapElement = document.createElement('wrapper');
|
||||||
var backupText = oldTextNode.cloneNode(true);
|
var backupText = oldTextNode.cloneNode(true);
|
||||||
wrapElement.appendChild(oldTextNode.cloneNode(true));
|
wrapElement.appendChild(oldTextNode.cloneNode(true));
|
||||||
parent.replaceChild(wrapElement,oldTextNode);
|
parent.replaceChild(wrapElement,oldTextNode);
|
||||||
|
|
||||||
var bounds = this.getBounds(wrapElement);
|
var bounds = this.getBounds(wrapElement);
|
||||||
|
|
||||||
|
|
||||||
parent.replaceChild(backupText,wrapElement);
|
parent.replaceChild(backupText,wrapElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// console.log(range);
|
// console.log(range);
|
||||||
// console.log("'"+oldTextNode.nodeValue+"'"+bounds.left)
|
// console.log("'"+oldTextNode.nodeValue+"'"+bounds.left)
|
||||||
this.printText(oldTextNode.nodeValue,bounds.left,bounds.bottom,ctx);
|
this.printText(oldTextNode.nodeValue,bounds.left,bounds.bottom,ctx);
|
||||||
|
|
||||||
switch(text_decoration) {
|
switch(text_decoration) {
|
||||||
case "underline":
|
case "underline":
|
||||||
// Draws a line at the baseline of the font
|
// 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
|
// 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);
|
this.newRect(ctx,bounds.left,Math.round(bounds.top+metrics.baseline+metrics.lineWidth),bounds.width,1,color);
|
||||||
break;
|
break;
|
||||||
case "overline":
|
case "overline":
|
||||||
this.newRect(ctx,bounds.left,bounds.top,bounds.width,1,color);
|
this.newRect(ctx,bounds.left,bounds.top,bounds.width,1,color);
|
||||||
break;
|
break;
|
||||||
case "line-through":
|
case "line-through":
|
||||||
// TODO try and find exact position for 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);
|
this.newRect(ctx,bounds.left,Math.ceil(bounds.top+metrics.middle+metrics.lineWidth),bounds.width,1,color);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
oldTextNode = newTextNode;
|
oldTextNode = newTextNode;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
34
src/Util.js
34
src/Util.js
@ -22,18 +22,18 @@ html2canvas.prototype.withinBounds = function(src,dst){
|
|||||||
|
|
||||||
html2canvas.prototype.clipBounds = function(src,dst){
|
html2canvas.prototype.clipBounds = function(src,dst){
|
||||||
|
|
||||||
var x = Math.max(src.left,dst.left);
|
var x = Math.max(src.left,dst.left);
|
||||||
var y = Math.max(src.top,dst.top);
|
var y = Math.max(src.top,dst.top);
|
||||||
|
|
||||||
var x2 = Math.min((src.left+src.width),(dst.left+dst.width));
|
var x2 = Math.min((src.left+src.width),(dst.left+dst.width));
|
||||||
var y2 = Math.min((src.top+src.height),(dst.top+dst.height));
|
var y2 = Math.min((src.top+src.height),(dst.top+dst.height));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
left:x,
|
left:x,
|
||||||
top:y,
|
top:y,
|
||||||
width:x2-x,
|
width:x2-x,
|
||||||
height:y2-y
|
height:y2-y
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,8 +65,8 @@ html2canvas.prototype.getBounds = function(el){
|
|||||||
var p = $(el).offset();
|
var p = $(el).offset();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
left: p.left + parseInt(this.getCSS(el,"border-left-width"),10),
|
left: p.left + this.getCSS(el,"border-left-width",true),
|
||||||
top: p.top + parseInt(this.getCSS(el,"border-top-width"),10),
|
top: p.top + this.getCSS(el,"border-top-width",true),
|
||||||
width:$(el).innerWidth(),
|
width:$(el).innerWidth(),
|
||||||
height:$(el).innerHeight()
|
height:$(el).innerHeight()
|
||||||
}
|
}
|
||||||
@ -145,7 +145,7 @@ html2canvas.prototype.formatZ = function(zindex,position,parentZ,parentNode){
|
|||||||
if (parentPosition!="static" && typeof parentPosition != "undefined"){
|
if (parentPosition!="static" && typeof parentPosition != "undefined"){
|
||||||
zindex = 0;
|
zindex = 0;
|
||||||
}
|
}
|
||||||
/*else{
|
/*else{
|
||||||
return parentZ;
|
return parentZ;
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
@ -177,8 +177,12 @@ html2canvas.prototype.getContents = function(el){
|
|||||||
* Function for fetching the css attribute
|
* Function for fetching the css attribute
|
||||||
* TODO remove jQuery dependancy
|
* TODO remove jQuery dependancy
|
||||||
*/
|
*/
|
||||||
html2canvas.prototype.getCSS = function(el,attribute){
|
html2canvas.prototype.getCSS = function(el,attribute,intOnly){
|
||||||
return $(el).css(attribute);
|
if (intOnly){
|
||||||
|
return parseInt($(el).css(attribute),10);
|
||||||
|
}else{
|
||||||
|
return $(el).css(attribute);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user