I am looking for a way to capture the complete canvas (including elements that are moved outside the canvas) to an image. I am using the KineticJS library and I am aware of the toDataURL function. The problem is that the image is clipped to the canvas bounds.
As a workaround I thought to copy all elements on the canvas to a temporary hidden canvas which is big enough to fit all elements and then use the toDataURL function. I was wondering if there is a cleaner approach?
Interesting problem. I like the temporary canvas idea. Also, you could just resize the main canvas, apply an offsetting translation to all child elements, capture the image, then reverse-translate and resize back. This wouldn't be any more complex than copying to a hidden canvas. Plus, the single canvas approach would be more memory efficient.
Just my 3 cents.
I would agree with Alvin, you could just resize the canvas, here's how:
stage.setWidth(window.innerWidth); // inner width of your window
stage.setHeight(window.innerHeight); // inner height of your window
stage.draw(); //redraw
This would resize your stage to the width and height of your window, but this would not account for the possibility that elements would be farther than your window, but you can just modify the number inside the .set functions to account for the farthest right/left one.
If you were looking for a quick way to copy all elements in your canvas to another stage you could serialize it:
var json = stage.toJSON();
var newStage = Kinetic.Node.create(stageJson, 'newContainer');
Related
I'm trying to create a matrix of canvases which each would be the size of the device-width and device-height. The idea is to have this matrix from where the view would move from canvas to canvas by pressing a button. So basically you would only see one canvas at a time, and others would locate up/down and left/right out of the screen.
I'm really new to javascript and webdesign so I'm not sure if the canvas element is the best way to do this at all. I don't have any code to show because I just started this project and wanted to ask first to get it right from the begining.
Is the approach of multiple canvases a good way to go or what would be better option and how to do it?
Thanks!
This is a small start to get you started with how you can make canvas elements dynamically. You should look at W3 Schools for reference on how to edit DOM elements. Create element in the DOM.
window.onload = function() {
var canvasElements = [];
var canvas1 = document.createElement("canvas");
canvas1.id = "canvas1";
canvasElements.push(canvas1);
}
What you want in your solution
1) Make a CSS class with full width and height of the page.
2) Add canvas elements dynamically to the page using JavaScript and DOM manipulation.
3) For each canvas, add it to the DOM, and do the logic you want with it (render elements and draw circles / images whatnot). This will require a lot of JavaScript, so I would suggest you start out simple with a single canvas.
I hope that gets you going.
1) I'm caching a container filled with objects and then getting the canvas with .cacheCanvas in easel. I use this canvas as a bitmap image for my background (for performance reasons).
2) When I want to make minor changes to the image, rather than re-caching the large container, I get the context('2d') of the cachedCanvas(that I store in an easel Bitmap() ) and I draw onto the cachedCanvas.
The issue i'm having is when I draw onto the context of a cachedCanvas, it seems like the canvas is shared with the container and the bitmap, so when I do step 2) all of the imageDraws that I do are also done to the container. After repeating step 1) I want just the container and it's objects. (Not all of the context.draws that I did in step 2) )
TLDR: Is there a proper way to draw on a cachedCanvas, but also have the ability to revert to the original cachedCanvas?
This was solved by using uncache();
I would like to create an element, that shows a red circle. Once the user clicks on it, she can record her voice. In order to show the LIVE mode, I'd like to make the circle "breath" according to the incoming frequencies.
I'm experimenting with a <canvas> element. That means it creates a circle that gets bigger and smaller, depending on the variable arcrad. However, the lines are being drawn correctly, but they do not disappear afterwards. I tried to apply .clip() but can't get it to work...
if (arcrad <= 10) arcrad = 10;
analyserContext.beginPath();
analyserContext.arc(100,120,arcrad,0,2*Math.PI);
analyserContext.closePath();
analyserContext.lineWidth = 2;
analyserContext.strokeStyle = 'red';
analyserContext.stroke();
Any ideas - or completely different strategies for this use case?
Canvas will overdraw by default. For your animation you’ll need to clean the canvas at the start of each frame. Use something the following at the start of your drawing function:
analyserContext.clearRect(0,0,200,200);
assuming your canvas is 200 pixels wide and high. It’s worth pointing out that sometimes you don’t want to completely clear the animation field every frame. For example, if you were to draw a semi transparent rectangle over the frame at the beginning (instead of clearing it) then you’d end up with a basic ‘bullet time’ style effect.
It's a normal behavior. Once something it's drawn on the canvas, it's there forever. You have to think like if you were painting something: what has been done cannot be undone.
Luckily, you still have solutions:
1) redraw another circle on top of the first one with the background color. It's really not the recommend way, but it still can be useful
2) use clearRect method (see How to clear the canvas for redrawing)
There are numerous ways to clear a canvas pre drawing to create animation:
How to clear the canvas for redrawing
simplest in my mind:
canvas.width=canvas.width;
though can equally use clearRect (which is actually quicker and won't reset the entire canvas if that is an issue regarding transforms etc!) over the region or whole canvas.
Get the likes of:
http://jsfiddle.net/dw17jxee/
I have a polygon object (say a car) drawn inside a HTML5 canvas with help of methods moveTo and lineTo. I want to repeatedly draw that object at different positions in the canvas (simulating a moving object). My problem is that the previous drawn object is not getting cleared. Instead, multiple images are drawn on the canvas. How can I fix this issue?
You have to clear the canvas at the start of every draw frame
context.clearRect(0, 0, canvas.width, canvas.height);
Canvases are just arrays of pixels, they know nothing of the shapes you have drawn.
There are animation tricks that used to be used on bitmapped displays (e.g. "xor drawing") that can be used to remove the old shape before you draw the new one, but on modern machines it's generally far simpler (and perfectly fast) to just erase the canvas and start again for each frame.
Given your comments to other answers, I'd suggest just using two Canvases - one for the static background and one for the car. If the background image is static it could even be an <img> element instead of a Canvas.
If the car image is static you could also just draw that once, and then use CSS positioning to set its position relative to the background for each frame.
suppose your shape is car then you first have to assign a new graphic like:
car.graphics = new createjs.Graphics();
car.graphics
.setStrokeStyle(1)
.beginStroke("#000000")
.moveTo()
.lineTo()
.lineTo()
I'm creating a HTML Canvas object using this javascript code:
var Canvas = document.createElement("canvas");
Canvas.style.width = "500px";
and then i'm drawing text upon it.
When the canvas is displayed, the whole canvas has been scaled up (including content) to to match the 500px width, which results in ugly resampling. What i really want, is that the content stay the same size, only the canvas itself made bigger.
Any ideas?
Try changing the element’s width instead of its CSS width.
Canvas.width = 500;
Thomas' answer is correct, but it sound's like you also want to keep the existing content on the canvas. When you change the canvas size, it automatically gets cleared and reset to it's default state. Because of that, you will either need to redraw the contents, or copy the contents to another canvase (using drawImage), resize the canvas, then copy the contents back (again, using drawImage).