mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
Calculate correct bounds for text/elements under nested transforms
This commit is contained in:
parent
c5135f4839
commit
aafb0cfb9c
@ -44,20 +44,8 @@ export class Bounds {
|
||||
}
|
||||
}
|
||||
|
||||
export const parseBounds = (node: HTMLElement, isTransformed: boolean): Bounds => {
|
||||
return isTransformed ? offsetBounds(node) : Bounds.fromClientRect(node.getBoundingClientRect());
|
||||
};
|
||||
|
||||
const offsetBounds = (node: HTMLElement): Bounds => {
|
||||
// //$FlowFixMe
|
||||
const parent = node.offsetParent ? offsetBounds(node.offsetParent) : {top: 0, left: 0};
|
||||
|
||||
return new Bounds(
|
||||
node.offsetLeft + parent.left,
|
||||
node.offsetTop + parent.top,
|
||||
node.offsetWidth,
|
||||
node.offsetHeight
|
||||
);
|
||||
export const parseBounds = (node: HTMLElement): Bounds => {
|
||||
return Bounds.fromClientRect(node.getBoundingClientRect());
|
||||
};
|
||||
|
||||
export const calculatePaddingBox = (bounds: Bounds, borders: Array<Border>): Bounds => {
|
||||
|
@ -88,10 +88,15 @@ export default class NodeContainer {
|
||||
zIndex: parseZIndex(style.zIndex)
|
||||
};
|
||||
|
||||
if (this.isTransformed()) {
|
||||
// getBoundingClientRect provides values post-transform, we want them without the transformation
|
||||
node.style.transform = 'matrix(1,0,0,1,0,0)';
|
||||
}
|
||||
|
||||
this.image =
|
||||
// $FlowFixMe
|
||||
node.tagName === 'IMG' ? imageLoader.loadImage(node.currentSrc || node.src) : null;
|
||||
this.bounds = parseBounds(node, this.isTransformed());
|
||||
this.bounds = parseBounds(node);
|
||||
if (__DEV__) {
|
||||
this.name = `${node.tagName.toLowerCase()}${node.id
|
||||
? `#${node.id}`
|
||||
|
@ -35,7 +35,8 @@ const parseNodeTree = (
|
||||
stack: StackingContext,
|
||||
imageLoader: ImageLoader
|
||||
): void => {
|
||||
node.childNodes.forEach((childNode: Node) => {
|
||||
for (let childNode = node.firstChild, nextNode; childNode; childNode = nextNode) {
|
||||
nextNode = childNode.nextSibling;
|
||||
if (childNode.nodeType === Node.TEXT_NODE) {
|
||||
//$FlowFixMe
|
||||
if (childNode.data.trim().length > 0) {
|
||||
@ -72,7 +73,7 @@ const parseNodeTree = (
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const createsRealStackingContext = (container: NodeContainer, node: HTMLElement): boolean => {
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
import {ucs2} from 'punycode';
|
||||
import type TextContainer from './TextContainer';
|
||||
import {Bounds} from './Bounds';
|
||||
import {Bounds, parseBounds} from './Bounds';
|
||||
import {TEXT_DECORATION} from './parsing/textDecoration';
|
||||
|
||||
import FEATURES from './Feature';
|
||||
@ -40,19 +40,32 @@ export const parseTextBounds = (textContainer: TextContainer, node: Text): Array
|
||||
) {
|
||||
if (FEATURES.SUPPORT_RANGE_BOUNDS) {
|
||||
textBounds.push(new TextBounds(text, getRangeBounds(node, offset, text.length)));
|
||||
} else {
|
||||
const replacementNode = node.splitText(text.length);
|
||||
textBounds.push(new TextBounds(text, getWrapperBounds(node)));
|
||||
node = replacementNode;
|
||||
}
|
||||
} else if (!FEATURES.SUPPORT_RANGE_BOUNDS) {
|
||||
node = node.splitText(text.length);
|
||||
}
|
||||
offset += text.length;
|
||||
}
|
||||
return textBounds;
|
||||
};
|
||||
|
||||
/*
|
||||
else if (container.node && typeof container.node.data === 'string') {
|
||||
var replacementNode = container.node.splitText(text.length);
|
||||
var bounds = this.getWrapperBounds(container.node, container.parent.hasTransform());
|
||||
container.node = replacementNode;
|
||||
return bounds;
|
||||
}*/
|
||||
const getWrapperBounds = (node: Text): Bounds => {
|
||||
const wrapper = node.ownerDocument.createElement('html2canvaswrapper');
|
||||
wrapper.appendChild(node.cloneNode(true));
|
||||
const parentNode = node.parentNode;
|
||||
if (parentNode) {
|
||||
parentNode.replaceChild(wrapper, node);
|
||||
const bounds = parseBounds(wrapper);
|
||||
if (wrapper.firstChild) {
|
||||
parentNode.replaceChild(wrapper.firstChild, wrapper);
|
||||
}
|
||||
return bounds;
|
||||
}
|
||||
return new Bounds(0, 0, 0, 0);
|
||||
};
|
||||
|
||||
const getRangeBounds = (node: Text, offset: number, length: number): Bounds => {
|
||||
|
11
src/index.js
11
src/index.js
@ -19,10 +19,7 @@ export type Options = {
|
||||
type: ?string
|
||||
};
|
||||
|
||||
const html2canvas = (
|
||||
element: HTMLElement,
|
||||
config: Options
|
||||
): Promise<HTMLCanvasElement> => {
|
||||
const html2canvas = (element: HTMLElement, config: Options): Promise<HTMLCanvasElement> => {
|
||||
const logger = new Logger();
|
||||
|
||||
const ownerDocument = element.ownerDocument;
|
||||
@ -91,7 +88,11 @@ const html2canvas = (
|
||||
}
|
||||
}
|
||||
|
||||
const renderer = new CanvasRenderer(canvas, {scale: options.scale, backgroundColor, imageStore});
|
||||
const renderer = new CanvasRenderer(canvas, {
|
||||
scale: options.scale,
|
||||
backgroundColor,
|
||||
imageStore
|
||||
});
|
||||
return renderer.render(stack);
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user