mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
Merge remote-tracking branch 'niklasvh/develop' into develop
Conflicts: src/Parse.js src/Preload.js
This commit is contained in:
commit
3edf9fa743
@ -327,18 +327,16 @@
|
||||
|
||||
var canvas = document.createElement('canvas'),
|
||||
ctx = canvas.getContext('2d'),
|
||||
gradient, grad, i, len, img;
|
||||
gradient, grad, i, len;
|
||||
|
||||
canvas.width = bounds.width;
|
||||
canvas.height = bounds.height;
|
||||
|
||||
// TODO: add support for multi defined background gradients (like radial gradient example in background.html)
|
||||
// TODO: add support for multi defined background gradients
|
||||
gradient = _html2canvas.Generate.parseGradient(src, bounds);
|
||||
|
||||
img = new Image();
|
||||
|
||||
if(gradient){
|
||||
if(gradient.type === 'linear'){
|
||||
if(gradient) {
|
||||
if(gradient.type === 'linear') {
|
||||
grad = ctx.createLinearGradient(gradient.x0, gradient.y0, gradient.x1, gradient.y1);
|
||||
|
||||
for (i = 0, len = gradient.colorStops.length; i < len; i+=1) {
|
||||
@ -353,8 +351,7 @@
|
||||
ctx.fillStyle = grad;
|
||||
ctx.fillRect(0, 0, bounds.width, bounds.height);
|
||||
|
||||
img.src = canvas.toDataURL();
|
||||
} else if(gradient.type === 'circle'){
|
||||
} else if(gradient.type === 'circle') {
|
||||
|
||||
grad = ctx.createRadialGradient(gradient.cx, gradient.cy, 0, gradient.cx, gradient.cy, gradient.rx);
|
||||
|
||||
@ -370,8 +367,7 @@
|
||||
ctx.fillStyle = grad;
|
||||
ctx.fillRect(0, 0, bounds.width, bounds.height);
|
||||
|
||||
img.src = canvas.toDataURL();
|
||||
} else if(gradient.type === 'ellipse'){
|
||||
} else if(gradient.type === 'ellipse') {
|
||||
|
||||
// draw circle
|
||||
var canvasRadial = document.createElement('canvas'),
|
||||
@ -382,7 +378,7 @@
|
||||
canvasRadial.width = canvasRadial.height = di;
|
||||
|
||||
grad = ctxRadial.createRadialGradient(gradient.rx, gradient.ry, 0, gradient.rx, gradient.ry, ri);
|
||||
|
||||
|
||||
for (i = 0, len = gradient.colorStops.length; i < len; i+=1) {
|
||||
try {
|
||||
grad.addColorStop(gradient.colorStops[i].stop, gradient.colorStops[i].color);
|
||||
@ -397,21 +393,12 @@
|
||||
|
||||
ctx.fillStyle = gradient.colorStops[i - 1].color;
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.drawImage(canvasRadial, gradient.cx - gradient.rx, gradient.cy - gradient.ry, 2 * gradient.rx, 2 * gradient.ry);
|
||||
|
||||
imgRadial = new Image();
|
||||
imgRadial.onload = function() { // wait until the image is filled
|
||||
|
||||
// transform circle to ellipse
|
||||
ctx.drawImage(imgRadial, gradient.cx - gradient.rx, gradient.cy - gradient.ry, 2 * gradient.rx, 2 * gradient.ry);
|
||||
|
||||
img.src = canvas.toDataURL();
|
||||
|
||||
};
|
||||
imgRadial.src = canvasRadial.toDataURL();
|
||||
}
|
||||
}
|
||||
|
||||
return img;
|
||||
return canvas;
|
||||
};
|
||||
|
||||
_html2canvas.Generate.ListAlpha = function(number) {
|
||||
|
572
src/Parse.js
572
src/Parse.js
@ -326,144 +326,372 @@ _html2canvas.Parse = function (images, options) {
|
||||
);
|
||||
}
|
||||
|
||||
function renderBorders(el, ctx, bounds, clip){
|
||||
function getBorderData(element) {
|
||||
return ["Top", "Right", "Bottom", "Left"].map(function(side) {
|
||||
return {
|
||||
width: getCSSInt(element, 'border' + side + 'Width'),
|
||||
color: getCSS(element, 'border' + side + 'Color')
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function getBorderRadiusData(element) {
|
||||
return ["TopLeft", "TopRight", "BottomRight", "BottomLeft"].map(function(side) {
|
||||
return getCSS(element, 'border' + side + 'Radius');
|
||||
});
|
||||
}
|
||||
|
||||
var getCurvePoints = (function(kappa) {
|
||||
|
||||
return function(x, y, r1, r2) {
|
||||
var ox = (r1) * kappa, // control point offset horizontal
|
||||
oy = (r2) * kappa, // control point offset vertical
|
||||
xm = x + r1, // x-middle
|
||||
ym = y + r2; // y-middle
|
||||
return {
|
||||
topLeft: bezierCurve({
|
||||
x:x,
|
||||
y:ym
|
||||
}, {
|
||||
x:x,
|
||||
y:ym - oy
|
||||
}, {
|
||||
x:xm - ox,
|
||||
y:y
|
||||
}, {
|
||||
x:xm,
|
||||
y:y
|
||||
}),
|
||||
topRight: bezierCurve({
|
||||
x:x,
|
||||
y:y
|
||||
}, {
|
||||
x:x + ox,
|
||||
y:y
|
||||
}, {
|
||||
x:xm,
|
||||
y:ym - oy
|
||||
}, {
|
||||
x:xm,
|
||||
y:ym
|
||||
}),
|
||||
bottomRight: bezierCurve({
|
||||
x:xm,
|
||||
y:y
|
||||
}, {
|
||||
x:xm,
|
||||
y:y + oy
|
||||
}, {
|
||||
x:x + ox,
|
||||
y:ym
|
||||
}, {
|
||||
x:x,
|
||||
y:ym
|
||||
}),
|
||||
bottomLeft: bezierCurve({
|
||||
x:xm,
|
||||
y:ym
|
||||
}, {
|
||||
x:xm - ox,
|
||||
y:ym
|
||||
}, {
|
||||
x:x,
|
||||
y:y + oy
|
||||
}, {
|
||||
x:x,
|
||||
y:y
|
||||
})
|
||||
};
|
||||
};
|
||||
})(4 * ((Math.sqrt(2) - 1) / 3));
|
||||
|
||||
function bezierCurve(start, startControl, endControl, end) {
|
||||
|
||||
var lerp = function (a, b, t) {
|
||||
return {
|
||||
x:a.x + (b.x - a.x) * t,
|
||||
y:a.y + (b.y - a.y) * t
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
start: start,
|
||||
startControl: startControl,
|
||||
endControl: endControl,
|
||||
end: end,
|
||||
subdivide: function(t) {
|
||||
var ab = lerp(start, startControl, t),
|
||||
bc = lerp(startControl, endControl, t),
|
||||
cd = lerp(endControl, end, t),
|
||||
abbc = lerp(ab, bc, t),
|
||||
bccd = lerp(bc, cd, t),
|
||||
dest = lerp(abbc, bccd, t);
|
||||
return [bezierCurve(start, ab, abbc, dest), bezierCurve(dest, bccd, cd, end)];
|
||||
},
|
||||
curveTo: function(borderArgs) {
|
||||
borderArgs.push(["bezierCurve", startControl.x, startControl.y, endControl.x, endControl.y, end.x, end.y]);
|
||||
},
|
||||
curveToReversed: function(borderArgs) {
|
||||
borderArgs.push(["bezierCurve", endControl.x, endControl.y, startControl.x, startControl.y, start.x, start.y]);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function parseCorner(borderArgs, radius1, radius2, corner1, corner2, x, y) {
|
||||
if (radius1[0] > 0 || radius1[1] > 0) {
|
||||
borderArgs.push(["line", corner1[0].start.x, corner1[0].start.y]);
|
||||
corner1[0].curveTo(borderArgs);
|
||||
corner1[1].curveTo(borderArgs);
|
||||
} else {
|
||||
borderArgs.push(["line", x, y]);
|
||||
}
|
||||
|
||||
if (radius2[0] > 0 || radius2[1] > 0) {
|
||||
borderArgs.push(["line", corner2[0].start.x, corner2[0].start.y]);
|
||||
}
|
||||
}
|
||||
|
||||
function drawSide(borderData, radius1, radius2, outer1, inner1, outer2, inner2) {
|
||||
var borderArgs = [];
|
||||
|
||||
if (radius1[0] > 0 || radius1[1] > 0) {
|
||||
borderArgs.push(["line", outer1[1].start.x, outer1[1].start.y]);
|
||||
outer1[1].curveTo(borderArgs);
|
||||
} else {
|
||||
borderArgs.push([ "line", borderData.c1[0], borderData.c1[1]]);
|
||||
}
|
||||
|
||||
if (radius2[0] > 0 || radius2[1] > 0) {
|
||||
borderArgs.push(["line", outer2[0].start.x, outer2[0].start.y]);
|
||||
outer2[0].curveTo(borderArgs);
|
||||
borderArgs.push(["line", inner2[0].end.x, inner2[0].end.y]);
|
||||
inner2[0].curveToReversed(borderArgs);
|
||||
} else {
|
||||
borderArgs.push([ "line", borderData.c2[0], borderData.c2[1]]);
|
||||
borderArgs.push([ "line", borderData.c3[0], borderData.c3[1]]);
|
||||
}
|
||||
|
||||
if (radius1[0] > 0 || radius1[1] > 0) {
|
||||
borderArgs.push(["line", inner1[1].end.x, inner1[1].end.y]);
|
||||
inner1[1].curveToReversed(borderArgs);
|
||||
} else {
|
||||
borderArgs.push([ "line", borderData.c4[0], borderData.c4[1]]);
|
||||
}
|
||||
|
||||
return borderArgs;
|
||||
}
|
||||
|
||||
function calculateCurvePoints(bounds, borderRadius, borders) {
|
||||
|
||||
var x = bounds.left,
|
||||
y = bounds.top,
|
||||
w = bounds.width,
|
||||
h = bounds.height,
|
||||
width = bounds.width,
|
||||
height = bounds.height,
|
||||
|
||||
tlh = borderRadius[0][0],
|
||||
tlv = borderRadius[0][1],
|
||||
trh = borderRadius[1][0],
|
||||
trv = borderRadius[1][1],
|
||||
brv = borderRadius[2][0],
|
||||
brh = borderRadius[2][1],
|
||||
blh = borderRadius[3][0],
|
||||
blv = borderRadius[3][1],
|
||||
|
||||
topWidth = width - trh,
|
||||
rightHeight = height - brv,
|
||||
bottomWidth = width - brh,
|
||||
leftHeight = height - blv;
|
||||
|
||||
return {
|
||||
topLeftOuter: getCurvePoints(
|
||||
x,
|
||||
y,
|
||||
tlh,
|
||||
tlv
|
||||
).topLeft.subdivide(0.5),
|
||||
|
||||
topLeftInner: getCurvePoints(
|
||||
x + borders[3].width,
|
||||
y + borders[0].width,
|
||||
Math.max(0, tlh - borders[3].width),
|
||||
Math.max(0, tlv - borders[0].width)
|
||||
).topLeft.subdivide(0.5),
|
||||
|
||||
topRightOuter: getCurvePoints(
|
||||
x + topWidth,
|
||||
y,
|
||||
trh,
|
||||
trv
|
||||
).topRight.subdivide(0.5),
|
||||
|
||||
topRightInner: getCurvePoints(
|
||||
x + Math.min(topWidth, width + borders[3].width),
|
||||
y + borders[0].width,
|
||||
(topWidth > width + borders[3].width) ? 0 :trh - borders[3].width,
|
||||
trv - borders[0].width
|
||||
).topRight.subdivide(0.5),
|
||||
|
||||
bottomRightOuter: getCurvePoints(
|
||||
x + bottomWidth,
|
||||
y + rightHeight,
|
||||
brh,
|
||||
brv
|
||||
).bottomRight.subdivide(0.5),
|
||||
|
||||
bottomRightInner: getCurvePoints(
|
||||
x + Math.min(bottomWidth, width + borders[3].width),
|
||||
y + Math.min(rightHeight, height + borders[0].width),
|
||||
Math.max(0, brh - borders[1].width),
|
||||
Math.max(0, brv - borders[2].width)
|
||||
).bottomRight.subdivide(0.5),
|
||||
|
||||
bottomLeftOuter: getCurvePoints(
|
||||
x,
|
||||
y + leftHeight,
|
||||
blh,
|
||||
blv
|
||||
).bottomLeft.subdivide(0.5),
|
||||
|
||||
bottomLeftInner: getCurvePoints(
|
||||
x + borders[3].width,
|
||||
y + leftHeight,
|
||||
Math.max(0, blh - borders[3].width),
|
||||
Math.max(0, blv - borders[2].width)
|
||||
).bottomLeft.subdivide(0.5)
|
||||
};
|
||||
}
|
||||
|
||||
function getBorderClip(element, borderPoints, borders, radius, bounds) {
|
||||
var backgroundClip = getCSS(element, 'backgroundClip'),
|
||||
borderArgs = [];
|
||||
|
||||
switch(backgroundClip) {
|
||||
case "content-box":
|
||||
case "padding-box":
|
||||
parseCorner(borderArgs, radius[0], radius[1], borderPoints.topLeftInner, borderPoints.topRightInner, bounds.left + borders[3].width, bounds.top + borders[0].width);
|
||||
parseCorner(borderArgs, radius[1], radius[2], borderPoints.topRightInner, borderPoints.bottomRightInner, bounds.left + bounds.width - borders[1].width, bounds.top + borders[0].width);
|
||||
parseCorner(borderArgs, radius[2], radius[3], borderPoints.bottomRightInner, borderPoints.bottomLeftInner, bounds.left + bounds.width - borders[1].width, bounds.top + bounds.height - borders[2].width);
|
||||
parseCorner(borderArgs, radius[3], radius[0], borderPoints.bottomLeftInner, borderPoints.topLeftInner, bounds.left + borders[3].width, bounds.top + bounds.height - borders[2].width);
|
||||
break;
|
||||
|
||||
default:
|
||||
parseCorner(borderArgs, radius[0], radius[1], borderPoints.topLeftOuter, borderPoints.topRightOuter, bounds.left, bounds.top);
|
||||
parseCorner(borderArgs, radius[1], radius[2], borderPoints.topRightOuter, borderPoints.bottomRightOuter, bounds.left + bounds.width, bounds.top);
|
||||
parseCorner(borderArgs, radius[2], radius[3], borderPoints.bottomRightOuter, borderPoints.bottomLeftOuter, bounds.left + bounds.width, bounds.top + bounds.height);
|
||||
parseCorner(borderArgs, radius[3], radius[0], borderPoints.bottomLeftOuter, borderPoints.topLeftOuter, bounds.left, bounds.top + bounds.height);
|
||||
break;
|
||||
}
|
||||
|
||||
return borderArgs;
|
||||
}
|
||||
|
||||
function parseBorders(element, bounds, borders){
|
||||
var x = bounds.left,
|
||||
y = bounds.top,
|
||||
width = bounds.width,
|
||||
height = bounds.height,
|
||||
borderSide,
|
||||
borderData,
|
||||
bx,
|
||||
by,
|
||||
bw,
|
||||
bh,
|
||||
i,
|
||||
borderArgs,
|
||||
borderBounds,
|
||||
borders = (function(el){
|
||||
var borders = [],
|
||||
sides = ["Top","Right","Bottom","Left"],
|
||||
s;
|
||||
|
||||
for (s = 0; s < 4; s+=1){
|
||||
borders.push({
|
||||
width: getCSSInt(el, 'border' + sides[s] + 'Width'),
|
||||
color: getCSS(el, 'border' + sides[s] + 'Color')
|
||||
});
|
||||
}
|
||||
|
||||
return borders;
|
||||
|
||||
}(el)),
|
||||
// http://www.w3.org/TR/css3-background/#the-border-radius
|
||||
borderRadius = (function( el ) {
|
||||
var borders = [],
|
||||
sides = ["TopLeft","TopRight","BottomRight","BottomLeft"],
|
||||
s;
|
||||
borderRadius = getBorderRadiusData(element),
|
||||
borderPoints = calculateCurvePoints(bounds, borderRadius, borders),
|
||||
borderData = {
|
||||
clip: getBorderClip(element, borderPoints, borders, borderRadius, bounds),
|
||||
borders: []
|
||||
};
|
||||
|
||||
for (s = 0; s < 4; s+=1){
|
||||
borders.push( getCSS(el, 'border' + sides[s] + 'Radius') );
|
||||
}
|
||||
for (borderSide = 0; borderSide < 4; borderSide++) {
|
||||
|
||||
return borders;
|
||||
})( el );
|
||||
|
||||
|
||||
|
||||
for ( borderSide = 0; borderSide < 4; borderSide+=1 ) {
|
||||
borderData = borders[ borderSide ];
|
||||
borderArgs = [];
|
||||
if (borderData.width>0){
|
||||
if (borders[borderSide].width > 0) {
|
||||
bx = x;
|
||||
by = y;
|
||||
bw = w;
|
||||
bh = h - (borders[2].width);
|
||||
bw = width;
|
||||
bh = height - (borders[2].width);
|
||||
|
||||
switch(borderSide){
|
||||
switch(borderSide) {
|
||||
case 0:
|
||||
// top border
|
||||
bh = borders[0].width;
|
||||
|
||||
i = 0;
|
||||
borderArgs[ i++ ] = [ "line", bx, by ]; // top left
|
||||
borderArgs[ i++ ] = [ "line", bx + bw, by ]; // top right
|
||||
borderArgs[ i++ ] = [ "line", bx + bw - borders[ 1 ].width, by + bh ]; // bottom right
|
||||
borderArgs[ i++ ] = [ "line", bx + borders[ 3 ].width, by + bh ]; // bottom left
|
||||
|
||||
borderArgs = drawSide({
|
||||
c1: [bx, by],
|
||||
c2: [bx + bw, by],
|
||||
c3: [bx + bw - borders[1].width, by + bh],
|
||||
c4: [bx + borders[3].width, by + bh]
|
||||
}, borderRadius[0], borderRadius[1],
|
||||
borderPoints.topLeftOuter, borderPoints.topLeftInner, borderPoints.topRightOuter, borderPoints.topRightInner);
|
||||
break;
|
||||
case 1:
|
||||
// right border
|
||||
bx = x + w - (borders[1].width);
|
||||
bx = x + width - (borders[1].width);
|
||||
bw = borders[1].width;
|
||||
|
||||
i = 0;
|
||||
borderArgs[ i++ ] = [ "line", bx, by + borders[ 0 ].width]; // top left
|
||||
borderArgs[ i++ ] = [ "line", bx + bw, by ]; // top right
|
||||
borderArgs[ i++ ] = [ "line", bx + bw, by + bh + borders[ 2 ].width ]; // bottom right
|
||||
borderArgs[ i++ ] = [ "line", bx, by + bh ]; // bottom left
|
||||
|
||||
borderArgs = drawSide({
|
||||
c1: [bx + bw, by],
|
||||
c2: [bx + bw, by + bh + borders[2].width],
|
||||
c3: [bx, by + bh],
|
||||
c4: [bx, by + borders[0].width]
|
||||
}, borderRadius[1], borderRadius[2],
|
||||
borderPoints.topRightOuter, borderPoints.topRightInner, borderPoints.bottomRightOuter, borderPoints.bottomRightInner);
|
||||
break;
|
||||
case 2:
|
||||
// bottom border
|
||||
by = (by + h) - (borders[2].width);
|
||||
by = (by + height) - (borders[2].width);
|
||||
bh = borders[2].width;
|
||||
|
||||
i = 0;
|
||||
borderArgs[ i++ ] = [ "line", bx + borders[ 3 ].width, by ]; // top left
|
||||
borderArgs[ i++ ] = [ "line", bx + bw - borders[ 2 ].width, by ]; // top right
|
||||
borderArgs[ i++ ] = [ "line", bx + bw, by + bh ]; // bottom right
|
||||
borderArgs[ i++ ] = [ "line", bx, by + bh ]; // bottom left
|
||||
|
||||
borderArgs = drawSide({
|
||||
c1: [bx + bw, by + bh],
|
||||
c2: [bx, by + bh],
|
||||
c3: [bx + borders[3].width, by],
|
||||
c4: [bx + bw - borders[2].width, by]
|
||||
}, borderRadius[2], borderRadius[3],
|
||||
borderPoints.bottomRightOuter, borderPoints.bottomRightInner, borderPoints.bottomLeftOuter, borderPoints.bottomLeftInner);
|
||||
break;
|
||||
case 3:
|
||||
// left border
|
||||
bw = borders[3].width;
|
||||
|
||||
i = 0;
|
||||
borderArgs[ i++ ] = [ "line", bx, by ]; // top left
|
||||
borderArgs[ i++ ] = [ "line", bx + bw, by + borders[ 0 ].width ]; // top right
|
||||
borderArgs[ i++ ] = [ "line", bx + bw, by + bh ]; // bottom right
|
||||
borderArgs[ i++ ] = [ "line", bx, by + bh + borders[ 2 ].width ]; // bottom left
|
||||
|
||||
borderArgs = drawSide({
|
||||
c1: [bx, by + bh + borders[2].width],
|
||||
c2: [bx, by],
|
||||
c3: [bx + bw, by + borders[0].width],
|
||||
c4: [bx + bw, by + bh]
|
||||
}, borderRadius[3], borderRadius[0],
|
||||
borderPoints.bottomLeftOuter, borderPoints.bottomLeftInner, borderPoints.topLeftOuter, borderPoints.topLeftInner);
|
||||
break;
|
||||
}
|
||||
|
||||
borderBounds = {
|
||||
left:bx,
|
||||
top:by,
|
||||
width: bw,
|
||||
height:bh
|
||||
};
|
||||
|
||||
if (clip){
|
||||
borderBounds = clipBounds(borderBounds, clip);
|
||||
}
|
||||
|
||||
|
||||
if ( borderBounds.width > 0 && borderBounds.height > 0 ) {
|
||||
|
||||
if ( borderData.color !== "transparent" ){
|
||||
ctx.setVariable( "fillStyle", borderData.color );
|
||||
|
||||
var shape = ctx.drawShape(),
|
||||
numBorderArgs = borderArgs.length;
|
||||
|
||||
for ( i = 0; i < numBorderArgs; i++ ) {
|
||||
shape[( i === 0) ? "moveTo" : borderArgs[ i ][ 0 ] + "To" ].apply( null, borderArgs[ i ].slice(1) );
|
||||
}
|
||||
|
||||
numDraws+=1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
borderData.borders.push({
|
||||
args: borderArgs,
|
||||
color: borders[borderSide].color
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return borders;
|
||||
return borderData;
|
||||
}
|
||||
|
||||
function createShape(ctx, args) {
|
||||
var shape = ctx.drawShape();
|
||||
args.forEach(function(border, index) {
|
||||
shape[(index === 0) ? "moveTo" : border[0] + "To" ].apply(null, border.slice(1));
|
||||
});
|
||||
return shape;
|
||||
}
|
||||
|
||||
function renderBorders(ctx, borderArgs, color) {
|
||||
if (color !== "transparent") {
|
||||
ctx.setVariable( "fillStyle", color);
|
||||
createShape(ctx, borderArgs);
|
||||
ctx.fill();
|
||||
numDraws+=1;
|
||||
}
|
||||
}
|
||||
|
||||
function renderFormValue (el, bounds, stack){
|
||||
|
||||
@ -512,118 +740,27 @@ _html2canvas.Parse = function (images, options) {
|
||||
numDraws+=1;
|
||||
}
|
||||
|
||||
function renderBackgroundSlice (ctx, image, x, y, width, height, elx, ely){
|
||||
var sourceX = (elx - x > 0) ? elx-x :0,
|
||||
sourceY= (ely - y > 0) ? ely-y : 0;
|
||||
|
||||
drawImage(
|
||||
ctx,
|
||||
image,
|
||||
Math.floor(sourceX), // source X
|
||||
Math.floor(sourceY), // source Y
|
||||
Math.ceil(image.width-sourceX), // source Width
|
||||
Math.ceil(image.height-sourceY), // source Height
|
||||
Math.ceil(x+sourceX), // destination X
|
||||
Math.ceil(y+sourceY), // destination Y
|
||||
Math.ceil(width-sourceX), // destination width
|
||||
Math.ceil(height-sourceY) // destination height
|
||||
);
|
||||
}
|
||||
|
||||
function renderBackgroundRepeat(ctx, image, backgroundPosition, bounds) {
|
||||
var bgy,
|
||||
height,
|
||||
add,
|
||||
h;
|
||||
var offsetX = Math.round(bounds.left + backgroundPosition.left),
|
||||
offsetY = Math.round(bounds.top + backgroundPosition.top);
|
||||
|
||||
backgroundPosition.top -= Math.ceil(backgroundPosition.top / image.height) * image.height;
|
||||
|
||||
for(bgy = (bounds.top + backgroundPosition.top); bgy < (bounds.height + bounds.top); bgy = Math.floor(bgy+image.height) - add) {
|
||||
h = Math.min(image.height,(bounds.height + bounds.top) - bgy);
|
||||
|
||||
height = (Math.floor(bgy + image.height) > h + bgy) ? (h + bgy) - bgy : image.height;
|
||||
|
||||
if (bgy < bounds.top){
|
||||
add = bounds.top - bgy;
|
||||
bgy = bounds.top;
|
||||
} else {
|
||||
add = 0;
|
||||
}
|
||||
|
||||
renderBackgroundRepeatX(ctx, image, backgroundPosition, bounds.left, bgy, bounds.width, height);
|
||||
|
||||
if (add > 0){
|
||||
backgroundPosition.top += add;
|
||||
}
|
||||
}
|
||||
ctx.createPattern(image);
|
||||
ctx.translate(offsetX, offsetY);
|
||||
ctx.fill();
|
||||
ctx.translate(-offsetX, -offsetY);
|
||||
}
|
||||
|
||||
function renderBackgroundNoRepeat(ctx, image, backgroundPosition, x, y, w, h) {
|
||||
var bgdw = w - backgroundPosition.left,
|
||||
bgdh = h - backgroundPosition.top,
|
||||
bgsx = backgroundPosition.left,
|
||||
bgsy = backgroundPosition.top,
|
||||
bgdx = backgroundPosition.left + x,
|
||||
bgdy = backgroundPosition.top + y;
|
||||
|
||||
if (bgsx<0){
|
||||
bgsx = Math.abs( bgsx );
|
||||
bgdx += bgsx;
|
||||
bgdw = Math.min( w, image.width - bgsx );
|
||||
} else {
|
||||
bgdw = Math.min( bgdw, image.width );
|
||||
bgsx = 0;
|
||||
}
|
||||
|
||||
if (bgsy < 0){
|
||||
bgsy = Math.abs( bgsy );
|
||||
bgdy += bgsy;
|
||||
bgdh = Math.min( h, image.height - bgsy );
|
||||
} else {
|
||||
bgdh = Math.min( bgdh, image.height );
|
||||
bgsy = 0;
|
||||
}
|
||||
|
||||
if (bgdh > 0 && bgdw > 0){
|
||||
drawImage(
|
||||
ctx,
|
||||
image,
|
||||
bgsx,
|
||||
bgsy,
|
||||
image.width,
|
||||
image.height,
|
||||
bgdx,
|
||||
bgdy,
|
||||
bgdw + backgroundPosition.left,
|
||||
bgdh + backgroundPosition.top
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function renderBackgroundRepeatY (ctx, image, backgroundPosition, x, y, w, h){
|
||||
var height,
|
||||
width = Math.min(image.width, w),
|
||||
bgy;
|
||||
|
||||
backgroundPosition.top -= Math.ceil(backgroundPosition.top / image.height) * image.height;
|
||||
|
||||
for (bgy = y + backgroundPosition.top; bgy < h + y; bgy = Math.round(bgy + image.height)){
|
||||
height = (Math.floor(bgy + image.height) > h + y) ? (h+y) - bgy : image.height;
|
||||
renderBackgroundSlice(ctx, image, x + backgroundPosition.left, bgy,width, height, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
function renderBackgroundRepeatX(ctx, image, backgroundPosition, x, y, w, h){
|
||||
var height = Math.min(image.height, h),
|
||||
width,
|
||||
bgx;
|
||||
|
||||
backgroundPosition.left -= Math.ceil(backgroundPosition.left / image.width) * image.width;
|
||||
|
||||
for (bgx = x + backgroundPosition.left; bgx < w + x; bgx = Math.round(bgx + image.width)) {
|
||||
width = (Math.floor(bgx + image.width) > w + x) ? (w + x) - bgx : image.width;
|
||||
renderBackgroundSlice(ctx, image, bgx,(y + backgroundPosition.top), width, height, x, y);
|
||||
}
|
||||
function backgroundRepeatShape(ctx, image, backgroundPosition, bounds, left, top, width, height) {
|
||||
var args = [];
|
||||
args.push(["line", Math.round(left), Math.round(top)]);
|
||||
args.push(["line", Math.round(left + width), Math.round(top)]);
|
||||
args.push(["line", Math.round(left + width), Math.round(height + top)]);
|
||||
args.push(["line", Math.round(left), Math.round(height + top)]);
|
||||
createShape(ctx, args);
|
||||
ctx.save();
|
||||
ctx.clip();
|
||||
renderBackgroundRepeat(ctx, image, backgroundPosition, bounds);
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
function renderBackgroundColor(ctx, backgroundBounds, bgcolor) {
|
||||
@ -646,15 +783,18 @@ _html2canvas.Parse = function (images, options) {
|
||||
|
||||
switch (backgroundRepeat) {
|
||||
case "repeat-x":
|
||||
renderBackgroundRepeatX(ctx, image, backgroundPosition, bounds.left, bounds.top, backgroundSize.width, backgroundSize.height);
|
||||
backgroundRepeatShape(ctx, image, backgroundPosition, bounds,
|
||||
bounds.left, bounds.top + backgroundPosition.top, 99999, backgroundSize.height);
|
||||
break;
|
||||
|
||||
case "repeat-y":
|
||||
renderBackgroundRepeatY(ctx, image, backgroundPosition, bounds.left, bounds.top, backgroundSize.width, backgroundSize.height);
|
||||
backgroundRepeatShape(ctx, image, backgroundPosition, bounds,
|
||||
bounds.left + backgroundPosition.left, bounds.top, backgroundSize.width, 99999);
|
||||
break;
|
||||
|
||||
case "no-repeat":
|
||||
renderBackgroundNoRepeat(ctx, image, backgroundPosition, bounds.left, bounds.top, backgroundSize.width, backgroundSize.height);
|
||||
backgroundRepeatShape(ctx, image, backgroundPosition, bounds,
|
||||
bounds.left + backgroundPosition.left, bounds.top + backgroundPosition.top, backgroundSize.width, backgroundSize.height);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -704,7 +844,7 @@ _html2canvas.Parse = function (images, options) {
|
||||
zIndex: setZ(getCSS(element, "zIndex"), (parentStack) ? parentStack.zIndex : null),
|
||||
opacity: setOpacity(ctx, element, parentStack),
|
||||
cssPosition: getCSS(element, "position"),
|
||||
borders: renderBorders(element, ctx, bounds, false),
|
||||
borders: getBorderData(element),
|
||||
clip: (parentStack && parentStack.clip) ? _html2canvas.Util.Extend( {}, parentStack.clip ) : null
|
||||
};
|
||||
|
||||
@ -740,13 +880,25 @@ _html2canvas.Parse = function (images, options) {
|
||||
stack = createStack(element, parentStack, bounds),
|
||||
borders = stack.borders,
|
||||
ctx = stack.ctx,
|
||||
backgroundBounds = getBackgroundBounds(borders, bounds, stack.clip);
|
||||
backgroundBounds = getBackgroundBounds(borders, bounds, stack.clip),
|
||||
borderData = parseBorders(element, bounds, borders);
|
||||
|
||||
createShape(ctx, borderData.clip);
|
||||
|
||||
ctx.save();
|
||||
ctx.clip();
|
||||
|
||||
if (backgroundBounds.height > 0 && backgroundBounds.width > 0){
|
||||
renderBackgroundColor(ctx, backgroundBounds, bgcolor);
|
||||
renderBackgroundColor(ctx, bounds, bgcolor);
|
||||
renderBackgroundImage(element, backgroundBounds, ctx);
|
||||
}
|
||||
|
||||
ctx.restore();
|
||||
|
||||
borderData.borders.forEach(function(border) {
|
||||
renderBorders(ctx, border.args, border.color);
|
||||
});
|
||||
|
||||
switch(element.nodeName){
|
||||
case "IMG":
|
||||
if ((image = loadImage(element.getAttribute('src')))) {
|
||||
|
@ -122,10 +122,9 @@ _html2canvas.Preload = function( options ) {
|
||||
// opera throws exception on external-content.html
|
||||
try {
|
||||
background_image = _html2canvas.Util.getCSS(el, 'backgroundImage');
|
||||
}catch(e) {
|
||||
} catch(e) {
|
||||
h2clog("html2canvas: failed to get background-image - Exception: " + e.message);
|
||||
}
|
||||
|
||||
background_images = _html2canvas.Util.parseBackgroundImage(background_image);
|
||||
for(var imageIndex = background_images.length; imageIndex-- > 0;) {
|
||||
background_image = background_images[imageIndex];
|
||||
@ -136,7 +135,6 @@ _html2canvas.Preload = function( options ) {
|
||||
background_image.args.length === 0 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (background_image.method === 'url') {
|
||||
src = background_image.args[0];
|
||||
methods.loadImage(src);
|
||||
|
48
src/Queue.js
48
src/Queue.js
@ -4,6 +4,41 @@ function h2cRenderContext(width, height) {
|
||||
storage: storage,
|
||||
width: width,
|
||||
height: height,
|
||||
clip: function() {
|
||||
storage.push({
|
||||
type: "function",
|
||||
name: "clip",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
translate: function() {
|
||||
storage.push({
|
||||
type: "function",
|
||||
name: "translate",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
fill: function() {
|
||||
storage.push({
|
||||
type: "function",
|
||||
name: "fill",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
save: function() {
|
||||
storage.push({
|
||||
type: "function",
|
||||
name: "save",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
restore: function() {
|
||||
storage.push({
|
||||
type: "function",
|
||||
name: "restore",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
fillRect: function () {
|
||||
storage.push({
|
||||
type: "function",
|
||||
@ -11,6 +46,13 @@ function h2cRenderContext(width, height) {
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
createPattern: function() {
|
||||
storage.push({
|
||||
type: "function",
|
||||
name: "createPattern",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
drawShape: function() {
|
||||
|
||||
var shape = [];
|
||||
@ -34,6 +76,12 @@ function h2cRenderContext(width, height) {
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
arcTo: function() {
|
||||
shape.push({
|
||||
name: "arcTo",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
bezierCurveTo: function() {
|
||||
shape.push({
|
||||
name: "bezierCurveTo",
|
||||
|
@ -98,16 +98,12 @@ _html2canvas.Renderer.Canvas = function( options ) {
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.fillStyle = fstyle;
|
||||
|
||||
var drawShape = function(args) {
|
||||
|
||||
var i, len = args.length;
|
||||
var createShape = function(args) {
|
||||
ctx.beginPath();
|
||||
for ( i = 0; i < len; i++ ) {
|
||||
ctx[ args[ i ].name ].apply( ctx, args[ i ]['arguments'] );
|
||||
}
|
||||
args.forEach(function(arg) {
|
||||
ctx[arg.name].apply(ctx, arg['arguments']);
|
||||
});
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
|
||||
};
|
||||
|
||||
if ( options.svgRendering && zStack.svgRender !== undefined ) {
|
||||
@ -149,8 +145,10 @@ _html2canvas.Renderer.Canvas = function( options ) {
|
||||
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 === "createPattern") {
|
||||
ctx.fillStyle = ctx.createPattern(renderItem['arguments'][0], "repeat");
|
||||
} else if (renderItem.name === "drawShape") {
|
||||
drawShape(renderItem['arguments']);
|
||||
createShape(renderItem['arguments']);
|
||||
} else if (renderItem.name === "fillText") {
|
||||
if (!usingFlashcanvas || renderItem['arguments'][1] < flashMaxSize && renderItem['arguments'][2] < flashMaxSize) {
|
||||
ctx.fillText.apply( ctx, renderItem['arguments'] );
|
||||
@ -175,6 +173,8 @@ _html2canvas.Renderer.Canvas = function( options ) {
|
||||
}
|
||||
ctx.drawImage.apply( ctx, renderItem['arguments'] );
|
||||
}
|
||||
} else {
|
||||
ctx[renderItem.name].apply(ctx, renderItem['arguments']);
|
||||
}
|
||||
|
||||
|
||||
|
60
tests/cases/background/clip.html
Normal file
60
tests/cases/background/clip.html
Normal file
@ -0,0 +1,60 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Background attribute tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style>
|
||||
html {
|
||||
background-color: red;
|
||||
}
|
||||
body {
|
||||
background-color: lime;
|
||||
}
|
||||
.small div{
|
||||
width:100px;
|
||||
height:100px;
|
||||
float:left;
|
||||
margin:10px;
|
||||
border:1px solid #000;
|
||||
}
|
||||
|
||||
.medium div{
|
||||
width:200px;
|
||||
height:200px;
|
||||
float:left;
|
||||
margin:10px;
|
||||
border:20px solid transparent;
|
||||
border-width: 10px 20px 30px 40px;
|
||||
background: green;
|
||||
}
|
||||
|
||||
.small, .medium{
|
||||
clear:both;
|
||||
}
|
||||
|
||||
div{
|
||||
display:block;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="medium">
|
||||
<div style="background:url(../../assets/image.jpg);background-clip: border-box;"></div>
|
||||
<div style="background:url(../../assets/image.jpg);background-clip: padding-box;"></div>
|
||||
<div style="background:url(../../assets/image.jpg);background-clip: content-box;"></div>
|
||||
<div style="background:url(../../assets/image.jpg);"></div>
|
||||
</div>
|
||||
|
||||
<div class="medium">
|
||||
<div style="background-clip: border-box;"></div>
|
||||
<div style="background-clip: padding-box;"></div>
|
||||
<div style="background-clip: content-box;"></div>
|
||||
<div style=""></div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
60
tests/cases/border/radius.html
Normal file
60
tests/cases/border/radius.html
Normal file
@ -0,0 +1,60 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Borders tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style type="text/css">
|
||||
div {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
display: inline-block;
|
||||
margin: 10px;
|
||||
background:#6F428C;
|
||||
border-style: solid;
|
||||
border-radius: 50px;
|
||||
}
|
||||
|
||||
.box1 {
|
||||
border-width: 1px;
|
||||
border-left-color: #00b5e2;
|
||||
border-top-color: red;
|
||||
border-right-color: green;
|
||||
}
|
||||
|
||||
.box2 {
|
||||
border-width: 3px;
|
||||
border-left-color: #00b5e2;
|
||||
border-top-color: red;
|
||||
border-right-color: green;
|
||||
}
|
||||
|
||||
.box3 {
|
||||
border-width: 10px;
|
||||
border-left-color: transparent;
|
||||
border-top-color: red;
|
||||
border-right-color: green;
|
||||
}
|
||||
|
||||
.box4 {
|
||||
border-width: 50px;
|
||||
border-left-color: transparent;
|
||||
border-top-color: red;
|
||||
border-top-width: 10px;
|
||||
border-right-color: green;
|
||||
border-bottom-right-radius: 190px;
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
html {
|
||||
background: #3a84c3;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="box1"> </div>
|
||||
<div class="box2"> </div>
|
||||
<div class="box3"> </div>
|
||||
<div class="box4"> </div>
|
||||
</body>
|
||||
</html>
|
37
tests/rangetest.html
Normal file
37
tests/rangetest.html
Normal file
@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Range tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<style>
|
||||
#tests {
|
||||
font-family:Arial;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="tests"></div>
|
||||
<script>
|
||||
var div = document.getElementById("tests"), item, range, textNode, bounds;
|
||||
|
||||
for (var i = 6; i < 72; i++) {
|
||||
item = document.createElement("div");
|
||||
item.style.fontSize = i + "px";
|
||||
item.style.lineHeight = (10 + i * 2) + "px";
|
||||
textNode = document.createTextNode(i);
|
||||
item.appendChild(textNode);
|
||||
div.appendChild(item);
|
||||
|
||||
range = document.createRange();
|
||||
range.setStart(textNode, 0);
|
||||
range.setEnd(textNode, i.toString().length);
|
||||
bounds = range.getBoundingClientRect();
|
||||
|
||||
textNode.nodeValue += " " + bounds.height + " " + bounds.bottom + (i % 3 === 0);
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
<script src="test.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -1,31 +1,33 @@
|
||||
<table><thead><tr><td></td><th>chrome<br />23.0.1271.97</th><th>firefox<br />12.0</th><th>iexplorer<br />9</th></tr></thead><tbody>
|
||||
<tr><td>background/clip.html</td><td>100%</td><td>100%</td><td>99.89%</td></tr>
|
||||
<tr><td>background/encoded.html</td><td>100%</td><td>100%</td><td>100%</td></tr>
|
||||
<tr><td>background/linear-gradient.html</td><td>82.27%</td><td>85.64%</td><td>100%</td></tr>
|
||||
<tr><td>background/multi.html</td><td>96.6%</td><td>96.45%</td><td>96.89%</td></tr>
|
||||
<tr><td>background/position.html</td><td>97.03%</td><td>96.97%</td><td>97.03%</td></tr>
|
||||
<tr><td>background/radial-gradient.html</td><td>57.9%</td><td>54.87%</td><td>94.02%</td></tr>
|
||||
<tr><td>background/repeat.html</td><td>100%</td><td>100%</td><td>100%</td></tr>
|
||||
<tr><td>background/linear-gradient.html</td><td>89.87%</td><td>90.73%</td><td>100%</td></tr>
|
||||
<tr><td>background/multi.html</td><td>96.6%</td><td>96.45%</td><td>96.85%</td></tr>
|
||||
<tr><td>background/position.html</td><td>100%</td><td>100%</td><td>99.87%</td></tr>
|
||||
<tr><td>background/radial-gradient.html</td><td>73.23%</td><td>70.32%</td><td>94.02%</td></tr>
|
||||
<tr><td>background/repeat.html</td><td>100%</td><td>100%</td><td>99.92%</td></tr>
|
||||
<tr><td>border/dashed.html</td><td>96.45%</td><td>98.38%</td><td>97.7%</td></tr>
|
||||
<tr><td>border/dotted.html</td><td>97.41%</td><td>96.46%</td><td>95.93%</td></tr>
|
||||
<tr><td>border/double.html</td><td>97.96%</td><td>97.87%</td><td>97.95%</td></tr>
|
||||
<tr><td>border/radius.html</td><td>99.74%</td><td>99.77%</td><td>99.75%</td></tr>
|
||||
<tr><td>border/solid.html</td><td>99.97%</td><td>99.97%</td><td>99.98%</td></tr>
|
||||
<tr><td>forms.html</td><td>95.96%</td><td>94.55%</td><td>95.02%</td></tr>
|
||||
<tr><td>forms.html</td><td>95.96%</td><td>94.55%</td><td>95.01%</td></tr>
|
||||
<tr><td>images/canvas.html</td><td>99.86%</td><td>100%</td><td>100%</td></tr>
|
||||
<tr><td>images/cross-origin.html</td><td>97.99%</td><td>97.58%</td><td>99.35%</td></tr>
|
||||
<tr><td>images/empty.html</td><td>99.86%</td><td>99.87%</td><td>99.85%</td></tr>
|
||||
<tr><td>images/images.html</td><td>83.72%</td><td>96.93%</td><td>55.09%</td></tr>
|
||||
<tr><td>images/svg.html</td><td>99.92%</td><td>96.79%</td><td>99.93%</td></tr>
|
||||
<tr><td>list/decimal-leading-zero.html</td><td>99.63%</td><td>99.72%</td><td>35.04%</td></tr>
|
||||
<tr><td>list/decimal.html</td><td>99.64%</td><td>99.73%</td><td>35.06%</td></tr>
|
||||
<tr><td>list/lower-alpha.html</td><td>99.65%</td><td>99.73%</td><td>35.05%</td></tr>
|
||||
<tr><td>list/upper-roman.html</td><td>99.45%</td><td>99.61%</td><td>35.11%</td></tr>
|
||||
<tr><td>overflow.html</td><td>96.85%</td><td>97.49%</td><td>96.51%</td></tr>
|
||||
<tr><td>text/linethrough.html</td><td>97.14%</td><td>94.12%</td><td>45.74%</td></tr>
|
||||
<tr><td>text/text.html</td><td>95.71%</td><td>94.67%</td><td>79.85%</td></tr>
|
||||
<tr><td>text/underline-lineheight.html</td><td>97.06%</td><td>92.35%</td><td>51.38%</td></tr>
|
||||
<tr><td>text/underline.html</td><td>97.65%</td><td>93.5%</td><td>45.69%</td></tr>
|
||||
<tr><td>visibility.html</td><td>99.19%</td><td>98.92%</td><td>99.39%</td></tr>
|
||||
<tr><td>zindex/z-index1.html</td><td>97.09%</td><td>99.38%</td><td>99.54%</td></tr>
|
||||
<tr><td>zindex/z-index2.html</td><td>95.94%</td><td>98.16%</td><td>97.81%</td></tr>
|
||||
<tr><td>zindex/z-index3.html</td><td>98.98%</td><td>98.55%</td><td>98.68%</td></tr>
|
||||
<tr><td>list/decimal-leading-zero.html</td><td>99.63%</td><td>99.72%</td><td>35.88%</td></tr>
|
||||
<tr><td>list/decimal.html</td><td>99.64%</td><td>99.73%</td><td>35.89%</td></tr>
|
||||
<tr><td>list/lower-alpha.html</td><td>99.65%</td><td>99.73%</td><td>35.89%</td></tr>
|
||||
<tr><td>list/upper-roman.html</td><td>99.45%</td><td>99.61%</td><td>35.94%</td></tr>
|
||||
<tr><td>overflow.html</td><td>96.85%</td><td>97.49%</td><td>96.5%</td></tr>
|
||||
<tr><td>text/linethrough.html</td><td>97.14%</td><td>94.12%</td><td>47.08%</td></tr>
|
||||
<tr><td>text/text.html</td><td>95.71%</td><td>94.67%</td><td>85.01%</td></tr>
|
||||
<tr><td>text/underline-lineheight.html</td><td>97.06%</td><td>92.35%</td><td>53%</td></tr>
|
||||
<tr><td>text/underline.html</td><td>97.65%</td><td>93.5%</td><td>47.02%</td></tr>
|
||||
<tr><td>visibility.html</td><td>99.19%</td><td>98.81%</td><td>99.39%</td></tr>
|
||||
<tr><td>zindex/z-index1.html</td><td>96.99%</td><td>99.27%</td><td>99.44%</td></tr>
|
||||
<tr><td>zindex/z-index2.html</td><td>95.85%</td><td>98.06%</td><td>97.72%</td></tr>
|
||||
<tr><td>zindex/z-index3.html</td><td>98.6%</td><td>98.29%</td><td>98.56%</td></tr>
|
||||
</tbody></table>
|
@ -13,7 +13,7 @@ var h2cSelector, h2cOptions;
|
||||
document.write(srcStart + '/tests/assets/jquery.plugin.html2canvas.js' + scrEnd);
|
||||
var html2canvas = ['Core', 'Generate', 'Parse', 'Preload', 'Queue', 'Renderer', 'Util', 'Support', 'Font', 'renderers/Canvas'], i;
|
||||
for (i = 0; i < html2canvas.length; ++i) {
|
||||
document.write(srcStart + '/src/' + html2canvas[i] + '.js' + scrEnd);
|
||||
document.write(srcStart + '/src/' + html2canvas[i] + '.js?' + Math.random() + scrEnd);
|
||||
}
|
||||
window.onload = function() {
|
||||
h2cSelector = [document.body];
|
||||
|
Loading…
Reference in New Issue
Block a user