I have a very simple question : is it possible to use globalCompositeOperation for only a restricted number of images?
For example, I draw a lot of stuff into my canvas. And on top of everything, and completed unrelated, I want to do some operations on two images (and I just want the result to be displayed, not both images). How can that be done?
For now, doing such operations affects everything that's already drawn underneath.
So a solution I found is doing the operations in another canvas, which I display on top of my main, first canvas. But this looks bad. First, it hits performances. Then, it doesn't feel intuitive. And last, I loose control over the layers : whatever is in my second canvas will always be on top of the first canvas.
This looks like a pretty simple feature, I hope I'm just bad at googling!
Thanks a lot!
Create a offscreen canvas and use it as a work space. You can create many as long as you have the RAM to store them.
To create an offscreen canvas
function createCanvas(w,h){
var canvas = document.createElement("canvas");
canvas.width = w;
canvas.height = h;
canvas.ctx = ctx.getContext("2d");
return canvas;
}
Easy as that and then you just treat it as an image. To draw to another canvas
var offScreenCan = createCanvas(1024,1024);
offScreenCan.ctx.drawImage(myImage); // put something on the canvas
ctx.drawImage(offScreenCan,0,0); // draw that canvas to another
I attach the context to the canvas rather than wrap the canvas in a containing object. I used to worry that the canvas would affect performance now I convert all images to canvas as soon as I load them and it does not impact performance at all.
Related
I am trying to verify that this happens no matter what, and there's no way to bypass it. It seems pretty silly to me that createjs uses this architecture. But I noticed that creating a stage from an existing canvas element removes all shapes, writings, etc from the canvas? Code is below:
html:
<canvas id="canvas" width="800" height="400"></canvas>
js:
var canv = document.getElementById("canvas");
var stage = new createjs.Stage(canv);
var ctx = canv.getContext('2d');
ctx.beginPath();
ctx.arc(50,50,10,0,2*Math.PI);
ctx.stroke();
createjs.Ticker.addEventListener("tick", tick);//circle created is overwritten here!!!?! Why createjs!?
//stage.update();
createjs.MotionGuidePlugin.install();
var shape1 = new createjs.Shape();
shape1.graphics.f("#000000").dc(0,0,10);
var path1 = new createjs.Shape();
path1.graphics.beginStroke("#ff0000").mt(0,0).qt(50,100,100,0);
stage.addChild(path1, shape1);
createjs.Tween.get(shape1).to({guide:{ path:[0,0, 50,100, 100,0] }},2000, createjs.Ease.cubicInOut);
function tick(event) {
stage.update();
}
Is this something that cannot be bypassed? It seems silly to me that createjs wouldn't just actually use the existing element unerased. If not, what is the point in passing in an element in the first place, why doesn't it just create a canvas element, and give you the ID? Anyways, if this is how it's going to be, unfortunately, I am going to have to go somewhere else. Sad, because createjs seemed pretty useful.
CreateJS uses a retained graphics mode, that is, it stores the state and redraws it each time. This is because the canvas is basically a big Bitmap with drawing commands – clearing the stage is the only way to remove the previous state.
But good news! There are lots of ways to get around these limitations if you want to blend CreateJS content with other content, or even make additive drawing effects.
The first is easy, which is setting autoClear. This will prevent the clear, and just draw the new contents over the old one.
stage.autoClear = false;
The second is a bit tougher, but great for instances where you want to mix CreateJS content with other libraries or effects. You can basically use the other canvas as the source to a Bitmap you include in CreateJS:
// Create a child for CreateJS referencing the other canvas
var bmp = new createjs.Bitmap(otherCanvas);
// Add it at the bottom (or top or wherever) in your new CreateJS canvas
stage.addChildAt(bmp, 0);
This is a great approach because it lets you put your content wherever you want, edit it separately, etc.
If you have a different case this doesn't cover, let me know and I can try to make a recommendation!
Cheers.
This may be off topic but I'm not sure where else to go with this question. I'm just getting started with HTML5 canvas element and all of the incredibly powerful things it can do. I was hoping someone could offer some advise. When working with custom paths and bezier curves, what is the easiest/best way to visualize where the points belong on the canvas to achieve a desired effect. Right now it feels like I'm just guessing plotting points in any place hoping to end up with the right angle/shape that I want.
To be more specific I want to create a shape that will act as an image mask, and will later need to animate this shape. Much like this fiddle http://jsfiddle.net/jimrhoskins/dDUC3/1/ (someone else's work) but since I can't see where the picture is on the canvas or where any of the points are, I'm really just guessing at the approximate shape I need to make. I'm just wondering if there's a better way, or some function in javascript that can map the location of an image and give me at least a better place to start.
Here is what I know/have tried already
// Grab the Canvas and Drawing Context
var canvas = document.getElementById('c');
var context = canvas.getContext('2d');
// Create an image element
var img = document.createElement('IMG');
// When the image is loaded, draw it
img.onload = function () {
// Save the state, so we can undo the clipping
context.save();
// Create a shape, of some sort
context.beginPath();
context.moveTo(somex, somey);
context.bezierCurveTo(somexstart, someystart, somexcontrol, someycontro, somexend, someyend);
context.arcTo(somecoordinates);
context.closePath();
// Clip to the current path
context.clip();
context.drawImage(img, 0, 0);
// Undo the clipping
context.restore();
}
// Specify the src to load the image
img.src = "url";
How about opening the image in an SVG editor. Drawing a path on a layer above the image. Then open the SVG and copy the coordinates?
Try an SVG Editor. You can get the points there. You can add images too. SVG animation is used nowadays as well. If you have Adobe Illustrator, it will be easier to draw there and just save it as SVG.
For a Project I want to take the content of a canvas (Called SAVE_CV) and display it in another, smaller canvas.
Some things that I am aware of so far that could be causing me problems: resizing a canvas clears its content, the JS-size of a canvas is different from the CSS-size.
I want the smaller canvas to be 500px wide and appropriately high.
function restoreTaggingCV() {
var cv = document.getElementById( 'taggingCV' );
var ctx = cv.getContext( "2d" );
var styleHeight = SAVE_CV.height * 500 / SAVE_CV.width;
ctx.drawImage(SAVE_CV, 0, 0, cv.width, cv.height);
}
This is my Code so far. Whenever I try to resize the smaller canvas appropriately it only gives me a blank canvas with nothing in it. I tried to set the size with "cv.height = X" and "cv.style.height = styleHeight + 'px'" but neither worked. Also I would love to set the width of the canvas using CSS.
Appreciate any help.
EDIT
I want the image in a picture because later I want the user to mark areas in the smaller version which I then want to use to create individual imaged from the big version. I want to visualise thise area to the user. I probably could do all this by using an image and putting divs over it or something but I just fell more comfident using a canvas since I am pritty new to HTML and CSS.
Try using the CanvasRenderingContext2d.prototype.scale method. It sets the scale factor of the canvas and renders anything in the current state with it's dimensions multiplied by the factor.
So before you use the drawImage function, you scale the context appropriately (in this case, down). For example:
context.save();
context.scale(0.5, 0.5);
context.drawImage(canvas, 0, 0);
context.restore();
This would render the canvas on the context at 0.5 times it's current size. See in this fiddle how I used it to mirror a larger canvas onto a smaller, separate one.
Canvas objects don't like to be resised. After drawing Your image simply convert it toDataURL() and set as image source. They You may resize image as you want.
$img.attr('src',canvas.toDataURL());
I am trying to grab a particular part of the canvas and then put that image back onto the canvas in a very particular way. However, it seems that the get and put ImageData methods work on an absolute canvas that is not affected by image manipulations. Is there any way to use translations with the get and put dataImage operations in HTML5?
I have a line drawing that occurs at an angle and I want to capture that image, put it on its own canvas, do some processing on it, and then put it back on the canvas at that exact angle and position. I originally thought I could do this by repositioning the canvas based on the position and angle of the drawing, but this did not work because get and put dataImage use absolute rather than relative coordinates.
You could send the data to an image, and draw the image to the new canvas for processing. That way, you will get what appears on the canvas, exactly as it appears.
var img = new Image();
img.onload = function(){
processingCanvas.width = this.width;
processingCanvas.height = this.height;
processingCanvas.drawImage(this,0,0);
}
img.src = originalCanvas.toDataURL();
And boom, it's on your processing canvas (after you wait for it some). As long as you don't have an absolutely HUGE canvas, this method should work rather quickly. Just get everything you want, and make sure it is visible on the canvas. And then you know how to get the processed data back to the other canvas. I hope this was what you were looking for.
Hi I am playing around with shapes and canvas and I have a question:
So say I have this code that draws a nice rectangle on the canvas:
$("#create_rectangle").bind("click", function() {
if(canvas[0].getContext){
var ctx = canvas[0].getContext('2d');
ctx.strokeRect(50,50,50,50);
}
});
Now I say I want to store a reference to that rectangle so that I can make alteration to it at a later stage. The stokeRect() method does not seem to return any value. How do I reference that particular rectangle that was created?
Well you can't reference it, but you can include it in a draw function which depending your arguments allow you to move/rotate hide etc.
It very depend on what you want to do with this shape.
This tutorial can be helpfull to understand manipulation of shape.
http://simonsarris.com/blog/140-canvas-moving-selectable-shapes
You can't.
Canvas is basically just a canvas. You throw some paint at it, it dries and you're done. You can't take your paint and move it somewhere else—but you can paint over it.
What you may want is SVG. It keeps track of shapes and other assorted things so that you can change them, deal with interactions much more precisely, et cetera.