Image fallback in canvas with Raphael - javascript

I have to draw some images (using a for cycle) and I want to load a fallback image if it can't find the right image.
My javascript:
var image = paper_layer.image(image_selected, x, y, width, height);
$('image').one('error', function () {
console.log('image not found')
image_selected='/my_path/not_found.png'
var image = paper_layer.image(image_selected, x, y, width, height);
});
The problem is that when miss an image this function add an fallback image for each image, even the ones found.
I tried this too but it doesn't works (no fallback appears, the message 'image not found' don't appear on console):
var image = paper_layer.image(image_selected, x, y, width, height);
image.onerror=function () {
console.log('image not found')
image_selected='/my_path/not_found.png'
var image = paper_layer.image(image_selected, x, y, width, height);
};
PS: I'm using Raphael

paper_layer.image does not return an HTMLImageElement object, but some sort of Raphael object.
That however seems to contain the reference to the actual image element under the key 0 - so try image[0].onerror=..., that should correctly bind the error handler to the actual HTML image element.

Related

Cannot export Canvas to PDF

I'm trying to print a canvas in a PDF file that I'm creating. The issue is that I always get a black rectangle in my PDF instead of the graph that I can see on my web page.
I generate the canvas like this:
<div class="col-md-6 featurePanel" style="display: none;">
<div id="canvasContainer_#featureID"></div>
</div>
It's filled by JS:
function SetFeatureValues(measID, measIndex, measCount, featureID, canvasID, name, humL, humR, femL, femR, thor, lumb, reference, type, color, ResTable) {
if (ResTable.length == measCount) {
var element = document.createElement("canvas");
element.id = canvasID;
element.classList.add("ThreeDDogGraph");
document.getElementById('canvasContainer_' + featureID).appendChild(element);
_3ddogvis.scene(0.0, true, ResTable, canvasID);
}
}
Then I export it to a PDF file:
function RenderFeature(pdf, currentTopPosition, currentLeftPasition, canvas) {
var newCanvas = document.createElement('canvas');
let context = newCanvas.getContext('2d');
newCanvas.width = width;
newCanvas.height = height;
context.drawImage(document.querySelector('#' + canvas.id), 0, 0, width, height);
var newCanvasImg = newCanvas.toDataURL("image/png");
pdf.addImage(newCanvasImg, 'png', currentLeftPasition, currentTopPosition, graphWidth, graphHeight, undefined, 'FAST');
}
After downloading the file I get a black rectangle in my PDF with the dimensions of my canvas.
EDIT:
If I try to copy the canvas (as propose obscure) I also get a black picture and the error message:
Unable to clone WebGL context as it has preserveDrawingBuffer=false
As I use a library done by someone else, I cannot set the preserveDrawingBuffer to true.
Is there a solution to get a picture from a canvas with preserveDrawingBuffer set to false?

html2canvas option type: 'view' still render full body

I would like to get only viewport screenshot from the library html2canvas.js, set option type to 'view' should do the trick but i'm still getting the entire body.
Don't really get why this is not working actually.
Here is the code i'm currently running:
html2canvas(document.body, { type: 'view' }).then(function(canvas) {
var img = canvas.toDataURL("image/png");
$('.ticket-img').attr('src', img);
});
There is no such option as { type: 'view' }. If you are trying to capture just what is visible to the user there isn't an exact settings for that.
I'd probably say you'd need to process the output after the screenshot was taken. So take the screenshot then use the window scrollX/scrollY and window width/height to crop the resulting canvas.
Something like
function clip( srcCanvas, x, y, width, height ) {
var destCanvas = document.createElement("canvas");
var destCtx = destCanvas.getContext("2d");
destCanvas.width = width;
destCanvas.height = height;
destCtx.drawImage( srcCanvas.getImageData(x,y,width,height), 0, 0 );
return destCanvas;
}

Javascript SVG clipto with clip rule (fabricjs)

There is the exemple in img
http://imgur.com/rFdcctc
I have a background where i put an image (phone case).
After that i put a rectangle on the top side (50% top). (canvas)
On that i put an svg that is an another mask (that follow the case curves).
The svg is the same as the entire background in size. So to only have the top of the SVG i "clip" a rectangle on to it.
var clipTo = function(ctx) {
var w = mask.width, h = mask.height;
var x = -w/2, y = -h/2;
var rx = 0, ry = 0;
ctx.moveTo(x+rx, y);
ctx.lineTo(x+w-rx, y);
ctx.lineTo(x+w, y+(h/2)-ry);
ctx.lineTo(x+rx,y+(h/2));
ctx.lineTo(x,y+ry);
ctx.closePath();
};
mask.setClipTo(clipTo);
And it works fine. But when i put a dragable image on it the image is mask by the SVG but not the clip rectangle, as if the clip is still there. (in the image, the content of the red rectangle should be invisible)
I have found that there is a clip-rule :
https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/clip-rule
that could maybe with luck enventually should do it, but i have no idea how to apply it in javascript (i use fabricjs)
So if someone has an idea... :)
Thank you

paper.js removeOnDown(); within node.js & socket.io

I use Paper.js 0.9.18 and node socket.io 1.0.6 to build a collaborative board.
At mouse down a .png image will draw in canvas and it's visible for all connected users.
With a second mouse click, a new png image will be drawn to any new position on the canvas (visible for all users) and the first image will be removed simultaneously (but "local" only).
path.removeOnDown();
http://paperjs.org/reference/path/#removeondown
this works fine for the active user on his own canvas only. But the .png image for all other users will not removed. My question is, how does Paper.js's .removeOnDown(); works within node & socket.io? Any ideas? Maybe there are other ways to realize that?
The paper script I use
assets/js/script.js:
function onMouseDown(event) {
var x = event.point.x;
var y = event.point.y;
var rotate = ff;
drawAircraft( x, y, rotate);
// Pass the data for this position and rotate of the png image
// to a special function for later
emitAircraft( x, y, rotate);
}
function drawAircraft( x, y, rotate ) {
// Render the circle with Paper.js:
var raster = new Raster('./assets/img/Black-Aircraft-Icon.png');
raster.position = [x,y];
raster.scale(0.2);
raster.rotate(rotate);
// Refresh the view, so we always get an update:
view.draw();
// Remove the path (raster), next time the mouse is pressed:
raster.removeOnDown();
}
// An object to describe the aircraft draw data
function emitAircraft( x, y, rotate ) {
var data = {
x: x,
y: y,
rotate: rotate
};
// send a 'drawAircraft' event with data to the server
socket.emit( 'drawAircraft', data)
console.log( data )
}
socket.on( 'drawAircraft', function( data ) {
console.log( data );
// Draw the circle using the data sent from another user
drawAircraft( data.x, data.y, data.rotate );
})
html:
<canvas id="draw" resize="true" keepalive="true"></canvas>
<script src="assets/js/paper-full.js"></script>
<script type="text/paperscript" src="assets/js/script.js" canvas="draw"></script>
Thanks to all in advance
Sun

INDEX_SIZE_ERR when drawImage on canvas

I need to draw an Image object to a canvas but I've got an INDEX_SIZE_ERR exception in Firefox and IE10 but not in Chrome nor Safari...
According to the W3C: If one of the sw or sh arguments is zero, the implementation must raise an INDEX_SIZE_ERR exception..
Here is the code that causes the problem:
function writePhotoOnCanvas(data, width, height) {
// Get the canvas
var canvasGallery = document.getElementById("canvasGallery");
// Clear the canvas
canvasGallery.width = canvasGallery.width;
// Get its context
var ctxCapture = canvasGallery.getContext("2d");
// Create an image in order to draw in the canvas
var img = new Image();
// Set image width
img.width = width;
// Set image height
img.height = height;
// To do when the image is loaded
img.onload = function() {
console.log("img.width="+img.width+", img.height="+img.height);
console.log("width="+width+", height="+height+", canvasGallery.width="+canvasGallery.width+", canvasGallery.height="+canvasGallery.height);
// Draw the picture
try {
ctxCapture.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvasGallery.width, canvasGallery.height);
} catch(e) {
console.error(e.message);
}
};
// Set image content from specified photo
img.src = data;
}
The console shows:
img.width=640, img.height=480
width=640, height=480, canvasGallery.width=589, canvasGallery.height=440
Index or size is negative or greater than the allowed amount
What is the source of the problem?
Thanks
You are manually setting the width and height of the image (img.width = width; img.height = height;). I don't really understand why you are doing this, but it is likely unnecessary.
These should be calculated automatically from the image data you load. Try to remove them to see what the actual size of the data is.
The image width and height are read-only properties so they will cause the code to break in some browser.
If you absolutely want to set the width and height before loading the image you can do:
var img = new Image(width, height);
Then you can read img.width and img.height when image has loaded (or read img.naturalWidth and img.naturalHeight to get the original dimension).
There is no need though to do this. Simply call your drawImage() like this:
ctxCapture.drawImage(img, 0, 0, canvasGallery.width, canvasGallery.height);
This will use the full dimension of the image and scale it to the canvasGallery's dimension.
Tip: If you are using this function to load several images you will want to exchange img with this inside your onload handler.
Modified code:
function writePhotoOnCanvas(data, width, height) {
var canvasGallery = document.getElementById("canvasGallery");
var ctxCapture = canvasGallery.getContext("2d");
/// setting width to clear does not work in all browser, to be sure:
ctxCapture.clearRect(0, 0, canvasGallery.width, canvasGallery.height);
var img = new Image();
img.onload = function() {
// Draw the picture
try {
ctxCapture.drawImage(this, 0, 0,
canvasGallery.width, canvasGallery.height);
} catch(e) {
console.error(e.message);
}
};
// Set image content from specified photo
img.src = data;
}

Categories

Resources