I recently found using stage.toDataURL for saving stage content as a image.(KineticJS version 5.0.1)
Custom Shape drawFunc content with core HTML5 canvas object will not applied in image after saving an image.
###################### ImagesPlease see attached image to get better clarity.
1)Original canvas(stage).
https://f.cloud.github.com/assets/1320926/2300781/c8167c30-a107-11e3-9b61-acf94005c252.png
2)Image after saving stage content test1
https://f.cloud.github.com/assets/1320926/2300784/fc5343b6-a107-11e3-8c69-07cccc4d7ac4.png
We see that the vertical string "Sample Text" will not saved or it's invisible whatever it is.
###################### Code1)Here is my code of shape object where line was printed vertically "Sample Text"
var sampleText = new Kinetic.Shape({
drawFunc: function(context) {
var ctx=this.getContext()._context;
ctx.beginPath();
var maxWidth = 2;
var lineHeight = 25;
var x = 415;
var y = 700;
var text = 'Sample Text';
ctx.font = '15pt Calibri';
ctx.fillStyle = 'green';
//Function for vetical text display
wrapText(ctx, text, x, y, maxWidth, lineHeight);
ctx.closePath();
ctx.fill();
ctx.restore();
},
});
//wrapText function if needed
function wrapText(context, text, x, y, maxWidth, lineHeight) {
var words = text.split('');
var line = '';
//alert(context);
for(var n = 0; n < words.length; n++) {
var testLine = line + words[n] + ' ';
var metrics = context.measureText(testLine);
var testWidth = 20;
if (testWidth > maxWidth && n > 0) {
context.fillText(line, x, y);
line = words[n] + ' ';
y += lineHeight;
}
else {
line = testLine;
}
}
context.fillText(line, x, y);
}
2)Stage code for saving an image
stage.toDataURL({
callback: function(dataUrl) {
/*
* here you can do anything you like with the data url.
* In this tutorial we'll just open the url with the browser
* so that you can see the result as an image
*/
$('#theimage').attr('src',dataUrl);
$.ajax({
type: "POST",
url: "save.php",
data: { imageData: dataUrl },
});
}
});
Please advise.
Thanks in advance for your time and consideration.
-Naitik.
You chould not use this.getContext()._context
because _context
is "private" property (starts with undescore). It is not KinetiJS way. Use context
as in an example: http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-shape-tutorial/
Your solution:
var sampleText = new Kinetic.Shape({
drawFunc: function(ctx) {
ctx.beginPath();
var maxWidth = 2;
var lineHeight = 25;
var x = 0;
var y = 0;
var text = 'Sample Text';
ctx.setAttr("font", '15pt Calibri');
ctx.setAttr('fillStyle','green');
//Function for vetical text display
wrapText(ctx, text, x, y, maxWidth, lineHeight);
ctx.closePath();
// KineticJS specific context method
ctx.fillStrokeShape(this);
}
});
function wrapText(context, text, x, y, maxWidth, lineHeight) {
var words = text.split('');
var line = '';
//alert(context);
for(var n = 0; n < words.length; n++) {
var testLine = line + words[n] + ' ';
var metrics = context._context.measureText(testLine);
var testWidth = 20;
if (testWidth > maxWidth && n > 0) {
context.fillText(line, x, y);
line = words[n] + ' ';
y += lineHeight;
}
else {
line = testLine;
}
}
context.fillText(line, x, y);
}
Demo: http://jsbin.com/xolen/1/edit
Note: KineticJS's context has not measureText
method, so you have to use _context
property. I think measureText
method will be added soon.