I'm currently trying to create a page with dynamically generated images, which are not shapes, drawn into a canvas to create an animation.
The first thing I tried was the following:
//create plenty of those:
var imageArray = ctx.createImageData(0,0,16,8);
//fill them with RGBA values...
//then draw them
ctx.putImageData(imageArray,x,y);
The problem is that the images are overlapping and that putImageData
simply... puts the data in the context, with no respect to the alpha channel as specified in the w3c:
pixels in the canvas are replaced wholesale, with no composition, alpha blending, no shadows, etc.
So I thought, well how can I use Image
s and not ImageData
s?
I tried to find a way to actually put the ImageData
object back into an image but it appears it can only be put in a canvas context. So, as a last resort, I tried to use the toDataURL()
method of a 16x8 canvas(the size of my images) and to stick the result as src
of my ~600 images.
The result was beautiful, but was eating up 100% of my CPU...(which it did not with putImageData
, ~5% cpu) My guess is that for some unknown reason the image is re-loaded from the image/png
data URI each time it is drawn... but that would be plain weird... no? It also seems to take a lot more RAM than my previous 开发者_如何学运维technique.
So, as a result, I have no idea how to achieve my goal.
How can I dynamically create alpha-channelled images in javascript and then draw them at an appreciable speed on a canvas?
Is the only real alternative using a Java applet?
Thanks for your time.
Not knowing, what you really want to accomplish:
Did you have a look at the drawImage
-method of the rendering-context?
Basically, it does the composition (as specified by the globalCompositeOperation
-property) for you -- and it allows you to pass in a canvas element as the source.
So could probably do something along the lines of:
var offScreenContext = document.getCSSCanvasContext( "2d", "synthImage", width, height);
var pixelBuffer = offScreenContext.createImageData( tileWidth, tileHeight );
// do your image synthesis and put the updated buffer back into the context:
offScreenContext.putImageData( pixelBuffer, 0, 0, tileOriginX, tileOriginY, tileWidth, tileHeight );
// assuming 'ctx' is the context of the canvas that actually gets drawn on screen
ctx.drawImage(
offScreenContext.canvas, // => the synthesized image
tileOriginX, tileOriginY, tileWidth, tileHeight, // => frame of offScreenContext that get's drawn
originX, originY, tileWidth, tileHeight // => frame of ctx to draw in
);
Assuming that you have an animation you want to loop over, this has the added benefit of only having to generate the frames once into some kind of sprite-map so that in subsequent iterations you'll only ever need to call ctx.drawImage()
-- at the expense of an increased memory footprint of course...
Why don't you use SVG?
If you have to use canvas, maybe you could implement drawing an image on a canvas yourself?
var red = oldred*(1-alpha)+imagered*alpha
...and so on...
getCSSCanvasContext seems to be WebKit only, but you could also create an offscreen canvas like this:
var canvas = document.createElement('canvas')
canvas.setAttribute('width',300);//use whatever you like for width and height
canvas.setAttribute('height',200);
Which you can then draw to and draw onto another canvas with the drawImage method.
精彩评论