mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
Fix text rendering for IE and Opera
This commit is contained in:
parent
18d95d669b
commit
15ca3381eb
@ -13,6 +13,6 @@
|
||||
"globals": {
|
||||
"jQuery": true
|
||||
},
|
||||
"predef": ["NodeParser", "NodeContainer", "StackingContext", "TextContainer", "ImageLoader", "CanvasRenderer", "Renderer", "Support", "bind", "Promise",
|
||||
"predef": ["NodeParser", "NodeContainer", "StackingContext", "TextContainer", "ImageLoader", "CanvasRenderer", "Renderer", "Support", "bind", "Promise", "getBounds", "offsetBounds",
|
||||
"ImageContainer", "ProxyImageContainer", "DummyImageContainer", "Font", "FontMetrics", "GradientContainer", "LinearGradientContainer", "WebkitGradientContainer", "log", "smallImage", "parseBackgrounds"]
|
||||
}
|
||||
|
@ -37,9 +37,9 @@ function renderDocument(document, options, windowWidth, windowHeight) {
|
||||
document.querySelector(selector).removeAttribute(html2canvasNodeAttribute);
|
||||
var clonedWindow = container.contentWindow;
|
||||
var node = clonedWindow.document.querySelector(selector);
|
||||
var support = new Support();
|
||||
var support = new Support(clonedWindow.document);
|
||||
var imageLoader = new ImageLoader(options, support);
|
||||
var bounds = NodeParser.prototype.getBounds(node);
|
||||
var bounds = getBounds(node);
|
||||
var width = options.type === "view" ? Math.min(bounds.width, windowWidth) : documentWidth();
|
||||
var height = options.type === "view" ? Math.min(bounds.height, windowHeight) : documentHeight();
|
||||
var renderer = new CanvasRenderer(width, height, imageLoader);
|
||||
@ -343,6 +343,7 @@ function NodeContainer(node, parent) {
|
||||
this.parent = parent;
|
||||
this.stack = null;
|
||||
this.bounds = null;
|
||||
this.offsetBounds = null;
|
||||
this.visible = null;
|
||||
this.computedStyles = null;
|
||||
this.styles = {};
|
||||
@ -500,19 +501,28 @@ NodeContainer.prototype.parseTextShadows = function() {
|
||||
NodeContainer.prototype.parseTransform = function() {
|
||||
var transformRegExp = /(matrix)\((.+)\)/;
|
||||
var transform = this.prefixedCss("transform");
|
||||
if (transform !== null && transform !== "none") {
|
||||
var matrix = parseMatrix(transform.match(transformRegExp));
|
||||
if (matrix) {
|
||||
return {
|
||||
origin: this.prefixedCss("transformOrigin"),
|
||||
matrix: matrix
|
||||
};
|
||||
}
|
||||
var matrix = parseMatrix(transform.match(transformRegExp));
|
||||
var offset = this.parseBounds();
|
||||
if (matrix) {
|
||||
var origin = this.prefixedCss("transformOrigin").split(" ").map(removePx).map(asFloat);
|
||||
origin[0] += offset.left;
|
||||
origin[1] += offset.top;
|
||||
|
||||
return {
|
||||
origin: origin,
|
||||
matrix: matrix
|
||||
};
|
||||
}
|
||||
return {
|
||||
origin: [0, 0],
|
||||
matrix: [1, 0, 0, 1, 0, 0]
|
||||
};
|
||||
};
|
||||
|
||||
NodeContainer.prototype.parseBounds = function() {
|
||||
return this.bounds || (this.bounds = this.hasTransform() ? offsetBounds(this.node) : getBounds(this.node));
|
||||
};
|
||||
|
||||
|
||||
NodeContainer.prototype.hasTransform = function() {
|
||||
var transform = this.prefixedCss("transform");
|
||||
return (transform !== null && transform !== "none" && transform !== "matrix(1, 0, 0, 1, 0, 0)");
|
||||
};
|
||||
|
||||
NodeContainer.prototype.TEXT_SHADOW_PROPERTY = /((rgba|rgb)\([^\)]+\)(\s-?\d+px){0,})/g;
|
||||
@ -627,6 +637,44 @@ function parseBackgrounds(backgroundImage) {
|
||||
return results;
|
||||
}
|
||||
|
||||
function removePx(str) {
|
||||
return str.replace("px", "");
|
||||
}
|
||||
|
||||
function asFloat(str) {
|
||||
return parseFloat(str);
|
||||
}
|
||||
|
||||
function getBounds(node) {
|
||||
if (node.getBoundingClientRect) {
|
||||
var clientRect = node.getBoundingClientRect();
|
||||
var isBody = node.nodeName === "BODY";
|
||||
var width = isBody ? node.scrollWidth : node.offsetWidth;
|
||||
return {
|
||||
top: clientRect.top,
|
||||
bottom: clientRect.bottom || (clientRect.top + clientRect.height),
|
||||
right: clientRect.left + width,
|
||||
left: clientRect.left,
|
||||
width: width,
|
||||
height: isBody ? node.scrollHeight : node.offsetHeight
|
||||
};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
function offsetBounds(node) {
|
||||
var parent = node.offsetParent ? offsetBounds(node.offsetParent) : {top: 0, left: 0};
|
||||
|
||||
return {
|
||||
top: node.offsetTop + parent.top,
|
||||
bottom: node.offsetTop + node.offsetHeight + parent.top,
|
||||
right: node.offsetLeft + parent.left + node.offsetWidth,
|
||||
left: node.offsetLeft + parent.left,
|
||||
width: node.offsetWidth,
|
||||
height: node.offsetHeight
|
||||
};
|
||||
}
|
||||
|
||||
function NodeParser(element, renderer, support, imageLoader, options) {
|
||||
log("Starting NodeParser");
|
||||
this.renderer = renderer;
|
||||
@ -763,7 +811,7 @@ NodeParser.prototype.newStackingContext = function(container, hasOwnStacking) {
|
||||
|
||||
NodeParser.prototype.createStackingContexts = function() {
|
||||
this.nodes.forEach(function(container) {
|
||||
if (isElement(container) && (this.isRootElement(container) || hasOpacity(container) || isPositionedForStacking(container) || this.isBodyWithTransparentRoot(container) || hasTransform(container))) {
|
||||
if (isElement(container) && (this.isRootElement(container) || hasOpacity(container) || isPositionedForStacking(container) || this.isBodyWithTransparentRoot(container) || container.hasTransform())) {
|
||||
this.newStackingContext(container, true);
|
||||
} else if (isElement(container) && ((isPositioned(container) && zIndex0(container)) || isInlineBlock(container) || isFloating(container))) {
|
||||
this.newStackingContext(container, false);
|
||||
@ -786,55 +834,33 @@ NodeParser.prototype.sortStackingContexts = function(stack) {
|
||||
stack.contexts.forEach(this.sortStackingContexts, this);
|
||||
};
|
||||
|
||||
NodeParser.prototype.parseBounds = function(nodeContainer) {
|
||||
return nodeContainer.bounds = this.getBounds(nodeContainer.node);
|
||||
};
|
||||
|
||||
NodeParser.prototype.getBounds = function(node) {
|
||||
if (node.getBoundingClientRect) {
|
||||
var clientRect = node.getBoundingClientRect();
|
||||
var isBody = node.nodeName === "BODY";
|
||||
var width = isBody ? node.scrollWidth : node.offsetWidth;
|
||||
return {
|
||||
top: clientRect.top,
|
||||
bottom: clientRect.bottom || (clientRect.top + clientRect.height),
|
||||
right: clientRect.left + width,
|
||||
left: clientRect.left,
|
||||
width: width,
|
||||
height: isBody ? node.scrollHeight : node.offsetHeight
|
||||
};
|
||||
}
|
||||
return {};
|
||||
};
|
||||
|
||||
NodeParser.prototype.parseTextBounds = function(container) {
|
||||
return function(text, index, textList) {
|
||||
if (container.parent.css("textDecoration") !== "none" || text.trim().length !== 0) {
|
||||
if (this.support.rangeBounds) {
|
||||
if (container.parent.css("textDecoration").substr(0, 4) !== "none" || text.trim().length !== 0) {
|
||||
if (this.support.rangeBounds && !container.parent.hasTransform()) {
|
||||
var offset = textList.slice(0, index).join("").length;
|
||||
return this.getRangeBounds(container.node, offset, text.length);
|
||||
} else if (container.node && typeof(container.node.data) === "string") {
|
||||
var replacementNode = container.node.splitText(text.length);
|
||||
var bounds = this.getWrapperBounds(container.node);
|
||||
var bounds = this.getWrapperBounds(container.node, container.parent.hasTransform());
|
||||
container.node = replacementNode;
|
||||
return bounds;
|
||||
}
|
||||
} else if (!this.support.rangeBounds) {
|
||||
} else if(!this.support.rangeBounds || container.parent.hasTransform()){
|
||||
container.node = container.node.splitText(text.length);
|
||||
}
|
||||
return {};
|
||||
};
|
||||
};
|
||||
|
||||
NodeParser.prototype.getWrapperBounds = function(node) {
|
||||
var wrapper = node.ownerDocument.createElement('wrapper');
|
||||
NodeParser.prototype.getWrapperBounds = function(node, transform) {
|
||||
var wrapper = node.ownerDocument.createElement('html2canvaswrapper');
|
||||
var parent = node.parentNode,
|
||||
backupText = node.cloneNode(true);
|
||||
|
||||
wrapper.appendChild(node.cloneNode(true));
|
||||
parent.replaceChild(wrapper, node);
|
||||
|
||||
var bounds = this.getBounds(wrapper);
|
||||
var bounds = transform ? offsetBounds(wrapper) : getBounds(wrapper);
|
||||
parent.replaceChild(backupText, wrapper);
|
||||
return bounds;
|
||||
};
|
||||
@ -846,6 +872,8 @@ NodeParser.prototype.getRangeBounds = function(node, offset, length) {
|
||||
return range.getBoundingClientRect();
|
||||
};
|
||||
|
||||
function ClearTransform() {}
|
||||
|
||||
NodeParser.prototype.parse = function(stack) {
|
||||
// http://www.w3.org/TR/CSS21/visuren.html#z-index
|
||||
var negativeZindex = stack.contexts.filter(negativeZIndex); // 2. the child stacking contexts with negative stack levels (most negative first).
|
||||
@ -862,13 +890,16 @@ NodeParser.prototype.parse = function(stack) {
|
||||
this.renderQueue.push(container);
|
||||
if (isStackingContext(container)) {
|
||||
this.parse(container);
|
||||
this.renderQueue.push(new ClearTransform());
|
||||
}
|
||||
}, this);
|
||||
};
|
||||
|
||||
NodeParser.prototype.paint = function(container) {
|
||||
try {
|
||||
if (isTextNode(container)) {
|
||||
if (container instanceof ClearTransform) {
|
||||
this.renderer.ctx.restore();
|
||||
} else if (isTextNode(container)) {
|
||||
this.paintText(container);
|
||||
} else {
|
||||
this.paintNode(container);
|
||||
@ -881,13 +912,12 @@ NodeParser.prototype.paint = function(container) {
|
||||
NodeParser.prototype.paintNode = function(container) {
|
||||
if (isStackingContext(container)) {
|
||||
this.renderer.setOpacity(container.opacity);
|
||||
var transform = container.parseTransform();
|
||||
if (transform) {
|
||||
this.renderer.setTransform(transform);
|
||||
this.renderer.ctx.save();
|
||||
if (container.hasTransform()) {
|
||||
this.renderer.setTransform(container.parseTransform());
|
||||
}
|
||||
}
|
||||
|
||||
var bounds = this.parseBounds(container);
|
||||
var bounds = container.parseBounds();
|
||||
var borderData = this.parseBorders(container);
|
||||
this.renderer.clip(borderData.clip, function() {
|
||||
this.renderer.renderBackground(container, bounds, borderData.borders.map(getWidth));
|
||||
@ -1254,11 +1284,6 @@ function hasOpacity(container) {
|
||||
return container.css("opacity") < 1;
|
||||
}
|
||||
|
||||
function hasTransform(container) {
|
||||
var transform = container.prefixedCss("transform");
|
||||
return transform !== null && transform !== "none";
|
||||
}
|
||||
|
||||
function bind(callback, context) {
|
||||
return function() {
|
||||
return callback.apply(context, arguments);
|
||||
@ -1516,8 +1541,8 @@ CanvasRenderer.prototype.setOpacity = function(opacity) {
|
||||
|
||||
CanvasRenderer.prototype.setTransform = function(transform) {
|
||||
this.ctx.translate(transform.origin[0], transform.origin[1]);
|
||||
this.ctx.setTransform.apply(this.ctx, transform.matrix);
|
||||
this.ctx.translate(transform.origin[0], transform.origin[1]);
|
||||
this.ctx.transform.apply(this.ctx, transform.matrix);
|
||||
this.ctx.translate(-transform.origin[0], -transform.origin[1]);
|
||||
};
|
||||
|
||||
CanvasRenderer.prototype.setVariable = function(property, value) {
|
||||
@ -1588,12 +1613,12 @@ StackingContext.prototype.getParentStack = function(context) {
|
||||
return parentStack ? (parentStack.ownStacking ? parentStack : parentStack.getParentStack(context)) : context.stack;
|
||||
};
|
||||
|
||||
function Support() {
|
||||
this.rangeBounds = this.testRangeBounds();
|
||||
function Support(document) {
|
||||
this.rangeBounds = this.testRangeBounds(document);
|
||||
this.cors = this.testCORS();
|
||||
}
|
||||
|
||||
Support.prototype.testRangeBounds = function() {
|
||||
Support.prototype.testRangeBounds = function(document) {
|
||||
var range, testElement, rangeBounds, rangeHeight, support = false;
|
||||
|
||||
if (document.createRange) {
|
||||
|
4
build/html2canvas.min.js
vendored
4
build/html2canvas.min.js
vendored
File diff suppressed because one or more lines are too long
@ -28,9 +28,9 @@ function renderDocument(document, options, windowWidth, windowHeight) {
|
||||
document.querySelector(selector).removeAttribute(html2canvasNodeAttribute);
|
||||
var clonedWindow = container.contentWindow;
|
||||
var node = clonedWindow.document.querySelector(selector);
|
||||
var support = new Support();
|
||||
var support = new Support(clonedWindow.document);
|
||||
var imageLoader = new ImageLoader(options, support);
|
||||
var bounds = NodeParser.prototype.getBounds(node);
|
||||
var bounds = getBounds(node);
|
||||
var width = options.type === "view" ? Math.min(bounds.width, windowWidth) : documentWidth();
|
||||
var height = options.type === "view" ? Math.min(bounds.height, windowHeight) : documentHeight();
|
||||
var renderer = new CanvasRenderer(width, height, imageLoader);
|
||||
|
@ -3,6 +3,7 @@ function NodeContainer(node, parent) {
|
||||
this.parent = parent;
|
||||
this.stack = null;
|
||||
this.bounds = null;
|
||||
this.offsetBounds = null;
|
||||
this.visible = null;
|
||||
this.computedStyles = null;
|
||||
this.styles = {};
|
||||
@ -160,19 +161,28 @@ NodeContainer.prototype.parseTextShadows = function() {
|
||||
NodeContainer.prototype.parseTransform = function() {
|
||||
var transformRegExp = /(matrix)\((.+)\)/;
|
||||
var transform = this.prefixedCss("transform");
|
||||
if (transform !== null && transform !== "none") {
|
||||
var matrix = parseMatrix(transform.match(transformRegExp));
|
||||
if (matrix) {
|
||||
return {
|
||||
origin: this.prefixedCss("transformOrigin"),
|
||||
matrix: matrix
|
||||
};
|
||||
}
|
||||
var matrix = parseMatrix(transform.match(transformRegExp));
|
||||
var offset = this.parseBounds();
|
||||
if (matrix) {
|
||||
var origin = this.prefixedCss("transformOrigin").split(" ").map(removePx).map(asFloat);
|
||||
origin[0] += offset.left;
|
||||
origin[1] += offset.top;
|
||||
|
||||
return {
|
||||
origin: origin,
|
||||
matrix: matrix
|
||||
};
|
||||
}
|
||||
return {
|
||||
origin: [0, 0],
|
||||
matrix: [1, 0, 0, 1, 0, 0]
|
||||
};
|
||||
};
|
||||
|
||||
NodeContainer.prototype.parseBounds = function() {
|
||||
return this.bounds || (this.bounds = this.hasTransform() ? offsetBounds(this.node) : getBounds(this.node));
|
||||
};
|
||||
|
||||
|
||||
NodeContainer.prototype.hasTransform = function() {
|
||||
var transform = this.prefixedCss("transform");
|
||||
return (transform !== null && transform !== "none" && transform !== "matrix(1, 0, 0, 1, 0, 0)");
|
||||
};
|
||||
|
||||
NodeContainer.prototype.TEXT_SHADOW_PROPERTY = /((rgba|rgb)\([^\)]+\)(\s-?\d+px){0,})/g;
|
||||
@ -286,3 +296,41 @@ function parseBackgrounds(backgroundImage) {
|
||||
appendResult();
|
||||
return results;
|
||||
}
|
||||
|
||||
function removePx(str) {
|
||||
return str.replace("px", "");
|
||||
}
|
||||
|
||||
function asFloat(str) {
|
||||
return parseFloat(str);
|
||||
}
|
||||
|
||||
function getBounds(node) {
|
||||
if (node.getBoundingClientRect) {
|
||||
var clientRect = node.getBoundingClientRect();
|
||||
var isBody = node.nodeName === "BODY";
|
||||
var width = isBody ? node.scrollWidth : node.offsetWidth;
|
||||
return {
|
||||
top: clientRect.top,
|
||||
bottom: clientRect.bottom || (clientRect.top + clientRect.height),
|
||||
right: clientRect.left + width,
|
||||
left: clientRect.left,
|
||||
width: width,
|
||||
height: isBody ? node.scrollHeight : node.offsetHeight
|
||||
};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
function offsetBounds(node) {
|
||||
var parent = node.offsetParent ? offsetBounds(node.offsetParent) : {top: 0, left: 0};
|
||||
|
||||
return {
|
||||
top: node.offsetTop + parent.top,
|
||||
bottom: node.offsetTop + node.offsetHeight + parent.top,
|
||||
right: node.offsetLeft + parent.left + node.offsetWidth,
|
||||
left: node.offsetLeft + parent.left,
|
||||
width: node.offsetWidth,
|
||||
height: node.offsetHeight
|
||||
};
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ NodeParser.prototype.newStackingContext = function(container, hasOwnStacking) {
|
||||
|
||||
NodeParser.prototype.createStackingContexts = function() {
|
||||
this.nodes.forEach(function(container) {
|
||||
if (isElement(container) && (this.isRootElement(container) || hasOpacity(container) || isPositionedForStacking(container) || this.isBodyWithTransparentRoot(container) || hasTransform(container))) {
|
||||
if (isElement(container) && (this.isRootElement(container) || hasOpacity(container) || isPositionedForStacking(container) || this.isBodyWithTransparentRoot(container) || container.hasTransform())) {
|
||||
this.newStackingContext(container, true);
|
||||
} else if (isElement(container) && ((isPositioned(container) && zIndex0(container)) || isInlineBlock(container) || isFloating(container))) {
|
||||
this.newStackingContext(container, false);
|
||||
@ -157,55 +157,33 @@ NodeParser.prototype.sortStackingContexts = function(stack) {
|
||||
stack.contexts.forEach(this.sortStackingContexts, this);
|
||||
};
|
||||
|
||||
NodeParser.prototype.parseBounds = function(nodeContainer) {
|
||||
return nodeContainer.bounds = this.getBounds(nodeContainer.node);
|
||||
};
|
||||
|
||||
NodeParser.prototype.getBounds = function(node) {
|
||||
if (node.getBoundingClientRect) {
|
||||
var clientRect = node.getBoundingClientRect();
|
||||
var isBody = node.nodeName === "BODY";
|
||||
var width = isBody ? node.scrollWidth : node.offsetWidth;
|
||||
return {
|
||||
top: clientRect.top,
|
||||
bottom: clientRect.bottom || (clientRect.top + clientRect.height),
|
||||
right: clientRect.left + width,
|
||||
left: clientRect.left,
|
||||
width: width,
|
||||
height: isBody ? node.scrollHeight : node.offsetHeight
|
||||
};
|
||||
}
|
||||
return {};
|
||||
};
|
||||
|
||||
NodeParser.prototype.parseTextBounds = function(container) {
|
||||
return function(text, index, textList) {
|
||||
if (container.parent.css("textDecoration") !== "none" || text.trim().length !== 0) {
|
||||
if (this.support.rangeBounds) {
|
||||
if (container.parent.css("textDecoration").substr(0, 4) !== "none" || text.trim().length !== 0) {
|
||||
if (this.support.rangeBounds && !container.parent.hasTransform()) {
|
||||
var offset = textList.slice(0, index).join("").length;
|
||||
return this.getRangeBounds(container.node, offset, text.length);
|
||||
} else if (container.node && typeof(container.node.data) === "string") {
|
||||
var replacementNode = container.node.splitText(text.length);
|
||||
var bounds = this.getWrapperBounds(container.node);
|
||||
var bounds = this.getWrapperBounds(container.node, container.parent.hasTransform());
|
||||
container.node = replacementNode;
|
||||
return bounds;
|
||||
}
|
||||
} else if (!this.support.rangeBounds) {
|
||||
} else if(!this.support.rangeBounds || container.parent.hasTransform()){
|
||||
container.node = container.node.splitText(text.length);
|
||||
}
|
||||
return {};
|
||||
};
|
||||
};
|
||||
|
||||
NodeParser.prototype.getWrapperBounds = function(node) {
|
||||
var wrapper = node.ownerDocument.createElement('wrapper');
|
||||
NodeParser.prototype.getWrapperBounds = function(node, transform) {
|
||||
var wrapper = node.ownerDocument.createElement('html2canvaswrapper');
|
||||
var parent = node.parentNode,
|
||||
backupText = node.cloneNode(true);
|
||||
|
||||
wrapper.appendChild(node.cloneNode(true));
|
||||
parent.replaceChild(wrapper, node);
|
||||
|
||||
var bounds = this.getBounds(wrapper);
|
||||
var bounds = transform ? offsetBounds(wrapper) : getBounds(wrapper);
|
||||
parent.replaceChild(backupText, wrapper);
|
||||
return bounds;
|
||||
};
|
||||
@ -217,6 +195,8 @@ NodeParser.prototype.getRangeBounds = function(node, offset, length) {
|
||||
return range.getBoundingClientRect();
|
||||
};
|
||||
|
||||
function ClearTransform() {}
|
||||
|
||||
NodeParser.prototype.parse = function(stack) {
|
||||
// http://www.w3.org/TR/CSS21/visuren.html#z-index
|
||||
var negativeZindex = stack.contexts.filter(negativeZIndex); // 2. the child stacking contexts with negative stack levels (most negative first).
|
||||
@ -233,13 +213,16 @@ NodeParser.prototype.parse = function(stack) {
|
||||
this.renderQueue.push(container);
|
||||
if (isStackingContext(container)) {
|
||||
this.parse(container);
|
||||
this.renderQueue.push(new ClearTransform());
|
||||
}
|
||||
}, this);
|
||||
};
|
||||
|
||||
NodeParser.prototype.paint = function(container) {
|
||||
try {
|
||||
if (isTextNode(container)) {
|
||||
if (container instanceof ClearTransform) {
|
||||
this.renderer.ctx.restore();
|
||||
} else if (isTextNode(container)) {
|
||||
this.paintText(container);
|
||||
} else {
|
||||
this.paintNode(container);
|
||||
@ -252,13 +235,12 @@ NodeParser.prototype.paint = function(container) {
|
||||
NodeParser.prototype.paintNode = function(container) {
|
||||
if (isStackingContext(container)) {
|
||||
this.renderer.setOpacity(container.opacity);
|
||||
var transform = container.parseTransform();
|
||||
if (transform) {
|
||||
this.renderer.setTransform(transform);
|
||||
this.renderer.ctx.save();
|
||||
if (container.hasTransform()) {
|
||||
this.renderer.setTransform(container.parseTransform());
|
||||
}
|
||||
}
|
||||
|
||||
var bounds = this.parseBounds(container);
|
||||
var bounds = container.parseBounds();
|
||||
var borderData = this.parseBorders(container);
|
||||
this.renderer.clip(borderData.clip, function() {
|
||||
this.renderer.renderBackground(container, bounds, borderData.borders.map(getWidth));
|
||||
@ -625,11 +607,6 @@ function hasOpacity(container) {
|
||||
return container.css("opacity") < 1;
|
||||
}
|
||||
|
||||
function hasTransform(container) {
|
||||
var transform = container.prefixedCss("transform");
|
||||
return transform !== null && transform !== "none";
|
||||
}
|
||||
|
||||
function bind(callback, context) {
|
||||
return function() {
|
||||
return callback.apply(context, arguments);
|
||||
|
@ -66,8 +66,8 @@ CanvasRenderer.prototype.setOpacity = function(opacity) {
|
||||
|
||||
CanvasRenderer.prototype.setTransform = function(transform) {
|
||||
this.ctx.translate(transform.origin[0], transform.origin[1]);
|
||||
this.ctx.setTransform.apply(this.ctx, transform.matrix);
|
||||
this.ctx.translate(transform.origin[0], transform.origin[1]);
|
||||
this.ctx.transform.apply(this.ctx, transform.matrix);
|
||||
this.ctx.translate(-transform.origin[0], -transform.origin[1]);
|
||||
};
|
||||
|
||||
CanvasRenderer.prototype.setVariable = function(property, value) {
|
||||
|
@ -1,9 +1,9 @@
|
||||
function Support() {
|
||||
this.rangeBounds = this.testRangeBounds();
|
||||
function Support(document) {
|
||||
this.rangeBounds = this.testRangeBounds(document);
|
||||
this.cors = this.testCORS();
|
||||
}
|
||||
|
||||
Support.prototype.testRangeBounds = function() {
|
||||
Support.prototype.testRangeBounds = function(document) {
|
||||
var range, testElement, rangeBounds, rangeHeight, support = false;
|
||||
|
||||
if (document.createRange) {
|
||||
|
@ -10,7 +10,7 @@
|
||||
margin-top: 100px;
|
||||
}
|
||||
#second {
|
||||
border: 10px solid red;
|
||||
border: 15px solid red;
|
||||
background: darkseagreen;
|
||||
-webkit-transform: rotate(7.5deg); /* Chrome, Safari 3.1+ */
|
||||
-moz-transform: rotate(7.5deg); /* Firefox 3.5-15 */
|
||||
@ -27,14 +27,19 @@
|
||||
transform: rotate(-70.5deg); /* Firefox 16+, IE 10+, Opera 12.10+ */
|
||||
|
||||
}
|
||||
#fourth {
|
||||
background: #bc8f8f;
|
||||
}
|
||||
|
||||
div {
|
||||
display: inline-block;
|
||||
padding: 10px;
|
||||
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="first">First level content <div id="second">with second level content <div id="third">and third level content</div>, ending second</div>, ending first</div>
|
||||
<div id="fourth">something else</div>
|
||||
</body>
|
||||
</html>
|
||||
|
45
tests/cases/transform/translate.html
Normal file
45
tests/cases/transform/translate.html
Normal file
@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Nested transform tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style>
|
||||
#first {
|
||||
background: indianred;
|
||||
margin-top: 100px;
|
||||
}
|
||||
#second {
|
||||
border: 10px solid red;
|
||||
background: darkseagreen;
|
||||
-webkit-transform: translate(125px); /* Chrome, Safari 3.1+ */
|
||||
-moz-transform: translate(125px); /* Firefox 3.5-15 */
|
||||
-ms-transform: translate(125px); /* IE 9 */
|
||||
-o-transform: translate(125px); /* Opera 10.50-12.00 */
|
||||
transform: translate(125px);
|
||||
}
|
||||
#third {
|
||||
background: cadetblue;
|
||||
-webkit-transform: translate(-100px, -25px); /* Chrome, Safari 3.1+ */
|
||||
-moz-transform: translate(100px, -25px); /* Firefox 3.5-15 */
|
||||
-ms-transform: translate(100px, -25px); /* IE 9 */
|
||||
-o-transform: translate(100px, -25px); /* Opera 10.50-12.00 */
|
||||
transform: translate(100px, -25px);
|
||||
-webkit-transform-origin: 100px 50px;
|
||||
-moz-transform-origin: 100px 50px;
|
||||
-ms-transform-origin: 100px 50px;
|
||||
-o-transform-origin: 100px 50px;
|
||||
transform-origin: 100px 50px;
|
||||
|
||||
}
|
||||
div {
|
||||
display: inline-block;
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="first">First level content <div id="second">with second level content <div id="third">and third level content</div>, ending second</div>, ending first</div>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user