canvas is cleared on mousedown, sketch.js & jquery 2.0.0 - javascript

11I'm using sketch.js from here: http://intridea.github.io/sketch.js/ and jquery 2.0.0
On my page, I have a list of images presented like so:
<img src="http://url.to/image"><br><span class="background">click for background</span>
and a canvas, set up like so:
<canvas id="simple_sketch" style="border: 2px solid black;"></canvas>
relevant JavaScript:
var winwidth = 800;
var winheight = 600;
$('#simple_sketch').attr('width', winwidth).attr('height', winheight);
$('#simple_sketch').sketch();
$('.background').on('click', function(event) {
event.preventDefault();
var imgurl = $(this).parent().attr('href');
console.log('imgurl: ' + imgurl);
var n = imgurl.split('/');
var size = n.length;
var file = '../webkort/' + n[size - 1];
var sigCanvas = document.getElementById('simple_sketch');
var context = sigCanvas.getContext('2d');
var imageObj = new Image();
imageObj.src = imgurl;
imageObj.onload = function() {
context.drawImage(this, 0, 0,sigCanvas.width,sigCanvas.height);
};
alert('background changed');
});
Backgrounds are changed just as I want them to, but whenever I click on the canvas, the backgound image is cleared. As per a suggestion on this thread: html5 canvas background image disappear on mousemove I commented out this.el.width = this.canvas.width(); on line 116 of sketch.js, but to no avail.
Any help appreciated!
EDIT: jsfiddle: http://jsfiddle.net/RXFX4/1/
EDIT: Couldn't figure out how to do this with sketch.js, so instead went with jqScribble (link posted in comments) which has the ability to do this as a built-in function instead.

Find this line on the library - sketch.js and delete/comment it out.
this.el.width = this.canvas.width();
Good luck

Assign the url on the image source after the onload event. If the image is already loaded, the event is probably firing before you are hooking it. Which means that your drawImage is never being called.
var imageObj = new Image();
imageObj.onload = function() {
context.drawImage(this, 0, 0,sigCanvas.width,sigCanvas.height);
};
imageObj.src = imgurl;
EDIT: I'm going to take a shot in the dark here, since I'm not familiar with sketchjs
I'm thinking that your problem is that you are completely re-render the canvas when you click your 'change background' link. Notice that if you draw, then click the change background, you lose your drawing.
However, notice that once you click again, the background disappears, and you get your original drawing back again. This tells me that sketchjs is keeping track of what has been drawn on it's own in-memory canvas, and then it drops it onto the target. The problem, then, is that when this in-memory canvas is drawn, it completely replaces the contents of the target canvas with it's own.
I notice in some of the sketchjs examples, if you want a background they actually assign the canvas a background style. In your example, you are drawing the background directly onto the canvas. The prior probably works because sketchjs knows to incorporate the background style when it draws. However, it does not know that when you drew your fresh background image, it should be using that.
Can you just change the background style on the canvas element, instead of drawing directly on the canvas?

Related

simple HTML5 canvas image not displaying

I'm new to this - I just can't figure out why this isn't working. When I remove Display:none from HTML, the image works correctly so I know the path to the image is correct. But it's not drawing on the canvas. Thanks for your time.
HTML:
<canvas width="840" height="900" id="Canvas6">
Your browser does not support this feature.
</canvas>
<img src="image/logo.png" id="img1" width="825" height="272" style="display:none;">
<script type="text/javascript" src="js/main.js"></script>
Main.JS JAVASCRIPT:
var theCanvas = document.getElementById('Canvas6');
if (theCanvas && theCanvas.getContext) {
var ctx = theCanvas.getContext("2d");
if (ctx) {
//Create a variable to hold our image
var srcImg = document.getElementById("img1");
//Draw an image directly onto the canvas
ctx.drawImage(srcImg, 0,0);
//Draw a scaled down image
//drawImage(srcImg, dx, dy, dw, dh)
}
}
In html file, the first best thing you have done is used the 'script' tag right at the end of the html file.
This ensures that the "Critical Render Time" is minimized, and the display items in HTML are shown first. (Not a huge impact on this case, because here you are using the JS to draw/display, but this approach is really good when you use your js for other purposes like calculations etc., and you don't want to stop the other HTML items from displaying because of an ongoing calculation.)
Now that the canvas is ready, its time to throw the image on the canvas.
Try using the border property (style="border: 2px dotted black") to see the container area of the canvas.
Hmmm !! But the image doesn't show in canvas. WHY ??
Images(or any other files) take atleast some time to get processed. By the time they are getting processed to be loaded on the screen, your canvas is already getting displayed. Hence you see an empty canvas.
So, the solution is to make everything else wait, till the time image gets loaded.
How do we do that ? Just use the "Event Listener".
EventListener is the property of Window object. (window.addEventListener("load", some_func_to_run , false);). We generally use this, when we want our window/page/browser to wait for something, but hey , we can use it for our images as well.
var cvs = document.getElementById("canvas"); // Getting the control of the canvas
var ctx = cvs.getContext("2d"); //Getting the control of the useful HTML object getContext . This object brings in a lot of useful methods like drawImage, fillRect etc.
//create images
var bg = new Image(); // Creating image objects
bg.src = "images/bg.png"; //Setting the source file
//create images ends
//load images first
bg.addEventListener("load" , draw , false); //**IMPORTANT : Just remove this line and you will start facing this problem of empty canvas again
//loading images ends
function draw() {
ctx.drawImage(bg,0,0); // Putting the image and its coordinates on the canvas
}
draw(); // Calling the draw function to put the image on canvas
<html>
<body>
<canvas id="canvas" width="288" height="512" style="border: 2px dotted black"> </canvas>
<script src="flappyBird.js"></script>
</body>
</html>
So, it all about using Event Listener and asking everything to wait till the image gets loaded.
Hope this help. :)
If you try to place an image on a Canvas before it has loaded, it will not show. It is not like the img tag that will show the image whenever it loads. I surrounded your JS with an onload and it worked for me.
document.getElementById("img1").onload = function() { /* Your JS */ };
You have to wait for the image to load before you can draw it on the canvas, so set your drawing code to run on the window load event (by which time all images are loaded). Also, you don't need to include the markup for the image on the page, where you have to then prevent it from displaying with CSS. You can just create the image object and set the source attribute in the javascript. For example:
var img = document.createElement('img');
img.src = 'image/logo.png';
window.addEventListener('load', function(){
var theCanvas = document.getElementById('Canvas6');
if (theCanvas && theCanvas.getContext) {
var ctx = theCanvas.getContext("2d");
if (ctx) {
ctx.drawImage(img, 0,0);
}
}
});

Image not being drawn on canvas as expected from dyantree onActivate event handler

I have an image that I want to display when a non-folder node is activated.
Expand the folder node.
Click on a non-folder node and that node's image will not be displayed as expected.
Click on a node that is different from the node in the previous step then click on the node from the last step and that node's image will be displayed as expected.
For some reason a node's image will not be displayed until the onActivate event is fired for that node at least at least twice (i.e. by visiting another node, then coming back to the node in question).
I tried several ways of getting around this. The only way that that worked for me was to use the onRender event handler instead of onActivate, but that considerably reduces the speed of the tree in production (potentially 5000+ nodes displayed at any given time).
I also believe I have followed all the recommendations #pimvdb provided in his answer to a similar question here and here, but to no avail. I have tried setting the image src before and after declaring the onload function, but it doesn't seem to matter either way.
Any pointers would be appreciated.
jsFiddle
Dyantree
P.S. After you see this problem once you may have to clear your cache to see it again.
Apparently the image(s) were loading fine, the problem was how/when I was resizing the canvas for the image. Here is a jsFiddle with the fix. I changed this...
function loadImage(node) {
var imageObj = new Image();
imageObj.onload = function() {
ctx.drawImage(imageObj, 0, 0);
};
imageObj.src = node.data.imageUrl;
canvasObj.attr("height", imageObj.height + "px");
canvasObj.attr("width", imageObj.width + "px");
}
to this...
function loadImage(node) {
var imageObj = new Image();
imageObj.onload = function() {
canvasObj.attr("height", imageObj.height + "px");
canvasObj.attr("width", imageObj.width + "px");
ctx.drawImage(imageObj, 0, 0);
};
imageObj.src = node.data.imageUrl;
}

swapping div with canvas elements using javascript

I have 2 div. Every div has a canvas element. At the beginning of my program I put an image on the canvas. The images are different. Then I try to swap the divs using
var contentofmyfirstdiv = $('#myfirstdiv').html();
var contentofmyseconddiv = $('#myseconddiv').html();
$('#myseconddiv').html(contentofmyfirstdiv);
$('#myfirstdiv').html(contentofmyseconddiv)
;
All works except that every canvas is empty. It seems the "contentof..." didn't get the image from the canvas... Anyone knows how to swap the content of the canvas? I am using Firefox.
You are serializing to html and reparsing it, this is lossy operation. Instead you should operate
on the live DOM tree directly:
var contentofmyfirstdiv = $('#myfirstdiv').children().detach();
var contentofmyseconddiv = $('#myseconddiv').children().detach();
$('#myseconddiv').append(contentofmyfirstdiv);
$('#myfirstdiv').append(contentofmyseconddiv)
Here's a demo that doesn't do justice but nevertheless http://jsfiddle.net/9JdqQ/
What's retained compared to serialization are unserializable attributes, event listeners, element data (canvas image etc)..
If you are only using images to draw on the canvas there is really no need for the canvas - you could just use the images directly and swap those.
However, if you need to use canvas for other reasons you can extract the data directly from one, draw the other canvas to this, and then put the data from the first to the second.
This method shows a way that doesn't need DOM manipulation.
One option using a new canvas as a swap:
var temp = document.createElement('img');
temp.width = canvas1.width;
temp.height = canvas1.height;
//swap
var tempctx = temp.getContext('2d');
tempctx.drawImage(canvas1, 0, 0);
ctx1.drawImage(canvas2, 0, 0);
ctx2.drawImage(temp, 0, 0);
The other method using an image element as a swap:
var temp = canvas1.toDataURL();
ctx1.drawImage(canvas2, 0, 0);
var img = document.createElement('img');
img.onload = function() {ctx2.drawImage(this, 0, 0);}
img.src = temp;
The latter not optimal in speed as you need to compress and encode the data-uri.
Note that this example assume the images being of the same size. If the images are of different sizes you will need to handle this as well by setting canvas1 and 2 to the correct sizes after the image is copied to swap and before you redraw.
swap = canvas1
resize canvas1 = canvas2
draw canvas2 to canvas1
resize canvas2 = swap
draw swap to canvas2

Add image to canvas using paper JS

I used normal javascript to add image to canvas and this is the code
var canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
canvas_image();
function canvas_image(){
can_img = new Image();
can_img.src = 'Chrysanthemum.jpg';
can_img.onload = function(){
context.drawImage(can_img, 100, 100);
}
}
How can i add image to canvas using paperJS library?
Quoting from the paperjs.org tutorial on rasters:
Images need to already be loaded when they are added to a Paper.js project. Working with local images or images hosted on other websites may throw security exceptions on certain browsers.
So you need an image somewhere that is preferably visually hidden:
<img id="mona" class="visuallyhidden" src="mona.jpg" width="320" height="491">
And the PaperScript code could look like this:
// Create a raster item using the image tag with id="mona"
var raster = new Raster('mona');
Then you can reposition, scale or rotate like so:
// Move the raster to the center of the view
raster.position = view.center;
// Scale the raster by 50%
raster.scale(0.5);
// Rotate the raster by 45 degrees:
raster.rotate(45);
And here is a paperjs.org sketch to play with.
First, If you want to work with JavaScript directly look at this tutorial.
Once you understand it, you would have something like this to load image in raster
paper.install(window);
window.onload = function() {
// Setup directly from canvas id:
paper.setup('myCanvas');
var raster = new paper.Raster({source: 'Chrysanthemum.jpg', position: view.center});
}

Problem with getImageData function

So, I'm using this function getImageData on the "context" variable that I've made inside of the <script> part, and when I do something such as draw a rectangle then do ctx.getImageData.data[0] it will show the red value of that rectangle that I drew on the canvas. But, when I import an image and draw it onto the canvas, and try to use the getImageData.data[0] all I get is 0, which makes no sense, I'm not sure why it is not reading the image correctly. I've tried tutorials on this but they're all vague and only have segments written together.
So, when I draw the rectangle, its color value comes out just fine, but again, when I draw the image, even without drawing the rectangle on the canvas, I never get the value of that particular pixel on the image.
Can someone help me? Here's my currrent code:
<html>
<head>
<title>
Color Test :)
</title>
</head>
<body>
<canvas id = "ColorTest" width = "500" height = "500">
please don't use shitty browsers :)
</canvas>
<script>
//netscape.security.PrivilegeManage…
var canvas = document.getElementById("ColorTest")
, ctx = canvas.getContext("2d")
, image = new Image()
image.onload = function(){
ctx.drawImage(image,0,0)
}
image.src = 'Pikachu.gif'
ctx.fillStyle = "rgb(123,40,170)"
ctx.fillRect(0,0,100,100)
var imagedata = ctx.getImageData(0,0,100,100)
, spot = 0
while(imagedata.data[spot] == 0){
spot++
}
console.log(imagedata.data[0])
</script>
</body>
</html>
Does the following alert anything sensible?
image.onload = function() {
ctx.drawImage(image, 0, 0);
var id = ctx.getImageData(0,0,canvas.width,canvas.height);
alert([id.data[0], id.data[1], id.data[2], id.data[3]].join(", "));
}
It could be that the image is transparent. Try with a single color non-transperent image.
What browser are you using? Using getImageData when loading an image from another domain is not allowed (security issue), and if I remember correctly there is some browsers that have problems determining the domain when running scripts localy

Categories

Resources