mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
first implementation for matrix transforms
This commit is contained in:
parent
518dd702a2
commit
10b40821e5
18
src/Core.js
18
src/Core.js
@ -166,6 +166,20 @@ _html2canvas.Util.Bounds = function (element) {
|
||||
return bounds;
|
||||
};
|
||||
|
||||
// TODO ideally, we'd want everything to go through this function instead of Util.Bounds,
|
||||
// but would require further work to calculate the correct positions for elements with offsetParents
|
||||
_html2canvas.Util.OffsetBounds = function (element) {
|
||||
var parent = element.offsetParent ? _html2canvas.Util.OffsetBounds(element.offsetParent) : {top: 0, left: 0};
|
||||
|
||||
return {
|
||||
top: element.offsetTop + parent.top,
|
||||
bottom: element.offsetTop + element.offsetHeight + parent.top,
|
||||
left: element.offsetLeft + parent.left,
|
||||
width: element.offsetWidth,
|
||||
height: element.offsetHeight
|
||||
};
|
||||
};
|
||||
|
||||
function toPX(element, attribute, value ) {
|
||||
var rsLeft = element.runtimeStyle && element.runtimeStyle[attribute],
|
||||
left,
|
||||
@ -295,14 +309,13 @@ function backgroundBoundsFactory( prop, el, bounds, image, imageIndex, backgroun
|
||||
if(prop !== 'backgroundSize') {
|
||||
left -= (backgroundSize || image).width*percentage;
|
||||
}
|
||||
|
||||
} else {
|
||||
if(prop === 'backgroundSize') {
|
||||
if(bgposition[0] === 'auto') {
|
||||
left = image.width;
|
||||
} else {
|
||||
if (/contain|cover/.test(bgposition[0])) {
|
||||
var resized = _html2canvas.Util.resizeBounds( image.width, image.height, bounds.width, bounds.height, bgposition[0] );
|
||||
var resized = _html2canvas.Util.resizeBounds(image.width, image.height, bounds.width, bounds.height, bgposition[0]);
|
||||
left = resized.width;
|
||||
topPos = resized.height;
|
||||
} else {
|
||||
@ -335,6 +348,7 @@ _html2canvas.Util.BackgroundPosition = function( el, bounds, image, imageIndex,
|
||||
var result = backgroundBoundsFactory( 'backgroundPosition', el, bounds, image, imageIndex, backgroundSize );
|
||||
return { left: result[0], top: result[1] };
|
||||
};
|
||||
|
||||
_html2canvas.Util.BackgroundSize = function( el, bounds, image, imageIndex ) {
|
||||
var result = backgroundBoundsFactory( 'backgroundSize', el, bounds, image, imageIndex );
|
||||
return { width: result[0], height: result[1] };
|
||||
|
59
src/Parse.js
59
src/Parse.js
@ -48,16 +48,18 @@ _html2canvas.Parse = function (images, options) {
|
||||
}
|
||||
}
|
||||
|
||||
function capitalize(m, p1, p2) {
|
||||
if (m.length > 0) {
|
||||
return p1 + p2.toUpperCase();
|
||||
}
|
||||
}
|
||||
|
||||
function textTransform (text, transform) {
|
||||
switch(transform){
|
||||
case "lowercase":
|
||||
return text.toLowerCase();
|
||||
case "capitalize":
|
||||
return text.replace( /(^|\s|:|-|\(|\))([a-z])/g , function (m, p1, p2) {
|
||||
if (m.length > 0) {
|
||||
return p1 + p2.toUpperCase();
|
||||
}
|
||||
} );
|
||||
return text.replace( /(^|\s|:|-|\(|\))([a-z])/g, capitalize);
|
||||
case "uppercase":
|
||||
return text.toUpperCase();
|
||||
default:
|
||||
@ -127,16 +129,16 @@ _html2canvas.Parse = function (images, options) {
|
||||
}
|
||||
}
|
||||
|
||||
function getTextBounds(state, text, textDecoration, isLast) {
|
||||
function getTextBounds(state, text, textDecoration, isLast, transform) {
|
||||
var bounds;
|
||||
if (support.rangeBounds) {
|
||||
if (support.rangeBounds && !transform) {
|
||||
if (textDecoration !== "none" || Util.trimText(text).length !== 0) {
|
||||
bounds = textRangeBounds(text, state.node, state.textOffset);
|
||||
}
|
||||
state.textOffset += text.length;
|
||||
} else if (state.node && typeof state.node.nodeValue === "string" ){
|
||||
var newTextNode = (isLast) ? state.node.splitText(text.length) : null;
|
||||
bounds = textWrapperBounds(state.node);
|
||||
bounds = textWrapperBounds(state.node, transform);
|
||||
state.node = newTextNode;
|
||||
}
|
||||
return bounds;
|
||||
@ -149,7 +151,7 @@ _html2canvas.Parse = function (images, options) {
|
||||
return range.getBoundingClientRect();
|
||||
}
|
||||
|
||||
function textWrapperBounds(oldTextNode) {
|
||||
function textWrapperBounds(oldTextNode, transform) {
|
||||
var parent = oldTextNode.parentNode,
|
||||
wrapElement = doc.createElement('wrapper'),
|
||||
backupText = oldTextNode.cloneNode(true);
|
||||
@ -157,7 +159,7 @@ _html2canvas.Parse = function (images, options) {
|
||||
wrapElement.appendChild(oldTextNode.cloneNode(true));
|
||||
parent.replaceChild(wrapElement, oldTextNode);
|
||||
|
||||
var bounds = Util.Bounds(wrapElement);
|
||||
var bounds = transform ? Util.OffsetBounds(wrapElement) : Util.Bounds(wrapElement);
|
||||
parent.replaceChild(backupText, wrapElement);
|
||||
return bounds;
|
||||
}
|
||||
@ -195,7 +197,7 @@ _html2canvas.Parse = function (images, options) {
|
||||
}
|
||||
|
||||
textList.forEach(function(text, index) {
|
||||
var bounds = getTextBounds(state, text, textDecoration, (index < textList.length - 1));
|
||||
var bounds = getTextBounds(state, text, textDecoration, (index < textList.length - 1), stack.transform.matrix);
|
||||
if (bounds) {
|
||||
drawText(text, bounds.left, bounds.bottom, ctx);
|
||||
renderTextDecoration(ctx, textDecoration, bounds, metrics, color);
|
||||
@ -947,14 +949,21 @@ _html2canvas.Parse = function (images, options) {
|
||||
return ctx.setVariable("globalAlpha", getCSS(element, "opacity") * ((parentStack) ? parentStack.opacity : 1));
|
||||
}
|
||||
|
||||
function setTransform(ctx, element, parentStack) {
|
||||
function removePx(str) {
|
||||
return str.replace("px", "");
|
||||
}
|
||||
|
||||
var transformRegExp = /(matrix)\((.+)\)/;
|
||||
|
||||
function getTransform(element, parentStack) {
|
||||
var transform = getCSS(element, "transform") || getCSS(element, "-webkit-transform") || getCSS(element, "-moz-transform") || getCSS(element, "-ms-transform") || getCSS(element, "-o-transform");
|
||||
var transformOrigin = getCSS(element, "transform-origin") || getCSS(element, "-webkit-transform-origin") || getCSS(element, "-moz-transform-origin") || getCSS(element, "-ms-transform-origin") || getCSS(element, "-o-transform-origin");
|
||||
var transformOrigin = getCSS(element, "transform-origin") || getCSS(element, "-webkit-transform-origin") || getCSS(element, "-moz-transform-origin") || getCSS(element, "-ms-transform-origin") || getCSS(element, "-o-transform-origin") || "0px 0px";
|
||||
|
||||
transformOrigin = transformOrigin.split(" ").map(removePx).map(Util.asFloat);
|
||||
|
||||
var matrix;
|
||||
var TRANSFORM_REGEXP = /(matrix)\((.+)\)/;
|
||||
if (transform && transform !== "none") {
|
||||
var match = transform.match(TRANSFORM_REGEXP);
|
||||
var match = transform.match(transformRegExp);
|
||||
if (match) {
|
||||
switch(match[1]) {
|
||||
case "matrix":
|
||||
@ -970,14 +979,14 @@ _html2canvas.Parse = function (images, options) {
|
||||
};
|
||||
}
|
||||
|
||||
function createStack(element, parentStack, bounds) {
|
||||
function createStack(element, parentStack, bounds, transform) {
|
||||
var ctx = h2cRenderContext((!parentStack) ? documentWidth() : bounds.width , (!parentStack) ? documentHeight() : bounds.height),
|
||||
stack = {
|
||||
ctx: ctx,
|
||||
opacity: setOpacity(ctx, element, parentStack),
|
||||
cssPosition: getCSS(element, "position"),
|
||||
borders: getBorderData(element),
|
||||
transform: setTransform(ctx, element, parentStack),
|
||||
transform: transform,
|
||||
clip: (parentStack && parentStack.clip) ? Util.Extend( {}, parentStack.clip ) : null
|
||||
};
|
||||
|
||||
@ -1006,16 +1015,26 @@ _html2canvas.Parse = function (images, options) {
|
||||
return backgroundBounds;
|
||||
}
|
||||
|
||||
function renderElement(element, parentStack, pseudoElement){
|
||||
var bounds = Util.Bounds(element),
|
||||
function getBounds(element, transform) {
|
||||
var bounds = (transform.matrix) ? Util.OffsetBounds(element) : Util.Bounds(element);
|
||||
transform.origin[0] += bounds.left;
|
||||
transform.origin[1] += bounds.top;
|
||||
return bounds;
|
||||
}
|
||||
|
||||
function renderElement(element, parentStack, pseudoElement) {
|
||||
var transform = getTransform(element, parentStack),
|
||||
bounds = getBounds(element, transform),
|
||||
image,
|
||||
bgcolor = (ignoreElementsRegExp.test(element.nodeName)) ? "#efefef" : getCSS(element, "backgroundColor"),
|
||||
stack = createStack(element, parentStack, bounds),
|
||||
stack = createStack(element, parentStack, bounds, transform),
|
||||
borders = stack.borders,
|
||||
ctx = stack.ctx,
|
||||
backgroundBounds = getBackgroundBounds(borders, bounds, stack.clip),
|
||||
borderData = parseBorders(element, bounds, borders);
|
||||
|
||||
|
||||
|
||||
createShape(ctx, borderData.clip);
|
||||
|
||||
ctx.save();
|
||||
|
@ -85,7 +85,9 @@ _html2canvas.Renderer.Canvas = function(options) {
|
||||
ctx.save();
|
||||
|
||||
if (storageContext.transform.matrix) {
|
||||
ctx.translate(storageContext.transform.origin[0], storageContext.transform.origin[1]);
|
||||
ctx.transform.apply(ctx, storageContext.transform.matrix);
|
||||
ctx.translate(-storageContext.transform.origin[0], -storageContext.transform.origin[1]);
|
||||
}
|
||||
|
||||
if (storageContext.clip){
|
||||
|
Loading…
Reference in New Issue
Block a user