I have two canvas:
· The first one is the canvas I want to export that contains a pattern as a background (filled through js) and some images that the user will put by clicking the canvas.
· The second one is above the first one and is used as a sort of "preview" of the images that will be pasted on the first canvas.
In a nutshell: by mousemoving on the second canvas I see the preview of the image I'll paste, while by clicking (again on the second canvas) I will parse the image on the FIRST canvas.
Ignoring the HTML code which is supposely not the problem, my script is this one:
$(window).ready(function(){
$(document).ready(function(){
$('myCanvas').ready(function(){
canvasObject = new canvasElement ('myCanvas','2d');
canvasObject.initSea();
canvasLayer1 = new canvasElement ('myCanvas2','2d');
$('#myCanvas2').on("click",function(mouseClickEvent){
$(this).off('mousemove');
var position = canvasLayer1.getMouseCoordinates(mouseClickEvent);
canvasObject.parseImage('elements/objects/wooden_turrets.png',(position.x),(position.y));
});
$('#myCanvas2').on("mousemove",function(mouseMoveEvent){
canvasLayer1.reset();
var currentPos = canvasLayer1.getMouseCoordinates(mouseMoveEvent);
canvasLayer1.parseImage('elements/objects/wooden_turrets.png',(currentPos.x),(currentPos.y));
});
$('#render').click(function() {
canvasObject.renderSVG();
});
});
});
});
function canvasElement (id, context){
this.id = id;
this.canvas = document.getElementById(id);
this.context = this.canvas.getContext(context);
}
canvasElement.prototype.parseImage = function (imgurl, x, y) {
tmpContext = this.context;
var imgObject = new Image();
imgObject.onload = function() {
tmpContext.drawImage(imgObject, x, y);
};
imgObject.src = imgurl;
};
canvasElement.prototype.reset = function () {
tmpContext = this.context;
// tmpContext.setTransform(1, 0, 0, 1, 0, 0);
tmpContext.clearRect(0, 0, this.canvas.width, this.canvas.height);
};
canvasElement.prototype.getMouseCoordinates = function (mouseEvent) {
var area = this.canvas.getBoundingClientRect();
return {
x: mouseEvent.clientX - area.left,
y: mouseEvent.clientY - area.top
};
};
canvasElement.prototype.initSea = function () {
var tmpCanvas = this.canvas;
var tmpContext = this.context;
var seaImg = new Image();
seaImg.src = 'elements/land/water.png';
seaImg.onload = function () {
var pattern = tmpContext.createPattern(seaImg,"repeat");
tmpContext.rect(0,0,tmpCanvas.width,tmpCanvas.height);
tmpContext.fillStyle = pattern;
tmpContext.fill();
}
console.log('filling');
};
canvasElement.prototype.renderSVG = function () {
var imgObject = this.canvas.toDataURL("image/png");
window.location = imgObject;
};
Now, everything is fine and is working perfectly, but whenever I'm calling the method renderSVG() which refers to the canvas method toDataURL("image/png");
I get this error:
Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
Now, I've checked a couple of questions similar to mine like:
This: toDataURL throw Uncaught Security exception This: Get security error when saving canvas object into an image
But what I'm not getting is why it is throwing a security error since the images ARE on my domain (in this case locally), not in any other domain.
So the questions are:
1) Why is this happening? shouldn't it be exporting without any issue since the images are located on the same domain as the canvas?
2) I've looked forward thinking that, perhaps, using some libraries such as fabric.js would help me, since I've seen a lot of comfort functions but will the same error occur even using any of them?
3) Is there any way to avoid this issue?
Thanks.