0.5.0 rewrite

This commit is contained in:
MoyuScript
2014-01-19 18:04:27 +02:00
parent 3998fd7658
commit 355bde3655
24 changed files with 1387 additions and 6175 deletions

View File

@@ -1,126 +0,0 @@
_html2canvas.Renderer.Canvas = function(options) {
options = options || {};
var doc = document,
safeImages = [],
testCanvas = document.createElement("canvas"),
testctx = testCanvas.getContext("2d"),
Util = _html2canvas.Util,
canvas = options.canvas || doc.createElement('canvas');
function createShape(ctx, args) {
ctx.beginPath();
args.forEach(function(arg) {
ctx[arg.name].apply(ctx, arg['arguments']);
});
ctx.closePath();
}
function safeImage(item) {
if (safeImages.indexOf(item['arguments'][0].src) === -1) {
testctx.drawImage(item['arguments'][0], 0, 0);
try {
testctx.getImageData(0, 0, 1, 1);
} catch(e) {
testCanvas = doc.createElement("canvas");
testctx = testCanvas.getContext("2d");
return false;
}
safeImages.push(item['arguments'][0].src);
}
return true;
}
function renderItem(ctx, item) {
switch(item.type){
case "variable":
ctx[item.name] = item['arguments'];
break;
case "function":
switch(item.name) {
case "createPattern":
if (item['arguments'][0].width > 0 && item['arguments'][0].height > 0) {
try {
ctx.fillStyle = ctx.createPattern(item['arguments'][0], "repeat");
} catch(e) {
Util.log("html2canvas: Renderer: Error creating pattern", e.message);
}
}
break;
case "drawShape":
createShape(ctx, item['arguments']);
break;
case "drawImage":
if (item['arguments'][8] > 0 && item['arguments'][7] > 0) {
if (!options.taintTest || (options.taintTest && safeImage(item))) {
ctx.drawImage.apply( ctx, item['arguments'] );
}
}
break;
default:
ctx[item.name].apply(ctx, item['arguments']);
}
break;
}
}
return function(parsedData, options, document, queue, _html2canvas) {
var ctx = canvas.getContext("2d"),
newCanvas,
bounds,
fstyle,
zStack = parsedData.stack;
canvas.width = canvas.style.width = options.width || zStack.ctx.width;
canvas.height = canvas.style.height = options.height || zStack.ctx.height;
fstyle = ctx.fillStyle;
ctx.fillStyle = (Util.isTransparent(parsedData.backgroundColor) && options.background !== undefined) ? options.background : parsedData.backgroundColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = fstyle;
queue.forEach(function(storageContext) {
// set common settings for canvas
ctx.textBaseline = "bottom";
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){
ctx.beginPath();
ctx.rect(storageContext.clip.left, storageContext.clip.top, storageContext.clip.width, storageContext.clip.height);
ctx.clip();
}
if (storageContext.ctx.storage) {
storageContext.ctx.storage.forEach(function(item) {
renderItem(ctx, item);
});
}
ctx.restore();
});
Util.log("html2canvas: Renderer: Canvas renderer done - returning canvas obj");
if (options.elements.length === 1) {
if (typeof options.elements[0] === "object" && options.elements[0].nodeName !== "BODY") {
// crop image to the bounds of selected (single) element
bounds = _html2canvas.Util.Bounds(options.elements[0]);
newCanvas = document.createElement('canvas');
newCanvas.width = Math.ceil(bounds.width);
newCanvas.height = Math.ceil(bounds.height);
ctx = newCanvas.getContext("2d");
ctx.drawImage(canvas, bounds.left, bounds.top, bounds.width, bounds.height, 0, 0, bounds.width, bounds.height);
canvas = null;
return newCanvas;
}
}
return canvas;
};
};

View File

@@ -1,206 +0,0 @@
/*
html2canvas @VERSION@ <http://html2canvas.hertzen.com>
Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
http://www.twitter.com/niklasvh
Released under MIT License
*/
// WARNING THIS file is outdated, and hasn't been tested in quite a while
_html2canvas.Renderer.SVG = function( options ) {
options = options || {};
var doc = document,
svgNS = "http://www.w3.org/2000/svg",
svg = doc.createElementNS(svgNS, "svg"),
xlinkNS = "http://www.w3.org/1999/xlink",
defs = doc.createElementNS(svgNS, "defs"),
i,
a,
queueLen,
storageLen,
storageContext,
renderItem,
el,
settings = {},
text,
fontStyle,
clipId = 0,
methods;
methods = {
_create: function( zStack, options, doc, queue, _html2canvas ) {
svg.setAttribute("version", "1.1");
svg.setAttribute("baseProfile", "full");
svg.setAttribute("viewBox", "0 0 " + Math.max(zStack.ctx.width, options.width) + " " + Math.max(zStack.ctx.height, options.height));
svg.setAttribute("width", Math.max(zStack.ctx.width, options.width) + "px");
svg.setAttribute("height", Math.max(zStack.ctx.height, options.height) + "px");
svg.setAttribute("preserveAspectRatio", "none");
svg.appendChild(defs);
for (i = 0, queueLen = queue.length; i < queueLen; i+=1){
storageContext = queue.splice(0, 1)[0];
storageContext.canvasPosition = storageContext.canvasPosition || {};
//this.canvasRenderContext(storageContext,parentctx);
/*
if (storageContext.clip){
ctx.save();
ctx.beginPath();
// console.log(storageContext);
ctx.rect(storageContext.clip.left, storageContext.clip.top, storageContext.clip.width, storageContext.clip.height);
ctx.clip();
}*/
if (storageContext.ctx.storage){
for (a = 0, storageLen = storageContext.ctx.storage.length; a < storageLen; a+=1){
renderItem = storageContext.ctx.storage[a];
switch(renderItem.type){
case "variable":
settings[renderItem.name] = renderItem['arguments'];
break;
case "function":
if (renderItem.name === "fillRect") {
el = doc.createElementNS(svgNS, "rect");
el.setAttribute("x", renderItem['arguments'][0]);
el.setAttribute("y", renderItem['arguments'][1]);
el.setAttribute("width", renderItem['arguments'][2]);
el.setAttribute("height", renderItem['arguments'][3]);
el.setAttribute("fill", settings.fillStyle);
svg.appendChild(el);
} else if(renderItem.name === "fillText") {
el = doc.createElementNS(svgNS, "text");
fontStyle = settings.font.split(" ");
el.style.fontVariant = fontStyle.splice(0, 1)[0];
el.style.fontWeight = fontStyle.splice(0, 1)[0];
el.style.fontStyle = fontStyle.splice(0, 1)[0];
el.style.fontSize = fontStyle.splice(0, 1)[0];
el.setAttribute("x", renderItem['arguments'][1]);
el.setAttribute("y", renderItem['arguments'][2] - (parseInt(el.style.fontSize, 10) + 3));
el.setAttribute("fill", settings.fillStyle);
// TODO get proper baseline
el.style.dominantBaseline = "text-before-edge";
el.style.fontFamily = fontStyle.join(" ");
text = doc.createTextNode(renderItem['arguments'][0]);
el.appendChild(text);
svg.appendChild(el);
} else if(renderItem.name === "drawImage") {
if (renderItem['arguments'][8] > 0 && renderItem['arguments'][7]){
// TODO check whether even any clipping is necessary for this particular image
el = doc.createElementNS(svgNS, "clipPath");
el.setAttribute("id", "clipId" + clipId);
text = doc.createElementNS(svgNS, "rect");
text.setAttribute("x", renderItem['arguments'][5] );
text.setAttribute("y", renderItem['arguments'][6]);
text.setAttribute("width", renderItem['arguments'][3]);
text.setAttribute("height", renderItem['arguments'][4]);
el.appendChild(text);
defs.appendChild(el);
el = doc.createElementNS(svgNS, "image");
el.setAttributeNS(xlinkNS, "xlink:href", renderItem['arguments'][0].src);
el.setAttribute("width", renderItem['arguments'][7]);
el.setAttribute("height", renderItem['arguments'][8]);
el.setAttribute("x", renderItem['arguments'][5]);
el.setAttribute("y", renderItem['arguments'][6]);
el.setAttribute("clip-path", "url(#clipId" + clipId + ")");
// el.setAttribute("xlink:href", );
el.setAttribute("preserveAspectRatio", "none");
svg.appendChild(el);
clipId += 1;
/*
ctx.drawImage(
renderItem['arguments'][0],
renderItem['arguments'][1],
renderItem['arguments'][2],
renderItem['arguments'][3],
renderItem['arguments'][4],
renderItem['arguments'][5],
renderItem['arguments'][6],
renderItem['arguments'][7],
renderItem['arguments'][8]
);
*/
}
}
break;
default:
}
}
}
/*
if (storageContext.clip){
ctx.restore();
}
*/
}
_html2canvas.Util.log("html2canvas: Renderer: SVG Renderer done - returning SVG DOM obj");
return svg;
}
};
return methods;
};

53
src/renderers/canvas.js Normal file
View File

@@ -0,0 +1,53 @@
function CanvasRenderer() {
Renderer.call(this);
this.canvas = document.createElement("canvas");
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
this.ctx = this.canvas.getContext("2d");
this.ctx.textBaseline = "bottom";
document.body.appendChild(this.canvas);
}
CanvasRenderer.prototype = Object.create(Renderer.prototype);
CanvasRenderer.prototype.setFillStyle = function(color) {
this.ctx.fillStyle = color;
return this.ctx;
};
CanvasRenderer.prototype.rectangle = function(left, top, width, height, color) {
this.setFillStyle(color).fillRect(left, top, width, height);
};
CanvasRenderer.prototype.drawShape = function(shape, color) {
this.shape(shape);
this.setFillStyle(color).fill();
};
CanvasRenderer.prototype.clip = function(shape, callback, context) {
this.ctx.save();
this.shape(shape).clip();
callback.call(context);
this.ctx.restore();
};
CanvasRenderer.prototype.shape = function(shape) {
this.ctx.beginPath();
shape.forEach(function(point, index) {
this.ctx[(index === 0) ? "moveTo" : point[0] + "To" ].apply(this.ctx, point.slice(1));
}, this);
this.ctx.closePath();
return this.ctx;
};
CanvasRenderer.prototype.font = function(color, style, variant, weight, size, family) {
this.setFillStyle(color).font = [style, variant, weight, size, family].join(" ");
};
CanvasRenderer.prototype.setOpacity = function(opacity) {
this.ctx.globalAlpha = opacity;
};
CanvasRenderer.prototype.text = function(text, left, bottom) {
this.ctx.fillText(text, left, bottom);
};