mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
Use Color objects for colors
This commit is contained in:
parent
068151cc91
commit
15dd95c15c
@ -14,6 +14,6 @@
|
||||
"globals": {
|
||||
"jQuery": true
|
||||
},
|
||||
"predef": ["NodeParser", "NodeContainer", "StackingContext", "TextContainer", "PseudoElementContainer", "ImageLoader", "CanvasRenderer", "Renderer", "Support", "bind", "Promise", "getBounds", "offsetBounds", "XHR",
|
||||
"predef": ["NodeParser", "NodeContainer", "Color", "StackingContext", "TextContainer", "PseudoElementContainer", "ImageLoader", "CanvasRenderer", "Renderer", "Support", "bind", "Promise", "getBounds", "offsetBounds", "XHR",
|
||||
"ImageContainer", "ProxyImageContainer", "DummyImageContainer", "Font", "FontMetrics", "GradientContainer", "LinearGradientContainer", "WebkitGradientContainer", "SVGContainer", "SVGNodeContainer", "FrameContainer", "html2canvas", "log", "smallImage", "parseBackgrounds", "loadUrlDocument", "decode64", "Proxy", "ProxyURL"]
|
||||
}
|
||||
|
153
dist/html2canvas.js
vendored
153
dist/html2canvas.js
vendored
@ -833,6 +833,10 @@ function Color(value) {
|
||||
this.hex3(value);
|
||||
}
|
||||
|
||||
Color.prototype.isTransparent = function() {
|
||||
return this.a === 0;
|
||||
};
|
||||
|
||||
var _hex3 = /^#([a-f0-9]{3})$/i;
|
||||
|
||||
Color.prototype.hex3 = function(value) {
|
||||
@ -883,6 +887,11 @@ Color.prototype.rgba = function(value) {
|
||||
return match !== null;
|
||||
};
|
||||
|
||||
Color.prototype.toString = function() {
|
||||
return this.a !== null ?
|
||||
"rgba(" + [this.r, this.g, this.b, this.a].join(",") + ")" :
|
||||
"rgb(" + [this.r, this.g, this.b].join(",") + ")";
|
||||
};
|
||||
|
||||
Color.prototype.namedColor = function(value) {
|
||||
var color = colors[value.toLowerCase()];
|
||||
@ -890,6 +899,9 @@ Color.prototype.namedColor = function(value) {
|
||||
this.r = color[0];
|
||||
this.g = color[1];
|
||||
this.b = color[2];
|
||||
} else if (value.toLowerCase() === "transparent") {
|
||||
this.r = this.g = this.b = this.a = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
return !!color;
|
||||
@ -1335,30 +1347,30 @@ function LinearGradientContainer(imageData) {
|
||||
if (hasDirection) {
|
||||
imageData.args[0].split(" ").reverse().forEach(function(position) {
|
||||
switch(position) {
|
||||
case "left":
|
||||
this.x0 = 0;
|
||||
this.x1 = 1;
|
||||
break;
|
||||
case "top":
|
||||
this.y0 = 0;
|
||||
this.y1 = 1;
|
||||
break;
|
||||
case "right":
|
||||
this.x0 = 1;
|
||||
this.x1 = 0;
|
||||
break;
|
||||
case "bottom":
|
||||
this.y0 = 1;
|
||||
this.y1 = 0;
|
||||
break;
|
||||
case "to":
|
||||
var y0 = this.y0;
|
||||
var x0 = this.x0;
|
||||
this.y0 = this.y1;
|
||||
this.x0 = this.x1;
|
||||
this.x1 = x0;
|
||||
this.y1 = y0;
|
||||
break;
|
||||
case "left":
|
||||
this.x0 = 0;
|
||||
this.x1 = 1;
|
||||
break;
|
||||
case "top":
|
||||
this.y0 = 0;
|
||||
this.y1 = 1;
|
||||
break;
|
||||
case "right":
|
||||
this.x0 = 1;
|
||||
this.x1 = 0;
|
||||
break;
|
||||
case "bottom":
|
||||
this.y0 = 1;
|
||||
this.y1 = 0;
|
||||
break;
|
||||
case "to":
|
||||
var y0 = this.y0;
|
||||
var x0 = this.x0;
|
||||
this.y0 = this.y1;
|
||||
this.x0 = this.x1;
|
||||
this.x1 = x0;
|
||||
this.y1 = y0;
|
||||
break;
|
||||
}
|
||||
}, this);
|
||||
} else {
|
||||
@ -1369,7 +1381,7 @@ function LinearGradientContainer(imageData) {
|
||||
this.colorStops = imageData.args.slice(hasDirection ? 1 : 0).map(function(colorStop) {
|
||||
var colorStopMatch = colorStop.match(this.stepRegExp);
|
||||
return {
|
||||
color: colorStopMatch[1],
|
||||
color: new Color(colorStopMatch[1]),
|
||||
stop: colorStopMatch[3] === "%" ? colorStopMatch[2] / 100 : null
|
||||
};
|
||||
}, this);
|
||||
@ -1417,6 +1429,7 @@ function NodeContainer(node, parent) {
|
||||
this.offsetBounds = null;
|
||||
this.visible = null;
|
||||
this.computedStyles = null;
|
||||
this.colors = {};
|
||||
this.styles = {};
|
||||
this.backgroundImages = null;
|
||||
this.transformData = null;
|
||||
@ -1484,6 +1497,10 @@ NodeContainer.prototype.cssInt = function(attribute) {
|
||||
return (isNaN(value)) ? 0 : value; // borders in old IE are throwing 'medium' for demo.html
|
||||
};
|
||||
|
||||
NodeContainer.prototype.color = function(attribute) {
|
||||
return this.colors[attribute] || (this.colors[attribute] = new Color(this.css(attribute)));
|
||||
};
|
||||
|
||||
NodeContainer.prototype.cssFloat = function(attribute) {
|
||||
var value = parseFloat(this.css(attribute));
|
||||
return (isNaN(value)) ? 0 : value;
|
||||
@ -1597,7 +1614,7 @@ NodeContainer.prototype.parseTextShadows = function() {
|
||||
for (var i = 0; shadows && (i < shadows.length); i++) {
|
||||
var s = shadows[i].match(this.TEXT_SHADOW_VALUES);
|
||||
results.push({
|
||||
color: s[0],
|
||||
color: new Color(s[0]),
|
||||
offsetX: s[1] ? parseFloat(s[1].replace('px', '')) : 0,
|
||||
offsetY: s[2] ? parseFloat(s[2].replace('px', '')) : 0,
|
||||
blur: s[3] ? s[3].replace('px', '') : 0
|
||||
@ -1817,8 +1834,8 @@ function NodeParser(element, renderer, support, imageLoader, options) {
|
||||
var parent = new NodeContainer(element, null);
|
||||
if (element === element.ownerDocument.documentElement) {
|
||||
// http://www.w3.org/TR/css3-background/#special-backgrounds
|
||||
var canvasBackground = new NodeContainer(this.renderer.isTransparent(parent.css('backgroundColor')) ? element.ownerDocument.body : element.ownerDocument.documentElement, null);
|
||||
renderer.rectangle(0, 0, renderer.width, renderer.height, canvasBackground.css('backgroundColor'));
|
||||
var canvasBackground = new NodeContainer(parent.color('backgroundColor').isTransparent() ? element.ownerDocument.body : element.ownerDocument.documentElement, null);
|
||||
renderer.rectangle(0, 0, renderer.width, renderer.height, canvasBackground.color('backgroundColor'));
|
||||
}
|
||||
parent.visibile = parent.isElementVisible();
|
||||
this.createPseudoHideStyles(element.ownerDocument);
|
||||
@ -2001,7 +2018,7 @@ NodeParser.prototype.createStackingContexts = function() {
|
||||
};
|
||||
|
||||
NodeParser.prototype.isBodyWithTransparentRoot = function(container) {
|
||||
return container.node.nodeName === "BODY" && this.renderer.isTransparent(container.parent.css('backgroundColor'));
|
||||
return container.node.nodeName === "BODY" && container.parent.color('backgroundColor').isTransparent();
|
||||
};
|
||||
|
||||
NodeParser.prototype.isRootElement = function(container) {
|
||||
@ -2161,16 +2178,16 @@ NodeParser.prototype.paintCheckbox = function(container) {
|
||||
var r = [3, 3];
|
||||
var radius = [r, r, r, r];
|
||||
var borders = [1,1,1,1].map(function(w) {
|
||||
return {color: '#A5A5A5', width: w};
|
||||
return {color: new Color('#A5A5A5'), width: w};
|
||||
});
|
||||
|
||||
var borderPoints = calculateCurvePoints(bounds, radius, borders);
|
||||
|
||||
this.renderer.clip(container.backgroundClip, function() {
|
||||
this.renderer.rectangle(bounds.left + 1, bounds.top + 1, bounds.width - 2, bounds.height - 2, "#DEDEDE");
|
||||
this.renderer.rectangle(bounds.left + 1, bounds.top + 1, bounds.width - 2, bounds.height - 2, new Color("#DEDEDE"));
|
||||
this.renderer.renderBorders(calculateBorders(borders, bounds, borderPoints, radius));
|
||||
if (container.node.checked) {
|
||||
this.renderer.font('#424242', 'normal', 'normal', 'bold', (size - 3) + "px", 'arial');
|
||||
this.renderer.font(new Color('#424242'), 'normal', 'normal', 'bold', (size - 3) + "px", 'arial');
|
||||
this.renderer.text("\u2714", bounds.left + size / 6, bounds.top + size - 1);
|
||||
}
|
||||
}, this);
|
||||
@ -2182,9 +2199,9 @@ NodeParser.prototype.paintRadio = function(container) {
|
||||
var size = Math.min(bounds.width, bounds.height) - 2;
|
||||
|
||||
this.renderer.clip(container.backgroundClip, function() {
|
||||
this.renderer.circleStroke(bounds.left + 1, bounds.top + 1, size, '#DEDEDE', 1, '#A5A5A5');
|
||||
this.renderer.circleStroke(bounds.left + 1, bounds.top + 1, size, new Color('#DEDEDE'), 1, new Color('#A5A5A5'));
|
||||
if (container.node.checked) {
|
||||
this.renderer.circle(Math.ceil(bounds.left + size / 4) + 1, Math.ceil(bounds.top + size / 4) + 1, Math.floor(size / 2), '#424242');
|
||||
this.renderer.circle(Math.ceil(bounds.left + size / 4) + 1, Math.ceil(bounds.top + size / 4) + 1, Math.floor(size / 2), new Color('#424242'));
|
||||
}
|
||||
}, this);
|
||||
};
|
||||
@ -2229,7 +2246,7 @@ NodeParser.prototype.paintText = function(container) {
|
||||
var family = container.parent.css('fontFamily');
|
||||
var shadows = container.parent.parseTextShadows();
|
||||
|
||||
this.renderer.font(container.parent.css('color'), container.parent.css('fontStyle'), container.parent.css('fontVariant'), weight, size, family);
|
||||
this.renderer.font(container.parent.color('color'), container.parent.css('fontStyle'), container.parent.css('fontVariant'), weight, size, family);
|
||||
if (shadows.length) {
|
||||
// TODO: support multiple text shadows
|
||||
this.renderer.fontShadow(shadows[0].color, shadows[0].offsetX, shadows[0].offsetY, shadows[0].blur);
|
||||
@ -2252,14 +2269,14 @@ NodeParser.prototype.renderTextDecoration = function(container, bounds, metrics)
|
||||
case "underline":
|
||||
// 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
|
||||
this.renderer.rectangle(bounds.left, Math.round(bounds.top + metrics.baseline + metrics.lineWidth), bounds.width, 1, container.css("color"));
|
||||
this.renderer.rectangle(bounds.left, Math.round(bounds.top + metrics.baseline + metrics.lineWidth), bounds.width, 1, container.color("color"));
|
||||
break;
|
||||
case "overline":
|
||||
this.renderer.rectangle(bounds.left, Math.round(bounds.top), bounds.width, 1, container.css("color"));
|
||||
this.renderer.rectangle(bounds.left, Math.round(bounds.top), bounds.width, 1, container.color("color"));
|
||||
break;
|
||||
case "line-through":
|
||||
// TODO try and find exact position for line-through
|
||||
this.renderer.rectangle(bounds.left, Math.ceil(bounds.top + metrics.middle + metrics.lineWidth), bounds.width, 1, container.css("color"));
|
||||
this.renderer.rectangle(bounds.left, Math.ceil(bounds.top + metrics.middle + metrics.lineWidth), bounds.width, 1, container.color("color"));
|
||||
break;
|
||||
}
|
||||
};
|
||||
@ -2270,7 +2287,7 @@ NodeParser.prototype.parseBorders = function(container) {
|
||||
var borders = ["Top", "Right", "Bottom", "Left"].map(function(side) {
|
||||
return {
|
||||
width: container.cssInt('border' + side + 'Width'),
|
||||
color: container.css('border' + side + 'Color'),
|
||||
color: container.color('border' + side + 'Color'),
|
||||
args: null
|
||||
};
|
||||
});
|
||||
@ -2785,9 +2802,9 @@ Renderer.prototype.renderBackground = function(container, bounds, borderData) {
|
||||
};
|
||||
|
||||
Renderer.prototype.renderBackgroundColor = function(container, bounds) {
|
||||
var color = container.css("backgroundColor");
|
||||
if (!this.isTransparent(color)) {
|
||||
this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, container.css("backgroundColor"));
|
||||
var color = container.color("backgroundColor");
|
||||
if (!color.isTransparent()) {
|
||||
this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, color);
|
||||
}
|
||||
};
|
||||
|
||||
@ -2796,7 +2813,7 @@ Renderer.prototype.renderBorders = function(borders) {
|
||||
};
|
||||
|
||||
Renderer.prototype.renderBorder = function(data) {
|
||||
if (!this.isTransparent(data.color) && data.args !== null) {
|
||||
if (!data.color.isTransparent() && data.args !== null) {
|
||||
this.drawShape(data.args, data.color);
|
||||
}
|
||||
};
|
||||
@ -2805,27 +2822,27 @@ Renderer.prototype.renderBackgroundImage = function(container, bounds, borderDat
|
||||
var backgroundImages = container.parseBackgroundImages();
|
||||
backgroundImages.reverse().forEach(function(backgroundImage, index, arr) {
|
||||
switch(backgroundImage.method) {
|
||||
case "url":
|
||||
var image = this.images.get(backgroundImage.args[0]);
|
||||
if (image) {
|
||||
this.renderBackgroundRepeating(container, bounds, image, arr.length - (index+1), borderData);
|
||||
} else {
|
||||
log("Error loading background-image", backgroundImage.args[0]);
|
||||
}
|
||||
break;
|
||||
case "linear-gradient":
|
||||
case "gradient":
|
||||
var gradientImage = this.images.get(backgroundImage.value);
|
||||
if (gradientImage) {
|
||||
this.renderBackgroundGradient(gradientImage, bounds, borderData);
|
||||
} else {
|
||||
log("Error loading background-image", backgroundImage.args[0]);
|
||||
}
|
||||
break;
|
||||
case "none":
|
||||
break;
|
||||
default:
|
||||
log("Unknown background-image type", backgroundImage.args[0]);
|
||||
case "url":
|
||||
var image = this.images.get(backgroundImage.args[0]);
|
||||
if (image) {
|
||||
this.renderBackgroundRepeating(container, bounds, image, arr.length - (index+1), borderData);
|
||||
} else {
|
||||
log("Error loading background-image", backgroundImage.args[0]);
|
||||
}
|
||||
break;
|
||||
case "linear-gradient":
|
||||
case "gradient":
|
||||
var gradientImage = this.images.get(backgroundImage.value);
|
||||
if (gradientImage) {
|
||||
this.renderBackgroundGradient(gradientImage, bounds, borderData);
|
||||
} else {
|
||||
log("Error loading background-image", backgroundImage.args[0]);
|
||||
}
|
||||
break;
|
||||
case "none":
|
||||
break;
|
||||
default:
|
||||
log("Unknown background-image type", backgroundImage.args[0]);
|
||||
}
|
||||
}, this);
|
||||
};
|
||||
@ -2852,10 +2869,6 @@ Renderer.prototype.renderBackgroundRepeating = function(container, bounds, image
|
||||
}
|
||||
};
|
||||
|
||||
Renderer.prototype.isTransparent = function(color) {
|
||||
return (!color || color === "transparent" || color === "rgba(0, 0, 0, 0)");
|
||||
};
|
||||
|
||||
function StackingContext(hasOwnStacking, opacity, element, parent) {
|
||||
NodeContainer.call(this, element, parent);
|
||||
this.ownStacking = hasOwnStacking;
|
||||
@ -3103,8 +3116,8 @@ function CanvasRenderer(width, height) {
|
||||
|
||||
CanvasRenderer.prototype = Object.create(Renderer.prototype);
|
||||
|
||||
CanvasRenderer.prototype.setFillStyle = function(color) {
|
||||
this.ctx.fillStyle = color;
|
||||
CanvasRenderer.prototype.setFillStyle = function(fillStyle) {
|
||||
this.ctx.fillStyle = fillStyle;
|
||||
return this.ctx;
|
||||
};
|
||||
|
||||
|
4
dist/html2canvas.min.js
vendored
4
dist/html2canvas.min.js
vendored
File diff suppressed because one or more lines are too long
12
src/color.js
12
src/color.js
@ -12,6 +12,10 @@ function Color(value) {
|
||||
this.hex3(value);
|
||||
}
|
||||
|
||||
Color.prototype.isTransparent = function() {
|
||||
return this.a === 0;
|
||||
};
|
||||
|
||||
var _hex3 = /^#([a-f0-9]{3})$/i;
|
||||
|
||||
Color.prototype.hex3 = function(value) {
|
||||
@ -62,6 +66,11 @@ Color.prototype.rgba = function(value) {
|
||||
return match !== null;
|
||||
};
|
||||
|
||||
Color.prototype.toString = function() {
|
||||
return this.a !== null ?
|
||||
"rgba(" + [this.r, this.g, this.b, this.a].join(",") + ")" :
|
||||
"rgb(" + [this.r, this.g, this.b].join(",") + ")";
|
||||
};
|
||||
|
||||
Color.prototype.namedColor = function(value) {
|
||||
var color = colors[value.toLowerCase()];
|
||||
@ -69,6 +78,9 @@ Color.prototype.namedColor = function(value) {
|
||||
this.r = color[0];
|
||||
this.g = color[1];
|
||||
this.b = color[2];
|
||||
} else if (value.toLowerCase() === "transparent") {
|
||||
this.r = this.g = this.b = this.a = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
return !!color;
|
||||
|
@ -7,30 +7,30 @@ function LinearGradientContainer(imageData) {
|
||||
if (hasDirection) {
|
||||
imageData.args[0].split(" ").reverse().forEach(function(position) {
|
||||
switch(position) {
|
||||
case "left":
|
||||
this.x0 = 0;
|
||||
this.x1 = 1;
|
||||
break;
|
||||
case "top":
|
||||
this.y0 = 0;
|
||||
this.y1 = 1;
|
||||
break;
|
||||
case "right":
|
||||
this.x0 = 1;
|
||||
this.x1 = 0;
|
||||
break;
|
||||
case "bottom":
|
||||
this.y0 = 1;
|
||||
this.y1 = 0;
|
||||
break;
|
||||
case "to":
|
||||
var y0 = this.y0;
|
||||
var x0 = this.x0;
|
||||
this.y0 = this.y1;
|
||||
this.x0 = this.x1;
|
||||
this.x1 = x0;
|
||||
this.y1 = y0;
|
||||
break;
|
||||
case "left":
|
||||
this.x0 = 0;
|
||||
this.x1 = 1;
|
||||
break;
|
||||
case "top":
|
||||
this.y0 = 0;
|
||||
this.y1 = 1;
|
||||
break;
|
||||
case "right":
|
||||
this.x0 = 1;
|
||||
this.x1 = 0;
|
||||
break;
|
||||
case "bottom":
|
||||
this.y0 = 1;
|
||||
this.y1 = 0;
|
||||
break;
|
||||
case "to":
|
||||
var y0 = this.y0;
|
||||
var x0 = this.x0;
|
||||
this.y0 = this.y1;
|
||||
this.x0 = this.x1;
|
||||
this.x1 = x0;
|
||||
this.y1 = y0;
|
||||
break;
|
||||
}
|
||||
}, this);
|
||||
} else {
|
||||
@ -41,7 +41,7 @@ function LinearGradientContainer(imageData) {
|
||||
this.colorStops = imageData.args.slice(hasDirection ? 1 : 0).map(function(colorStop) {
|
||||
var colorStopMatch = colorStop.match(this.stepRegExp);
|
||||
return {
|
||||
color: colorStopMatch[1],
|
||||
color: new Color(colorStopMatch[1]),
|
||||
stop: colorStopMatch[3] === "%" ? colorStopMatch[2] / 100 : null
|
||||
};
|
||||
}, this);
|
||||
|
@ -9,6 +9,7 @@ function NodeContainer(node, parent) {
|
||||
this.offsetBounds = null;
|
||||
this.visible = null;
|
||||
this.computedStyles = null;
|
||||
this.colors = {};
|
||||
this.styles = {};
|
||||
this.backgroundImages = null;
|
||||
this.transformData = null;
|
||||
@ -76,6 +77,10 @@ NodeContainer.prototype.cssInt = function(attribute) {
|
||||
return (isNaN(value)) ? 0 : value; // borders in old IE are throwing 'medium' for demo.html
|
||||
};
|
||||
|
||||
NodeContainer.prototype.color = function(attribute) {
|
||||
return this.colors[attribute] || (this.colors[attribute] = new Color(this.css(attribute)));
|
||||
};
|
||||
|
||||
NodeContainer.prototype.cssFloat = function(attribute) {
|
||||
var value = parseFloat(this.css(attribute));
|
||||
return (isNaN(value)) ? 0 : value;
|
||||
@ -189,7 +194,7 @@ NodeContainer.prototype.parseTextShadows = function() {
|
||||
for (var i = 0; shadows && (i < shadows.length); i++) {
|
||||
var s = shadows[i].match(this.TEXT_SHADOW_VALUES);
|
||||
results.push({
|
||||
color: s[0],
|
||||
color: new Color(s[0]),
|
||||
offsetX: s[1] ? parseFloat(s[1].replace('px', '')) : 0,
|
||||
offsetY: s[2] ? parseFloat(s[2].replace('px', '')) : 0,
|
||||
blur: s[3] ? s[3].replace('px', '') : 0
|
||||
|
@ -9,8 +9,8 @@ function NodeParser(element, renderer, support, imageLoader, options) {
|
||||
var parent = new NodeContainer(element, null);
|
||||
if (element === element.ownerDocument.documentElement) {
|
||||
// http://www.w3.org/TR/css3-background/#special-backgrounds
|
||||
var canvasBackground = new NodeContainer(this.renderer.isTransparent(parent.css('backgroundColor')) ? element.ownerDocument.body : element.ownerDocument.documentElement, null);
|
||||
renderer.rectangle(0, 0, renderer.width, renderer.height, canvasBackground.css('backgroundColor'));
|
||||
var canvasBackground = new NodeContainer(parent.color('backgroundColor').isTransparent() ? element.ownerDocument.body : element.ownerDocument.documentElement, null);
|
||||
renderer.rectangle(0, 0, renderer.width, renderer.height, canvasBackground.color('backgroundColor'));
|
||||
}
|
||||
parent.visibile = parent.isElementVisible();
|
||||
this.createPseudoHideStyles(element.ownerDocument);
|
||||
@ -193,7 +193,7 @@ NodeParser.prototype.createStackingContexts = function() {
|
||||
};
|
||||
|
||||
NodeParser.prototype.isBodyWithTransparentRoot = function(container) {
|
||||
return container.node.nodeName === "BODY" && this.renderer.isTransparent(container.parent.css('backgroundColor'));
|
||||
return container.node.nodeName === "BODY" && container.parent.color('backgroundColor').isTransparent();
|
||||
};
|
||||
|
||||
NodeParser.prototype.isRootElement = function(container) {
|
||||
@ -353,16 +353,16 @@ NodeParser.prototype.paintCheckbox = function(container) {
|
||||
var r = [3, 3];
|
||||
var radius = [r, r, r, r];
|
||||
var borders = [1,1,1,1].map(function(w) {
|
||||
return {color: '#A5A5A5', width: w};
|
||||
return {color: new Color('#A5A5A5'), width: w};
|
||||
});
|
||||
|
||||
var borderPoints = calculateCurvePoints(bounds, radius, borders);
|
||||
|
||||
this.renderer.clip(container.backgroundClip, function() {
|
||||
this.renderer.rectangle(bounds.left + 1, bounds.top + 1, bounds.width - 2, bounds.height - 2, "#DEDEDE");
|
||||
this.renderer.rectangle(bounds.left + 1, bounds.top + 1, bounds.width - 2, bounds.height - 2, new Color("#DEDEDE"));
|
||||
this.renderer.renderBorders(calculateBorders(borders, bounds, borderPoints, radius));
|
||||
if (container.node.checked) {
|
||||
this.renderer.font('#424242', 'normal', 'normal', 'bold', (size - 3) + "px", 'arial');
|
||||
this.renderer.font(new Color('#424242'), 'normal', 'normal', 'bold', (size - 3) + "px", 'arial');
|
||||
this.renderer.text("\u2714", bounds.left + size / 6, bounds.top + size - 1);
|
||||
}
|
||||
}, this);
|
||||
@ -374,9 +374,9 @@ NodeParser.prototype.paintRadio = function(container) {
|
||||
var size = Math.min(bounds.width, bounds.height) - 2;
|
||||
|
||||
this.renderer.clip(container.backgroundClip, function() {
|
||||
this.renderer.circleStroke(bounds.left + 1, bounds.top + 1, size, '#DEDEDE', 1, '#A5A5A5');
|
||||
this.renderer.circleStroke(bounds.left + 1, bounds.top + 1, size, new Color('#DEDEDE'), 1, new Color('#A5A5A5'));
|
||||
if (container.node.checked) {
|
||||
this.renderer.circle(Math.ceil(bounds.left + size / 4) + 1, Math.ceil(bounds.top + size / 4) + 1, Math.floor(size / 2), '#424242');
|
||||
this.renderer.circle(Math.ceil(bounds.left + size / 4) + 1, Math.ceil(bounds.top + size / 4) + 1, Math.floor(size / 2), new Color('#424242'));
|
||||
}
|
||||
}, this);
|
||||
};
|
||||
@ -421,7 +421,7 @@ NodeParser.prototype.paintText = function(container) {
|
||||
var family = container.parent.css('fontFamily');
|
||||
var shadows = container.parent.parseTextShadows();
|
||||
|
||||
this.renderer.font(container.parent.css('color'), container.parent.css('fontStyle'), container.parent.css('fontVariant'), weight, size, family);
|
||||
this.renderer.font(container.parent.color('color'), container.parent.css('fontStyle'), container.parent.css('fontVariant'), weight, size, family);
|
||||
if (shadows.length) {
|
||||
// TODO: support multiple text shadows
|
||||
this.renderer.fontShadow(shadows[0].color, shadows[0].offsetX, shadows[0].offsetY, shadows[0].blur);
|
||||
@ -444,14 +444,14 @@ NodeParser.prototype.renderTextDecoration = function(container, bounds, metrics)
|
||||
case "underline":
|
||||
// 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
|
||||
this.renderer.rectangle(bounds.left, Math.round(bounds.top + metrics.baseline + metrics.lineWidth), bounds.width, 1, container.css("color"));
|
||||
this.renderer.rectangle(bounds.left, Math.round(bounds.top + metrics.baseline + metrics.lineWidth), bounds.width, 1, container.color("color"));
|
||||
break;
|
||||
case "overline":
|
||||
this.renderer.rectangle(bounds.left, Math.round(bounds.top), bounds.width, 1, container.css("color"));
|
||||
this.renderer.rectangle(bounds.left, Math.round(bounds.top), bounds.width, 1, container.color("color"));
|
||||
break;
|
||||
case "line-through":
|
||||
// TODO try and find exact position for line-through
|
||||
this.renderer.rectangle(bounds.left, Math.ceil(bounds.top + metrics.middle + metrics.lineWidth), bounds.width, 1, container.css("color"));
|
||||
this.renderer.rectangle(bounds.left, Math.ceil(bounds.top + metrics.middle + metrics.lineWidth), bounds.width, 1, container.color("color"));
|
||||
break;
|
||||
}
|
||||
};
|
||||
@ -462,7 +462,7 @@ NodeParser.prototype.parseBorders = function(container) {
|
||||
var borders = ["Top", "Right", "Bottom", "Left"].map(function(side) {
|
||||
return {
|
||||
width: container.cssInt('border' + side + 'Width'),
|
||||
color: container.css('border' + side + 'Color'),
|
||||
color: container.color('border' + side + 'Color'),
|
||||
args: null
|
||||
};
|
||||
});
|
||||
|
@ -36,9 +36,9 @@ Renderer.prototype.renderBackground = function(container, bounds, borderData) {
|
||||
};
|
||||
|
||||
Renderer.prototype.renderBackgroundColor = function(container, bounds) {
|
||||
var color = container.css("backgroundColor");
|
||||
if (!this.isTransparent(color)) {
|
||||
this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, container.css("backgroundColor"));
|
||||
var color = container.color("backgroundColor");
|
||||
if (!color.isTransparent()) {
|
||||
this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, color);
|
||||
}
|
||||
};
|
||||
|
||||
@ -47,7 +47,7 @@ Renderer.prototype.renderBorders = function(borders) {
|
||||
};
|
||||
|
||||
Renderer.prototype.renderBorder = function(data) {
|
||||
if (!this.isTransparent(data.color) && data.args !== null) {
|
||||
if (!data.color.isTransparent() && data.args !== null) {
|
||||
this.drawShape(data.args, data.color);
|
||||
}
|
||||
};
|
||||
@ -56,27 +56,27 @@ Renderer.prototype.renderBackgroundImage = function(container, bounds, borderDat
|
||||
var backgroundImages = container.parseBackgroundImages();
|
||||
backgroundImages.reverse().forEach(function(backgroundImage, index, arr) {
|
||||
switch(backgroundImage.method) {
|
||||
case "url":
|
||||
var image = this.images.get(backgroundImage.args[0]);
|
||||
if (image) {
|
||||
this.renderBackgroundRepeating(container, bounds, image, arr.length - (index+1), borderData);
|
||||
} else {
|
||||
log("Error loading background-image", backgroundImage.args[0]);
|
||||
}
|
||||
break;
|
||||
case "linear-gradient":
|
||||
case "gradient":
|
||||
var gradientImage = this.images.get(backgroundImage.value);
|
||||
if (gradientImage) {
|
||||
this.renderBackgroundGradient(gradientImage, bounds, borderData);
|
||||
} else {
|
||||
log("Error loading background-image", backgroundImage.args[0]);
|
||||
}
|
||||
break;
|
||||
case "none":
|
||||
break;
|
||||
default:
|
||||
log("Unknown background-image type", backgroundImage.args[0]);
|
||||
case "url":
|
||||
var image = this.images.get(backgroundImage.args[0]);
|
||||
if (image) {
|
||||
this.renderBackgroundRepeating(container, bounds, image, arr.length - (index+1), borderData);
|
||||
} else {
|
||||
log("Error loading background-image", backgroundImage.args[0]);
|
||||
}
|
||||
break;
|
||||
case "linear-gradient":
|
||||
case "gradient":
|
||||
var gradientImage = this.images.get(backgroundImage.value);
|
||||
if (gradientImage) {
|
||||
this.renderBackgroundGradient(gradientImage, bounds, borderData);
|
||||
} else {
|
||||
log("Error loading background-image", backgroundImage.args[0]);
|
||||
}
|
||||
break;
|
||||
case "none":
|
||||
break;
|
||||
default:
|
||||
log("Unknown background-image type", backgroundImage.args[0]);
|
||||
}
|
||||
}, this);
|
||||
};
|
||||
@ -102,7 +102,3 @@ Renderer.prototype.renderBackgroundRepeating = function(container, bounds, image
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
Renderer.prototype.isTransparent = function(color) {
|
||||
return (!color || color === "transparent" || color === "rgba(0, 0, 0, 0)");
|
||||
};
|
||||
|
@ -17,8 +17,8 @@ function CanvasRenderer(width, height) {
|
||||
|
||||
CanvasRenderer.prototype = Object.create(Renderer.prototype);
|
||||
|
||||
CanvasRenderer.prototype.setFillStyle = function(color) {
|
||||
this.ctx.fillStyle = color;
|
||||
CanvasRenderer.prototype.setFillStyle = function(fillStyle) {
|
||||
this.ctx.fillStyle = fillStyle;
|
||||
return this.ctx;
|
||||
};
|
||||
|
||||
|
@ -16,11 +16,13 @@
|
||||
it("bisque", function () {
|
||||
var c = new Color("bisque");
|
||||
assertColor(c, 255, 228, 196, null);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
|
||||
it("BLUE", function () {
|
||||
var c = new Color("BLUE");
|
||||
assertColor(c, 0, 0, 255, null);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
@ -28,33 +30,39 @@
|
||||
it("rgb(1,3,5)", function () {
|
||||
var c = new Color("rgb(1,3,5)");
|
||||
assertColor(c, 1, 3, 5, null);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
|
||||
it("rgb(222, 111, 50)", function () {
|
||||
var c = new Color("rgb(222, 111, 50)");
|
||||
assertColor(c, 222, 111, 50, null);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
|
||||
it("rgb( 222, 111 , 50)", function () {
|
||||
var c = new Color("rgb(222 , 111 , 50)");
|
||||
assertColor(c, 222, 111, 50, null);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("rgba()", function() {
|
||||
it("rgba(200,3,5,0)", function () {
|
||||
var c = new Color("rgba(200,3,5,0)");
|
||||
assertColor(c, 200, 3, 5, 0);
|
||||
it("rgba(200,3,5,1)", function () {
|
||||
var c = new Color("rgba(200,3,5,1)");
|
||||
assertColor(c, 200, 3, 5, 1);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
|
||||
it("rgba(222, 111, 50, 0.22)", function () {
|
||||
var c = new Color("rgba(222, 111, 50, 0.22)");
|
||||
assertColor(c, 222, 111, 50, 0.22);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
|
||||
it("rgba( 222, 111 , 50, 0.123 )", function () {
|
||||
var c = new Color("rgba(222 , 111 , 50, 0.123)");
|
||||
assertColor(c, 222, 111, 50, 0.123);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
@ -62,16 +70,33 @@
|
||||
it("#7FFFD4", function () {
|
||||
var c = new Color("#7FFFD4");
|
||||
assertColor(c, 127, 255, 212, null);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
|
||||
it("#f0ffff", function () {
|
||||
var c = new Color("#f0ffff");
|
||||
assertColor(c, 240, 255, 255, null);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
|
||||
it("#fff", function () {
|
||||
var c = new Color("#fff");
|
||||
assertColor(c, 255, 255, 255, null);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("transparency", function() {
|
||||
it("transparent", function () {
|
||||
var c = new Color("transparent");
|
||||
assertColor(c, 0, 0, 0, 0);
|
||||
expect(c.isTransparent()).to.equal(true);
|
||||
});
|
||||
|
||||
it("rgba(255,255,255,0)", function () {
|
||||
var c = new Color("rgba(255,255,255,0)");
|
||||
assertColor(c, 255, 255, 255, 0);
|
||||
expect(c.isTransparent()).to.equal(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -12,7 +12,7 @@ var h2cSelector, h2cOptions;
|
||||
}
|
||||
|
||||
var sources = ['log', 'punycode/punycode', 'core', 'nodecontainer', 'pseudoelementcontainer', 'stackingcontext', 'textcontainer', 'support', 'imagecontainer', 'dummyimagecontainer', 'proxyimagecontainer', 'gradientcontainer',
|
||||
'lineargradientcontainer', 'webkitgradientcontainer', 'svgcontainer', 'svgnodecontainer', 'imageloader', 'nodeparser', 'font', 'fontmetrics', 'renderer', 'promise', 'xhr', 'framecontainer', 'proxy', 'renderers/canvas'];
|
||||
'lineargradientcontainer', 'webkitgradientcontainer', 'svgcontainer', 'svgnodecontainer', 'imageloader', 'nodeparser', 'font', 'fontmetrics', 'renderer', 'promise', 'xhr', 'framecontainer', 'proxy', 'color', 'renderers/canvas'];
|
||||
|
||||
['/tests/assets/jquery-1.6.2'].concat(window.location.search === "?selenium" ? ['/dist/html2canvas'] : sources.map(function(src) { return '/src/' + src; })).forEach(appendScript);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user